CS452 - Real-Time Programming - Winter 2016

Lecture 15 - Serial I/O, Debugging

Pubilc Service Announcements

  1. Due date for kernel 4: 22 February.

Serial I/O 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. The byte is moved into the shift register and shifted out.
  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 the following set of events occur.

  1. The train application puts a byte in the hold register, which is loaded and shifted out.
  2. The stop bit is transmitted.
  3. Two things happen in parallel.
    1. In the train controller,
      • The train controller sees the stop bit.
      • Then, probably on the next clock edge, it latches the character and negates CTS.
      • After one or two clock cycles the byte is clear of the train UART, and CTS is re-asserted.
    2. In the ARM CPU
      • The train xmit interrupt occurs.
      • The train application checks if there another byte to send, and
      • if there is, it checks CTS.
    The train application is assumed to check CTS after the train controller has negated it. It may even be unaware that CTS is negated for a short while. Regardless, because the two sets of events happen in parallel the result is non-deterministic.
  4. If CTS is set, the train application puts the next byte in the hold register.
Whether the final action succeeds, drops a character or crashes the train controller is determined by the whims of the gods.

How do you solve this problem is for you to discover. Hint, interrupts occur in a deterministic order.

Primitives for Serial I/O

We are supposed to support

int Get( int server-tid, int port )


int Put( int server-tid, int port, char c )

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

How should we handle a terminal?


  1. Line editing
  2. Echo
    Either Or

Many other issues come up below as we consider possible task structures.

How ahould we handle the train controller

Bandwidth of communication with the train controller will probably be the limiting factor in your trains project.

Debugging Real-time Programs

The most common set of debugging tools used by experienced programmers is the oldest: printf, grep & stack trace.

Debugging real-time programs, at its base, is just the same as any other debugging, just the same as discovery in any empirical science or any kind of problem solving.

  1. Gather data.
  2. Create a model that explains the data
  3. Test the model
  4. If the model is not correct, go to 1.
  5. Remember that the model is ALWAYS provisional: data collected later may invalidate it, no matter how much data has confirmed it.

But real-time programs are harder to debug. Why? There are new types of bugs.

Critical Races

There is no known method for eliminating critical races.

It is, in principle, impossible to test away critical races. Why?

Tools you might use to assist debugging


The memory contents are not wiped by reset. Some of the most difficult errors can be detected only by using the contents of memory after a reset. Produce useful results by inserting

      str   pc, <magic location>
many places in your code. Redboot can tell you the contents of the magic places after the program crashes. Then, with the assistance of a load map, you can find out where you were in which code when the problem occurred.

You can often find out this information by looking at the garbage output that often appears at the bottom of the screen. One set of eight characters is the hex address of the instruction that could not be executed. With a load map and assembly listings you can find the instruction on which the program died.

In RedBoot you can, in principle, trace any of the kernel data structures by examining the kernel's stack, but it's extremely arduous to do so.


What does it do?

How do you get it started?

Breakpoint is a special case of a particular sort of tool that is very common.

Getting information closer to real-time.

Stack Trace

In single-threaded programs this is often the most useful tool.

What is the equivalent of a stack trace in a real-time multi-tasking environment?

Return to: