Skip to content

FreeRTOS: Tasks, Communication and Memory

Lecture 12 · Real-Time Operating Systems

FreeRTOS provides a concrete example of the mechanisms behind the RTOS overview. This chapter considers a single-core configuration with preemptive scheduling. Kernel configuration and the processor port determine the available behaviour.

Task execution and state

A task has a function, priority, stack and task control block. A context switch preserves enough processor state for the task to resume. A task function normally loops and blocks when it has no work; it must not simply return.

State Meaning Typical transition
Ready Able to execute, waiting for the processor Selected by the scheduler → Running
Running Currently using the processor Wait for input → Blocked
Blocked Waiting for an event or timeout Event or timeout → Ready
Suspended Explicitly excluded from scheduling Explicit resume → Ready

A newly ready high-priority task can pre-empt a lower-priority task. A task unblocked by a timeout does not necessarily execute immediately: it must still win the scheduling decision. See the official task-state definitions.

Choose the communication mechanism

Need Mechanism What to account for
Pass data items Queue Item size, capacity, copies and timeouts
Signal an event Binary semaphore or task notification Whether repeated events may be merged
Count available units Counting semaphore Initial and maximum count
Protect a shared object Mutex Ownership and priority inheritance

Queue items have a fixed size and are copied into queue storage. If the item is a pointer, only the pointer is copied: the application must manage the pointed-to object's lifetime and ownership. Blocking on an empty queue allows other ready tasks to execute; polling continuously consumes processor time.

FreeRTOS mutexes provide a basic priority inheritance mechanism; binary semaphores do not. Mutexes are for task mutual exclusion and must not be used from an interrupt handler. The kernel's simplified inheritance behaviour also needs care when a task holds multiple mutexes. See the mutex documentation.

Interrupts and deferred work

An interrupt handler should acknowledge the event, capture the necessary information and wake a task to perform longer processing. Use the permitted FromISR APIs, follow the port's interrupt-priority restrictions, and request a reschedule when required. An interrupt handler cannot block waiting for a queue or mutex.

Define what happens when events arrive faster than the task can process them. A full queue, lost notification or overwritten sample must have an intentional response rather than silently invalidating the system model.

Memory is part of the design

Budget for each task's stack, kernel objects, queued data and application buffers. Static allocation lets the application provide object storage in advance; dynamic allocation requests storage from a heap. FreeRTOS supports both, depending on configuration. See static and dynamic allocation.

The lecture discusses these heap implementations:

Heap Main distinction
heap_1 Allocates without freeing
heap_2 Frees blocks without coalescing adjacent free blocks
heap_3 Wraps the C library allocator
heap_4 Coalesces adjacent free blocks
heap_5 Extends the coalescing approach to multiple memory regions

Coalescing helps with fragmentation but does not itself prove constant allocation time or guarantee success. For timing-critical paths, establish allocation bounds or allocate required objects before normal execution.

From kernel settings to a timing argument

Record priorities, preemption configuration, tick rate, interrupt behaviour, stack sizes and queue bounds alongside the task parameters. Using an RTOS does not by itself guarantee deadlines: schedulability analysis must match the configured application and include relevant overheads.

Check your understanding

A task blocks on a queue for at most ten ticks. Does that guarantee it processes a message within ten ticks?

No. The timeout bounds the queue wait; the task can then wait in Ready state and still needs execution time to handle a message. A timeout may also occur without receiving any message.