2025-10-01 11:37 AM
I would like to ensure that I can use HAL_FDCAN_GetRxFifoFillLevel() function in HAL_FDCAN_RxFifo0Callback() like this:
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE)
{
// used loop to read all messages from FIFO
while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0)
{
can_msg_t rx_msg = {0};
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_msg.hdr, rx_msg.data) != HAL_OK)
{
break;
}
rx_msg.data.data_len = (uint8_t)dlc_to_bytes(rx_msg.hdrDataLength);
// put rx msg to queue
osMessageQueuePut(rx_queue_handle, &rx_msg, 0, 0);
}
}
}
When I googling more whether I can use HAL_FDCAN_GetRxFifoFillLevel() in ISR CalIback I got:
HAL_FDCAN_GetRxFifoFillLevel is not guaranteed to be ISR-safe because it's a read operation on a peripheral register that doesn't automatically handle atomic operations, which are required in interrupt contexts to prevent data corruption from race conditions with the main application. To safely use it from an ISR, you must implement a mechanism to ensure the read operation is atomic, such as temporarily disabling interrupts or using a mutex if in an RTOS environment
Solved! Go to Solution.
2025-10-02 3:17 AM
Hello @JiriCep
While it’s not particularly recommended, it’s also not a major issue. If a new message is received while the code is inside the while loop, the interrupt context will persist, as it won’t preempt itself. The loop will simply continue as long as there are messages in the FIFO. So, if another message arrives during the loop, it will just result in another iteration.
Since an OS is being used here, another approach could be to set a flag or semaphore in the interrupt, which would signal a thread to come and read the received messages, rather than processing them directly in the interrupt.
HAL_FDCAN_GetRxFifoFillLevel will return the fill level of the FIFO at the moment the function is called, which might change immediately after if the register is updated. However, since this check is inside a loop, the code will continue to process the next message. Since it’s a FIFO, as long as it’s not full, nothing will be overwritten.
2025-10-02 3:17 AM
Hello @JiriCep
While it’s not particularly recommended, it’s also not a major issue. If a new message is received while the code is inside the while loop, the interrupt context will persist, as it won’t preempt itself. The loop will simply continue as long as there are messages in the FIFO. So, if another message arrives during the loop, it will just result in another iteration.
Since an OS is being used here, another approach could be to set a flag or semaphore in the interrupt, which would signal a thread to come and read the received messages, rather than processing them directly in the interrupt.
HAL_FDCAN_GetRxFifoFillLevel will return the fill level of the FIFO at the moment the function is called, which might change immediately after if the register is updated. However, since this check is inside a loop, the code will continue to process the next message. Since it’s a FIFO, as long as it’s not full, nothing will be overwritten.
2025-10-02 5:55 AM
@Saket_Om Many Thanks for clarifying.