tension between flexibility and performance
In cs452 we take guaranteed response time as the defining quality of real-time computation.
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( ); }
From the time that the ready bit sets until the first instruction of do-it is executed
while( !ready ) ; do-it;
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.
and
,
beq
, ldb
, and
,and
beq
Maybe this isn't fast enough for you. Here's an "improvement", for your amusement
L10000000: nop .... L2: nop L1: nop L0: ldb r0, DATA-ADDRESS // get the next byte mov pc, r5 // r5 contains the address to which we branch
In the initialization code we determine, by experiment, exactly how many
nops we need in order to land on the ldb
instruction just after
the ready bit sets.
one NOP
There's a lesson for everybody in this extreme example. (Actually there are more extreme examples, and they are used also.) Wherever there is a nicely structured solution with response time x seconds there is a disgustingly-structured example with reponse time less than x.
What if the CPU has to both things at once?
E.g.,
Unless the rate of bytes coming in and rate of clock ticks are identical
Polling loops allow you to manage more than one condition/activity pair at the same time.
The basic polling loop
FOREVER { if( c1 ) a1; if( c2 ) a2; ... if( cN ) aN; }
if( c<n>
) +
execution time of a<n>}
Suppose you want a better response time for a1. Then try the loop
FOREVER { if( c1 ) a1; if( c2 ) a2; if( c1 ) a1; if( c3 ) a3; ... if( c1 ) a1; if( cN ) aN; }
Worst case response time for a1
if( c1 )
+ maximum over n of execution
time for if( cn ) an
Suppose the response time is still too long, because the execution of one action, say a2, is too long. Then you can break a2 into two parts
FOREVER { if( c1 ) a1; if( c2 ) { a2.1; half-done = TRUE; } if( c1 ) a1; if( half-done ) { a2.2; half-done = FALSE; } ... }
This is strarting to get a little complicated and we haven't said anything about inter-action communication
Provided and maintained by CSCF
linux.student.cs
Connected to UARTs
Only really two
Byte addressable, word size 32 bits
Separate instruction and data caches
GNU tool chain
Partial implementation
Returns when program terminates
COM2 uses monitor; COM1 goes to train
Communication protocol existing since forever.
Why do we still use it in the age of USB, etc.
Three wires
Wired like this
GND ---------- GND XMIT --\ /---- XMIT X RCV----/ \---- RCV
What could be simpler?
Distinguish Data Terminal Equipment (DTE) from Data Circuit-terminating Equipment (DCE)
On the DE-9 connector we have for DTE
5 -- GND 3 -- XMIT 2 -- RCV
and for DCE
5 -- GND 3 -- RCV 2 -- XMIT
A very simple `straight through' cable connects these perfectly. But when we conect DTE to DTE we need the cable above, which is called a `null modem'.
Three wire works fine as long as both ends of the wire are much faster than the wire itself. But the train controller is very slow. Why?
The train controller needs to be able to say STOP. How is this done?
XOFF, XON
CTS, RTS
Return to: