Does the return value of xTaskResumeAll realy indicate the task has already been yielded?

The problem is described based on the ARM CM3/4F porting and some following configurations.

  • configKERNEL_INTERRUPT_PRIORITY is 0xf0 (priority 15)
  • configMAX_SYSCALL_INTERRUPT_PRIORITY is 0x50 (mask exceptions which priority level is below 5)
  • The taskYIELD (abbreviation of taskYIELD_IF_USING_PREEMPTION) macro first sets PendSV to pending state and executes the processor barrier (a “DSB” instruction followed by an “ISB” instruction.) According to Application Note 321, the handler of PendSV should be recognized by the processor immediately after the execution of the “ISB” instruction.
  • The handler of PendSV reschedules the current task.

The function, xTaskResumeAll, conditionally executes the taskYIELD macro and set the return value just before leaving the critical section. The critical section decreases the execution priority by setting BASEPRI to 0x50. According to Joseph Yiu, however, the handler of PendSV should not be taken after the execution of processor barrier at the taskYIELD macro because the execution priority has been decreased. Note that the return value, xAlreadyYielded, is set but the task is not yielded yet. If it is vTaskDelay invokes the xTaskResumeAll, I think the result may mislead vTaskDelay to skip the execution of portYIELD_WITHIN_API macro and make a delayed task continue to execute.

I am not sure the reasoning above is quite right. Also, I tried to reproduce the process on STM32F429 DISCO but the generation of PendSV handler is uncertain when using the GDB “stepi” or “nexti” commands. Thus, my question is that is this reasoning reasonable?

PS. One of the rebuttal of the above reasoning I can image is the compiler barrier at the vPortSetBASEPRI inline function invoked by vPortExitCritical function. But unlike vPortRaiseBASEPRI function, there is no “ISB” instruction that the processor can recognize the change of BASEPRI immediately. Thus, I still cannot figure out is the reasoning reasonable?

I presume you are talking about this line: https://sourceforge.net/p/freertos/code/HEAD/tree/tags/V10.2.1/FreeRTOS/Source/tasks.c#l2265

I presume you mean the line referenced above will not actually cause the pendSV handler to execute because it is called from inside a critical section.

I presume you are talking about this line: https://sourceforge.net/p/freertos/code/HEAD/tree/tags/V10.2.1/FreeRTOS/Source/tasks.c#l2262 - if so you are correct because at this point all that has happened is the pendSV interrupt has been pended, but not yet executed because of the aforementioned critical section. On this line: https://sourceforge.net/p/freertos/code/HEAD/tree/tags/V10.2.1/FreeRTOS/Source/tasks.c#l2278 the critical section is exited, which clears the interrupt priority mask, which in turn allows the pended PendSV interrupt to execute. Therefore the PendSV, and potentially a context switch, will occur BEFORE xTaskResumeAll() returns.

I’m not following this part. Are you saying that vTaskDelay() calls xTaskResumeAll(), and if xTaskResumeAll() returns before a pended context switch executes, then vTaskDelay() may not block the calling task immediately? If so, then I don’t think that can happen, because xTaskResumeAll() can’t return without any pended context switches (performed in the PendSV handler) executing.

Did I miss something? I didn’t read through the reference links in your post but Joseph Yiu and other Arm Cortex-M experts within Arm are very familiar with the FreeRTOS Cortex-M port layers.

Thanks for the replay. Yes, the three presumptions you described are what I want to express at the first post.

I think I was wrong. When the critical section is exited, the pending PendSV will be taken. My intuition was that there is no processor barrier (an “ISB” instruction) at vPortSetBASEPRI (CM4F/portmacro.h:l102). According to Sec B5.2.3 in v7-M manual, however, increasing and decreasing execution priority through MSR instruction have different results. Increase the execution priority (lower the value) through MSR instruction does not need a memory barrier instruction. Thus, the change of the execution priority can be recognized immediately. I think this clear my doubt. Thank you.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.