# Lecture 3 - Odds and Ends

## Public Service Annoucements

1. Due date for assignment 0
2. Remember to get a partner
3. Caches, optimization, clock speed, FIFOs
4. Libraries: memcpy in particular
5. Questions about using a timer
6. Comments about first.pdf
• Compilation spits out .s files and a load map.
• You must set PATH correctly.
• Using the load map.
• tftp directory might gain subdirectories once groups are formed.
• Six arm box and terminal sets available: two in the outer room. Only two are connected to trains.
7. Once upon a time global variables were a tool of the devil.
They still are!

## Timers

How does one keep time in a computer?

• for busses, crystal oscillator in a phase-locked loop
• cycle counter
• for timeofday( ), interrupts from a timer
• ntpd

In practice, how do you find out the time for a0?

• Use the 32 bit register.
• Load the starting value into the load register. The starting value should be chosen to count to zero in 10 msec.
• Start the timer counting by setting the enable bit in the control/status register.
• Read the count register -- fine for polling loop, not fine for your kernel

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

## 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 for a1

• When does the worst case response time for a2 occur?
• What is the worst case response time for a2?
• Sum over i of
• execution time of `if( c<i>` ) plus
• execution time of `a<i>}`

#### 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 your testing?

• Probably not.

#### Testing more than once

Suppose you need 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`

• The sum of
• the execution time of `if( c1 ) a1` plus
• the maximum over N of the execution times of `if( cN ) aN`

#### Breaking long actions 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; }
...
}
```

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

### Talking to the train controller

This is the hardest part of Ass. 0. If nothing happens to the train the problem can be

• a bug in your code,
• a misunderstanding of UART documentation,
• an error in UART documentation,
• the train controller not receiving,
• your software sending the wrong bytes,
• a misunderstanding of the Marklin documentation,
• an error in the Marklin documentation, or
• something else.

Putting a terminal into the line between the ARM box and the train controller will help you to eliminate possible sources or error more easily. In fact, old dumb terminals had an extra connector on the back and passed everything coming in on one connector out the other while displaying it on the screen, just to make debugging communications easier.

Today you can achieve the same thing using the two COM parts of a simple PC.

• Unplug the cable connecting the COM1 port on the ARM box.
• Connect a COM port on the PC to the COM1 port of the ARM box.
• Connect the other COM port on the PC to the train controller.
• Either use terminal emulators to pass bytes from one COM port to the other, and vice versa, or write a tiny C program to do the same thing, displaying the bytes as you pass them through.
This is an important problem solving technique that you use all the time, possibly without noticing it: break a complex problem into two or more simple ones.

Turning a train headlight on and off is an easy way to see if you are communicating with the train controller successfully.

### States of Three-way Switches

The three way switches are actually a pair of switches so they have four states
 Switch 1 Switch 2 Result Straight Straight Straight Straight Curved Curve Right Curved Straight Curve Left Curved Curved Probable Derailment

# UART Flow Control

All hardware & software has buffers somewhere

• Buffers always overflow, sooner or later
• When buffers overflow something bad happens
• Lose data either off the end, or off the start, depends on implementation
• You can control it with software (^S & ^Q)
• Often loses part of the transmission because of unpredictable time lags
• You can control it with hardware, which is what the train controller does.

### Three-wire RS-232

We need what's called a null modem. Without the crossover it's called straight through.

 connects to signal ground signal ground transmit (XMIT) receive (RCV) receive (RCV) transmit (XMIT)

### Five-wire RS-232

Two extra wires are added to provide flow control

• Clear to Send (CTS) asserted when a receiver is ready to receive input, negated when the receiver is not ready to receive input.
• Written by the receiver; read by the transmitter.
• Request to Send (RTS), asserted when the transmitter has bytes ready to transmit, negated when the transmitter has nothing to transmit
• Written by the transmitter, read by the receiver.
 connects to signal ground signal ground transmit (XMIT) receive (RCV) receive (RCV) transmit (XMIT) clear to send (CTS) request to send (RTS) request to send (RTS) clear to send (CTS)

The train controller asserts RTS, which is read as CTS by the UART. The train controller ignores the RS-232 input if you send when CTS is not asserted.

### Error conditions in UARTs

There is a receive status register that tells you something about receive errors. It's bits are:

• 0: FE, framing error. This usually means that you have mismatched speeds.
• 1: PE, parity error. This has meaning only if you are including a parity bit.
• 2: BE, break error. Some systems put break on the line, which indicates that something has gone wrong.
• 3: OE, overrun error. This means that a second byte was received before the first one was read, which usually means that your receive software is too slow.

#### A few interesting things about RedBoot

What's in the flash ROM of the board is a partial implementation of Redboot.

• fconfig :: NOT
• load (tftp)
• go [address]
• examine, copy, fill memory
The program you have written so far is allocating local memory on a stack?
• Where is Redboot's stack?
This enables you to get a clean return to RedBoot when your program terminates.

When your program crashes Redboot catches the exception, and puts out some information for gcc to hook into your program. (Don't bother trying to use gdb!) You see it on the bottom two lines of output. It's useless except for one 8 digit number starting 00218 or 00219. This is the address of the last instruction the CPU attempted to execute. Using the load map and the assembly code you can find exactly how far the program got before crashing. Unfortunately, the error may have occurred long before execution stopped.

Return to: