Skip to main content
Graduate
May 13, 2025
Solved

CAN FIFO filling faster than flushing

  • May 13, 2025
  • 4 replies
  • 1033 views

We set up classic CAN on the stm32h747I-DISCO dev board and listen for interrupts on every message:

extern "C" void HAL_FDCAN_RxFifo0Callback(fdcan_handle* hfdcan, std::uint32_t RxFifo0ITs)
{
 if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_FULL) != RESET)
 {
 LOG_ERROR("FIFO0 full\n");
 }
 if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) != RESET)
 {
 LOG_ERROR("FIFO0 message lost\n");
 }
 if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
 {
 if (auto* can_reader = can_reader_instance.load(); nullptr != can_reader)
 {
 can_reader->flush(can::fdcan1);
 }
 }
}

 

in flush(), we call HAL_FDCAN_GetRxMessage() over and over to read the FIFO elements into an std::vector and then we print them from the vector. We are anticipating an average message frequency of 1 message per 1ms, but at this speed, we are seeing the FIFO fill up faster than we can read from it. The fastest I have seen a message be handled on our device is around 7ms per message. Should we be able to read the messages fast enough? I have read that DMA is not available for CAN, so are there any other optimizations to be made other than just reading from the FIFO on every message with HAL_FDCAN_GetRxMessage() ?

    This topic has been closed for replies.
    Best answer by Ozone

    > in flush(), we call HAL_FDCAN_GetRxMessage() over and over to read the FIFO elements into an std::vector and then we print them from the vector.

    Calling a "print" function, most probably interrupt based, from within the interrupt context ?
    I consider this a bad idea.

    >... but at this speed, we are seeing the FIFO fill up faster than we can read from it.

    I never dealt with the CAN peripheral of a H7 device, does it contain a hardware FIFO ?
    Because the other STM32 devices I know do not, they have only message boxes (usually 3).


    But in general, I would recommend to profile your application, to see were it spends this time.

     

    4 replies

    Technical Moderator
    May 13, 2025

    Hello,

    Unfortunately there is no other mechanism to read the CAN messages. You need to read the message from Rx FIFO with the CPU.

    Increase as much as possible your CPU frequency in your case 400MHz max (in SMPS).

    Super User
    May 13, 2025

    You can definitely get better performance than 7ms per message, or even 1ms per message. That's an eternity.

    OzoneAnswer
    Explorer
    May 13, 2025

    > in flush(), we call HAL_FDCAN_GetRxMessage() over and over to read the FIFO elements into an std::vector and then we print them from the vector.

    Calling a "print" function, most probably interrupt based, from within the interrupt context ?
    I consider this a bad idea.

    >... but at this speed, we are seeing the FIFO fill up faster than we can read from it.

    I never dealt with the CAN peripheral of a H7 device, does it contain a hardware FIFO ?
    Because the other STM32 devices I know do not, they have only message boxes (usually 3).


    But in general, I would recommend to profile your application, to see were it spends this time.

     

    Technical Moderator
    May 13, 2025

    + What is the interrupt preemption priority you set for the Rx interrupt? set it to the highest one.