Page 1 of 1
Phantom messages read - possible bug in PCAN Linux
Posted: Wed 8. Jan 2020, 14:36
by Fojtik
After disconnecting and connecting CAN cable I have read bunch of phantom CAN messages, see attached file for details. First number is time mark in [ms].
Code: Select all
8182873 Message P-CAN received Id=1, Len=4 0 0 0 0
8182873 Message P-CAN received Id=2, Len=4 0 0 0 4
8182873 Message P-CAN received Id=3, Len=4 0 0 0 8
8182873 Message P-CAN received Id=2, Len=4 0 0 0 4
8182873 Message P-CAN received Id=3, Len=4 0 0 0 8
We are sending only messages with ID=
0x81. I suspect this to be deffect of CAN library.
Is there any fix available?
You could see a code that we accept only messages with
stsResult==PCAN_ERROR_OK.
Code: Select all
TPCANStatus stsResult = CAN_Read(myObj->m_Channel, &PeakCanMsg, &TimestampBuffer);
while(stsResult==PCAN_ERROR_OK && PeakCanMsg.LEN<=sizeof(MessageCanUDP::Payload))
{
MessageCanUDP *pMsg = new MessageCanUDP;
pMsg->CobID = PeakCanMsg.ID;
pMsg->Type = PeakCanMsg.MSGTYPE;
pMsg->Length = PeakCanMsg.LEN;
memcpy(pMsg->Payload, PeakCanMsg.DATA, PeakCanMsg.LEN);
pMsg->Timemark = TimestampBuffer.micros + 1000*TimestampBuffer.millis + 1000000*TimestampBuffer.millis_overflow;
{ // locked scope, do not remove curly braces.
CritSectionLocker Lck(myObj->ListLocker);
myObj->RxList.push_back(pMsg);
}
myObj->PacketCounter++;
myObj->m_WaitCondition->SetEvent();
ErrorCount = 0;
stsResult = CAN_Read(myObj->m_Channel, &PeakCanMsg, &TimestampBuffer);
}
As you can note the situation is even worse and phantom messages are continuously received after cable event.
Re: Phantom messages read - possible bug in PCAN Linux
Posted: Wed 8. Jan 2020, 19:07
by Fojtik
This "unwanted" message could be caused by service message (they start without any request), but even when so, the service mesasage does not signalise select command, so the receiver dependent on "select" hangs.
Code: Select all
/** Internal working thread that listens for new messages. */
void *CanPeak::WorkerThread(void *pObject)
{
CanPeak *myObj = reinterpret_cast<CanPeak*>(pObject);
TPCANMsg PeakCanMsg;
TPCANTimestamp TimestampBuffer;
int fd;
fd_set fds;
struct timeval timeout;
int ErrorCount = 0;
myObj->ActivityFlag = THREAD_RUNNING;
// myObj->BlockingMode(0);
CAN_GetValue(myObj->m_Channel, PCAN_RECEIVE_EVENT, &fd, sizeof fd);
// initializes an fd_set with that File Descriptor, it will be used to get "read" notifications
FD_ZERO(&fds);
FD_SET(fd, &fds);
while(myObj->ActivityFlag>=THREAD_RUNNING && myObj->m_Channel!=PCAN_NONEBUS) // Set Running = 1 externally to ask for shutdown.
{
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int err = select(fd+1, &fds, NULL, NULL, &timeout);
if(err!=0) // Timeout ocurred -> err==0.
{
if(err!=1 || !FD_ISSET(fd, &fds))
{
fprintf(stderr, "\n%u Select(%xh) failure: %d.", GetTickCount_ms(), myObj->m_Channel, err);
Sleep(1); // Relax from error.
continue;
}
}
TPCANStatus stsResult = CAN_Read(myObj->m_Channel, &PeakCanMsg, &TimestampBuffer);
while(stsResult==PCAN_ERROR_OK && PeakCanMsg.LEN<=sizeof(MessageCanUDP::Payload))
{
MessageCanUDP *pMsg = new MessageCanUDP;
pMsg->CobID = PeakCanMsg.ID;
pMsg->Type = PeakCanMsg.MSGTYPE;
pMsg->Length = PeakCanMsg.LEN;
memcpy(pMsg->Payload, PeakCanMsg.DATA, PeakCanMsg.LEN);
pMsg->Timemark = TimestampBuffer.micros + 1000*TimestampBuffer.millis + 1000000*TimestampBuffer.millis_overflow;
{ // locked scope, do not remove curly braces.
CritSectionLocker Lck(myObj->ListLocker);
myObj->RxList.push_back(pMsg);
}
myObj->PacketCounter++;
myObj->m_WaitCondition->SetEvent();
ErrorCount = 0;
stsResult = CAN_Read(myObj->m_Channel, &PeakCanMsg, &TimestampBuffer);
}
if(PCAN_ERROR_QRCVEMPTY==stsResult || PCAN_ERROR_OK==stsResult) continue;
fprintf(stderr, "\n%u P-CAN read error: %u.", GetTickCount_ms(), (unsigned)stsResult);
if(ErrorCount++ > 10)
{
Sleep((ErrorCount>100) ? 10 : 1);
if(ErrorCount>200 && stsResult==PCAN_ERROR_UNKNOWN) // The CAN device is probably disconnected.
{
fd = myObj->m_Channel;
myObj->CloseCom();
myObj->ActivityFlag = THREAD_TERMINATED;
return 0;
}
}
}
myObj->ActivityFlag = THREAD_TERMINATED;
return 0;
}
Re: Phantom messages read - possible bug in PCAN Linux
Posted: Thu 9. Jan 2020, 08:50
by PEAK-Support
It looks like you use the CharDev Driver (always add the info which driver type you use to a request).
You have to check always also the Message Type of a incomming CAN Frame
Your data looks like you receice MSGTYPE_STATUS which does not include any real Messages (MSGTYPE_STATUS).
Code: Select all
/*
* MSGTYPE bits of element MSGTYPE in structure TPCANMsg
*/
#define MSGTYPE_STANDARD 0x00 // marks a standard frame
#define MSGTYPE_RTR 0x01 // marks a remote frame
#define MSGTYPE_EXTENDED 0x02 // declares a extended frame
#define MSGTYPE_SELFRECEIVE 0x04 // self-received message
#define MSGTYPE_STATUS 0x80 // used to mark a status TPCANMsg
The message type (see TPCANMessageType) of a CAN message indicates if the message is a 11-bit, 29-bit, RTR, or status message. This value should be checked every time a message has been read successfully. If the bit PCAN_MESSAGE_STATUS is set in the TPCANMsg.MSGTYPE field, the message is a status message. The ID and LEN fields do not contain valid data. The first 4 data bytes of the message contain the Error Code. The MSB of the Error Code is in data byte 0, the LSB is in data byte 3.
Examples:
Data0 Data1 Data2 Data3 Error Error Code Description
00h 00h 00h 02h PCAN_ERROR_OVERRUN 0002h CAN controller has been read out too late.
00h 00h 00h 04h PCAN_ERROR_BUSLIGHT 0004h Bus error: An error counter has reached the 'Light' limit.
00h 00h 00h 08h PCAN_ERROR_BUSHEAVY 0008h Bus error: An error counter has reached the 'Heavy' limit.
00h 00h 00h 10h PCAN_ERROR_BUSOFF 0010h Bus error: CAN Controller is in 'Bus Off' state.
Keep in mind --> When your CAN node send and you have no 2nd active CAN node on the CAN Bus, you have no node that could ACK the Frames anymore !