I am making a FreeRTOS BMS application using S32K311 MCU and MC33774A AFE. Communication with AFE is via direct SPI drivers in interrupt mode.
In addition to it I am using CAN ports in interrupt mode for communicating with vehicle and charger. When i send CAN data on any of the ports at less than 100ms interval code halts at
CAN ISR is as follows
What is possibly going wrong and how to handle this/
Solved! Go to Solution.
Hi,
if SPI is getting blocked due to high CAN load, it likely means that the CAN ISR is consuming too much CPU time or starving other interrupts, especially SPI, which is also interrupt-driven. This can cause the SPI transaction to never complete, leaving your TD_Wait() function stuck in its polling loop.
CAN ISR priority is probably too high, preventing SPI ISR from executing.
Solutions to unblock SPI could be lower CAN Interrupt Priority, set it lower than SPI and lower than configMAX_SYSCALL_INTERRUPT_PRIORITY.
This allows SPI ISR to preempt CAN ISR when needed.
Below are some additional hints...
- Reduce CAN ISR Load
Minimize work done in the CAN ISR. Move logging and processing to a FreeRTOS task via a queue.
- Use DMA for SPI
If supported by app, switch SPI to DMA mode to reduce ISR dependency and improve throughput.
- Add Timeout to TD_Wait()
Prevent infinite blocking by adding a timeout or using FreeRTOS synchronization (e.g., semaphore).
- Profile ISR Execution Time
Use a logic analyzer or MCU trace tools to measure ISR durations and identify bottlenecks.
BR, Petr
Setting CAN ISR priority lower than SPI did the job. Now MCU is not halting and CAN task is running without data loss.
Hi,
if SPI is getting blocked due to high CAN load, it likely means that the CAN ISR is consuming too much CPU time or starving other interrupts, especially SPI, which is also interrupt-driven. This can cause the SPI transaction to never complete, leaving your TD_Wait() function stuck in its polling loop.
CAN ISR priority is probably too high, preventing SPI ISR from executing.
Solutions to unblock SPI could be lower CAN Interrupt Priority, set it lower than SPI and lower than configMAX_SYSCALL_INTERRUPT_PRIORITY.
This allows SPI ISR to preempt CAN ISR when needed.
Below are some additional hints...
- Reduce CAN ISR Load
Minimize work done in the CAN ISR. Move logging and processing to a FreeRTOS task via a queue.
- Use DMA for SPI
If supported by app, switch SPI to DMA mode to reduce ISR dependency and improve throughput.
- Add Timeout to TD_Wait()
Prevent infinite blocking by adding a timeout or using FreeRTOS synchronization (e.g., semaphore).
- Profile ISR Execution Time
Use a logic analyzer or MCU trace tools to measure ISR durations and identify bottlenecks.
BR, Petr