You are on page 1of 36

4.

REAL-TIME OPERATING SYSTEMS

4.1 Introduction
4.2 Context switching mechanisms
4.3 Scheduling policies
4.3.1 Preemptive Priority-Based Scheduling
4.3.2 Round-Robin Scheduling
4.4 Message passing and shared memory communications
4.4.1 Shared Memory with Mutexes
4.4.2 Shared Memory with Interrupt Locks
4.4.3 Shared Memory with Preemption Locks
4.5 Inter-process communication
4.1 INTRODUCTION

 Embedded OS
 Why an OS at all?
 Same reasons why we need one for a traditional computer.
it serves as the core software that manages and controls the
hardware resources of the computer
 Not all services provided by an operating system are needed
for every device or system.
REASONS WHY AN OPERATING SYSTEM IS NEEDED IN
EMBEDDED SYSTEMS
 Here are some reasons why an operating system is needed in
embedded systems,
 Resource Management:

- An embedded OS helps manage system resources efficiently, including


memory, processor, and peripherals.
 Task Scheduling:

- Operating systems provide task scheduling mechanisms to manage the


execution of multiple tasks or processes in a timely and efficient manner
 Device Abstraction:
- An OS abstracts hardware complexity, providing a uniform interface
for application development. This abstraction simplifies the development
process and allows applications to be hardware-independent.
THE REQUIREMENTS FOR AN OPERATING SYSTEM Antilock Braking System

can vary depending on the specific use case, hardware capabilities, and intended functionality of the device.
Large variety of requirements and environments:
 1. Critical applications with high functionality (e.g., medical applications, space shuttle, process automation):
 - Reliability and fault tolerance:These applications require high levels of reliability to ensure safe and consistent
operation. The operating system should be designed with fault-tolerant mechanisms, real-time capabilities, and rigorous
testing to minimize the risk of failures.
 - Deterministic performance:Real-time performance guarantees are essential for critical applications where timing
precision is crucial. The operating system should provide deterministic behavior to meet strict timing requirements.
 - Security: Robust security features are critical to protect sensitive data and prevent unauthorized access. The
operating system should include strong authentication, encryption, access controls, and secure communication
protocols.

 2. Critical applications with small functionality (e.g., Antilock Braking System (ABS), pacemaker):
 - Resource efficiency: These applications have limited hardware resources and require an operating system that is
lightweight and optimized for low-power consumption. The operating system should be tailored to run efficiently on
constrained devices without sacrificing performance.
 - Real-time responsiveness: Real-time capabilities are essential for critical applications with small functionality to
ensure timely and precise responses to external stimuli or events. The operating system should provide deterministic
behavior and low latency for critical operations.

 3. Less critical applications with varying functionality (e.g., smartphone, smart card, microwave oven):**
 - Flexibility and scalability: Operating systems for less critical applications should be flexible and scalable to
accommodate a wide range of functionalities and usage scenarios. Modularity and customization options can allow
users to adapt the system to their specific needs.
 - User experience: Emphasizing user-friendly interfaces, responsiveness, and intuitive interactions can enhance the
usability of the operating system for consumer-oriented devices like smartphones and smart cards.
 - Resource management:Efficient resource utilization and performance optimization are important for less critical
applications to ensure smooth operation without unnecessary resource consumption.
4.1 INTRODUCTION
 Why is a desktop OS not suited?
 Monolithic kernel is too feature rich: In a monolithic kernel
architecture, the entire operating system, including device drivers,
file system management, memory management, and system call
interfaces, is implemented as a single, large, and cohesive unit.
 Monolithic kernel is not modular, fault-tolerant, configurable,
modifiable, … .(This lack of modularity can make it challenging
to isolate and modify specific components without affecting the
entire system.)
 Takes too much memory space.
 It is often too resource hungry in terms of computation time.
 Not designed for mission-critical applications.
 Timing uncertainty too large.
4.1 INTRODUCTION
 What is an RTOS?
 An RTOS is a class of operating systems that are intended for real
time-applications
 What is a real time application?
 A real time application is an application that guarantees both
correctness of result and the added constraint of meeting a deadline
 So what is an RTOS?
 An operating system which follows the Real Time criteria.
 Efficiency, Predictability and Timeliness –important
 All components of an RTOS must have these properties.
 Some tasks which may delay things:
 Interrupt Processing, Context Switching, Inter-task communication,
4.1 INTRODUCTION
 So what makes an RTOS special?
 An RTOS will provide facilities to guarantee deadlines will be met
 An RTOS will provide scheduling algorithms in order to enable
deterministic behavior in the system
 An RTOS is valued more for predictability than throughput
 Design Philosophies
 Some of the design philosophies of an RTOS are with respect to:
 Scheduling
 Memory allocation
 Inter task communication
 Interrupt handlers
4.1 INTRODUCTION
 In some applications, an RTOS comprises only a
kernel, which is the core supervisory software
that provides minimal logic, scheduling, and
resource-management algorithms.
 Every RTOS has a kernel.
 an RTOS can be a combination of various
modules, including the kernel, a file system,
networking protocol stacks, and other
components required for a particular application,
as illustrated at a high level in Figure 4.1.
4.1 INTRODUCTION

Figure 4.1: High-level view of an RTOS, its kernel, and other components found in embedded systems .
4.2 CONTEXT SWITCHING MECHANISMS

 Each task has its own context, which is the state


of the CPU registers required each time it is
scheduled to run.
 A context switch occurs when the scheduler
switches from one task to another.
 To better understand what happens during a
context switch, let’s examine further what a
typical kernel does in this scenario.
4.2 CONTEXT SWITCHING MECHANISMS
 Every time a new task is created, the kernel also creates
and maintains an associated task control block (TCB).
 TCBs are system data structures that the kernel uses to
maintain task-specific information.
 TCBs contain everything a kernel needs to know about a
particular task.
 When a task is running, its context is highly dynamic.
This dynamic context is maintained in the TCB.
 When the task is not running, its context is frozen within
the TCB, to be restored the next time the task runs.
 A typical context switch scenario is illustrated in Figure
4.2.
4.2 CONTEXT SWITCHING MECHANISMS

Figure 4.2: Multitasking using a context switch


4.2 CONTEXT SWITCHING MECHANISMS
 As shown in Figure 4.2, when the kernel’s scheduler
determines that it needs to stop running task 1 and
start running task 2, it takes the following steps:
 The kernel saves task 1’s context information in its TCB.
 It loads task 2’s context information from its TCB, which
becomes the current thread of execution.
 The context of task 1 is frozen while task 2 executes, but
if the scheduler needs to run task 1 again, task 1 continues
from where it left off just before the context switch.
4.2 CONTEXT SWITCHING MECHANISMS

 The time it takes for the scheduler to switch from one task to
another is the context switch time.
 It is relatively insignificant compared to most operations that a
task performs.
 If an application’s design includes frequent context switching,
however, the application can incur unnecessary performance
overhead.
 Every time an application makes a system call, the scheduler
has an opportunity to determine if it needs to switch contexts.
 When the scheduler determines a context switch is necessary,
it relies on an associated module, called the dispatcher, to
make that switch happen.
4.2 CONTEXT SWITCHING MECHANISMS
 The dispatcher is the part of the scheduler that performs
context switching and changes the flow of execution.
 At any time an RTOS is running, the flow of execution,
also known as flow of control, is passing through one of
three areas: through an application task, through an ISR, or
through the kernel.
 When a task or ISR makes a system call, the flow of
control passes to the kernel to execute one of the system
routines provided by the kernel.
 When it is time to leave the kernel, the dispatcher is
responsible for passing control to one of the tasks in the
user’s application.
4.3 SCHEDULING POLICIES

 As mentioned earlier, the scheduler determines


which task runs by following a scheduling
algorithm (also known as scheduling policy).
 Most kernels today support two common
scheduling algorithms:
 preemptive priority-based scheduling, and
 round-robin scheduling
 The RTOS manufacturer typically predefines these
algorithms; however, in some cases, developers can
create and define their own scheduling algorithms.
 1. Preemptive Priority-Based Scheduling:
 In preemptive priority-based scheduling, tasks are assigned priorities, and the scheduler
selects the highest-priority task for execution. If a higher-priority task becomes ready to run,
it preempts the currently executing task, leading to a context switch. Preemptive scheduling
ensures that higher-priority tasks are given precedence over lower-priority tasks, which is
essential for real-time systems where tasks have strict deadlines or urgency levels.

 Advantages:
 - Supports task prioritization based on criticality or importance.
 - Ensures that high-priority tasks are executed promptly.
 - Helps meet real-time requirements by allowing time-critical tasks to preempt lower-priority
tasks.

 Disadvantages:
 - Priority inversion issues may occur, where a lower-priority task holds a resource needed by
