CS452 - Real-Time Programming - Spring 2012
Lecture 1 - Introduction
Pubilc Service Annoucements
- Due date for assignment 0/1
- Combination to trains lab
- Ubuntu 10.10
- How to compile and run your first
program
Practical Details: pdf
Embedded Systems
Most of the mediation between the internal representations and the
real-world is done by embedded systems
- invisible computing
- sense and control
- billions and billions sold
Development Model
Two box model
- develop on one box
- execute on a different box.
Development cycle
- edit & compile on one box
- download to second box
- execute
Problem one
- raw code that owns the hardware itself
- hardware-specific libraries provide access to hardware
- microcontroller/hopper example
Problem two
- OS-like abstraction of hardware
- looks like a bunch of libraries, plus a little more.
What is real-time programming?
Actually real-world programming, which means
- World is measured in seconds, metres, etc.
- Programs manipulate bits, bytes, words, which must be translated into
into real-world measures.
For example,
- formatted output: translate from int, which computers manipulate,
to decimal, which humans read
- out in the open: i2a( ), printf( )
- hidden: print, cout
- Banking: int translates into, e.g., number of cents
- program says dispense( 10000 ), which means `put five twemties
into the hopper'.
- microcontrollers start
- activating motors
- sensing forces
- reading digitized video
- etc.
- Train control: contents of messages map into change speed, switch
turn-out, sensor triggered
What is important for real-time?
- Throughput
- e.g., number of frames per second in a game
- e.g., frequency of sensor sampling in process control
- no solution except
- getting better hardware
- getting better algorithms
- restructuring the task
- Response time
In cs452 we take guaranteed response time as the defining quality of
real-time computation.
Serial I/O
Uses a device called a UART,
- which is really just two shift registers
- with a one byte buffer in front of each one
- plus one bit in a control register for each. They mean
- read: there's a byte you haven't read yet
- write: the buffer is empty, you can write
Busy Waiting
This is used to synchronize with an external event, minimizing response
time.
#define FOREVER for( ; ; )
FOREVER {
while( !ready( ) ) ;
do-it( );
}
or in another form
FOREVER {
if ( ready( ) ) do-it( );
}
Sometimes you only want to do the thing once, as you do when putting a
character on a serial line.
#define UART1_BASE 0x808c0000
#define UART_DATA_OFFSET 0x00 // low 8 bits
#define UART_FLAG_OFFSET 0x18 // low 8 bits
#define TXFF_MASK 0x20 // Transmit buffer full
flags = (int *)( UART1_BASE + UART_FLAG_OFFSET );
data = (int *)( UART1_BASE + UART_DATA_OFFSET );
while( ( *flags & TXFF_MASK ) ) ;
*data = c;
Worst case response time
From the time that the ready bit sets until the first instruction of do-it
is executed
- execution time for
while( !ready ) ;
do-it;
- Even a moderately optimizing compiler will produce good machine code.
Something like
ready:
ldb r0, STATUS-ADDRESS
and r0, r0, READY-BIT
beq _ready
do-it:
ldb r0, DATA-ADDRESS
Here do-it is acquiring a single byte from interface hardware when the
status register indicates that valid data is available in the dara
register.
- Worst case response time is the execution of
and,
beq, ldb, and and
beq
- Normally code like this would be inside a loop, acquiring one byte
after another until no more are available.
The problem with busy-waiting
What if the CPU has to two things at once?
E.g.,
- collect bytes coming in a serial port
- maintain a clock
Unless the rate of bytes coming in and rate of clock ticks are
identical
you are guaranteed to lose something sooner or later.
Return to: