5.5.10 · D1Embedded Systems & Real-Time Software

Foundations — FreeRTOS — task creation, priorities, xTaskCreate

1,943 words9 min readBack to topic

This page assumes nothing. Before you touch the parent note, you must be able to read every symbol it uses. So we build them one at a time, each anchored to a picture.


0. What is a "CPU core", and why is one a problem?

Picture a single cook standing at one stove. He can stir one pot at this instant. That is the whole difficulty: you have many pots (blink an LED, read a sensor, send UART bytes) but one pair of hands.

Figure — FreeRTOS — task creation, priorities, xTaskCreate

1. A while(1) loop — the shape of a "job"

for (;;) {        // read: "forever, do..."
    toggle_led();
    wait_a_bit();
}

Picture a loop of railway track: the train (the CPU's position in the code) goes round and round and never reaches a station where it stops.

Why the topic needs it: in FreeRTOS a task is exactly one of these loops. A normal C function is a straight road that ends with return; a task is a circle that never ends. (The parent's mistake #4 — "letting a task return" — is precisely breaking this circle.)


2. Stack — the scratch paper of a running loop

Figure — FreeRTOS — task creation, priorities, xTaskCreate

Because our one cook is switching between recipes, each recipe needs its own private notepad so their scribbles never mix. That notepad is the stack. Every task gets its own.

Read this as: bytes reserved = how many words you asked for × how many bytes one word is. On Cortex-M, sizeof(StackType_t) is 4, so 128 words → 512 bytes.


3. Priority — one number that ranks urgency

Picture a row of recipe cards, each with a number stamped in the corner. The manager always grabs the card with the highest number first.

The valid range is 0 .. (configMAX_PRIORITIES - 1). The -1 is just because we start counting at 0: if you allow 5 levels (configMAX_PRIORITIES = 5), the legal numbers are 0,1,2,3,4 — five values, top one is 4.


4. The four task states — where a job can "be"

Figure — FreeRTOS — task creation, priorities, xTaskCreate
State Plain words Uses CPU?
Running actively on the CPU right now yes (only one at a time)
Ready able to run, just waiting its turn no, but wants to
Blocked asleep until some event (a delay ends, data arrives) no — costs nothing
Suspended manually shelved until someone resumes it no

5. The scheduler — the manager that switches

Picture the manager scanning the recipe cards every moment: "Is anything more urgent than what the cook is doing right now? If yes — switch immediately."

The actual act of saving one task's registers and loading another's is a context switch; the saved bundle lives in a TCB (next section). Deep dive: Context Switching and the TCB.


6. The TCB — the task's identity card

Picture an index card the manager keeps per recipe: name, urgency number, and a bookmark saying "the cook was on step 7 of this recipe." When the manager returns to a task, it reads the bookmark and resumes exactly there.

Why the topic needs it: creating a task costs stack + one TCB of memory. That is why xTaskCreate can fail if the heap is too small.


7. Heap, pdPASS, and return codes

BaseType_t and UBaseType_t are simply FreeRTOS's names for "the CPU's natural signed / unsigned integer type" — use them as plain int-like whole numbers.


8. Ticks — how FreeRTOS counts time


9. Pointers and void * — passing a job its ingredients

In the parent's Example 1, (void*)13 smuggles the pin number 13 in through this pointer, and (int)pvParameters unpacks it back to an integer. The prefixes pv, pc, ux, px are just Hungarian hints: pv=pointer-to-void, pc=pointer-to-char, ux=unsigned, px=pointer.


Prerequisite map

One CPU core

Task = infinite loop

Four task states

Stack in words

TCB per task

Heap memory

Priority number

Scheduler picks highest ready

Ticks and tick rate

Blocked via vTaskDelay

void star parameter

xTaskCreate

Each foundation feeds xTaskCreate: you give it a loop, a stack size (words, drawn from the heap to build a TCB), a priority, and a parameter — then the scheduler runs it among the states, using ticks to time its sleeps.


Equipment checklist

Test yourself — reveal only after answering out loud.

How many things can one CPU core execute at the same instant?
Exactly one — everything else is fast switching creating an illusion.
What shape is a task's code, and how does it differ from a normal function?
An infinite loop (for(;;)) that never returns; a normal function ends with return.
What is a stack, and what unit does usStackDepth use?
A task's private scratch memory (local vars + call history); measured in words, not bytes.
On a 32-bit Cortex-M, how many bytes is one word?
4 bytes, so 128 words = 512 bytes.
In FreeRTOS, does a bigger priority number mean more or less urgent?
More urgent — the numerically largest Ready task runs.
What is the highest legal priority value if configMAX_PRIORITIES is 5?
4, because values run 0..configMAX_PRIORITIES-1.
Name the four task states.
Running, Ready, Blocked, Suspended.
Which task state uses zero CPU while waiting?
Blocked.
What does the scheduler do?
Picks the highest-priority Ready task to run, preempting lower ones.
What does the TCB store?
A task's priority, state, and stack pointer (its resume bookmark).
Why can xTaskCreate fail?
The heap can't fit the new stack + TCB; it returns errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY.
What does FreeRTOS count time in, and what converts ms to it?
Ticks; pdMS_TO_TICKS(ms) using configTICK_RATE_HZ.
Why is pvParameters a void *?
So a task can be handed any single argument regardless of its type.