Kvaser Leaf Light V2 w/ CAN Callbacks in C# (.NET)

I have developed a suite of applications designed to use a USB CAN interface and have adapted the CAN interface to work with a few different USB CAN adapters for testing/evaluation to see which is the most robust and reliable in the long run.

One quirk I am running into with the CANlib SDK is when reading CAN frames using the Canlib.canRead call, I am receiving duplicate frames in my callback function.

I have setup my callback function like so:

private void GetDataCallback(int handle, IntPtr context, UInt32 notifyEvent)
{
if (notifyEvent == Canlib.canNOTIFY_RX)
{
_mutex.WaitOne();
byte[] data = new byte[8];

while (Canlib.canRead(handle, out int id, data, out int dlc, out int flags, out long timestamp) == Canlib.canStatus.canOK)
{
CanRxService.Instance.QueueFrame(new CanFrame((uint)id, data, (byte)dlc, flags));
//Thread.Sleep(1);
}
_mutex.ReleaseMutex();
}
}

Note: _mutex is a, you guessed it, Mutex

It seems the issue occurs less when I include the call to Thread.Sleep but it still isn’t quite consistent. Another CAN-USB adapter I am using supports callbacks and I don’t have this issue at all.

Is this the proper way to read data from the callback function, or should I just read one CAN frame each time the callback function is called or what?

In every other way, this CAN USB adapter is the most reliable, aside from this one issue which seems rather sporadic.

On a side note, I also can’t get the acceptance filter to work:

This does not work:
Canlib.canSetAcceptanceFilter(_handle, ((Can.BOARD_ID_MASTER << 21) | (Can.NODE_ID_MASTER << 17)), 0x1FF0000, 1);

This does work (doing it myself in software):
if ((id & 0x1FF0000) != ((Can.BOARD_ID_MASTER << 21) | (Can.NODE_ID_MASTER << 17))) continue;

Thanks and best regards,
– Rick

  • 3 answers
  • 425 views
  • 12 months ago by RRiggott

3 Answers

A MAJOR modification to my earlier answer:

According to our own documentation (CANlib): "The callback function is called in the context of a high-priority thread created by CANlib. You should take precaution not to do any time consuming tasks in the callback. You must also arrange the synchronization between the callback and your other threads yourself."

This means a user thread and the callback thread could be attempting to use the same handle. So the handle needs a mutex to prevent simultaneous use.

  • November 22, 2018 2:08 pm | by Lars-Göran Fredriksson

Answer

  • November 15, 2018 11:57 am | by Hiba Babar

Hi!

When looking at your code (reading data) it seems to be correct.
It is important that you read all frames before you return, otherwise the event mechanism wont work properly.

It is wise to quickly read all data for later processing, and then "release" the callback function.

I do not think that you need the mutex unless your QueueFrame need it.

The "canSetAcceptanceFilter" question, please send a message to "[email protected]" and we will help you with it.

  • May 16, 2018 2:56 pm | by Lars-Göran Fredriksson

Your email address will not be published. Required fields are marked *

Your Answer