FreeRTOS — task creation, priorities, xTaskCreate
WHAT is a task?
A task is always in exactly one state:
| State | Meaning |
|---|---|
| Running | Currently using the CPU (only one at a time on single core) |
| Ready | Able to run, waiting for the CPU |
| Blocked | Waiting for an event (delay, queue, semaphore) — uses no CPU |
| Suspended | Removed from scheduling until resumed |

HOW you create a task: xTaskCreate
Priorities — the heart of scheduling
Worked Example 1 — two blinking LEDs
void vBlink(void *pvParameters) {
int pin = (int)pvParameters; // Why? pass which LED via param
for (;;) { // Why? a task NEVER returns
gpio_toggle(pin);
vTaskDelay(pdMS_TO_TICKS(500)); // Why? Blocked → frees CPU for others
}
}
void main(void) {
xTaskCreate(vBlink, "L1", 128, (void*)13, 1, NULL); // Why prio 1: above idle
xTaskCreate(vBlink, "L2", 128, (void*)14, 1, NULL); // Why same prio: fair share
vTaskStartScheduler(); // Why? hands control to FreeRTOS; never returns
for(;;); // Why? only reached if heap was too small
}Why pdMS_TO_TICKS? FreeRTOS counts time in ticks, not ms. This macro converts using configTICK_RATE_HZ, keeping code readable and portable.
Worked Example 2 — priority preemption
void vHigh(void *p){ for(;;){ readSensor(); vTaskDelay(pdMS_TO_TICKS(10)); } }
void vLow (void *p){ for(;;){ heavyMath(); } } // never blocks!
xTaskCreate(vLow, "low", 256, NULL, 1, NULL);
xTaskCreate(vHigh, "high", 256, NULL, 3, NULL); // Why prio 3 > 1: must preemptWhy does this work? Every 10 ms vHigh becomes Ready. Because 3 > 1 the scheduler preempts vLow instantly, runs the sensor read, then vHigh blocks again and vLow resumes its math. The sensor gets deterministic timing even though vLow hogs the CPU.
Worked Example 3 — checking the return value
TaskHandle_t h;
if (xTaskCreate(vBlink, "L", 4096, NULL, 1, &h) != pdPASS) {
// Why check? huge stack (4096 words = 16 KB) may exhaust the heap
error_blink(); // fail loudly instead of silently not running
}
vTaskDelete(h); // Why store handle? to delete/suspend this task laterRecall Feynman: explain to a 12-year-old
Imagine one cook (the CPU) in a kitchen with many recipes (tasks). The cook can only do one thing at a time, but a smart manager (the scheduler) makes him switch so fast it looks like all dishes are cooking at once. Each recipe has an urgency number — bigger number = drop everything and do this first. xTaskCreate is you handing the manager a new recipe card, telling him how much counter space (stack) it needs and how urgent it is. A good recipe says "now wait 5 minutes" (vTaskDelay) so the cook can go help others instead of standing idle.
Flashcards
In FreeRTOS, does a higher priority number mean more or less urgent?
What unit is usStackDepth in xTaskCreate?
What are the 6 parameters of xTaskCreate in order?
What does xTaskCreate return on success vs failure?
Why must a high-priority task block (e.g. vTaskDelay)?
What happens to two READY tasks of equal priority?
What are the four task states?
What is the TCB?
What runs at tskIDLE_PRIORITY (0)?
Why must a task function never return?
What does pdMS_TO_TICKS do and why is it needed?
What is preemption in the default FreeRTOS scheduler?
Connections
- FreeRTOS — vTaskDelay vs vTaskDelayUntil
- FreeRTOS — Queues and inter-task communication
- FreeRTOS — Semaphores and Mutexes
- Priority Inversion and Priority Inheritance
- Context Switching and the TCB
- ISR-safe APIs (FromISR) and deferred interrupt handling
- Heap memory management (heap_1..heap_5) in FreeRTOS
- Round-robin vs Preemptive Scheduling
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, microcontroller mein sirf ek CPU hota hai par kaam bahut saare — LED blink karo, sensor padho, UART pe data bhejo. Agar sab ek hi bade while(1) loop mein karoge to timing bigad jaati hai. FreeRTOS isko solve karta hai tasks se: har task apna alag chhota while(1) loop hai jo sochta hai ki poora CPU uske paas hai. Ek chhota sa scheduler itni tezi se task switch karta hai ki lagta hai sab parallel chal rahe hain. xTaskCreate se aap scheduler ko naya task de dete ho.
xTaskCreate ke 6 arguments yaad rakho: function (task ka body), name (sirf debug ke liye), stack depth (words mein, bytes mein nahi — Cortex-M pe ×4 karo bytes ke liye), parameter, priority, aur handle. Sabse bada trap: FreeRTOS mein bada number = zyada urgent. Yani priority 3 wala task priority 1 wale ko beech mein rok dega (preemption). "Big is Boss" yaad rakho.
Ek aur zaroori baat: high-priority task ko hamesha block karna chahiye — vTaskDelay ya queue/semaphore wait se. Agar high task bina ruke kaam karta rahega to neeche wale saare tasks bhookhe (starve) reh jayenge, LED kabhi nahi blink karega. Isliye real-time task apna zyaadatar time Blocked state mein rehta hai, sirf kaam aane par jaagta hai. Aur task function kabhi return mat karna — for(;;) mein wrap karo, warna scheduler crash ho jata hai.
Bas itna samajh lo: tasks = alag-alag recipes, scheduler = manager jo urgency dekh ke cook (CPU) ko switch karwata hai, aur xTaskCreate = nayi recipe card dena with stack size aur urgency. Yeh embedded real-time software ka foundation hai.