Click here to Skip to main content
15,894,180 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello Experts,
I have difficulties to establish communication with a microcontroller using CAN bus. My project has came into limit of a device hence I have to use multiple devices and controlling all of them via a CAN bus. Searching everywhere but no luck on helping me with CAN Layer2 API that I am using. I'm really new with CAN programming.

DLL used:
canL2.dll
Can_def.h
CANL2.H

Below example is C codes from Softing but I'm not sure how to use them with VC++.

Thanks in advance.
mraaf

What I have tried:

#include "can_def.h"  // dll import and export definitions
#include "canL2.h"    // definition of the API functions an the structures


main()
{
  int ret;
  CANL2_CH_STRUCT ch1, ch2;
  CAN_HANDLE can1, can2;
  L2CONFIG L2Config[2];
  char custom, *pName[2] = {NULL,NULL};
  PCHDSNAPSHOT pBuffer = NULL;
  unsigned long u32NeededBufferSize, u32NumOfChannels, u32ProvidedBufferSize, channelIndex;
  int sw_version, fw_version, hw_version, license, chip_type, i;


printf ("Analyzing your system ...\n");

  u32ProvidedBufferSize = 0;

  // call the function without a valid buffer size first to get the needed buffersize in "u32NeededBufferSize"
  ret = CANL2_get_all_CAN_channels(0, &u32NeededBufferSize, &u32NumOfChannels, NULL);

  if(!u32NumOfChannels)
  {
    printf("you have no Softing CAN interface card plugged in your Computer!\n");
    printf("plug a interface card first and start this program again after this.\n");
    custom=getch();
    exit(0);
  }

  if(ret)
  {
    printf("The driver reported a problem: Error Code %x\n", ret);
    custom=getch();
    exit(0);
  }
  
  
  pBuffer = malloc(u32NeededBufferSize);

  if(!pBuffer)
  {
    printf("Out of memory\n");
    custom=getch();
    exit(0);
  }

  u32ProvidedBufferSize = u32NeededBufferSize;

    
  ret = CANL2_get_all_CAN_channels(u32ProvidedBufferSize, &u32NeededBufferSize, &u32NumOfChannels, pBuffer);

  if(ret)
  {
    printf("The driver reported a problem: Error Code %x\n", ret);
    custom=getch();
    free(pBuffer);
    exit(0);
  }

  printf("You have %u Softing CAN channels in your system\n\n", u32NumOfChannels);

  printf("\tname\t\t serialnumber\t type\t\t chan.\t    open\n");
  printf("------------------------------------------------------------------------\n");
  printf("\n");

  for(channelIndex=0; channelIndex<u32NumOfChannels; channelIndex++)
  {
    PCHDSNAPSHOT pCh = &pBuffer[channelIndex];
    

    printf("% 17s\t %09u  % 18s\t %2u\t % 5s\n",
      pCh->ChannelName,
      pCh->u32Serial,
      getDeviceType(pCh->u32DeviceType),
      pCh->u32PhysCh,
      (pCh->bIsOpen) ? "yes" : "no");

    if(!pCh->bIsOpen)
    {
      if(ch<2)
      {
        pName[ch] = pCh->ChannelName;
        ch++;
      }
    }

  }
  
  if(ch < 2)
  {
    if(ch == 0)
    {
      printf("\nAll CAN channels are used by other applications!\n");
      printf("Type <return> to exit program!\n");
      custom=getch();
      free(pBuffer);
      exit(0);
    }

    printf("\nYou have only 1 channel plugged, the commands for the second channel will not \n");
    printf("be available!\n");
    printf("Type <return> to proceed!\n");
    custom=getch();
  }


  
  
  L2Config[0].bEnableAck = GET_FROM_SCIM;
  L2Config[0].bEnableErrorframe = GET_FROM_SCIM;
  L2Config[0].s32AccCodeStd = GET_FROM_SCIM;
  L2Config[0].s32AccCodeXtd = GET_FROM_SCIM;
  L2Config[0].s32AccMaskStd = GET_FROM_SCIM;
  L2Config[0].s32AccMaskXtd = GET_FROM_SCIM;
  L2Config[0].s32OutputCtrl = GET_FROM_SCIM;
  L2Config[0].s32Prescaler = GET_FROM_SCIM;
  L2Config[0].s32Sam = GET_FROM_SCIM;
  L2Config[0].s32Sjw = GET_FROM_SCIM;
  L2Config[0].s32Tseg1 = GET_FROM_SCIM;
  L2Config[0].s32Tseg2 = GET_FROM_SCIM;

  memcpy(&L2Config[1], &L2Config[0], sizeof(L2CONFIG));

  strcpy(ch1.sChannelName,pName[0]);

  if(ch > 1)
  {
    strcpy(ch2.sChannelName,pName[1]);
  }
  
  
/*
  strcpy(ch1.sChannelName,"Softing1");
  strcpy(ch2.sChannelName,"Softing2");
  */
  
  if(ch > 1)
  {
    printf("\ninitializing %s and %s\n", ch1.sChannelName, ch2.sChannelName);
  }
  else
  {
    printf("\ninitializing %s\n", ch1.sChannelName);
  }

  printf("Initialization started...\n");
  
  

  free(pBuffer);


  ret = INIL2_initialize_channel(&ch1.ulChannelHandle, ch1.sChannelName);

  if(ret)
  {
    printf("Error %u in INIL2_initialize_channel()\n",ret);
    custom=getch();
    return ret;
  }

  can1 = ch1.ulChannelHandle;

  if(ch > 1)
  {
    
    ret = INIL2_initialize_channel(&ch2.ulChannelHandle, ch2.sChannelName);
    
    if(ret)
    {
      printf("Error %u in INIL2_initialize_channel()\n",ret);
      custom=getch();
      return ret;
    }
    
    can2 = ch2.ulChannelHandle;
  }
  else
  {
    can2 = (CAN_HANDLE)INVALID_HANDLE_VALUE;
  }


  ret = PrepareForIntEvents(&L2Config[0], &can1, &L2Config[1], &can2);
  if(ret)
  {
    printf("Error %u in PrepareForIntEvents()\n",ret);
    custom=getch();
    return ret;
  }

  ret = CANL2_initialize_fifo_mode(can1, &L2Config[0]);
  if(ret)
  {
    printf("Error %u in CANL2_initialize_fifo_mode()\n",ret);
    printf("please configure the channel by the SCIM first\n");
    custom=getch();
      // use start->control panel->can for configuration of the card settings!
    return ret;
  }

  if(ch > 1)
  {
    ret = CANL2_initialize_fifo_mode(can2, &L2Config[1]);
    if(ret)
    {
      printf("Error %u in CANL2_initialize_fifo_mode()\n",ret);
      printf("please configure the channel by the SCIM first\n");
      custom=getch();
      // use start->control panel->can for configuration of the card settings!
      return ret;
    }
  }


  ret = CANL2_get_version(can1, &sw_version, &fw_version, &hw_version, &license, &chip_type);
  if(ret)
  {
    printf("Error %u in CANL2_get_version(CAN1)\n",ret);
  }


  printf("\n VERSION INFO CAN1: \n\n");
  printf("    - Software version: %u.%02u\n", sw_version/100, sw_version%100);
  printf("    - Firmware version: %u.%02u\n", fw_version/100, fw_version%100);
  printf("    - Hardware version: %x.%02x\n", hw_version/0x100, hw_version%0x100);
  printf("    - CAN chip        : %s\n", (chip_type==1000)? "SJA1000": (chip_type==161) ? "Infineon XC161" : "Infineon XE164");


  if(ch > 1)
  {
    
    ret = CANL2_get_version(can2, &sw_version, &fw_version, &hw_version, &license, &chip_type);
    if(ret)
    {
      printf("Error %u in CANL2_get_version(CAN1)\n",ret);
    }
    
    printf("\n VERSION INFO CAN2: \n\n");
    printf("    - Software version: %u.%02u\n", sw_version/100, sw_version%100);
    printf("    - Firmware version: %u.%02u\n", fw_version/100, fw_version%100);
    printf("    - Hardware version: %x.%02x\n", hw_version/0x100, hw_version%0x100);
    printf("    - CAN chip        : %s\n", (chip_type==1000)? "SJA1000": (chip_type==161) ? "Infineon XC161" : "Infineon XE164");
    
    
    
    printf("The 2 channels are online now!\n\n");
  }
  else
  {
    printf("\n\nThe CAN channel is online now, a second channel is not available!\n\n");
  }

  custom = 'h';
  do	// loop
		{
      
      Sleep(0);

      // User request	
      ret=UserRequestFIFO(custom, can1, can2);	
      
      // Loop till user request
      while (!kbhit()) 
      {
      }// end while
      
      custom=getch();
      
      if (ret < 0)	
      {
        printf("-->User request failed \n");
        INIL2_close_channel(can1);

        if(ch > 1)
        {
          INIL2_close_channel(can2);
        }

        return(-1);
      }
    } 
    while (custom != 'q');	// End inner loop

    SetEvent(hThreadEvents[1]);
    WaitForSingleObject(hIntThread[0], 2000);

    if(ch > 1)
    {
      SetEvent(hThreadEvents[3]);
      WaitForSingleObject(hIntThread[1], 2000);
    }

    for(i=0; i<((ch>1)? 2 : 1); i++)
    {
      CloseHandle(hIntThread[i]);
    }

    for(i=0; i<((ch>1)? 4 : 2); i++)
    {
      CloseHandle(hThreadEvents[i]);
    }

    INIL2_close_channel(can1);

    if(ch > 1)
    {
      INIL2_close_channel(can2);
    }

    return ret;
    
}
Posted
Updated 17-Apr-17 22:56pm

