FreeRTOS API functions must not be called from within a critical section – Please explain

From the documentation of taskENTER_CRITICAL(), I’ve seen this info “FreeRTOS API functions must not be called from within a critical section”. In one of my projects using Cortex M0, I happen to use xQueueSendFromISR() from within a critical section in an ISR. I face no problems in using this, so just wanted to know the EXACT TECHNICAL REASON of why this is mentioned. *P.S : I could only find Answers like “As a general Rule of Thumb …” . Can anyone please explain it in detail ? *

FreeRTOS API functions must not be called from within a critical section – Please explain

First, you should not be calling taskENTERCRITICAL inside an ISR, as it doesn’t end in FromISR (there is on many port a taskENTERCRITICALFROMISR routine that can be used if the port supports nested interrupts), and I don’t think that function has the same note. (I don’t know off hand if the M0 allows nested interurpts so it provides/needs a critical section in ISRs). The big issue is that if you call a FreeRTOS function that blocks inside a critical section, you run into an issue that the taskENTER_CRITICAL call says no other task or ISR will be run during it, but the blocking says that some other task should be run, so the result will by necessity break some expectation. ISRs never block, so this can’t be an issue for a critical section in an ISR. Many ports implement the scheduler call via a interrupt call, so it can’t be called in a critical section.

FreeRTOS API functions must not be called from within a critical section – Please explain

The Cortex-M0 does not have a basepri register, so critical sections don’t mask just a subset of interrupt priorities as per the Cortex-M3/4/7 ports, but all interrupts – so interrupt nesting isn’t supported directly by the kernel for that port. Therefore a critical section inside an interrupt is not necessary, and the “From ISR” versions of those functions referred to by Richard D are just null macros. The ‘rule of thumb’ description is given because it is not only dependent of the API function in use, but also dependent on the FreeRTOS port in use. For example, consider a port that uses a trap to perform a context switch synchronously – in a critical section the trap may just cause an exception (because of the state of the processor when you are in a critical section), whereas other architectures may not. In any case, anything that is supposed to block of switch to a higher priority task that doesn’t because you are in a critical section can cause application logic errors.

FreeRTOS API functions must not be called from within a critical section – Please explain

Thank you guys. I’m using a 4 year old code in which it said that taskENTERCRITICAL was introduced in the ISR context to fix a bug that occured years back. It works perfectly now, but under some rare cases we are having some issues. As far as FreeRTOS part is concerned, this is the one in which we are violating the rule. So we are now trying to find an alternative for this approach and is planning to use taskENTERCRITICALFROMISR (which is not a null macro). In fact, this is what is done inside that macro :- ** asm volatile( ” mrs r0, PRIMASK n” ” cpsid i n” ” bx lr ” ); ** Will this make any difference ?

FreeRTOS API functions must not be called from within a critical section – Please explain

FreeRTOS API functions must not be called from within a critical section – Please explain

On 1/14/2019 9:55 PM, Akshay wrote:
Thank you guys. I’m using a 4 year old code in which it said that taskENTER_CRITICAL was introduced in the ISR context to fix a bug that occured years back.
Really? Which code is that? Can you please give more information.

FreeRTOS API functions must not be called from within a critical section – Please explain

It’s a confidential code developed and maintained by previous developers in our company. But it looks something like this : taskENTERCRITICAL(); if(xQueueSendFromISR( ….)) { taskEXITCRITICAL(); … }
this is in an ISR context, and the addition of critical section is what is mentioned to be done as a workaround for a bug fix that occured long back (Nobody remembers the exact reason). I dont want to bring around new bugs in removing this but just wanted to know answers to these questions 1) Here, will the use of taskENTERCRITICALFROM_ISR (which is not a null macro in our case as mentioned above) make any difference? 2) Is there an alternative approach for the above mentioned code?

FreeRTOS API functions must not be called from within a critical section – Please explain

If the port supports nested interrupts, then taskENTERCRITICALFROMISR, which should be called something like: uint32t mask = taskENTERCRITICALFROMISR(); will block interrupts up to the level that is allowed to use the FreeRTOS FromISR API, from occuring until the next occurance of taskEXITCRITICALFROMISR(mask); (note the additon of a parameter in the calls) If it doesn’t support nested interrupts, then there is no need to do this, as nothing will be able to interfere. If nesting IS possible (or was in an earlier version of the code) the Critical Section may have been needed if some other ISR might play with that Queue also.

FreeRTOS API functions must not be called from within a critical section – Please explain

Thanks Richard. Now I know why taskENTERCRITICALFROM_ISR will be useless in our case. The thing which I still don’t understand is :
In any case, anything that is supposed to block of switch to a higher priority task that doesn’t because you are in a critical section can cause application logic errors
Can you explain this point in detail. How does context switching in a critical region cause application Logic errors ?

FreeRTOS API functions must not be called from within a critical section – Please explain

A context switch can’t happen in a critical setion, thats why you have a critical section, so you can’t switch to some new context. The issue comes if you want to test the status of something, and react appropriately, and not have to worry that something else might have changed the conditon. Note that xQueueSendFromISR internally uses a critical section for accessing the queue so it can test that there is room, and using it, without problems that someone else takes the space that it thought was available. In the code you posted, which had to be incomplete as the critical section was only ended if the send succedded, perhaps the else clause to handle a failed send needed to assume that some other ISR wasn’t going to come along and make room in the queue during its recovery. That would require a critical section. It could also be that at one point there was more code after the Send and before the end critical, that has since been removed, and now the critical section isn’t needed in this version.

FreeRTOS API functions must not be called from within a critical section – Please explain

+Akshay AJ akshay.aj@gadgeon.com On Thu, Jan 17, 2019 at 5:10 PM Richard Damon wrote:
A context switch can’t happen in a critical setion, thats why you have a critical section, so you can’t switch to some new context. The issue comes if you want to test the status of something, and react appropriately, and not have to worry that something else might have changed the conditon. Note that xQueueSendFromISR internally uses a critical section for accessing the queue so it can test that there is room, and using it, without problems that someone else takes the space that it thought was available. In the code you posted, which had to be incomplete as the critical section was only ended if the send succedded, perhaps the else clause to handle a failed send needed to assume that some other ISR wasn’t going to come along and make room in the queue during its recovery. That would require a critical section. It could also be that at one point there was more code after the Send and before the end critical, that has since been removed, and now the critical

section isn’t needed in this version.

FreeRTOS API functions must not be called from within a critical section – Please explain

https://sourceforge.net/p/freertos/discussion/382005/thread/7beb78c86f/?limit=25#3a80

Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/ To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/
— Regards, Akshay A J https://www.linkedin.com/in/akshay-a-j-a7744b106