In this lesson, you will learn how to map the lifecycle of an RTOS task as it transitions between states to manage CPU resources efficiently.
The Task Lifecycle
In a multitasking RTOS environment, the scheduler acts as a traffic controller. A task does not simply "run"; it exists in one of four primary states based on what it needs from the hardware:
- Running: The task currently has control of the CPU. Only one task can be in this state at a time on a single core.
- Ready: The task is capable of running but is waiting for a higher-priority task to yield the CPU.
- Blocked: The task is waiting for an external event, such as a timer expiration, a hardware interrupt, or data from a peripheral. It cannot run even if the CPU is free.
- Suspended: The task is deliberately put on hold by the system or another task. It is "invisible" to the scheduler until it is explicitly resumed.
Visualizing the Transitions
The transitions are governed by events. For example, when a task is Running and must wait for an I/O operation, it transitions to Blocked. Once the I/O completes, an interrupt signals the kernel, moving the task back to Ready.
Consider this logic flow represented by a task's decision-making process:
void Task_Handler(void *pvParameters) {
while(1) {
// State: Ready -> Running
Perform_Calculations();
// State: Running -> Blocked
// Waiting for a semaphore (e.g., waiting for serial data)
xSemaphoreTake(xSerialSemaphore, portMAX_DELAY);
// State: Blocked -> Ready -> Running
Process_Incoming_Data();
}
}
If a higher-priority task preempts this one during Perform_Calculations(), the scheduler moves our task from Running back to Ready without the task even realizing it was paused. The task remains Ready until the scheduler determines it is the highest-priority task again, at which point it transitions back to Running. Managing these states ensures that the CPU remains productive while respecting the timing constraints of your firmware.
Key Takeaway: The scheduler manages task states to ensure the highest-priority work is always running, while tasks waiting for external stimuli remain in a blocked state to conserve CPU cycles.