Professional Documents
Culture Documents
(A1430)
UNIT-III & IV RTOS
J. KRISHNA CHAITHANYA
Associate Professor
j.krishnachaitanya@vardhaman.org
states
Blocking is self-blocking by tasks, and moved to Running state via
other tasks interrupt signaling (when block-factor is
removed/satisfied)
When a task is unblocked with a higher priority over the running
task, the scheduler switches context immediately (for all preemptive RTOSs)
(See Fig 6.1)
3.1 Tasks 1
Issue Scheduler/Task signal exchange for block-unblock of
to vButtonTask (on user interruption by pressing a pushbutton), controlled by the main() which initializes the RTOS,
sets priority levels, and starts the RTOS
(See Fig 6.2, Fig 6.3, Fig 6.4)
stack, etc.
In addition, several tasks share common data (via global data
declaration; use of extern in one task to point to another task
that declares the shared data
Shared data caused the shared-data problem without
solutions discussed in Chp4 or use of Reentrancy
characterization of functions
(See Fig 6.5, Fig 6.6, Fig 6.7, and Fig 6.8)
3.2 Tasks 2
Reentrancy A function that works correctly regardless of the
is on callees stack
A reentrant function calls only reentrant functions
A reentrant function uses system hardware (shared resource)
atomically
or stacked?
See Fig 6.10 Is it reentrant? What about variable fError? Is
printf reentrant?
If shared variables are not protected, could they be accessed
Race condition
Assume the scenario in which
process A reads the free slot (e.g.
7) but before printing, CPU
switches to process B and process
B reads the free slot ( again 7 )
and prints its file name there and
updates it to 8. In that case when
CPU switches back to process A , it
starts from the point it left off
and writes its file in 7. Thus
process B never gets the print of
its file.
Situations like this , when two
processes are using the shared
data20and result depends on who
Race condition
Semaphore is one of the ways for providing
mutual exclusion by protecting critical regions.
21
Semaphores
22
Semaphore Definition
A semaphore is a data structure that is
shared by several processes. Semaphores are
most often used to synchronize operations (to
avoid race conditions) when multiple processes
access a common, non-shareable resource.
By using semaphores, we attempt to avoid
other multi-programming problems such as:
Starvation
Occurs when a process is habitually denied access
to a resource it needs.
Deadlock
23
Semaphore Definition
To indicate a process has gained access to the resource,
the process decrements the semaphore.
For events to progress correctly, the test and
decrement operation on the semaphore must be atomic
(i.e., no interruptible/indivisible).
There are two kinds of Semaphores:
Binary semaphores
Control access to a single resource, taking
the value of 0 (resource is in use) or 1
(resource is available).
Counting semaphores
24
Semaphore Definition
Semaphore is a nonnegative integer that is
stored in the kernel.
Access to the semaphore is provided by a
series of semaphore system calls.
25
.Figure
27
28
Manual Section
Return
Include
File(s)
Summary
Sets errno
Failure
Success
Yes
-1
in critical section
Each shared data (resource/device) requires a separate
routines), faster
Taking/Releasing semaphores (cant use them in interrupt
routines), slower, affecting response times of those tasks that
need the semaphore
Disabling task switches (no effect on interrupt routines), holds
all other tasks response
Contents
Message Queues, Mailboxes and Pipes
Timer Functions
Events
Memory Management
Interrupt Routines in an RTOS Environment
Message Queues,
Mailboxes and Pipes
void Task1(void)
{
if (!!problem arises)
vLogError(ERROR_TYPE_X);
void Task2(void)
while(FOREVER)
{
ReadFromQueue(&iErrorType);
++cErrors;
!! Send cErrors and iErrorType out on
network
}
if (!!problem arises)
vLogError(ERROR_TYPE_Y);
any data
and will return error code and block if not.
Write onto a queue the number of bytes taken up
by a void pointer
pOseQueue = OSQCreate(apvQueue,
SIZEOF_QUEUE);
!!Start Task1
!!Start Task2
}
void Task1(void) {
}
void Task2(void) {
}
void ErrorTask(void)
{
while(FOREVER)
{
iErrorType = (int)
OSQPend(pOseQueue,
WAIT_FOREVER, &byErr);
}
void vMainTask(void)
{
int *pTemperatures;
BYTE byErr;
while(TRUE)
{
pTemperatures =
(int*)OSQPend(pOseQueueTemp,
WAIT_FOREVER, &byErr);
if (pTemperatures[0] != pTemperatures[1])
!! Set Off howling alarm;
}
While(TRUE) {
pTemperatures =
(int*)malloc(2*sizeof*pTemperatures);
pTemperatures[0] =
pTemperatures[1] =
OSQPost(pOseQueueTemp,
(void*)pTemperatures);
}
}
Mailboxes
Much like queues.
RTOS can
Create, write ,check and read from mail
boxes.
The number of messages in a mailbox is
limited.
User can prioritize mailbox messages.
MultiTask!
sndmsg, rcvmsg, chkmsg
Pipes
Much like queues.
RTOS can
Create, write ,check and read from pipes.
Byte-oriented.
Use fread(), fwrite()
Pitfalls
Passing Pointers through a queue may create
shared data bugs
void vReadTemperaturesTask(void)
{
int *pTemperatures;
void vReadTemperaturesTask(void)
{
int iTemperatures[2];
While(TRUE) {
pTemperatures =
(int*)malloc(2*sizeof*pTemperatures);
While(TRUE) {
iTemperatures[0] =
iTemperatures[1] =
pTemperatures[0] =
pTemperatures[1] =
OSQPost(pOseQueueTemp,
(void*)iTemperatures);
OSQPost(pOseQueueTemp,
(void*)pTemperatures);
}
}
}
}
Timer Functions
Must Keep track of the passage of time
Offer taskDelay() functions.
void vMakePhoneCallTask(void)
{
taskDelay(100);
vDialingToneOn(*p_chPhoneNumber 0);
taskDelay(100);
vDialingToneOff();
Events
Procedure
1. More than task can block waiting
2. The events occurs
3. The RTOS will unblock all of tasks
Memory Management
Avoid malloc and free function
Slow and unpredictable
Use the functions that allocate and free
fixed-size buffers.
Predictable
At MultiTask! system
void *getbuf(PoolID, timeout);
void *reqbuf(PoolID);
void reluf(PoolID, *p_vBuffer);
Interrupt Routines
in an RTOS
Environment
Interrupt Routines must not call any RTOS
Interrupt Routines
Environment
in an RTOS
Interrupt Routines
Environment
in an RTOS
Interrupt Routines
in an RTOS
Environment
1. The RTOS intercepts all the interrupts and
then call your interrupt routine.
Interrupt Routines
in an RTOS
Environment
2. Disabling the scheduler for the
duration of the interrupt routine.
Interrupt Routines
in an RTOS
Environment
3.
Nested Interrupts
The RTOS must know
when the lower-priority interrupt
routine.
8.1 Overview
Prior to design, we must construct a specification of the ES to meet
hard)
Properties of the target hardware (for effective design of the ES), e.g., a 9600bps serial port that receives 1200 chars per second, requires an IR that
handles interrupts 1200 times each second. If chars can be written to RAM
using DMA, IR code will be different
Knowledge of microprocessor speed can the proc run the IR 1200 times per
sec?
Need all the software engineering skill you have, plus such properties as:
accordingly
ES design technique: Create all needed tasks, get them into blocked-
(See Fig 8.2 IR and parsing-task use different parts of the mail-buffer: tail and
head)
8.2 Principles 3
Problem Decomposition into Tasks How many tasks?
Considerations (+ if carefully decomposed and few tasks; and if theres no
choice):
+More tasks offer better control of overall response time
+Modularity different task for different device handling or functionality
+Encapsulation data and functionality can be encapsulated within
responsible task
- More tasks means data-sharing, hence more protection worries and long
8.2 Principles 3
Priorities (advantage of using RTOS software architecture):
Decomposing based on functionality and time criticality, separates ES
components into tasks (naturally), for quicker response time using task
prioritization high priority for time-critical ones, and low priority for others
Encapsulating functionality in Tasks
A dedicated task to encapsulate the handling of each shared device (e.g.,
comm
Need a task per stimuli? Same problems!
Recommended Task Structure
Modeled/Structured as State-Machines
Tasks run in an infinite loop
Tasks wait on RTOS for an event (expected in each tasks independent message queue)
Tasks declare their own private data to use (fully encapsulated)
Tasks block on in one place (RTOS signal), and not any other semaphore, no data
sharing
Tasks use no microprocessor time when their queues are empty
throughput
Where the RTOS offers an option to turn time-slicing off, turn it off!
linked and located together into same address space of ROM/RAM See
Chapter 9)
If possible write ES functions to interface with RTOS select features to
shell (and not the RTOS directly) improves portability since only the shell
may be rewritten fro RTOS to RTOS
8.3 An Examples
Issues that remain incomplete specs:
What is displayed? Timing info? Print-line length?
How often is float-level read?
What is the response time on push-button user interface response?
Printer speed number of lines per second?
What is the microprocessor speed? Which kind, 8-bit? The time to set/reset alarm?
Compute-time for # of gallons? 4-5 sec? (influences code design and tasking and
kind of microprocessor if no calc is required to set overflow alarm, that saves time!)
Knowing # gallons, what is the tolerant time-interval, or response-time, to set alarm?
Is reading a pair of temperature and float-level data for one tank at a time?
How is software interface to alarm-set off done write a bit flag to memory or power
cutoff to the alarm device
Does the microprocessor come with a timer?
IRs)
An Example
System Decomposition for Tasks
One low priority task that handles all # gallons calculations and detects leaks
8.3 An Example
Moving System Forward Putting it together as Scenarios
System is interrupt driven via interrupt routines responding to signals,
BIR
BHT
[pt]
D
T
PT
first line to printer; printer interrupts for print IR to send next line to printer; when
all lines (for report) are done, print IR signals print-formatting task for next report
A level task need to read, it interrupts the level-read-hardware routine; the level is
read by the hardware and the IR interrupts the task to read the new float level
Dealing with Shared Level-Data:
Three tasks need this data: level-calc for leak detection; display task; print formatting task
Reading level data and processing it by given task takes a few msec or msec
Use semaphores: let level-calc and display tasks read and process level in critical section
(CS) and let formatting task copy level data in CS, release semaphore, and format outside
CS
See Fig 8.9 and code listing in Chap 11 Black magic and wizardry!! SEng, an Art!
leading to errors
Protect semaphores and associated data encapsulate/hide them in a task
Let all tasks call a separate module (acting as an intermediary) to get to the
(See Fig 8.11 the incorrect alternative, which bypasses the intermediate
function
possible)
Characterizing real-time systems:
Made of n tasks that execute periodically every T n units of time
Each task worst case execution time, C n units of time and deadline of Dn
Assume task switching time is 0 and non-blocking on semaphore
Each task has priority Pn
Question: Cn = (Dn + Jn) < Tn, where Jn is some variability in tasks time
Predicting Cn is very important, and depends on avoiding variability in
(except for initialization/shadowing. The two memory space types are not
interchangeable
Trade-offs: packed data saves RAM space, but unpacking code takes ROM
space
Estimate space by:
A. Tasks take stack space, fewer tasks take less RAM space, inspect code to
estimate stack-bytes per task local variables, parameters, function nestinglevel, worst-case nesting of interrupt routines, space for the RTOS (or select
features) from the manual
B. Experimental runs of the code not easy and wont reflect worst-case
behavior
functions
Consider writing your own function to replace RTOS functions, watch RTOS
functions that call several others
Configure or customize the RTOS functions to suit only the needs of the ES
Study assembly listing of cross-compilers, and rework your C code or write
your own assembly unit/task
Use static variable instead of relying on stack variables (push/pop and
pointering takes space)
Copy data structures passed to a function, via a pointer, into the functions
local, static variables process the data and copy back into structures: tradeof code is slower
For an 8-bit processor, use char instead of int variable (int takes 2-bytes and
longer in calculations than 1-byte chars)
If ROM is really tight, experiment with coding most functions/tasks in
Saving Power
Some embedded systems run on battery, turning battery off for some
Look for the power-saving modes (enablers) which the manufacturers provide
Software can put microprocessor in one the modes via special instruction or
system
Embedded programs are targeted to a target processor (different from the
development/host processor and operating environment) that drives a device
or controls
What tools are needed to develop, test, and locate embedded software into
the target processor and its operating environment?
Distinction
Host: Where the embedded software is developed, compiled, tested,
debugged, optimized, and prior to its translation into target device. (Because
the host has keyboards, editors, monitors, printers, more memory, etc. for
development, while the target may have not of these capabilities for
developing the software.)
Target: After development, the code is cross-compiled, translated crossassembled, linked (into target processor instruction set) and located into the
target
the host must have a tool-chain that includes a cross-compiler, one which
runs on the host but produces code for the target processor
Cross-compiling doesnt guarantee correct target code due to (e.g.,
differences in word sizes, instruction sizes, variable declarations, library
functions)
Cross-Assemblers and Tool Chain
Host uses cross-assembler to assemble code in targets instruction syntax for
the target
Tool chain is a collection of compatible, translation tools, which are pipelined
to produce a complete binary/machine code that can be linked and located
into the target processor
(See Fig 9.1)
Address Resolution
Native Linker: produces host machine code on the hard-drive (in a named
file), which the loader loads into RAM, and then schedules (under the OS
control) the program to go to the CPU.
In RAM, the application program/codes logical addresses for, e.g.,
Locator: produces target machine code (which the locator glues into the
RTOS) and the combined code (called map) gets copied into the target ROM.
The locator doesnt stay in the target environment, hence all addresses are
RAM) for correct reset of initialized variables, in RAM, each time the
system comes up (esp. for initial values that are take #define
constants, and which can be changed)
In C programs, a host compiler may set all uninitialized variable to zero
or null, but this is not generally the case for embedded software crosscompilers (unless the startup code in ROM does so
If part(s) of a constant string is(are) expected to be changed during
code in ROM, which (could decompress and) load the embedded code
from ROM into RAM to execute quickly since RAM is faster, especially
for RISC microprocessors
(See Fig 9.7 Maps)
puller
The PROM programmer must be compatible with the format
(hardware) which emulates the target system, has all the ROM
circuitry, and a serial or network interface to the host system. The
locator loads the Map into the emulator, especially, for debugging
purposes.
Software on the host that loads the Map file into the emulator must
software on the host over a serial port or network connection (just like using
an EPROM)
Advantages:
No need to pull the flash (unlike PROM) for debugging different embedded code
Transferring code into flash (over a network) is faster and hassle-free
New versions of embedded software (supplied by vendor) can be loaded into flash
RAM, modify/debug, and reloading it into target flash memory using above methods
software
Post-shipment application problems are more tolerable than embedded
to exercise)
Develop reusable, repeatable test (difficult to do in target environment,
rest)
Scaffold provides (in software) all functionalities and calls to hardware as in
the hardware-dep and hardware components of the target system more like
a simulator for them!
(continued)
hw
Sw component (B) is vHandleByte, called by A to buffer characters, among
others
The test scaffold, vTestMain(), then calls vHandleByte(), to test if the system
(continued)
BYTE *p_by;
.
.
/* Send each of the characters in a_byTestCommand */
p_by = a_byTestCommand;
while (*p_by)
{
/* Send a single character as though received by the interrupt */
vHandleRxByte (*p_by);
/* Go to the next character */
++p_by;
}
.
.
rather than other part of the host environment, to avoid interruptions in the
scaffolds timing of events
This way, the scaffold has control over sequences of events in the test which
must occur within intervals of timer interrupts
Script Files and Output Files
To let the scaffold test the system in some sequence or repeated times, write
the printer interrupt many times but in a controlled order to avoid swamping
Making the scaffold automatically queue up requests-to-send output lines, by
automatically controlling the button interrupt routine, which will cause
successive pressing of a button to let the next output line be received from
the hardware (the printer interrupt routine). In this way, the hardwareindependent software is controlled by the scaffold, where the button
interrupts serve as a switch
The scaffold may contain multiple instances of the software-independent
code, and the scaffold serves as a controller of the communication between
the instances where each instance is called by the scaffold when the
hardware interrupt occurs (e.g., the scanner or the cash register). In this way,
the scaffold simulates the hardware (scanner or register) and provides
communication services to the software-independent code instances it calls.
See Fig 10.7
as low priority task within the RTOS and have nicely integrated testing
environment
4) The hard to justify limitations cant tell in scafold until the actual
test
Writing to the wrong hardware address software/hardware interactions
Realistic interrupt latency due to differences in processor speeds (host v.
target)
Real interrupts that cause shared-data problems, where real enable/disable is
the key
Differences in network addressing, size of data types, data packing schemes
portability issues
interpret it
Simulator takes the Map as input, reads the instructions from simulated
ROM, reads/writes from/to simulated registers
Provide a user interface to simulator for I/O, debugging (using, e.g., a macro
language)
times
Easier to test assembly code (for startup software and interrupt routines) in
simulator
Easier to test for portability since simulator takes same Map as the target
Other parts, e.g., timers and built-in peripherals, can be tested in the
corresponding simulated versions in the simulated microprocessor
architecture
What simulators cant help:
Simulating and testing ASICs, sensors, actuators, specialized radios (perhaps,
in future systems!!)
Lacking I/O interfaces in simulator to support testing techniques discussed
(unless additional provision is made for I/O to support the scaffold; and scripts
to format and reformat files between the simulator, simulated memory, and
the scaffold)
assumptions
If the expression is TRUE nothing happens, if FALSE, a message is
environment
On failure, assert causes a return to the host operating systems (cant
do on target, and cant print such message on target may not have
the display unit)
Assert macro that runs on the target are useful for spotting problems:
1) disabling interrupts and spin in infinite loop effectively stopping the
system
2) turn on some pattern of LEDs or blinking device
3) write special code memory for logic analyzer to read
4) write location of the instruction that cause problem to specific memory for
logic analyzer to read (the Map can help isolate which source code is the
culprit!)
5) execute an illegal op or other to stop the system e.g., using in-circuit
resistance/connectedness)
Oscilloscopes (scopes) test events that repeat periodically monitoring one or
two signals (graph of time v. voltage), triggering mechanism to indicate start
of monitoring, adjust vertical to know ground-signal, used as voltmeter (flat
graph at some vertical relative to ground signal), test if a device/part is
working is graph flat? Is the digital signal coming through expecting a
quick rising/falling edge (from 0 VCC or VCC 0) if not, scope will show
slow rising/falling indicating loading, bus fight, or other hardware problem
(See Fig 10.10, Fig 10.11, Fig 10.12, Fig 10.13, Fig 10.14)
simultaneously
It knows only of VCC and ground voltage levels (displays are like timing
diagrams) Real scopes display exact voltage (like analog)
Can be used to trigger on-symptom and track back in stored signal to isolate
problem
Many signals can be triggered at their low and/or high points and for how long
in that state
Used in Timing or State Mode
(See Fig 10.17 a typical Logic Analyzer with on-screen button, mouse,
address within the ICE (rather than the systems main ROM or RAM)
facilitates debugging
ICE v. LA
LAs have better trace and filtering mechanism, and easier to detail and find problems
LAs run in timing mode
LAs work with any microprocessor ICE is microprocessor-specific
LAs support many but select signals to attach, ICE requires connecting ALL signals
ICE is more invasive
and communicates with the debugging kernel over serial port or network,
without hardware modifications
Compiled, linked (may be located into Map) code is downloaded from the host
(by the portion on the host) to the target RAM or flash (received by the kernel)
Other designs: ROM Emulator interface and JPAG comm. port on the
target processor
(See Fig 10.19)