2025-11-24 8:39 AM - last edited on 2025-11-25 12:34 AM by mƎALLEm
In rm0316 rev 10 for the stm32F303x, the documentation for the ABRQ bits in the CAN_TSR transmit status register states:
Setting this bit has no effect when the mailbox is not pending for transmission.
I am finding on my STM32F303 that setting ABRQx when the mailbox is empty will actually clear the RQCPx and TXOKx status bits in the CAN_TSR.
This effect is important to note, because if you're using the TXOKx bit to determine if the message was transmitted or aborted and ABRQx was set after the mailbox finishes its transmission and becomes empty, you will think the message was successfully aborted (because TXOKx is cleared by the late abort) when it was actually transmitted.
Even if you disable interrupts and check the mailbox status immediately before setting the ABRQx bit, it seems like there is still a race condition where the mailbox transmission could complete between the read and write operations, which could occasionally cause the abort to be late. Is there a way to do this atomically?
A workaround that seems to work is to check both RQCPx=0 and ABRQx=0 after an abort request to determine if the abort request came in after the message was transmitted, but this appears to be undocumented behavior.
Thanks for listening and any suggestions or documentation I may have missed.
Solved! Go to Solution.
2026-02-03 5:42 AM
Hello,
This is an answer from our expert:
The recommended solution is to set the bit DBG_CAN_STOP = 1 in the DBGMCU_APB1_FZ register.
As stated in the reference manual (section “Debug MCU APB1 freeze register (DBGMCU_APB1_FZ)”, bit 25 DBG_CAN_STOP):
0: same behavior as in normal mode
1: the CAN receive registers are frozen when the core is halted
With this bit enabled, when the core is stopped by the debugger (breakpoint), the CAN peripheral is frozen. This allows you to observe the CAN status registers consistently, and in the case of a successful transmission you will correctly see: RQCP = 1, TXOK = 1, and TME = 1, as illustrated in Figure 394 (Transmit mailbox states) of RM0316.
So to conclude:
- In debug mode, if DBG_CANx_STOP is not enabled, the core can be halted while the CAN peripheral continues to run. This may lead to register states that do not fully match what is shown in the RM, which assumes a continuous real-time execution.
- In standalone mode (product in the field, without the core being halted by the debugger), the CAN operates normally and the behavior is in line with what is described in the reference manual.
To properly debug the product and correctly observe the bxCAN peripheral status, you need to set the DBG_CANx_STOP bit to 1. Otherwise, the true bxCAN state cannot be reliably observed while the core is halted.
Hope that answers your question.
2025-12-31 5:26 AM
Hello @arthur3, and sorry for the late reply.
I reproduced the behavior and I've escalated the topic internally for analysis. Internal ticket number: 224489
2026-02-03 5:42 AM
Hello,
This is an answer from our expert:
The recommended solution is to set the bit DBG_CAN_STOP = 1 in the DBGMCU_APB1_FZ register.
As stated in the reference manual (section “Debug MCU APB1 freeze register (DBGMCU_APB1_FZ)”, bit 25 DBG_CAN_STOP):
0: same behavior as in normal mode
1: the CAN receive registers are frozen when the core is halted
With this bit enabled, when the core is stopped by the debugger (breakpoint), the CAN peripheral is frozen. This allows you to observe the CAN status registers consistently, and in the case of a successful transmission you will correctly see: RQCP = 1, TXOK = 1, and TME = 1, as illustrated in Figure 394 (Transmit mailbox states) of RM0316.
So to conclude:
- In debug mode, if DBG_CANx_STOP is not enabled, the core can be halted while the CAN peripheral continues to run. This may lead to register states that do not fully match what is shown in the RM, which assumes a continuous real-time execution.
- In standalone mode (product in the field, without the core being halted by the debugger), the CAN operates normally and the behavior is in line with what is described in the reference manual.
To properly debug the product and correctly observe the bxCAN peripheral status, you need to set the DBG_CANx_STOP bit to 1. Otherwise, the true bxCAN state cannot be reliably observed while the core is halted.
Hope that answers your question.