In this post I want to give some background information why you should avoid using CAN Remote frames. Taking a closer look to the Bosch CAN specification you notice that the RTR (Remote Transmission Request) bit is defined to request a CAN frame with the same CAN identifier. The differences between a CAN data frame and a CAN remote frame are:
- A Remote frame sets the RTR bit to a recessive level
- A Remote frame has no data field
Let us have a look on common CAN bus HLPs (Higher-Layer-Protocols): CANopen has two optional services using Remote frames, DeviceNet and J1939 forbid Remote frames at all. And there are some good reasons for doing so.
Silicon manufacturers have chosen different approaches for handling the reception of a CAN Remote frame. The simple one is just setting a flag inside the CAN message buffer (my favorite choice). Another approach is to trigger the transmission of a CAN Data frame without software interaction. The problem: an interrupt is generated after successful transmission of the CAN Data frame. So there is no possibility to update the payload of that frame and the sender of the CAN Remote frame gets outdated information.
Another - still present - issue are incorrect implementations by silicon vendors. Either the chip does not respect the DLC value (forcing it to 0 for every CAN Remote frame) or it starts transmission of CAN Error frames upon reception of certain CAN Remote frame. The end-user, who does not even know what silicon is inside the CAN device, is then forced into a time-consuming fault analysis.
To draw a conclusion: Take your hands off CAN Remote frames!
How to avoid it in CANopen
The CiA Application Note AN802 /2/ illustrates the problems of CAN Remote frames in detail and explains how to operate CANopen networks without a RTR. The affected CANopen services are NMT Node-Guarding and PDO (transmission type RTR). Users of CoDeSys should make sure that Node-Guarding is disabled in the soft PLC and NMT Heartbeat is used instead.
CAN Remote frames on the STM32 family
If you are still not convinced to avoid CAN Remote frames and you like to use them on the bxCAN module: here is how we have implemented it. The bxCAN module simply sets a flag upon reception inside the FIFO mailbox RIR register. Just evaluate this and pass it to your application (and switch the red lamp on ).
// test for RTR bit
if(CAN1->sFIFOMailBox.RIR & CAN_RI0R_RTR)
In this example code we use the CANpie FD API to setup the message structure for the application.
/1/ ISO 11898-1, Road vehicles — Controller area network (CAN) — Part 1: Data link layer and physical signalling
/2/ CiA Application Note AN802 – CAN remote frames: Avoiding of usage, CiA specifications
/3/ CANpie FD documentation, https://canpie.github.io