Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

In the White paper 161204MasteringtheFreeRTOSRealTimeKernel-AHands-OnTutorialGuide, page 265, it says: /* A switch to another task cannot occur between the call to taskENTERCRITICAL() and the call to taskEXITCRITICAL(). Interrupts may still execute on FreeRTOS ports that allow interrupt nesting, but only interrupts whose logical priority is above the value assigned to the configMAXSYSCALLINTERRUPTPRIORITY constant – and those interrupts are not permitted to call FreeRTOS API functions. */ PORTA |= 0x01; But, Frome the Code xQueueGenericReset, it shows that “queueYIELDIFUSINGPREEMPTION” was invoked between “taskENTERCRITICAL()” and “taskEXIT_CRITICAL()” So, How to comprehensive this two conflicts? As reading from the code, i believe it is safe to volunter yield to another task. but the tow conflicts exists, which supporsed to be right?

Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

It depends on the kernel port. Assuming you are using a port that supports interrupt nesting then requesting a context switch inside a critical section will result in the switch being held pending until the critical section is exited – then when interrupts are re-enabled the pending context switch interrupt executes.

Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

that maybe work flow on cortex-m series, which support pendsv press under in interrupt context. but such as on CA9, the volunteer yield operation is done through “svc” call, which would step into svc flow directely and do the swich at once, i did not see any condition would block this switch, it seems the swith would happed and success on CA9 port., which meas voluteer yiled could be done in “taskENTERxxxx” and “taskEXITxxxx” region. may be i am wrong, but if let me know where i am, it woud be greateful to you! thank you.

Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

You are right, which is why I say it depends on the port. In the A9 case the context switch interrupt is synchronous and the kernel code itself is constructed to allow this within API functions – but application code should not perform a context switch inside a critical section and will most likely hit an assert() if they do.

Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

Thanks for your kindly clarification, and i learn this.

Can a Switch to another task occur between the call “taskENTER_CRITICAL” and “taskEXIT_CRITICAL”?

My understanding is as a general principle, you should not invoke FreeRTOS operations within a critical section. It may work for some functions on some ports, but in general it should be avoided. My personal guidelines are that critical section should be kept VERY short, you enter the section, do a few quick operations on globals that need to be done atomically, and then exit the critical section. As a quick guideline, if it is going to need to execute over 100 assembly instructions (and even that is somewhat high) thing strongly if you need this type of critical section. That rule tends to disallow calling most FreeRTOS functions. You only really need taskENTERCRITICAL/taskEXITCRITICAL if you need to protect the operation from an interrupt. It can be used to protect from other tasks, but for that purpose other methods work, and the reason to use taskENTER_CRITICAL there is that it is short so the lower overhead makes sense. FreeRTOS internally seems to use a similar guideline, although I think there the term is more it must be bounded time. Longer protected regions if only needing to protect from tasks could use vTaskSuspendAll()/vTaskResumeAll() or a mutex to provide the interlock, preference being based on the type of interactions. Longer protected regions that need to block a particular interrupt, will use a vTaskSuspendAll() with a disable of that particular interrupt. Longer protected regions that need to block many/all interrupt, tend to cause a serious look at the architecture to see if there is a better way to do it.