1 solution

To create a console application using a 3rd party DLL:
Create a new console application, copy the code into the _tmain() function and add the library in your project settings (project - build options - linker settings - add library).

Instead of adding the library in the project settings you can also use
#pragma comment( lib, "canL2")
in one of your source files (see comment (C-C++)[^]).

Note that you need also the library file canL2.lib because this is the file referenced by the project settings and the pragma instruction.

You can specify the full path to that LIB file or ensure that it is located within the library search path (e.g. by adding the path to the project settings).

The DLL file should be placed in the same directory as the application. During development these are the release and debug output directories.
 
Share this answer
 
Comments
mraaf 18-Apr-17 5:37am    
Thanks, it looks lot better now. But some of the functions still unrecognizable.
Jochen Arndt 18-Apr-17 5:49am    
You should provide more information about the problems like compiler errors and error codes returned by functions when the programming is running.

It is impossible to help without such information.

Note also that probably nobody here uses that library and the harwdare so that the code can be checked. This makes it more important to get detailed problem information (and may make it impossible to solve some problems).
mraaf 18-Apr-17 6:51am    
Noted. Sorry about that.
Will get it once I'am back in office tomorrow.
mraaf 19-Apr-17 5:39am    
Hi Jochen,
Below are errors from the compiler:

Error #1:
PCHDSNAPSHOT pBuffer = NULL;
unsigned long u32NeededBufferSize;

pBuffer = malloc(u32NeededBufferSize)
...error C2440: '=' : cannot convert from 'void *' to 'CHDSNAPSHOT *'
...Conversion from 'void*' to pointer to non-'void' requires an explicit cast


Error #2:
CANL2_CH_STRUCT ch1, ch2;
char *pName[2] = {NULL,NULL};

strcpy(ch1.sChannelName, pName[0]);
...error C2664: 'strcpy' : cannot convert parameter 1 from 'unsigned char [80]' to 'char *'
...Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


Error #3:
int ret;
CANL2_CH_STRUCT ch1, ch2;
PRAEDEF int MIDDEF INIL2_initialize_channel(CAN_HANDLE *pu32ChannelHandle, char *pChannelName); // CANL2.H

ret = INIL2_initialize_channel(&ch1.ulChannelHandle, ch1.sChannelName);
...error C2664: 'INIL2_initialize_channel' : cannot convert parameter 2 from 'unsigned char [80]' to 'char *'
...Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Jochen Arndt 19-Apr-17 5:45am    
That is because the example code is C while you are using C++ which has a stronger type checking.

Just do what the error messages suggest: Use casting.

pBuffer = (PCHDSNAPSHOT)malloc(u32NeededBufferSize);
strcpy((char*)ch1.sChannelName, pName[0]);
ret = INIL2_initialize_channel(&ch1.ulChannelHandle, (char*)ch1.sChannelName);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900