a higher-priority task.
 - Priority inversion can be mitigated using techniques like priority inheritance or priority
ceiling protocols.
4.3.1 PREEMPTIVE PRIORITY-BASED SCHEDULING

 Of the two scheduling algorithms introduced here,


most real-time kernels use preemptive priority-
based scheduling by default.
 As shown in Figure 4.3 with this type of
scheduling, the task that gets to run at any point is
the task with the highest priority among all other
tasks ready to run in the system.

Figure 4.3: Preemptive priority-based scheduling.


4.3.2 ROUND-ROBIN SCHEDULING
 Round-robin scheduling provides each task an equal
share of the CPU execution time.
 Pure round-robin scheduling cannot satisfy real-time
system requirements because in real-time systems,
tasks perform work of varying degrees of
importance.
 Instead, preemptive, priority-based scheduling can be
augmented with round-robin scheduling which uses
time slicing to achieve equal allocation of the CPU
for tasks of the same priority as shown in Figure 4.4.
4.3.2 ROUND-ROBIN SCHEDULING
 2. Round-Robin Scheduling:
 In round-robin scheduling, tasks are assigned a fixed time quantum or time slice for
execution on the CPU. The scheduler cycles through the ready tasks in a circular
manner, allocating each task a time slice to run. If a task does not complete within its
time quantum, it is preempted, and the next task in the queue is given CPU time.
Round-robin scheduling provides fairness in CPU allocation and prevents any single
task from monopolizing the CPU for an extended period.

 Advantages:
 - Provides fair allocation of CPU time among tasks.
 - Prevents tasks from starving by ensuring that each task gets a chance to run.
 - Simple and easy to implement.

 Disadvantages:
 - May not be suitable for real-time systems with strict timing requirements.
 - May lead to inefficiencies if tasks have varying execution times or resource
4.3.2 ROUND-ROBIN SCHEDULING

Figure 4.4: Round-robin and preemptive scheduling

With time slicing, each task executes for a defined interval, or time slice, in an
ongoing cycle, which is the round robin.
A run-time counter tracks the time slice for each task, incrementing on every
clock tick.
When one task’s time slice completes, the counter is cleared, and the task is
placed at the end of the cycle.
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 Message passing supports explicit data transfer
between processes; hence, it does not require a
shared memory and lends itself well to be
extended to distributed systems.
 This inter-process communication method
provides for two primitives:
 The SEND primitive sends a message to a given
destination.
 Symmetrically, RECEIVE receives a message from a
given source.
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 Communication can be signal-centric, data-
centric, or both.
 In signal-centric communication, all necessary
information is conveyed within the event signal
itself.
 In data-centric communication, information is
carried within the transferred data.
 When the two are combined, data transfer
accompanies event notification.
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS

 When communication involves data flow and is unidirectional,


this communication model is called loosely coupled
communication.
 In this model, the data producer does not require a response from
the consumer.
 Figure 4.5 illustrates an example of loosely coupled
communication.
 For example, an ISR for an I/O device retrieves data from a device
and routes the data to a dedicated processing task

Figure 4.5: Loosely coupled ISR-to-task communication using message queues


4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 In tightly coupled communication, the data movement is
bidirectional
 The data producer synchronously waits for a response to
its data transfer before resuming execution, or
 the response is returned asynchronously while the data
producer continues its function.

Figure 4.6: Tightly coupled task-to-task communication using message queues


4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 As shown in Figure 4.6, task #1 sends data to task #2
using message queue #2 and waits for confirmation to
arrive at message queue #1.
 The data communication is bidirectional.
 It is necessary to use a message queue for
confirmations because the confirmation should contain
enough information in case task #1 needs to re-send the
data.
 Task #1 can send multiple messages to task #2, i.e.,
task #1 can continue sending messages while waiting
for confirmation to arrive on message queue #2.
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 Communication has several purposes, including
the following:
 transferring data from one task to another,
 signaling the occurrences of events between tasks,
 allowing one task to control the execution of other
tasks,
 synchronizing activities, and
 implementing custom synchronization protocols for
resource sharing
 The first purpose of communication is for one
task to transfer data to another task
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATIONS
 The second purpose of communication is for one task to
signal the occurrences of events to another task.
 The third purpose of communication is for one task to
control the execution of other tasks. Tasks can have a
master/slave relationship, known as process control.
 The fourth purpose of communication is to synchronize
