You are on page 1of 30

An Embedded Software Primer

David E. Simon
Chapter 8: Basic Design Using a Real-Time
Operating System

1. Overview
2. Principles
3. An Example
4. Encapsulating Semaphores and Queues
5. Hard Real-Time Scheduling Considerations
6. Saving Memory Space
7. Saving Power

2
4/9/2006
Overview
 For a RT system, its function as well as response time are required.
 Criticality of meeting deadlines is also important and based on
whether it is a hard or soft RT system.
 Knowledge of system hardware – e.g. if a serial port receives 1K
characters/sec and each character causes an interrupt, system
should be able to handle it.
 Software design in accordance with previous chapters i.e. structure,
modularity, encapsulation and maintainability to be accounted for.

Principles

General Operation
 RTOS tasks normally are idle until an external event occurs or until
the next period of operation starts. The event might be freeing of a
semaphore or a message sent by another task which releases the
task from its blocked state.

3
4/9/2006
Principles (contd.)
 An e.g. Telegraph system is shown below
(Fig. 8.1 – Simon)

4
4/9/2006
Principles (contd.)
Write Short ISRs
 ISRs should be short mainly because
 Longer ISRs translate to slower task-code response
 ISRs are more bug-prone and harder to debug
 Common practice to make ISRs do the critical actions and pass on
the rest to the tasks.
 Suppose a system has following requirements
 Commands come from a serial port
 Commands end with a carriage return.
 Next command only arrives after system responds to previous one
 Characters at the serial port are not buffered
 System can respond to commands relatively slowly
 A bad design would be to implement everything in the ISR.
 A better way would be to have ISR buffer received characters until it
finds a carriage return, then send the buffered characters to another
(command parsing) task through a mailbox
 This keeps the ISR short and simple

5
4/9/2006
Principles (contd.)
How Many Tasks?
 Work needs to be divided among an optimum number of tasks
 Following are some advantages and disadvantages of having a large no. of
tasks
Advantages
 More control over response times. Critical tasks can be given higher priority as
opposed to a single task doing the entire work.
 More modularity, cleaner code
 Better data encapsulation. e.g. only the task for a network connection needs the
status of the network interface
Disadvantages
 More tasks  more shared data  more semaphore  more semaphore bugs and
corresponding handling time
 Same problem with mailboxes, pipes, queues etc.
 More stack space (memory)
 Increases context switching, hence less throughput
 More tasks  more RTOS calls  slower system. Often advisable to call RTOS
functions as less as possible
 Conclusion – Tasks should be as less as possible. More tasks should be
added only when necessary

6
4/9/2006
Principles (contd.)
You Need Tasks for Priority
 An e.g. where multiple tasks are needed is when some parts of the
work have tighter response times than others like in an embedded
system, a task handling power failure can be given higher priority
than the one performing mathematical calculations
You Need Tasks for Encapsulation
 More sense in having a task for hardware shared by other tasks
 E.g. a printer display is used to respond to the user, report paper
empty, paper jams etc.
 A separate display task ensures messages displayed in correct order,
stay long enough to be read
 Fig. 8.3 shows this diagrammatically
 Similarly when several system parts need to store data in a flash
memory, a task can be assigned for the purpose
 Task can allow one write at a time and set/reset a flag to indicate
when next write can take place

7
4/9/2006
Principles (contd.)
Other Tasks You Might or Might Not Need
 Many small tasks, simpler code
 Trade-off – more shared data and context switching
 Separate tasks for work that is in response to separate stimuli
 Trade-off – same as above

8
4/9/2006
Principles (contd.)
Recommended Task Structure
 Fig. 8.5 shows the pseudo-code for a
recommended task structure

9
4/9/2006
Principles (contd.)
 Task waits for a system signal (through a queue) in an infinite queue
Advantages
 Task only blocks in one place
 Tasks blocked when idle so no processor time used
 Task uses private data so no semaphores needed
 Structure similar to a window routine in MS Windows.
 Embedded systems tasks often modeled as state machines – state variables
stored in private variables in task

Avoid Creating and Destroying Tasks


 Two reasons to avoid doing this while system running
 These functions are the most time-consuming. Nothing constructive done so
