CS452 - Real-Time Programming - Winter 2015

Lecture 15 - Notifier/Server, UART Interrupts

Public Service Annoucements

  1. Kernel 4 revisions.

Serial I/O

Providing I/O for the terminal


  1. Enable RcvRdy, XmitRdy interrupts in UART.
  2. Enable combined interrupt in ICU


Notifier EVT_BL on RcvRdy event

  1. Interrupt occurs, AwaitEvent returns with received byte.
  2. Notifier Sends byte to server
  3. Server Replys,
  4. Notifier returns to the EVT_BL state
  5. After a while server runs again
    insert( ByteQ, byte );
    if ( ! empty( ClientQ ) ) Reply( extract( ClientQ ), extract( ByteQ ) );

When server receives Get request from client:

    insert( ClientQ, client );
    if ( !empty( ByteQ ) ) Reply( extract( ClientQ ), extract( ByteQ );


Transmitting is a little more tricky because two conditions must be met.

  1. Byte available to transmit
  2. Transmit holding register empty

Assume we put conjunction detection in the server

When server receives Put request from client

    insert( ByteQ, byte );
    if ( notRdy ) { notRdy = false; Reply( notifier, extract( ByteQ ) ) }
    Reply( client, ACK );

When server receives Ready request from Notifier:

    if ( empty( ByteQ ) ) notRdy = true;
    else Reply( notifier, extract( ByteQ );

The Notifier

Typical Notifier pseudocode:

  1. Enable XmitRdy interrupt
    	AwaitEvent( XmitRdy );
  2. Disable XmitRdy interrupt in UART
    	Send( server, ready, byte );
  3. Write byte on UART
There is something I don't like about this pseudocode. What is it?

This procedure assumes that the transmit bit never resets once it is set. Is this true?

Conjunction detection and buffer could just as easily be in the Notifier.

How should we handle a terminal?

Things to think about

  1. Line editing

Echo -- Either


Many other issues come up later in the course as we consider possible task structures.

Providing I/O for the train controller


As Above


For transmitting three conditions must be set

  1. Byte available to transmit
  2. Holding register empty
  3. CTS asserted

Primitives for Serial I/O

We are supposed to support

    int Get( int port )
    int Put( int port, char c )

These are wrappers for sends to one or more serial servers.

You will probably want something more complex in addition to Get and Put.

Timing Inconsistencies

CTS timing.

What you expect to occur when sending to the train controller

  1. The train application puts a byte in the hold register.
  2. The stop bit is transmitted.
  3. A train xmit interrupt occurs.
  4. The train application checks CTS.
  5. If CTS is set, you put the next byte in the hold register.

Sometimes an implementation based on this expectation surprises you. In reality what happens when you are sending to the train controller is the following.

  1. The train application puts a byte in the hold register.
  2. The stop bit is transmitted.
  3. Two things happen in parallel and Because they occur on separately clocked machines no guarantees exist about the order in which these actions will be interleaved. deterministic order. Thus the result of the following action is not deterministic.
  4. If CTS is set, the train application puts the next byte in the hold register.

Terminal Control Code Timing

The control codes you send to the terminal to move the cursor, blank the display, &, are byte sequences, mostly two bytes long. Consider the following scenario.

  1. You discover that your train application is spending too long writing to the terminal, and decide to speed it up using the FIFO.
  2. Turning on the FIFO solves the terminal problem.
  3. About a week before the final demo, after the train application has been running for 1 to 5 minutes, the terminal display messes up to the point where you can no longer enter commands.
What's the problem?

It might be a problem with output to the terminal.

Then, sometimes-squared, the terminal times out waiting for the remainder of the control code, and takes the next character as ordinary ASCII text, which it writes without having moved the cursor.

Return to:

Train Properties

Location: Where am I?

The usual answer is a combination of a landmark plus a measurement.

To get the second part of the answer you can

Train Philosophy

You can't do anything until you know where the train is. You accomplish this by

Measurement is costly, and you should squeeze every bit of information you can out of every measurement you make.

Train Measurement

A locomotive travels on the track at a given speed following the path created by directions of turn outs. Where is the train?

Measurement Noise

You do not get the same answer every time you measure. Here's why.

Measurement is tn, Sn

Actual location is Sn + v \Delta t = Sn + v (Mean delay) + v (Noise in measurement)

A second measurement is tm, Sm

Actual location is Sm + v \Delta t = Sm + v (Mean delay) + v (Noise in measurement)

Difference between measurements is tm - tn, Sm - Sn + 2 v (Noise in measurent)

How do you know where the locomotive is?

Note. I try to be consistent in distinguishing between two closely related concepts: speed and velocity.

Velocity is controlled by changing the train's speed, BUT, the mapping between speed and velocity is complex.

Important. Some of these effects matter; some don't. It's part of your task to find out which is which.

Furthermore, things can go wrong, such as

Avoiding such failures, or responding sensibly to them, is possible only if you have a `good enough' velocity calibration. (You get a perfect calibration only in the limit t->infinity, and train you are calibrating is dead long before that.) Failures like these also pollute your attempt to acquire reliable data for your calibration.

Factors that might effect a calibration.

In general the velocity of a locomotive may be a function of many variables

  1. which locomotive it is
  2. which speed is set
  3. time since the last speed change
  4. the velocity at which it was travelling before the last speed change
  5. where it is on the track
  6. how long since the track was cleaned
  7. how long since the locomotive was lubricated

Important. Some of these effects matter; some don't. It's part of your task to find out which is which.

1. Calibrating Stopping Distance

The simplest objective:

Sequence of events

  1. Train triggers sensor at t
  2. Application receives report at t 1 = t + Δ 1
  3. You give command at t 2 = t + Δ 1 + Δ 2
  4. Train receives and executes command at t 3 = t + Δ 1 + Δ 2 + Δ 3
  5. Train slows and stops at t 4 = t + Δ 1 + Δ 2 + Δ 3 + Δ 4

Questions you need to answer


  1. The sequence of events above has a whole lot of small delays that get added together
  2. Knowing where you stop is very important when running the train on routes that require reversing
  3. Clearly, knowing when you stop is equally important.

This is very time-consuming!

Now make a table

Sensor 1 Sensor 2 ...
Speed 6
Speed 8

There are enough measurements in each cell of the table that you can estimate the random error. (Check with other groups to make certain that your error is not too big.)

Based on calibrations I have seen in previous terms you will find substantial variation with speed setting and train, little variation with sensor.

Group across cells that have the `same' value. Maybe all have the same value.

Hint. Interacting with other groups is useful to confirm that you are on track. Of course, simply using another group's calibration, with or without saying so, is `academic dishonesty'.

2. Calibrating Constant Velocity

At this point there are a few places on the track where you can stop with a precision of a train length or better. However, suppose you want to reverse direction at a switch.

Knowing the Current Velocity

An implicit assumption you are making is that the future will closely resemble the past.

  1. You measure the time interval between two adjacent sensor reports.
  2. Knowing the distance between the sensors you calculate the velocity of the train

    Note that on average the lag mentioned above -- waiting for sensor read, time in train controller, time in your system before time stamp -- is unimportant.

  3. After many measurements you build a table

Using Resources Effectively

The most scarce resources

The most plentiful resource

Any time you can use a plentiful resource to eliminate use of a scarce one you have a win. For example

Practical Problems You Have to Solve

  1. The table is too big.
  2. The values you measure vary randomly.

The values you measure vary systematically

3. Calibrating Acceleration and Deceleration

How Long does it Take to Stop?

Try the following exercise.

  1. Choose a sensor.
  2. Put the train on a course that will cross the sensor.
  3. Run the train up to a constant speed.
  4. Give the speed zero command at a location that stops the train with its contact on the sensor
  5. Calculate the time between when you gave the command and when the sensor triggered.
  6. Look for regularities.

How Long does it Take the Train to Get up to Speed?

Return to: