Lost CAN-frames / Erroneous data in CAN-frames

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lost CAN-frames / Erroneous data in CAN-frames

1,341 Views
petpap
Contributor I

Hello,

We have lately had some strange CAN-frame problems. About once every 50 hour we lose one or several CAN-frames. Sometimes also erroneous data is received in the CAN-messageboxes.

 

We have a MPC5554 Controller with a FlexCAN2-module

 

We have three tasks which may access the messageboxes:
1. OS scheduled periodic polling and transmitting-function
2. Interrupt-handled polling function
3. Transmitting function of sporadic messages

 

We have set up 16 messageboxes for our three CAN-modules:
0-3 : Transmit messageboxes
4-13 : Periodically polled messageboxes
14-15 : Interrupt-handled RX-messageboxed

 

We suspect that when two or three of these taskes at the same time are accessing the registers of the CAN-module, this could result in unpredicable behaviour.

 

The tasks are implemented as follows:

 

1. OS scheduled periodic polling and transmitting-function:

For all CAN-modules:
    For all messageboxes 4-13 (mbuff) where flags raised :
        busy = 1;
        while (busy)
        {
             dummy = mbuff->CS.B.CODE; // locks MB
             busy = (uint8)(0x1 & dummy);
        }
        canID = mbuff->ID;
        length = mbuff->CS.B.LENGTH;
        memcpy(data, (uint8*)mbuff->DATA.B, length);

        dummy = touCan->TIMER.R; // releases lock of MB
    For all messages in TX-queue (use mbuff 0-3):
         mbuff->CS.B.CODE = CANHW_CODE_TX_NOT_READY; // code 1000
         mbuff->CS.B.LENGTH = size;
         mbuff->ID = canId;
         memcpy((U8 *) mbuff->DATA.B, data, size);
         mbuff->CS.B.CODE = CANHW_CODE_TX_ONCE; // code 1100


2. Interrupt-handled periodic polling function:

    For all flags raised in MB 14-15 (mbuff) of the current CAN-module:
        busy = 1;
        while (busy)
        {
         dummy = mbuff->CS.B.CODE; // locks MB
         busy = (uint8)(0x1 & dummy);
        }
        canID = mbuff->ID;
        length = mbuff->CS.B.LENGTH;
        memcpy(data, (uint8*)mbuff->DATA.B, length);

        dummy = touCan->TIMER.R; // releases lock of MB

 

3. Transmitting function of sporadic messages:
     Stop_Interrupts();

     mbuff->CS.B.CODE = CANHW_CODE_TX_NOT_READY; // code 1000
     mbuff->CS.B.LENGTH = size;
     mbuff->ID = canId;
     memcpy((U8 *) mbuff->DATA.B, data, size);
     mbuff->CS.B.CODE = CANHW_CODE_TX_ONCE; // code 1100

     Enable_Interrupts();


What can happen if we have locked an MB and then an interrupt is raised resulting  in handling of interrupt-handled messageboxes. After the interrupt-routine we return to the periodic polled function and start reading from a Messagebox which is not locked. What can happen? Can this result in lost CAN-frames or erroneous received CAN-frames?

 

Our errors occur for both periodically received CAN-frames and interrupt-handled CAN-frames.

 

Best regards
Peter Pap

Labels (1)
0 Kudos
Reply
1 Reply

678 Views
jbezem
Contributor III

I do not have exactly your setup, but the behaviour you describe looks like a race condition.

Especially the definition of 'busy': It looks like a global/function-static variable shared with the ISR;

if it is, you have a race-condition built-in, otherwise you could just as well have written

  while (mbuff->CS.B.CODE & 0x01); // Locks MB

Also, the "sporadic messages" block the interrupts, but if the "OS scheduled periodic polling and

transmitting" can be interrupted by the "sporadic messages" (round-robin or priority-driven scheduling),

chances are that the same message buffer is then overwritten, and after enabling the interrupts again,

the "OS scheduled" will resume its writing of the buffer, probably resulting in garbage.

For a more detailed analysis, more coding details would be required, though.

 

HTH,

 

Johan

0 Kudos
Reply