S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Hello NXP Team, I am working with the NXP S32K312 evaluation board using S32K3 RTD 7.0.1 (AUTOSAR 4.9.0). I am testing the FlexCAN transmit message-buffer abort functionality using the RTD APIs FlexCAN_Ip_Send() and FlexCAN_Ip_AbortTransfer(). The abort functionality is not behaving as expected in my tests. I have attached the project, MEX configuration, and test code for your reference. I would appreciate your guidance on the following three issues. 1. Aborting Multiple Transmit Message Buffers In my first test, I transmit messages using multiple message buffers and then issue abort requests for all those buffers. The test code is shown below. /* Transmit messages using MB0 to MB39. */
for (uint8_t lMb_u8 = 0U; lMb_u8 < 40U; lMb_u8++)
{
FlexCAN_Ip_Send(
INST_FLEXCAN_0,
lMb_u8,
&tx_info,
0x123U,
&dummyData[0]
);
}
/* Request abort for MB0 to MB39. */
for (uint8_t lMb_u8 = 0U; lMb_u8 < 40U; lMb_u8++)
{
FlexCAN_Ip_AbortTransfer(
INST_FLEXCAN_0,
lMb_u8
);
} All transmit requests use the same CAN ID, 0x123, while the message-buffer index varies from 0 to 39. The MCR[AEN] bit is set to 1, enabling the abort mechanism. However, all the messages are observed in PCAN-View, even though I issue abort requests for the message buffers. My expectation is that messages still pending transmission should be aborted, while messages that have already completed transmission cannot be aborted. Could you please clarify the following? Is there a recommended sequence for transmitting on multiple message buffers and then aborting all pending transmissions? 2. Aborting a Transmission using a single Message Buffer To isolate the issue, I created a second test that uses only message buffer 8. The sequence is: Call FlexCAN_Ip_Send() for MB8. Check the transfer status using FlexCAN_Ip_GetTransferStatus(). If the send is successful and the transfer status is FLEXCAN_STATUS_BUSY, call FlexCAN_Ip_AbortTransfer() for MB8. Read the transfer status again and inspect the hardware registers. The send API returns FLEXCAN_STATUS_SUCCESS, and the status check before the abort reports FLEXCAN_STATUS_BUSY. However, the abort API returns FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS (0x5). While debugging the RTD implementation, I found that the return status originates from the following condition inside FlexCAN_AbortTxTransfer(): FlexcanMbConfig = *FlexcanMb;
/* Check if the MBs have been safely inactivated */
if ((uint32)FLEXCAN_TX_INACTIVE ==
((FlexcanMbConfig & FLEXCAN_IP_CS_CODE_MASK)
>> FLEXCAN_IP_CS_CODE_SHIFT))
{
/* Transmission has occurred */
Result = FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
} The message buffer is located at 0x40304100 in the memory browser for my current configuration. After the abort request, the CODE field reads 0x8, which corresponds to the inactive/transmitted state, instead of the expected abort code 0x9. I also placed a breakpoint at the following statement in FlexCAN_AbortTxTransfer(): TimeStart = OsIf_GetCounter(
FLEXCAN_IP_SERVICE_TIMEOUT_TYPE
); At this point, IFLAG1[8] is set. In the current RTD implementation, the abort sequence writes FLEXCAN_TX_ABORT (0x9) to the message-buffer CODE field, then polls the corresponding message-buffer interrupt flag. The flag is cleared by FlexCAN_ClearMsgBuffIntStatusFlag() in FlexCAN_Ip_AbortTransfer() after the abort helper returns. My concern is that the interrupt flag may already be set from a completed transmission before the abort request is issued. If so, the polling loop could exit immediately without waiting for a new abort-completion event. However, I have not yet confirmed whether this is the cause of my issue. 3. Bus Off recovery with Automatic Recovery Disabled In a separate test, I am disabling automatic bus-off recovery and attempting to handle recovery through the application. When a bus-off condition occurs, my current approach is to deinitialize and then reinitialize the FlexCAN driver. However, after this sequence, subsequent calls to FlexCAN_Ip_Send() do not successfully transmit messages. Could you please advise on the recommended recovery procedure when automatic bus-off recovery is disabled? Specifically: Is deinitialization and reinitialization sufficient to recover the FlexCAN controller from bus-off? Should all outstanding TX message buffers be aborted or explicitly cleared before deinitialization? After reinitialization, must the message buffers be configured or initialized again before transmission? Are there any required steps involving the ESR1 status, MCR, CTRL1[BOFFREC], interrupt flags, or RTD internal transfer states before the controller can transmit again? What is the recommended sequence for recovering from bus-off while ensuring that no stale TX transfers or mailbox states prevent subsequent transmissions? I have attached the test project, MEX configuration, and relevant source code so that the configuration and API usage can be reviewed. Re: S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Hi@Yogs
I have summarized the answers to your three questions as follows:
(There’s quite a lot of content, and the formatting is a bit messy.)
Q1. Regarding "Flexcan Abort" question.
First, you need to understand that the FlexCAN Abort mechanism is only effective for TX message buffers (MBs) that are still in a pending state.
Regarding your first test:
MB0 is activated first;
FlexCAN begins scanning and proceeds to transmit the contents of MB0;
Meanwhile, the CPU continues configuring MB1, MB2, ..., MB39;
By the time the CPU finally reaches the second loop, the initial set of MBs has likely already finished transmitting.
Under conditions such as low bus load, successful ACK reception, and the 8-byte payload typical of Classical CAN,
the transmission of 40 frames can be completed very quickly.
The same applies to the second test, if the bus is idle, FlexCAN may well have already completed the transmission
before the CPU executes the abort command.
Therefore, neither of your two tests proves anything.
To properly verify an abort operation, you need to deliberately create a definitive "pending" window, rather than relying on the CPU's execution speed.
For example:
Configure another CAN node to continuously occupy the bus using a higher-priority ID—thereby keeping the target Message Buffer (MB) in a pending state—and then trigger the abort.
Q2:Why does a single-MB test return BUSY initially, yet return NO_TRANSFER_IN_PROGRESS upon an abort request?
A brief state mismatch can occur between the two:
`FlexCAN_Ip_Send()` sets the RTD (Run-Time Driver) state to `BUSY`.
The hardware begins transmission.
The frame transmission completes; the hardware updates the MB (Message Buffer) CODE to `0x8` and sets the `IFLAG`.
If the TX IRQ handler has not yet executed—or if the system is paused during breakpoint debugging—the RTD state structure may still remain as `BUSY`.
An `Abort` operation is called at this point.
Internally, the `Abort` function reads the MB CODE and finds it is already `0x8`.
It returns `FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS`.
Therefore:`GetTransferStatus() = BUSY`and`FlexCAN_Ip_AbortTransfer() = NO_TRANSFER_IN_PROGRESS`
are not necessarily contradictory.
The former may reflect software bookkeeping, while the latter confirms the actual hardware CODE.
Q3.Bus-off recovery
It is entirely feasible to recover from a "bus-off" state by reinitializing the CAN module. To manually perform a "bus-off" recovery, the application layer must first cease data transmission and cancel or discard all pending transmit (TX) requests(Abort).
Subsequently, the controller must undergo a complete deinitialization followed by a reinitialization. Following this, the application-layer receive (RX) message buffers (MBs) should be reconfigured, and any stale message buffer flags, error flags, and software transmission states must be cleared. Before resuming transmission, the application layer should verify that the controller has exited the "freeze" or "not-ready" state, and ensure that neither the transmit message buffers (TX MBs) nor the "ready-to-transmit" (RTD) status remain in a "busy" state.
Since you mentioned that your test failed, you likely overlooked the sequence mentioned above. I couldn't find any information regarding the bus-off recovery procedure in the attached files; if you still have questions about this, feel free to share your test project with me, and I can take a look to help you check it.
Re: S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Regarding Q1, I would like to clarify my test conditions. I am using a CAN baud rate of 500 kbps, and a Classical CAN frame with an 8-byte payload takes approximately 300 µs for transmission on the bus. In my test, I first submit the messages through the respective TX message buffers and then immediately execute the abort function. The abort function iterates through the corresponding message buffers and calls FlexCAN_AbortTxTransfer() for each one. So, the abort requests are being issued for the respective message buffers immediately after the transmission requests, rather than being delayed intentionally. I understand that the first few messages might have completed transmission before the abort loop reaches them. However, considering the approximate transmission duration and the number of messages submitted, I would expect some of the later message buffers to still have pending transmissions when their abort requests are issued. Could you help me understand whether there is another hardware condition or timing factor that would prevent those pending messages from being aborted? Re: S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Hi@Yogs
This is your default sequence for "abort MB" in your code;
for(uint8_t lMb_u8 = 0; lMb_u8 < 40; lMb_u8++)
{
FlexCAN_Ip_AbortTransfer(INST_FLEXCAN_0,lMb_u8);
}
I have modified it to "40 - 1Mb_u8".
for(uint8_t lMb_u8 = 0; lMb_u8 < 40; lMb_u8++)
{
FlexCAN_Ip_AbortTransfer(INST_FLEXCAN_0,40 - lMb_u8);
}
Below are the results of my testing.
I only received two frames of data; all other MBs were successfully aborted.
The results of this verification are sufficient to confirm my earlier hypothesis: the current MB had already been successfully sent before you executed the Abort MB operation. Re: S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Hi, Thank you for the explanation. I understood your recommendation and tested the reverse-order abort sequence. As you mentioned, this approach works better: I receive only two frames on the bus, while the remaining messages are successfully aborted. However, I have a few questions regarding the behaviour. 1. Why is reverse-order abortion necessary? Aren't the two loops essentially performing the same operation, with only the order of execution being different? Could you explain why starting the abort from the highest mailbox index makes such a significant difference? Is this related to the order in which FlexCAN scans or selects TX message buffers internally? Is reverse-order abortion a hardware requirement, or is it simply a recommended approach to increase the probability of aborting pending messages? 2. What about aborting a single message buffer? I also tested the abort functionality using only one message buffer: FlexCAN_Ip_Send( INST_FLEXCAN_0, 0U, &tx_info, 0x123U, &dummyData[0] ); FlexCAN_Ip_AbortTransfer(INST_FLEXCAN_0, 0U); I benchmarked the time between the execution of FlexCAN_Ip_Send() and the invocation of FlexCAN_Ip_AbortTransfer(). It takes approximately 10.3 µs. However, even with this short interval, the message is still transmitted on the CAN bus. I have also maintained a reasonable amount of bus load using higher-priority messages from PCAN-View, but the single-message abort is still unsuccessful. For comparison, when I use multiple message buffers for transmission and subsequently abort them in reverse order, the measured duration for the sequence is approximately 9.3 ms, and only two frames are received on the bus while the remaining messages are aborted. This raises another question: why does the single-message abort fail even when the abort request is issued approximately 10.3 µs after the send API returns, whereas the multi-mailbox reverse-order approach successfully aborts most of the messages? Could the single message already have been transferred to the internal TX Serial Message Buffer (TX SMB) before the abort request is issued? I would appreciate your clarification on how the hardware handles this scenario and how to reliably test the abort mechanism for a single message buffer. Re: S32K312 FlexCAN – TX Message Buffer Abort with AEN Enabled and Bus-Off Recovery Using RTD 7.0.1 Hi@Yogs
Why is an abort operation in reverse order necessary?
I didn’t mean to imply that it is necessary. Through these comparative test results, I am explaining that an abort might fail because the specific message buffer (MBn) you are attempting to abort has, in fact, already been successfully transmitted.
When you populate the message buffers sequentially—from MB0, MB1, ..., up to MB39—and then perform abort operations starting from MB0, it is possible that the target MB has already been successfully sent.
Consider a different approach: what if we initiate the aborts starting from MB39? This would ensure that the message buffers with higher indices are addressed for abortion first.
記事全体を表示