Unit 2 - Embedded Real-Time Operating Systems
Unit 2 - Embedded Real-Time Operating Systems
References:
1. Fast and Effective Embedded Systems Design: Applying the ARM mbed – by Rob Toulson and Tim
Wilmshurst
2. https://www.engineersgarage.com/article_page/rtos-real-time-operating-system/
3. https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/freertos_idf.html#a
pi-reference
4. NMU_Espressif_FreeRTOS_V2 PowerPoint – by Frank Adlam
Updated: 25 Feb 2025
Limits of conventional programming
• Conventional programs up to now:
3
RTOS Tasks
• A program written for an RTOS is structured into tasks or threads
• Each task is written as a self-contained program module.
• The tasks can be prioritised, though this is not always the case.
• RTOS performs 3 main functions:
• Decides which thread should run and duration
• Provides communication and synchronization between threads
• Controls use of resources between tasks, e.g. memory and hardware peripherals.
What is a thread?
• A group of instructions that execute to solve a portion of a problem.
• A “problem” could be:
• Design of a dishwasher system
• A “thread” for such a system can be:
• Manage water level thread
• Manage motor speed thread
• A single thread ‘thinks’ that it has the CPU available all the time.
4
RTOS Scheduling
• An RTOS has a thread scheduler, which will run all threads in a manner that
satisfies the constraints of the system.
• Scheduler uses a clock tick (from hardware internal timer) for scheduling
threads.
• At each tick, the scheduler determines if a different task should be given CPU
time.
• Different scheduling methods available, of which Round Robin is the most
common:
5
RTOS – Real-Time Operating System
• A Real-Time Operating System (RTOS) comprises of two components: “Real-
Time” and “Operating System”.
Real-time systems
• Systems in which the correctness of the system depends not only on the logical
result of computation, but also on the time at which the results are produced.
6
• RTOS does not necessarily increase the speed of execution, BUT provides much
more precise and predictable timing than general-purpose OS.
• RTOS is key to many embedded systems
• Embedded systems with relatively simple/small hardware/code might not
require an RTOS.
• Embedded systems with moderate-to-large software applications require some
form of scheduling, and hence RTOS.
7
Difference: RTOS v/s General Purpose OS
Determinism
• Key difference is “deterministic ” timing behaviour
• Deterministic timing – OS consume only known and expected amounts of time.
• In RTOS worst case latency is defined; Latency is not of a concern for General
Purpose OS.
Task Scheduling
• General purpose OS optimized to run applications and processes simultaneously
– all tasks receive at least some processing time.
• Consequence: Low-priority tasks may execute above other higher priority tasks
• RTOS uses priority-based preemptive scheduling – high-priority threads to meet
their deadlines consistently.
• All system calls are deterministic
• Important where delay could cause a safety hazard.
• The scheduling in RTOS is time based.
• In case of General purpose OS, like Windows/Linux, scheduling is process based.
8
Preemptive kernel
• In RTOS, all kernel operations are preemptible
• Means that a thread can be preempted (suspended) when a higher priority
thread has control
Priority Inversion
• A situation when lower priority thread holds a resource, while higher priority
thread is ready to use it.
• The lower priority thread prevents the higher priority thread to execute.
• RTOS have mechanisms to prevent priority inversion.
Usage
• RTOS used for embedded applications.
• General Purpose OS are used for Desktop PCs or other generally purpose PCs.
9
RTOS classification
• RTOS specifies a known maximum time for each of the operations that it
performs.
• Based upon the degree of tolerance in meeting deadlines, RTOS are classified
into following categories:
• Hard real-time – Degree of tolerance for missed deadlines is negligible. A missed
deadline can result in catastrophic failure of the system
• Firm real-time – Missing a deadline might result in an unacceptable quality reduction
but may not lead to failure of the complete system
• Soft real-time – Deadlines may be missed occasionally, but system doesn’t fail and
also, system quality is acceptable
• Hard real-time examples: motor vehicle airbags, automatic parachute
deployment, etc.
• Soft real-time examples: TV live broadcast etc.
• Determinism: An application is referred to as deterministic if its timing can be
guaranteed within a certain margin of error.
• Jitter: Timing error of a task over subsequent
iterations of a program or loop is referred to
as jitter; RTOS are optimized to minimize jitter.
10
RTOS features
• Multithreading and preemptability – The scheduler should be able to preempt
(suspend) any task in the system and allocate the resource to the thread that
needs it most even at peak load.
• Thread Priority – All tasks are assigned priority level to facilitate pre-emption.
The highest priority task that is ready to run will be the task that will be running.
• Inter Task Communication & Synchronization – Multiple tasks pass information
among each other in a timely fashion and ensuring data integrity
• Priority Inheritance – RTOS should have large number of priority levels and
should prevent priority inversion using priority inheritance.
• Short Latencies – The latencies are short and predefined.
• Task switching latency: The time needed to save the context of a currently executing
task and switching to another task.
• Interrupt latency: The time elapsed between execution of the last instruction of the
interrupted task and the first instruction in the interrupt handler.
• Interrupt dispatch latency: The time from the last instruction in the interrupt handler
to the next task scheduled to run.
11
RTOS architecture
Six types of common services are shown in the following figure below:
12
Task Management: Task/Thread Object
• RTOS application consist of small, schedulable, and sequential program units
known as “Tasks” or threads.
• Three time-critical properties
• Release time – the point in time from which the task can be executed.
• Deadline – point in time by which the task must complete.
• Execution time – time the task takes to execute.
• Each thread has its own registers and stack
13
• A Thread can be in the following states:
• RUNNING: The thread that is currently running is in the RUNNING state. Only one
thread at a time can be in this state.
• READY: Threads which are ready to run are in the READY state. Once the RUNNING
thread has terminated or is WAITING the next READY thread with the highest priority
becomes the RUNNING thread.
• WAITING: Threads that are waiting for an event to occur are in the WAITING state.
• INACTIVE: Threads that are not created or terminated are in the INACTIVE state.
These threads typically consume no system resources.
• When CPU control is changed from one task to another, context switching
occurs:
• context of the to-be-suspended task will be saved
• context of the to-be-executed task will be retrieved
14
Task Management: Scheduler
• The scheduler:
• keeps record of the state of each task
• selects thread that are ready to execute
• allocates the CPU to one of them.
• Various scheduling algorithms are used in RTOS:
• Polled Loop: Sequentially determines if specific task requires time.
• Polled System with interrupts: In addition to polling, it takes care of critical tasks.
15
• Round Robin: Sequences from task to task, each task getting a slice of time
• Hybrid System: Sensitive to sensitive interrupts, with Round Robin system working in
background
• Interrupt Driven: System continuously wait for the interrupts
• Non pre-emptive scheduling or Cooperative Multitasking: Highest priority task
executes for some time, then relinquishes control, re-enters ready state.
16
Synchronisation and communication:
Task Synchronisation
• Synchronization is essential:
• for tasks to share mutually exclusive resources (devices, buffers, etc.)
• and/or allow multiple concurrent tasks to be executed (e.g. Task A needs a result from
task B, so task A can only run till task B produces it).
• Task synchronization is achieved using two types of mechanisms:
Event Objects
• Used when task synchronization is required without resource sharing.
• Allow one or more tasks to keep waiting for a specified event to occur.
• Events are signals to a task:
• That effect the execution of a task.
• Typically come from outside the task.
• Can be combinatorial
• External hardware events:
• Water level full in dishwasher.
• Hardware pushbutton pressed.
• Software events:
• Another task has completed its operation. 17
Semaphores
• A semaphore has an associated:
• resource count – indicates availability of resource.
• wait queue – manages the tasks waiting for resources from the semaphore.
• A semaphore functions like a key that define whether a task has the access to
the resource.
• A task gets an access to the resource when it acquires the semaphore.
• If the semaphore is already in use, the requesting thread is suspended until the
semaphore is released by the current owner
• There are three types of semaphores:
• Binary – A value of 0 or 1 Counting Semaphores
• Counting – non-negative integer value
• Zero
• Another task is in specific critical section
• Resource is busy
• Non-zero
• You can enter critical section of code
• Resource is available
• Mutually Exclusion(Mutex) Semaphores
• Issues: Priority Inversion
18
Mutually Exclusion (Mutex) Semaphores
• Prevents conflicting access to common resource:
• Hardware Registers
• Peripherals
• Data structures
• The same as binary semaphore
• Mutexes can lead to deadlocks occurring
• RTOS provide priority inheritance to overcome problem of priority inversion:
• Mutex may have inheritance
Deadlocks:
• Each task waits for the other to release the mutex:
• Neither threads completes execution.
19
Synchronisation and communication:
Intertask Communication
• Intertask communication involves sharing of data among tasks through sharing
of memory space, transmission of data, etc.
• Intertask communications is executed using following mechanisms:
Message queues
• Send or receive messages placed in a shared memory.
• The queue may follow 1) First In First Out (FIFO), 2) Last in First Out(LIFO) or 3)
Priority (PRI) sequence.
• Usually, a message queue comprises of an associated queue control block (QCB),
name, unique ID, memory buffers, queue length, maximum message length and
one or more task waiting lists.
• Standard method for inter-task communication: Queue is allocated storage.
Definable size and number of entries. May contain data or pointers.
• Tasks can add messages: Many tasks can write message to the queue
• Tasks can pend on the queue.
20
Mailbox
• A message queue with a length of 1 is commonly known as a mailbox.
• What is it?
• Method to send ‘pointer’ sized asynchronous data between tasks.
• Often implemented as a simple queue.
• Tasks must agree on what ‘pointer’ points to
• Multiple tasks can wait on a message to be posted:
• Highest priority task wins in retrieving message.
• Multiple tasks can post a message:
• Only one message can be present in the mailbox at any time.
Pipes
• Provide simple communication channel used for unstructured data exchange
• A pipe does not store multiple messages but stream of bytes.
• Data flow from a pipe cannot be prioritized.
Remote procedure call (RPC)
• Permits distributed computing where task can invoke the execution of another
task on a remote computer.
21
Other services
Memory Management
• Two types of memory managements are provided in RTOS:
• Stack management – used during context switching for TCBs.
• Heap management – Memory other than memory used for program code,
program data and system stack is called heap memory
• Typical RTOSs provide memory allocation facilities:
• Frequently fixed block scheme.
• Deterministic service calls.
• Avoid memory fragmentation.
• RTOS System Calls for Memory Allocation:
• Allocate –allocate a block from memory.
• Free –release a block of memory.
• Query –query fixed block size, number of available blocks, etc. in a memory area
Timer Management
• Tasks need to be performed after scheduled durations. To keep track of the
delays, timers- relative and absolute- are provided in RTOS.
22
Interrupt and event handling
• RTOS provides various functions for interrupt and event handling:
• Defining interrupt handler
• Creation and deletion of ISR
• Referencing the state of an ISR
• Enabling and disabling of an interrupt
• Etc.
23
Priority Inversion
• What is it?
• When a lower priority task holds a resource that a higher priority task needs, the
higher priority task must wait (as if it were a lower priority task) until the lower
priority task releases the resource. In such scenario, the lower priority task executes
as if it has higher priority.
• Problem typically encountered in dealing with RTOS service like Semaphore
• Can be solved by Priority Inheritance:
• Not always the best solution, design it out!
24
Critical Sections
• What is it?
• A sequence of code that must execute atomically.
• E.g. update system data-structures
• Semaphores and Mutexes used to guard Critical Sections
• Locking interrupts (or scheduler) may be desirable:
• If manipulating only one variable or so.
• Less OS overhead.
• This may degenerate Interrupt Response
25
FreeRTOS: Overview
• FreeRTOS (Free Real-Time Operating System) is an open-source, lightweight real-
time operating system (RTOS) designed for embedded systems,
microcontrollers, and IoT devices.
• It provides task scheduling, resource management, and synchronization
features, allowing multiple tasks to run independently and efficiently on the
same processor.
Key Features:
• Multitasking with Task Scheduling
• FreeRTOS allows multiple tasks (functions running in parallel) to share the CPU.
• It uses a preemptive or cooperative scheduler to decide which task gets CPU time.
• Task
• Lightweight and Efficient
• Designed for microcontrollers with limited resources.
• Requires as little as 4KB of Flash memory and a few hundred bytes of RAM.
• Can run on bare-metal hardware without an underlying OS.
26
FreeRTOS: Overview
• Inter-Task Communication
• Queues: Tasks can send and receive messages safely.
• Semaphores & Mutexes: Prevents multiple tasks from accessing shared resources at the
same time (avoiding race conditions).
• Event Groups: Tasks can signal each other using events.
• Timers & Delays
• FreeRTOS provides software timers for executing functions at specific intervals.
• Tasks can be delayed using vTaskDelay() or vTaskDelayUntil().
• Portability & Hardware Support
• Supports hundreds of microcontrollers, including ESP32, STM32, ARM Cortex-M, AVR,
and PIC.
• Can be integrated into frameworks like ESP-IDF (for ESP32) and CMSIS-RTOS (for ARM
Cortex).
28
ESP32 FreeRTOS APIs
• The ESP32 uses the ESP-IDF framework, which includes a customized version of
FreeRTOS.
• The official documentation can be found at:
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system
/freertos_idf.html#tasks
• Although the code examples are written in an ESP-IDF style (which differs from
the Arduino framework), the FreeRTOS APIs can still be used directly in the
Arduino IDE with minor modifications.
• The remaining slides will focus solely on the fundamental principles necessary
for basic multithreaded applications.
• For more in-depth information and a comprehensive understanding, please
refer to the API documentation and examples provide on the Control Software
Moodle page.
29
FreeRTOS: vTaskDelay() vs. delay()
• vTaskDelay() is a non-blocking FreeRTOS function that puts the calling task into
a "Blocked" state for a specified time, allowing other tasks to execute.
vTaskDelay(xTicksToDelay);
Parameters:
Example:
30
FreeRTOS: xTaskCreate()
• Creates a new task and adds it to the list of tasks that are ready to run.
xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority,
pxCreatedTask);
Parameters:
• pvTaskCode – The function that will run as the task (must have void functionName(void *pvParameters) format).
• usStackDepth – The amount of stack memory allocated to the task (measured in words, not bytes).
• pvParameters – A pointer to data passed into the task when it starts (useful for passing configurations or task-specific
data).
• uxPriority – The priority level of the task (higher values mean higher priority).
• pxCreatedTask – A pointer to a variable that stores the handle of the created task (useful if the task needs to be
managed later). If not needed, this can be NULL.
Example:
31
Task function Task name Stack size (1000 words) No parameters Priority 1 No task handle needed
FreeRTOS: vTaskDelete
• A task can be deleted using vTaskDelete():
vTaskDelete(NULL); // Deletes the current task
32
FreeRTOS: Task/Thread Function
• In FreeRTOS, a task (also called a thread) is a function that runs independently
and is managed by the FreeRTOS scheduler.
• A FreeRTOS task must follow this structure:
void TaskFunction(void *pvParameters) {
while(1) { // Infinite loop (tasks usually run forever)
// Task code here
vTaskDelay(pdMS_TO_TICKS(1000)); // Non-blocking
delay
}
}
• void *pvParameters – Allows passing parameters to the task.
33
#define led0Pin 4 //LED0
Thread Example: #define led1Pin 16 //LED1
#define led2Pin 17 //LED2
void setup() {
pinMode(led0Pin, OUTPUT);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
void setup() {
// Create the event group
myEventGroup = xEventGroupCreate();
}
• events will be used later to test which bit was set exactly
Parameters:
• EventGroup – The handle to the event group that was created earlier.
• BitsToWaitFor – The bit (or bits) that the task is waiting for.
• ClearOnExit – Should the bit be cleared automatically after the task unblocks? (pdTRUE = yes, pdFALSE = no)
• WaitForAllBits – Should the function wait for all bits or just any one? (pdTRUE = yes, pdFALSE = no)
• Waiting for any one of multiple bits. This means that if any of EVENT_A or
EVENT_C bits are set, the task unblocks.
EventBits_t events = xEventGroupWaitBits(myEventGroup, EVENT_A | EVENT_C, pdTRUE, pdFALSE,
portMAX_DELAY);
38
FreeRTOS: Event Groups
Testing which bits were set
• After calling xEventGroupWaitBits(), the returned value (events in our case)
contains the event bits that were set at the time the function unblocked.
• You can test which bits were set using bitwise AND (&) operations.
EventBits_t events = xEventGroupWaitBits(myEventGroup, EVENT_A | EVENT_B, pdTRUE,
pdFALSE, pdMS_TO_TICKS(5000));
39
EventFlags Example:
Consider the following room temperature control system, which consist of:
• A heater – to increase the temperature in the room
• A temperature sensor – measures the temperature (0V = 0°C; 3V = 100°C)
• A LED – to indicate when temperature is too low or too high
Could do this with a State Machine and a Timer… (will attempt this first in class) OR
we could use RTOS…
40
define TEMP_HIGH 0b00000000000000000000000000000001
#define TEMP_LOW 0b00000000000000000000000000000100
TaskHandle_t LedTaskHandle;
TaskHandle_t HeaterTaskHandle;
EventGroupHandle_t MyEventFlags;
41
void HeaterControlTask(void *parameter) {
while (1) {
// Wait for only TEMP_LOW flag
xEventGroupWaitBits(MyEventFlags, TEMP_LOW, pdTRUE, pdTRUE, portMAX_DELAY);
ledcWrite(HEATER_PIN, 128); // 50% duty cycle (heater on)
vTaskDelay(pdMS_TO_TICKS(2000));
ledcWrite(HEATER_PIN, 255); // 100% duty cycle
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(TEMP_PIN, INPUT);
ledcAttach(HEATER_PIN, 1000, 8); // 1 kHz PWM, 8-bit resolution
MyEventFlags = xEventGroupCreate();
void loop() {
float tempValue = analogRead(TEMP_PIN) / 4095.0; // Normalize ADC value (0.0 -
1.0)
• BlockTime – Specifies how long the task should wait if the semaphore is not available.
Example:
xSemaphoreTake(myMutex, portMAX_DELAY);
• The portMAX_DELAY tells the task to wait indefinitely until the mutex is available. Other options:
45
Mutex Example:
Consider the following system which consist of:
• A LED (LED0 on SwLed Shield)
• A push button (PB3 on SwLed Shield)
• A push button (PB0 on SwLed Shield)
46
Solution:
Could do this with a Flowchart and Interrups and Timers… (will attempt this first in
class) OR we could use RTOS…
Using threads we could … :
• Thread 1 (loop()) to flash LED
• Thread 2 to turn LED ON
• Thread 3 to turn LED OFF
SemaphoreHandle_t myMutex;
47
void test_thread3(void *pvParameters) { // Task for turning LED Off
while (1) {
if (digitalRead(pb0Pin) == LOW) { // When pb0Pin is pressed
xSemaphoreTake(myMutex, portMAX_DELAY); // Lock access to LED
digitalWrite(ledPin, LOW); // LED OFF
while (digitalRead(pb0Pin) == LOW) { } //stay in the while loop until pb is released
xSemaphoreGive(myMutex); // Release access to LED
}
}
}
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(pb0Pin, INPUT_PULLUP);
pinMode(pb3Pin, INPUT_PULLUP);
myMutex = xSemaphoreCreateMutex();
48