throughput reduced
 Destroying a task often leaves bugs. If killed task holding a semaphore, all tasks
waiting for it blocked forever unless the RTOS handles this automatically
 Hence better to create all tasks at system startup and block idle tasks. Only
thing wasted is task stack space and a small overhead for tracking the task.

10
4/9/2006
Principles (contd.)
Turning Time-Slicing OFF
 Time-Slicing done in some RTOSs when 2 ready tasks have same priority.
 If allowed consider turning this option off
 Normally embedded systems have several compute-intensive tasks and in
most cases
 Either they have different urgency levels and hence given different priorities
 All have equal importance  either one can finish first
 Time-Slicing not helpful in both cases
 More context switches  less throughput
 Conclusion – Unless there is an advantage, avoid using it

Restricting RTOS Use


 Most RTOSs allow scaling to reduce memory.
 Hence if user code uses 10 pipes and 1 queue, it might be advisable to
replace queue with a 11th pipe and scale off the RTOS queue code
 Better to limit accesses to pipes, mailboxes etc. to reduce chances of bugs.
 Many RTOSs consist of an outer shell around actual RTOS. User can only
access this.
 Makes code portable, only shell needs to be rewritten when moving to another
OS
11
4/9/2006
An Example
Underground Tank Monitoring System
 System monitors up to 8 underground tanks by reading thermometers and
levels of floats in them.
 Float level is read by sending a command to the hardware which on obtaining
the level interrupts the microprocessor for later reading
 Temperature can be read anytime.
 Both temperature and float level used to find gasoline volume (gallons)
 Monitor tanks – set flag and set off alarm when level dropping consistently
(leak), or when level rising rapidly during tank refueling (overflow).
 User Interface – consists of a 16-button keypad, 20-char LCD and a thermal
printer.
 Keypad used to give commands like displaying levels, request reports,
histories etc.. Buttons interrupt the microprocessor
 A connector to an alarm bell to warn about system leaks or overflows. Turned
off through one of the keypad buttons
 Printer interrupts after printing each line, indicating it is ready for the next
 Display shows most recent data. Retains data on screen until changed by the
processor

12
4/9/2006
An Example (contd.)
Resolving a Timing Problem
 System needs to check tanks with rising floats several times per second.
 Also it takes 4-5 sec to calculate the gasoline quantity after the read which is
a problem
 Resolved by detecting overflows based on float levels alone and not
calculating the gasoline volume

Deciding to Use an RTOS


 4-5 sec gasoline quantity calculation is the most time consuming and must be
pre-empted when other processing is required to be done
 Without an RTOS, ISRs required to do tasks.
 Possible to manage with ISRs in current case but RTOS is a better option

Dividing Work into Tasks


 Following are the tasks needed
Level Calculation Task
 Calculates gasoline volume in each tank based on temperature and float level
 Takes 4-5 sec, hence modeled as a low priority task

13
4/9/2006
An Example (contd.)
 One task for all tanks
Overflow Detection Task
 Higher priority than level calculation task and leak detection
Float Hardware Task
 Tasks requiring the float level send requests to it
Button Handling Task
 Uses a state machine to keep track of buttons already pressed
Display Task
 Prevents tasks from interfering with each others displays.
Alarm Bell Task
 Shared hardware as several of the tasks can turn it on or off.
Print Formatting Task
 Lower priority than button handling task since it might take more than
1/10th of a second to format reports which must not interfere with the
button response
 Using interrupts is the most common way to signal tasks to start or
stop

14
4/9/2006
An Example (contd.)
Dealing with Shared Data
 Gasoline level is shared by several tasks (level calculation,
display, print etc. tasks)
 Can be dealt with either by having a semaphore or a separate
task
 If a semaphore is used, longest time a task will hold onto it is
1-2 ms – print formatting task, assuming all needed data is
first copied to its private variables.
 Hence no need for added complication of extra task
 Fig. 8.9 shows the final task division and message flow

15
4/9/2006
An Example (contd.)

16
4/9/2006
Encapsulating Semaphores
Encapsulating Semaphores
 Done by hiding the semaphore and
corresponding shared data in a module.
 Removes semaphore bugs
 Code below shows an e.g., shared variable
lSecondsToday can only be read through
the function lSecondsSinceMidnight
 If lSecondsToday is read directly it will
