CS452 - Real-Time Programming - Winter 2018

Lecture 2 - Polling Loops

Public Service Annoucements

  1. Substitute for the newsgroup: mailing list suggested.
  2. E-mail only to uwaterloo addresses
  3. Due date for assignment 0
  4. Instruction and data caches, compiler optimization, higher clock speed, UART FIFOs. Any one of these turned on during a0 may lead to one or another obscure bug.
  5. Libraries: memcpy in particular
  6. Nettops:
  7. Laptops:
  8. University gitlab: git.uwaterloo.ca
  9. Comments about first.pdf

Practical Details: pdf


"Smart" terminals

In the late 1970s Digital Equipment Corporation (now part of HP by way of Compaq) introduced a "smart" terminal called the VT100; the feature that made it "smart" was cursor addressing. There were keys added to its keyboard each of which sent several characters at once. The first character was always ESCAPE, so these key sequences were called escape sequences. Each sequence moved the cursor in some way. Putting these sequences into editors created the first full-screen editors: such as ked, keyboard editor for RT-11, late 1970s.

The first escape codes moved the cursor around the display. They were used more often by programs than by users. (Many were programs executed by keyboards that made a single key press return two or more keystrokes.) Without cursor adderssing it was necessary to write 80 X 24 characters to make a change to the display, even if only 2 characters were changing. With cursor addressing an escape sequence could put the cursor in the right place after which the program can send the characters to be changed.

Escape sequences vary from one terminal program to another with a common core which is the set created for the VT100.


Timers

How does one keep time in a computer?

There is one master clock, a crystal oscillator in a phase-locked loop. It is divided down to clock all the different parts of the computer. The frequency of a crystal oscillator is only precise to manufacturing tolerances. The master clock is a square wave signal, the edges of which latch data in clocked logic.

There are five counters available to you in the EP9302.

None of them drives the time-of-day functions you see in an operating system. What is the ntp daemon?

In practice, how do you find out the time for a0? You watch for the overflow of a timer.

In practice, how do you know that you are keeping accurate time?


Busy Waiting

This is used to synchronize with an external event, minimizing response time. This bit of code waits for something to be ready then does something as soon at whatever it is is ready. Then it waits for the same thing again and does the same action a second time.

    #define FOREVER for( ; ; )

    int ready( ) {
      return( *0xZZZZZZZZ & READY_BIT );
    }

    FOREVER {
      if ( ready( ) ) do-it( );
    }
  
Actually, the code above does not necessarily work. Almost every compiler in the world converts the above code to
    if ( ready( ) ) do-it( );
  
The compiler does not know that the value returned by ready( ) might change without an assignment somewhere in the code.

Note. The volatile keyword is one way of controlling the compiler. You can alternatively write assembly code or compile without optimiziation.

Worst case response time

The busy wait reponse time is very fast, But what if the CPU has to three things at once? For example,

  1. receive bytes coming to one serial port,
  2. receive bytes coming to another serial port, and
  3. maintain a clock in the terminal window.

To understand this problem we need to do a little mental arithmetic to see, for example, how long the CPU would spend busy-waiting.


Digression: How many bits in a byte?


Four questions.

Polling Loops

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;
}

Worst case response time

What you put into an action matters a lot.

Suppose you put busy-wait I/O to the train controller into an action

Will you catch it in the testing you do?

Testing more than once

Suppose you are getting events that trigger a1 too infrequently. 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

Breaking into pieces

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; }
      ...
    }
  
When we are using interrupts this is called opening up an interrupt window.

This is strarting to get a little complicated and we haven't said anything about inter-action communication. How would you accomplish that?


A few odds and ends about trains

  1. Put a terminal between the ARM box and the train controller.
  2. The three way switches are actually a pair of switches so they have four states
  3. Turning a train headlight on and off is an easy way to see if you are communicating with the train controller successfully.

Return to: