Skip to content

First, What Is It

  • RTOS (Real-Time Operating System): an operating system that makes several "tasks" appear to run at the same time; FreeRTOS is the most popular one in embedded systems.
  • Task: an independent piece of functionality (e.g., "read sensor", "handle button", "send network data"), each with its own stack.
  • Scheduler: the referee deciding "who gets the CPU now", switching tasks by priority and time slice.
  • Why it matters: task state machines, priorities, and "semaphore vs mutex" are nearly guaranteed exam/interview topics, and the path from bare-metal loops to complex projects runs through RTOS.

Breaking Down the Principle

1. Task State Machine

StateMeaningUses CPU?
RunningExecuting nowYes
ReadyQueued, waiting for the schedulerNo
BlockedWaiting for event/delay/queueNo (no busy wait)
SuspendedSuspended; must be resumed manuallyNo

Blocked is the key to low power: a waiting task yields the CPU instead of spinning.

2. Preemptive Scheduling: Higher Priority First

FreeRTOS is preemptive by default: when a higher-priority task becomes ready, it immediately preempts the running lower-priority task. Therefore:

  • A larger priority number means higher priority (the opposite of some other RTOSes — mind the convention).
  • Tasks of the same priority share the CPU by time slicing (each runs one tick, then switches).
  • Scheduling happens at switch points: task blocks/exits, time slice expires, or a higher-priority task becomes ready (including scheduling from an ISR).

3. Inter-Task Communication and Synchronization

Tasks cannot simply "share a global variable and be done" — synchronization mechanisms are needed:

MechanismEssenceTypical use
QueueData pipe; producer puts, consumer takesUART data to a processing task
SemaphoreCounter; Give/TakeEvent notification, resource counting
MutexOnly one task holds it at a timeProtecting shared resources (e.g., same Flash)
Event group / task notificationBit flags / direct notifyMulti-condition triggers, lightweight wake-up

Semaphore vs mutex (a top interview question):

  • A semaphore is a "counter + notification"; it does not care who gives/takes, good for "event happened" notifications.
  • A mutex has ownership (whoever takes it must release it) and supports priority inheritance, for protecting critical resources.
  • Misuse (using a mutex as a semaphore or vice versa) can cause deadlocks or logic errors.

4. Critical Sections and Priority Inversion

  • Critical section: code accessing shared resources, protected by disabling interrupts or holding a lock, to prevent task switches from corrupting data.
  • Priority inversion: a low-priority task holds a lock while a high-priority task waits — the high-priority task is effectively "held back" by the low one. FreeRTOS mutexes mitigate this with priority inheritance (temporarily raising the lock holder to the waiter's priority so it releases quickly).
  • Deadlock: two tasks each hold a lock and wait for the other's. Prevention: consistent lock order, timeouts, avoid nested locks.

How the SDK Implements It

The SDK example skeleton is a typical RTOS program: main() creates a task and starts the scheduler, which never returns:

c
xTaskCreate(app_start_task, "app_start", 1024, NULL,
            configMAX_PRIORITIES - 2, &app_start_handle);
/* Start the scheduler; tasks begin running and this never returns */
vTaskStartScheduler();

Communicating with queues/semaphores and yielding with vTaskDelay is the basic "taskified" style.

Common Exam & Interview Questions

In FreeRTOS, does a larger priority number mean higher or lower priority?

Larger number = higher priority (opposite of some RTOSes); same-priority tasks use time slicing.

Difference between Blocked and busy-waiting?

A blocked task yields the CPU so the scheduler runs other tasks (and the system can sleep); a busy while-loop keeps spinning and wastes CPU.

Difference between a semaphore and a mutex?

A semaphore is a counting/notification mechanism without ownership; a mutex has ownership, supports priority inheritance, and is meant to protect critical resources against priority inversion.

What is priority inversion and how does FreeRTOS mitigate it?

A low-priority task holding a lock blocks a high-priority task. FreeRTOS mutexes use priority inheritance — temporarily raising the holder's priority to the waiter's so it releases quickly.

Why disable interrupts in a critical section?

If a task switch or interrupt occurs while sharing variables, data can be corrupted. Entering a critical section (disabling interrupts) makes the code atomic; mutexes protect shared resources similarly.

Have questions?

For any other questions, visit the unified Q&A and discussion board: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23