lead to bugs.

17
4/9/2006
18
4/9/2006
19
4/9/2006
20
4/9/2006
21
4/9/2006
Encapsulating Queues
Encapsulating Queues
 If direct access is given to queues, following
problems might occur.
 Task might accidentally delete the queue
 Wrong format sent through the queue
 Programmer writes data intended for a task to
the wrong queue.
 Solution – same as above, encapsulate queue in a
module.
 If a function is used to encapsulate the queue, all
shared data must be protected by semaphores
and function must be reentrant
22
4/9/2006
Encapsulating Semaphores and
Queues (contd.)
 queues typically have a protocol or
format associated with.
 multiple message passing calls
increase the probability of a
communication mistake.
 encapsulating such calls into functions
that take specific arguments reduces
these errors.
23
4/9/2006
Hard Real-Time Scheduling
Considerations
 System must guarantee hard deadlines are met.
 Some simplifying assumptions,
 Task n restarts every Tn units of time (period),
hence it must complete before Tn
 Worst-case execution time: Cn
 Priority: Pn
 Tasks don’t block for semaphores, events etc.
 Deadline: Dn (in some cases ≠ Tn)
 Jitter: Jn

24
4/9/2006
Hard Real-Time Scheduling
Considerations
 All these used to determine whether system meets
deadlines
 Being predictable more important then being fast,
so that Cn well defined.
 This to be considered while writing subroutines –
they need to have relatively constant execution
times
 Buffer allocation time should be constant,
independent of the number of buffers (all or none)
allocated. Hence malloc should be avoided since
its execution time depends on current amount of
free memory
25
4/9/2006
Saving Memory Space
 Code stored in ROM, data in RAM
 If an RTOS is used, stack size needs to be
decided on.
 This is determined by no. of function calls,
function parameters and local variables. The
RTOS needs some space for itself
 For worst-case, also include nesting of ISRs
 An experimental way to determine stack
space – fill stack with recognizable data
pattern at startup, run for certain time, see
amount of data overwritten
26
4/9/2006
Saving Memory Space

 Following are some ways to save code space:


 Check if 2 functions not doing same task. E.g. if code calls
memcpy at 20 places and memmove once, try removing
this one call with memcpy and removing memmove from
program
 Check development tools. If memcpy calling causes tools
to call memmove, memset, strcpy etc. try writing your
own function that does not do this.
 Scale down RTOS as much as possible
 Check if C code doesn’t translate into too many assembly
instructions e.g. each of the following 3 methods to
initialize a struct variable result in different no. of assembly
instructions

27
4/9/2006
Saving Memory Space (contd.)
struct sMyStruct aMyData[3];
struct sMyStruct *pMyData[3];
int i;

// Method 1
aMyData[0].iMember = 0;
aMyData[1].iMember = 5;
aMyData[2].iMember = 10;

// Method 2
for(i=0;i<3;i++)
aMyData[i].iMember = i*5;

// Method 3
i=0;
pMyData = aMyData;
Do
{
pMyData ->iMember = i;
i +=5;
pMyData++;
}while (i<10);

28
4/9/2006
Saving Memory Space (contd.)
 Use static variables instead of stack ones as the read
and write translates to fewer assembly instructions in
most microprocessors
 Use char instead of int for 8-bit processors.
 As last option, write code directly in assembly
Saving Power
 Several embedded systems run on batteries so power is an
important issue.
 Most have at least one power saving mode (sleep mode,
idle mode, standby mode etc.)
 Common power-saving mode, one where processor stops
executing instructions, stops clock and any built-in
peripherals
29
4/9/2006
Saving Memory Space (contd.)
 Drawback – system needs to be restarted to function again
 program starts again from the beginning unless
necessary measures taken by software
 Another mode – microprocessor stops executing
instructions but on-board peripherals continue to operate.
An interrupt resumes operation from next instruction after it
was put to sleep
 Saves less power than 1st method, but no special h/w or
s/w required. Other things continue to function, e.g. DMA
can continue to send data to a UART
 Another method – turn entire system off, user will turn it
back on when needed. Values that might be needed at
restart again need to be stored in non-volatile memory
(EEPROM or flash)
30
4/9/2006

You might also like