Hello MBed Forum,
my student team and I want to use a CAN network to gather data over a small sensor network.
The sensors should react to a specific CAN-message which tells them in what time interval the sensor should post its readings to the network (we are using a STM32F103 which are equipped with SN65HVD23 CAN transceivers).
At first, we had problems with the MBedOS CAN filter, but found another way around it (Only a single CAN filter can be used with STM32F4xx devices - #2 by jeromecoutant). Now the sensor just receives messages with the specified identifiers in the filter. Everything works if every Message is properly acknowledged, however if one message does not get acknowledged due to poor connectivity or something else the chaos starts. The sending controller now continuously posts a transmit error message and all the receiving controllers transmit an error message. This only stops when both controllers are reset.
The Mbed documentation suggests a reset(), but our efforts have shown that triggering this can.reset() command only resets the TDerror or RDerror counter and therefore does not solve our problem.
Is this a common error or is there a specific strategy that we do not know of which could solve this problem?
Any help would be appreciated and many thanks in advance!
When the TEC (Transmitter Error Counter) of a CAN node overflows (exceeds 255), in order not to block the entire bus and the other healthy nodes, the node (CAN controller) shall change its state to “Bus-off”. If this happens the on-chip CAN controller also sets the BOFF (bus-off flag) to 1.
On the STM targets, depending on the ABOM (Automatic Bus-Off Management) bit in the CAN_MCR register, the CAN controller will recover from bus-off (become error active again) either automatically or on software request. But in both cases the CAN controller has to wait at least for the recovery sequence specified in the CAN standard (128 occurrences of 11 consecutive recessive bits monitored on CANRX).
If ABOM is enabled, the CAN controller will start the recovering sequence automatically after it has entered the bus-off state. If ABOM is disabled, the software must initiate the recovering sequence by requesting the CAN controller to enter and to leave initialization mode.
Unfortunately, in Mbed OS the ABOM is disabled by default. So you have two options:
Either to monitor the BOFF (bus-off flag) and when set initiate the recovering sequence by requesting the CAN controller to enter and to leave initialization mode by software.
Or to enable ABOM (Automatic Bus-Off Management) in the
_can_init_freq_direct function. You can find it in the
mbed-os/targets/TARGET_STM/can_api.c file. Just comment out the existing statement and add a new one as below:
static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz)
/* Use default values for rist init */
// obj->CanHandle.Init.ABOM = DISABLE;
obj->CanHandle.Init.ABOM = ENABLE;
If the bus failure is only occasional and the bus is then capable to produce a recovery sequence (128 occurrences of 11 consecutive recessive bits monitored on CANRX) then this might help improve your system behavior.
Best regards, Zoltan
Thank you Zoltan,
for the quick reply.
We will try enable ABOM (Automatic Bus-Off Management) and report back.
we tried your suggestion and looked a little further into the library. After that we decided to disable the automatic retransmission and to detect in the software if a CAN-message was sent correctly. Then we applied the new settings to an existing network with old sensors which were equipped with the MCP2515 controllers.
However, none of the sent messages was received correctly. We looked at the sent signals with an oscilloscope and found out that the messages are not sent correctly according to the CAN-standard.
I recorded this phenomenon with a logic analyzer and attached the file. It seems to me that the first part of the message is sent with a tenth of the set bitrate (50kb/s) and the last part is sent with the correct bitrate (500kb/s). The second recording is from one of our working sensors with 500kb/s and an 11-bit identifier.
Am I missing something here or is the CAN-transceiver broken?
Many thanks in advance for your help!
That’s sad. To be honest, I have used only Mbed 2 CAN API in real projects so far. It could happen there is a bug in the Mbed OS 6 CAN API. Nevertheless, I have a CAN Bus built up from nodes like [STM32F103C8 + MCP2551 (built with Mbed 2 CAN API)], [Arduino + MCP2515 + MCP2551] and [Raspberry Pi + MCP2515 + MCP2551]. The network runs 24/7 (at 500kb/s) for several years now with no major issues (it randomly fails about once a year probably due to strong interference). I will try to add a [STM32F103C8 + MCP2551] node built with Mbed OS 6 and let you know how it works.
Best regards, Zoltan