activities.
 When multiple tasks are waiting at the execution barrier,
each task waits for a signal from the last task that enters the
barrier, so that each task can continue its own execution.
 The fifth purpose of communication is to implement
additional synchronization protocols for resource sharing.
4.4 MESSAGE PASSING AND SHARED MEMORY COMMUNICATION
 Multiple ways of accomplishing resource
synchronization are available.
4.4.1 Shared Memory with Mutexes
 In this design pattern, task #1 and task #2 access

shared memory using a mutex for


synchronization.
 Each task must first acquire the mutex before

accessing the shared memory.


 Figure 4.7 shows the order of execution with

respect to each task.


4.4.1 SHARED MEMORY WITH MUTEXES

Figure 4.7: Task-to-task resource synchronization-shared memory guarded by mutex

•The task blocks if the mutex is already locked,


indicating that another task is accessing the shared
memory.
•The task releases the mutex after it completes its
operation on the shared memory.
4.4.2 SHARED MEMORY WITH INTERRUPT LOCKS
 In this design pattern, the ISR transfers data to the task using
shared memory, as shown in Figure 4.8.
 The ISR puts data into the shared memory, and the task removes
data from the shared memory and subsequently processes it.
 The interrupt lock is used for synchronizing access to the shared
memory.

Figure 4.8: ISR-to-task resource synchronization- shared memory guarded by interrupt lock
4.4.3 SHARED MEMORY WITH PREEMPTION LOCKS
 In this design pattern, two tasks transfer data to each other using
shared memory, as shown in Figure 4.9.
 Each task is responsible for disabling preemption before accessing
the shared memory.
 Unlike using a binary semaphore or a mutex lock, no waiting is
involved when using a preemption lock for synchronization.

Figure 4.9: Task-to-task resource synchronization-shared memory guarded by preemption lock


4.5 INTER-PROCESS COMMUNICATION
 An essential function of a multi-programmed operating system is
to allow processes to synchronize and exchange information; as a
whole, these functions are known as Inter Process
Communication (IPC).
 Semaphores, first introduced by Dijkstra in 1965, are a
synchronization device with an integer value, and on which the
following two primitive, atomic operations are defined.
 The P operation, often called DOWN or WAIT, checks if the current
value of the semaphore is greater than zero. If so, it decrements the
value and returns to the caller; otherwise, the invoking process goes into
the blocked state until another process performs a V on the same
semaphore.
 The V operation, also called UP, POST, or SIGNAL, checks whether
there is any process currently blocked on the semaphore. In this case, it
wakes exactly one of them up, allowing it to complete its P; otherwise,
it increments the value of the semaphore. The V operation never blocks.
4.5 INTER-PROCESS COMMUNICATION
 Semaphores are a very low-level IPC mechanism; therefore, they
have the obvious advantage of being simple to implement, at least
on uni-processor systems, and of having a very low overhead.
 By contrast, they are difficult to use, especially in complex
applications.
 Also related to mutual exclusion with semaphores is the problem
of priority inversion.
 Priority inversion occurs when a high-priority process is forced to
wait for a lower-priority process to exit a critical region, a situation
in contrast with the concept of relative task priorities.
 Most real-time operating systems take this kind of blocking into
account and implement several protocols to bound it; among these
we recall the priority inheritance and the priority ceiling protocols.
4.5 INTER-PROCESS COMMUNICATION
 To overcome the difficulties of semaphores, in
1974/1975, Hoare and Brinch Hansen introduced a
higher-level synchronization mechanism, the monitor.
 A monitor is a set of data structures and procedures that
operate on them
 Data structures are shared among all processes that can
use the monitor, and it effectively hides the data
structures it contains.
 The only way to access the data associated with the
monitor is through the procedures in the monitor itself.
 In addition, all procedures in the same monitor
are implicitly executed in mutual exclusion.
4.5 INTER-PROCESS COMMUNICATION
 Inside a monitor, condition variables can be used
to wait for events. Two atomic operations are
defined on a condition variable:
 The WAIT operation releases the monitor and blocks
the invoking process until another process performs a
SIGNAL on the same condition variable.
 The SIGNAL operation unblocks exactly one process
waiting on the condition variable. Then, to ensure that
mutual exclusion is preserved, the invoking process is
either forced to leave the monitor immediately
(Brinch Hansen’s approach), or is blocked until the
monitor becomes free again (Hoare’s approach).

You might also like