CS452 - Real-Time Programming - Fall 2010
Lecture 17 - Serial I/O: Implementation
Public Service Announcements
- Final exam: 9.30, December 16, 2010
Easy way to use interrupts
Enable only combined; read UART registers to decide what to do.
Think of the receive and transmit parts of the UART as separate state
machines
Handy Features
- Loopback state
- Loopback connector
- Terminal as line analyser
Implementation
The simplest way to handle the interrupts is to turn on only the combined
interrupt and then look at the registers of the device.
To identify the current interrupt
Read UARTxIntIDIntClr at 0x800[bc]001c
- Four bits, one for each interrupt
- (Write anything to this register to clear the modem status
interrupt)
When service is required, without FIFO.
Transmitting
- Initialization
- Set up the line control registers: high byte must be written last
- low: 0x808[cd]0010:[0-7] LSbyte of baud rate divisor
- middle: 0x808[cd]000c:[0-7] MSbyte of baud rate divisor
- high: 0x808[cd]0008:[0,1,2,3,4,56]
- 0: send a break
- 1: enable/disable parity
- 2: even/odd parity
- 3: one/two stop bits
- 4: enable/disable FIFO
- 56: number of bits per frame
- Set up the control register: 0x808[cd]0014:[0, 7]
- 0: enable/disable UART
- 7: loopback
- Read data and discard
- Enable receive interrupt
- Enable modem status interrupt: 0x808c0014:[3].
- When bytes arrive to transmit
- Add bytes to end of buffer
- Test CTS: 0x808c0018:[0]
- If asserted
- Test transmitter busy: (UARTxFlag at 0x808[cd]0018:[3])
- If busy
- enable transmit interrupt (UARTxCtrl at
0x808[cd]0014:[5])
- else
- write first byte to hold register (clears interrupt)
- If more bytes to transmit
- enable transmit interrupt (UARTxCtrl at
0x800[bc]0014)
- On transmit interrupt
- Test CTS
- If asserted
- write first byte to hold register (clears interrupt)
- if no more bytes to transmit
- disable transmit interrupt
- On modem status interrupt
- If OK to send
- Test transmitter busy
- If busy
- Enable transmit interrupt
- else
- if bytes to transmit (clears interrupt)
- write first byte to hold register
- if more bytes to transmit
- enable transmit interrupt.
Receiving
- Receive interrupt
- Read data (clears interrupt)
Using the FIFO
Left as an exercise.
Task Structure
We are supposed to support
int Get( int port )
and
int Put( int port, char c )
These are wrappers for sends to one or more serial servers.
- On Get the server blocks the client until data is available
- Does a non-blocking TryGet give you anything you cannot do with
task structure?
- Put is non-blocking. The guarantee is that the character has been added
to a buffer of characters to be transmitted, not that it has actually
been transmitted.
How many servers and notifiers?
|
one server |
two servers |
four servers |
| one
notifier
|
likely queue
congestion in
server
|
|
likely queue
congestion
in notifer
|
| two
notifiers
|
one per channel?
one per direction?
|
how should they
be paired?
|
|
| four
notifiers
|
certain queue
congestion
in server
|
likely queue
congestion in
server
|
best performance,
most tasks
|
How should we handle a terminal?
Issues
- Line editing
- undefined intermediate states
- well-defined trigger
- Echo
Either
- one server per channel,
- passing characters from one notifier to the other
Or
- courier connecting receive server to transmit server
- What characteristics does the terminal have? termcap follies
Many other issues come up below as we consider possible task
structures.
Return to: