Skip to main content

13 docs tagged with "freertos"

View all tags

Context Switching

A context switch is not a function call. A function call returns to its caller; a context switch enters on one task's stack and leaves on another's, and the code that resumes has no idea it was ever stopped. There is no C construct for that. What makes it possible on a Cortex-M is that the processor already performs most of it, for free, every time an exception is taken — and that an exception return reads its destination out of memory rather than from a register, so pointing it at a different stack points it at a different task.

Debugging and Tracing an RTOS

A breakpoint stops time. On bare metal that is a fair trade, because the interesting question is usually "what is in this variable", and a halted core answers it perfectly. Under an RTOS the interesting questions have changed shape: why did the control loop run 4 ms late, which task was holding that mutex, what ran between the interrupt and the response. Every one of those is a statement about a sequence in time, and the instant you halt, the sequence you wanted to observe is gone.

ISR-Safe APIs

Every kernel object in the previous six pages — the ready lists, the delayed list, each queue's two event lists, each mutex's holder field — is an ordinary linked list in RAM, and the kernel keeps it consistent by the only means a single-core Cortex-M offers: it masks interrupts around the update. That is the entire content of taskENTER_CRITICAL(). So a kernel API is not "thread-safe code" in the hosted sense; it is code that assumes nothing else on this core is running while it edits the list.

Priority Inversion and Deadlock

A priority is a promise about who gets the core when two tasks want it. A lock is a mechanism that can break that promise, and the reason is structural rather than accidental: a task holding a lock has implicitly borrowed the urgency of every task that will ever wait for it, and the scheduler has no way of knowing that until someone actually waits. Until that moment the holder is running at its own priority, and the system is scheduling a task that is, in effect, on the critical path of something far more urgent.

Queues and Message Passing

A queue looks like a data structure and is really a design decision. The structure part is unremarkable — a circular buffer with a head, a tail and two waiting lists. The decision is what makes it worth a page: a FreeRTOS queue copies the item in and copies it out again, and every property people value in queues follows from that one fact.

Semaphores and Mutexes

Adding a scheduler adds a second way for code to be interrupted. On bare metal the only thing that could run between your load and your store was an exception handler, and Critical Sections and Atomicity is the complete answer to that. Under a kernel, a task can also be pre-empted by another task, at any instruction, for reasons that have nothing to do with the NVIC. Masking interrupts no longer covers the hazard, because the thing that pre-empted you was the scheduler doing its job.

Software Timers and Delays

There are three clocks in a system running an RTOS and it is worth separating them before writing a single delay. There is the hardware timer, counting a crystal-derived clock in silicon, which does not know or care what software is doing. There is the tick, a periodic interrupt that increments a counter and is the only time the kernel can see. And there is the task's own experience of time, which is the tick as filtered through whether that task was actually running when something expired.

Stacks and Heaps in an RTOS

On bare metal there is one stack, the linker script decides where it starts, and the map file tells you how much room it has. Adopting a kernel deletes all three of those facts at once. There are now N+1 stacks; the linker knows about exactly one of them; and the other N are ordinary arrays — either carved out of a heap at runtime or declared as static — with nothing above or below them that the toolchain considers special.

Task Notifications and Event Groups

Queues, semaphores, mutexes and event groups are all objects. Each has its own allocation, its own handle, and its own place in the system's RAM budget, and a sender has to be given that handle before it can say anything. The kernel's own header states the distinction plainly: those four are "intermediary objects" for sending an event, and a task notification "is a method of sending an event directly to a task without the need for such an intermediary object."

Tasks and Scheduling

A task looks like an infinite loop written as if it owned the processor. That illusion is the whole product, and it is manufactured from three things: a block of RAM used as a stack, a small structure recording where that stack's pointer got to, and membership of exactly one linked list. Everything the scheduler does is move that structure between lists.

The RTOS Landscape

Every kernel on this page implements fixed-priority pre-emptive scheduling with a ready list per priority, blocking primitives, and a tick. If you compare them on scheduling behaviour you will find almost nothing to choose between them, and you will have compared the wrong thing. The scheduler is the commodity part.

Tickless Idle

Tasks and Scheduling established that the tick is a periodic interrupt — SysTick, by default 1000 Hz — that the kernel uses as its only window onto elapsed time. That periodicity is exactly what makes an RTOS system a bad candidate for the deep sleep modes earlier in this folder, for a reason that has nothing to do with how much idle time there is: a system that wakes once a millisecond to increment a counter never gets to stay in a low-power mode for longer than a millisecond, no matter how little else it has to do. Sleep Modes showed that Stop mode's wake latency comes from a regulator switch-back and, at the deepest setting, a flash re-power — real time that has to be paid on every entry and exit. Pay it a thousand times a second and the average current never gets anywhere near the deep-sleep floor in the table on that page; it is dominated by the wake-and-sleep-again overhead, not by the sleep current itself.

Why an RTOS

An RTOS does not make anything faster. It runs the same instructions on the same core at the same clock, and it adds work — a tick interrupt, a scheduler, a context switch — so a system that adopts one gets strictly less CPU time for its application. Anybody selling a kernel on performance is selling the wrong thing.