2025-05-13 4:22 AM
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() ?
2025-05-13 4:33 AM - edited 2025-05-13 4:42 AM
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).
2025-05-13 5:19 AM
You can definitely get better performance than 7ms per message, or even 1ms per message. That's an eternity.
2025-05-13 5:33 AM
> 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.
2025-05-13 6:37 AM
+ What is the interrupt preemption priority you set for the Rx interrupt? set it to the highest one.