Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by jiangtianyu007 on July 14, 2015

For cortex M3/M4, taskENTERCRITICAL/taskEXITCRITICAL mantain a global variable uxCriticalNesting to enable nest, and portSETINTERRUPTMASKFROMISR() - which returns the existing interrupt mask before setting the mask up, and portCLEARINTERRUPTMASKFROMISR() which sets the mask back to its previous value.

  1. I have known that we need to use taskENTERCRITICAL/taskEXITCRITICAL in tasks, and use portSETINTERRUPTMASKFROMISR/portCLEARINTERRUPTMASKFROMISR in ISRs. But why? why I can't use taskENTERCRITICAL/taskEXITCRITICAL in ISR? If I do, what will be happened?

  2. I have mentioned that because of a combination of the way the port works and the intelligence built into the NVIC it is probably ok to use taskENTERCRITICAL/taskEXITCRITICAL in ISRs. It means specifically only to the Cortex-M3/4 ports, it will be ok, but I don't know why other core architecture will be not allowed.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by rtel on July 14, 2015

I think on the Cortex-M you actually can use taskENTERCRITICAL() and taskEXITCRITICAL() in an ISR - but that is one of the very few of the 35+ ports where this is the case. The reason being that on that port you cannot enter an interrupt unless the critical nesting count is 0. In other ports, although it sounds odd, it is legitimate for the FreeRTOS code (not application code!) to context switch when the critical nesting count is non-zero, and in that case using taskENTERCRITICAL() and taskEXITCRITICAL() will be using the nesting count of a task (corrupting the context of a task).

There are several 'rules of thumb' that are stated as blanket rules, although they may not hold in all cases, because documenting each deviation is just too big a task and too confusing for end users. For example, there are rules about when an API function can and cannot be used which are stated as blanket rules that are safe in all cases, whereas the intricacies of the design means that sometimes the rules can be broken with no detrimental effect. Documenting each use case for each function is way too complex for end users, so its easier and safer to generalise rules to ensure safety in all cases.

Regards.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by jiangtianyu007 on July 15, 2015

Thanks for your reply.

But actually I am a little confused.

According to your reply, some issues need to be aligned with you.

Firstly, the reason why I can use taskENTERCRITICAL() and taskEXITCRITICAL() in an ISR for Cortex-M is that interrupt below configMAXSYSCALLINTERRUPT_PRIORITY will not happen unless the critical nesting count is zero. Is it right?

Secondly, for some other cpu architecture (can you tell me the cpu architecture, so I can look the related port code), context switch can happen even the critical nesting count is non-zero. Because in my mind, context switch need a interrupt to trigger, so does it means that even in critical section, interrupt also can happen?

Lastly, you mentioned that "in some case using taskENTERCRITICAL() and taskEXITCRITICAL() will be using the nesting count of a task (corrupting the context of a task)". Dose "using taskENTERCRITICAL() and taskEXITCRITICAL()" means using taskENTERCRITICAL() and taskEXITCRITICAL() in ISR? and Why it will lead to context corrupt? Can you give me some example or code snippet to explain?

Thanks in advance.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by rtel on July 15, 2015

The predecessor to the Cortex-M, the ARM7, is an example of an architecture port that would corrupt a task if it were to use taskENTER/EXIT_CRITICAL() in an interrupt - and yes I am only talking about in an interrupt. As per my previous email, it will corrupt the context of a task because it will corrupt the critical nesting count, which on architectures such as the ARM7 is part of the task's context.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by jiangtianyu007 on July 15, 2015

Thanks very much for your patient answers.

In FreeRTOSV8.2.1FreeRTOSSourceportableGCCARM7LPC2000portISR.c, I review the vPortEnterCritical/vPortExitCritical code. I don't konw much about the ARM7 architecture, but I believe the mechanism of taskENTERCRITICAL() and taskEXIT_CRITICAL() is same as Cortex-M architecture.

The critical nesting count is a global variable, so why you means it is part of the task's context for ARM7 architecture, and how can it corrupt? Can you give me some scenario to explain it.

Looking forward for your reply. Thanks in advance.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by rtel on July 15, 2015

The critical nesting method is the same between the ARM7 and Cortex-M, but the context switching mechanism is completely different.

It is because the critical nesting count is just a variable that it has to be saved and restored as part of the task context on the ARM7.

On the ARM7, when a task is switched out the variable is saved as part of the task context, and when a task is switch in the critical nesting count as that task expects to find it is restored again. This is just like the registers on the CPU - which are also used by all tasks - and so saved and restored as part of the task context. If an interrupt then uses the critical nesting count, it is using the count of a specific task - if the task context then gets saved before the interrupt exits the critical section, then the wrong value for that task will be saved, hence it is corrupt.

The way the Cortex-M is implemented, a context switch cannot happen unless the critical nesting count is 0, so there is no need to save it as part of the task's context.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by jiangtianyu007 on July 21, 2015

Thanks a lot for your detailed reply.

In my opinion, portSETINTERRUPTMASKFROMISR/portCLEARINTERRUPTMASKFROMI can be used in both task thread and ISR because interrupt mask status is stored in local variable other than gloabl variable(uxCriticalNesting). So why FreeRTOS use the two different method of entering critical section?

Why don't we only use portSETINTERRUPTMASKFROMISR/portCLEARINTERRUPTMASKFROMI to enter critical section both in task thread and ISR ?

Thanks in advance.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by rtel on July 21, 2015

...because the method used within interrupts takes stack space, whereas the method used outside of interrupts does not. That is not so important these days but was when FreeRTOS was frequently used on tiny MCUs where every byte of RAM counted.

...also because ports to small MCUs don't support interrupt nesting, so only have the task version.

Regards.


why taskENTER_CRITICAL/taskEXIT_CRITICAL can not be used in ISR ?

Posted by jiangtianyu007 on July 22, 2015

Thanks very much.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS