Hi,
I’m working on a driver for a sensor that communicate with a MCU (stm32f405rg) through a SPI bus. The MCU is using FreeRTOS. I have 3 choice when it comes to communication with SPI.
I’m concerned that if a task is preempting exactly during the transmision or reception, data might get lost. How can I avoid that? If possible I would like to avoid disabling other interrutpions and of course not having to disable the scheduler. And which of those 3 functions should I use when using freeRTOS?
Data shouldn’t or can’t get lost using any of the methods (in the correct way).
The low level SPI transfer is done in HW by the SPI controller.
Best performance is usually achieved using DMA especially when transferring larger chunks of data and omitting HAL should give leaner code / less footprint.
The first question is are you the SPI bus “Master”, or the “Slave”. Normally, the MCU here would be the master, so as Hartmut said, you shouldn’t loose data, since the master supplies the clock, unless the slave is unusual, and “times out” if the clock stops for awhile. If you are the slave, you almost certainly want to use an ISR or DMA (with an ISR to setup the next buffer when one is received).
If you are the master, then any of the methods should “work”, and the question comes which is the best.
DMA transfers then to be the fastest, unless the transfers are short, then the DMA setup might cost more than the DMA saves.
Using interrupts tends to be good, unless the SPI bus is so fast that the overhead of getting into the ISR uses up most of the time between when you can fill the SPI controller’s buffer.
I generally dislike using the polling I/O that the HAL typically uses, but if your typical message fits in the SPI controller buffer, or DMA isn’t available and the bus is fast enough that the ISR overhead is large, it may be applicable here (I tend to avoid the HAL).
My own SPI driver uses these sorts of heuristics to decide what to do. If message is shorter than the buffer, just load it in. Otherwise if DMA has been configured, use it, and lastly, based on the SPI bus speed either use an ISR or just transfer the data with polling.