Cortex M0+ critical section

Dear FreeRTOS ninjas, I am looking for some help and some pointers in the right direction regarding interrupts being turned off on Cortex M0+ FreeRTOS which is a problem for my application. The microcontroller that I use is STM32L052K8 and FreeRTOS version 8.2.3. I have been using FreeRTOS a few years now on different projects and I know why interrupts have to be turned off in critical sections or during a context switch (in short to prevent data/stack corruption). But on my current project disabling interrupts causes problems because of the following: My microcontroller communicates with another microcontroller by SPI (my micro is the SPI slave). The problem that I am having is that sometimes when a critical section executes, or during the context switch (vTaskSwitchContext), the FreeRTOS kernel disables all interrupts and my SPI master happens to start send data. Because interrupts are disabled my SPI ISR does not execute and I lose data. After that many bad things happen. I also have two timers that fire interrupts and have to be serviced ASAP. Also using a DMA to solve the SPI problem is not possible. My SPI ISR code and my timer code does not use FreeRTOS functions at all. The SPI master clock speed is relatively high, around 250k, and I have legacy code that uses critical sections (vPortEnterCritical/vPortExitCritical) extensively. My micro clock is 32MHz. All this means that there are times when the interrupts are disabled for long enough to cause problems. I realize that this problem could be easily solved on a Cortex M3/4 core by properly configuring FreeRTOS and using the BASEPRI register – but I am “stuck” with a Cortex M0 core. I tried to implement a couple of different solutions but each time the result was HardFault and or stack corruption. I could not find a thread with a similar problem but if there is any please link it in the reply. Does anyone have experience with this type of issue ? Thanks !

Cortex M0+ critical section

It sounds like the issue is that you have critical sections that are too long. FreeRTOS itself uses only very short critical sections, so if those are causing problems, then you need a better processor. You say you also use critical sections, of some of those are too long, then perhaps you need to change those critical sections to some other method. What FreeRTOS uses for longer exclusion is calls to vTaskSuspendAll()/xTaskResumeAll() which prevent the scheduler from changing what task runs. Another alternative for a selective lockout would be using a mutex (or a semaphore used as a mutex). taskENTERCRITICAL/taskEXITCRITICAL should only be used if you have a VERY short code sequence, just a few lines of code, and any loops with very limited number of cycles, to avoid such problems. ‘RealTime’ is based on requirements. You have some sort of spec on how fast you need to process your interrupts, that is a requirement. That also imposes a restriction on how long of a critical section you are allowed to use. Any Critical Section longer than that is a BUG in your code and must be changed. You choises are: change the code, change the processor to make it fast enough, or change the spec.

Cortex M0+ critical section

Thanks for the prompt reply and for the input. I have taskENTERCRITICAL() / taskEXITCRITICAL() in my legacy code that was written a long time ago and I guss my only option is to chaged that.

Cortex M0+ critical section

You need to understand what the section is protecting. If you need to protect from an ISR, that protection needs the taskENTER/EXIT_CRITICAL (but only over the part that needs ISR protection). A Mutex work best if there are just a limited set of other tasks, and parts of those tasks, you need protection from. It is the least impact on the rest of the system. Suspend/Resume is best if you need protection from lots of the rest of the program, or for lots of scattered read accesses. It can be best if there is a single update of the data, and lots of scattered readers.