Skip to main content
Explorer
October 1, 2025
Solved

HAL_FDCAN_GetRxFifoFillLevel() in HAL_FDCAN_RxFifo0Callback()

  • October 1, 2025
  • 1 reply
  • 275 views

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

 
I doubt it, is that correct?
 
Many Thanks.
    This topic has been closed for replies.
    Best answer by Saket_Om

    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.

    1 reply

    Saket_OmAnswer
    Technical Moderator
    October 2, 2025

    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.

    JiriCepAuthor
    Explorer
    October 2, 2025

    @Saket_Om  Many Thanks for clarifying.