I have a little misunderstanding about the difference between the task's TCB and the task stack in an RTOS, doesn't the TCB already carry all needed info about context switching such as registers values and so?
Thanks.
I have a little misunderstanding about the difference between the task's TCB and the task stack in an RTOS, doesn't the TCB already carry all needed info about context switching such as registers values and so?
Thanks.
C does not support threading or multitasking directly and is not thread aware, however a C implementation typically requires a stack for local variables, function parameters and function return addresses.
In a pre-emptive multi-threading environment, each thread must have an independent stack so that the non-thread aware C code has a distinct execution environment.
As you state the TCB contains "info about context switching such as registers values", which may be true in some implementations, in others the TCB may contain only the the value of the task's stack-pointer - with all other registers pushed to the thread's own stack on the context switch. During a context switch, the stack-pointer will be restored, then the context stored on the stack restored. The last register to be popped-off the thread's stack will be the and program-counter causing an immediate jump to the same location with the same same stack (and therefore same local variables and call stack), that it had when it was pre-empted.
Note that implementations may differ in various ways, but the above is a generalised description, rather than a description of FreeRTOS specifically.
The details of a FreeRTOS context switch using an AVR target as an example and a context switch caused by a OS tick is given at: https://www.freertos.org/implementation/a00018.html. There the TCB retains only the task's stack-pointer, the program counter is placed on the stack (automatically by the interrupt in this case example).
An example TCB structure (for ESP32) is given at http://esp32.info/docs/esp_idf/html/d3/d7e/structtskTaskControlBlock.html. Note it does not contain the register values - only the stack pointer, which as per the AVR example is all that is necessary in this case.