cancel
Showing results for 
Search instead for 
Did you mean: 

CAN FIFO filling faster than flushing

chipchop
Associate II

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() ?

4 REPLIES 4
mƎALLEm
ST Employee

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).

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".
Ozone
Principal

> 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.

 

mƎALLEm
ST Employee

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.