# Rx data rate on CAN bus faster than polling rate

I'm working on a safety-critical SIL 4 system and so interrupts have to be kept to a bare minimum (hence using only timer interrupts). CAN is used in polling mode.

Suppose data arrives at a CAN node and is not read from the buffer before another node sends its data, will the data be over written or corrupted or will the first node's data persist and the second node's data be lost?

Is it Ok to use more than one interrupt in a safety-critical SIL 4 system because the only way to service data in time without loss of data will be using the Rx interrupt for CAN or each node must be given a time slot to communicate on the bus (not good approach since CAN is multimaster communication protocol approach)?

Note: I'm using an LPC1778 microcontroller.

• Are you polling the CAN from the timer interrupt? – Jasen Jan 25 '16 at 5:20
• Since im using timer interrupt of 1 ms for timing reasons, i cant poll from ISR...itl be very slow – AkshayImmanuelD Jan 25 '16 at 5:56
• im polling from main() – AkshayImmanuelD Jan 25 '16 at 7:09
• Yes, You will loose the data if another node sends the data before you read it from buffer. – Swanand Jan 25 '16 at 11:19
• So an ISR is a must i can infer from your comment. But any justifications for use in a SIL 4 system? – AkshayImmanuelD Jan 25 '16 at 11:45

You should avoid interrupts when possible. Issues:

1. They mess up predictable real-time behavior.
2. Numerous interrupts may lead to unpredicted stack usage.
3. It is easy to write very subtle and very severe bugs when sharing data between an ISR and the background program.

That being said, you can avoid these problems with careful system design.

1) is only a problem for non-cyclic interrupts that may arrive at any point in time. As long as the interrupts have deterministic behavior and are triggered cyclically, you can use them. In that case they are no different than a high priority process and you can still predict real-time behavior of the system.

2) can be avoided by reducing the number of interrupt sources as far as possible. Other safety measures is to always allocate a stack which is larger than necessary, and most importantly: place the stack so that upon overflow, it doesn't fail-cascade into other RAM memory segments like .bss or .data! Here is a good article about this.

3) is the hardest one to protect yourself from. Every variable shared between an ISR and the background program has to be handled with lots of care. Two issues exist: re-entrancy and compiler optimizer problems.

Re-entrancy has to be solved in case-to-case basis with atomic access/semaphores/mutex or by temporarily disabling interrupts. This is always tricky and you have to ensure that you have considered every scenario, and that the produced machine code actually does what you think.

The other issue is where your compiler does not realize that your ISR is called by the MCU rather than from your code, and therefore fails to understand that all variables used by the ISR can be updated at any point in time. The compiler may then optimize the background code incorrectly, since it assumes that a certain variable is never used. This bug can be avoided by always declaring variables shared with an ISR as volatile.

Both of these issues are common sources for very subtle, but often severe bugs. There's no standard way to protect yourself against them, the closest thing to a safety measure is to only allow your most hardened C veteran to write all ISRs. Intermediately experienced programmers, not to mention beginners, always write these bugs, over and over again.

Because of this, it is very hard to justify the use of interrupts in safety-critical applications. You would have to spend lots of time on the design, tests and documentation to verify that every such interrupt is not causing problems. Therefore I can understand why some safety standards bans the use of interrupts entirely.

As for the specific issue of CAN, it sounds a bit like you have either picked the wrong MCU for the task or you are not using the CAN controller correctly. More advanced CAN controllers have rx buffers which you can set up for dedicated messages, and in addition an rx FIFO where the rest of the messages go. I'm pretty sure NXP have such CAN controllers for their Cortex-M families, at least they do on LPC11C.

With such an approach and a carefully designed application-layer CAN protocol, you should not need rx interrupts. All safety-critical CAN networks must be designed to send messages over and over again periodically. If you know that a certain message only arrives once every 5ms, then you merely have to ensure that your background program is fast enough to handle it before the next message arrives.

For SIL4 you would likely have more than one CAN bus: you would dedicate one bus for safety-critical real-time messages and put everything else on another non-critical bus. Redundancy solutions with multiple CAN buses transmitting the same critical data are also used sometimes.

• For limited CAN controllers that lack dedicated buffers, DMA together with a software FIFO might be a another alternative for avoiding interrupts. – Lundin Jan 27 '16 at 8:46
• True, but unfortunately the LPC1778 can't trigger the DMA from the CAN controllers :-( Otherwise it would be easy because the DMA can even reprogram itself. – Nils Pipenbrinck Jan 27 '16 at 9:28
• A closer look at this specific MCU shows that the CAN controller is a simple standard one, it does not support "mailbox" buffers. So this might be the wrong MCU for the task, or alternatively an external CAN controller could be used (which is a much more painful design, I wouldn't recommend it). – Lundin Jan 27 '16 at 9:45
• Yes exactly,RM57 has mailboxes..Hence very simple. LPC1778 has no mailbox or DMA...Hence i am forced to use interrupts. – AkshayImmanuelD Jan 27 '16 at 11:03
• @Lundin-Interrupts should be kept bare minimum-Agreed. What about the use of DMA? Shouldnt DMA also be kept minimum? – AkshayImmanuelD Jan 28 '16 at 12:57