CS452 - Real-Time Programming - Spring 2015
Lecture 14 - Notifier/Server, UART Interrupts
Public Service Annoucements
-
Due date for kernel3: 8 June, 2015
-
Results of performance measurement
Serial I/O
See pdf.
Implementation of Serial I/O
FIFO is assumed to be turned off; buffers are assumed to be in the
server.
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
- One of eight registers for interacting with the UART
- Four bits, one for each interrupt
- (Write anything to this register to clear the modem status
interrupt)
Providing I/O for the terminal
Initialization
- Enable RcvRdy, XmitRdy interrupts in UART.
- Enable combined interrupt in ICU
Receiving
Notifier EVT_BL on RcvRdy event
- Interrupt occurs, AwaitEvent returns with received byte.
- Notifier sends byte to server
- Server replies,
- Notifier returns to the EVT_BL state
- After a while server runs again
- Server checks GetQ
- If ( ! GetQ_Empty )
- Extract client from GetQ
- Reply( client, byte )
- Else put byte in RcvQ
When server receives Get request from client
- Server checks RcvQ
- If ( ! RcvQ_Empty )
- Extract byte from RcvQ
- Reply( client, byte )
- Else put client in GetQ
Other possibilities
-
Read the UART in the Notifier.
-
Read the UART in the Server.
Transmitting
Transmitting is a little more tricky because two conditions must be
met.
- Byte available to transmit
- Transmit holding register empty
Assume we put conjunction detection in the server
When server receives Put request from client
- Is Notifier ready?
- If ( Ready ) Reply( notifier, byte ); Reply( client, ... )
- Else insert byte in XmitQ; Reply( client, ... )
When server receives Ready request from Notifier
- If ( XmitQEmpty ) Mark notifier ready
- Else Extract byte from XmitQ; Reply( notifier, byte ); Reply( client
)
The Notifier
The procedure described here breaks an abstraction barrier. Is there
any other way to do what you want?
- Enable XmitRdy interrupt
- byte = AwaitEvt( XmitRdy )
- Disable XmitRdy interrupt in UART
- Send( server, ready, byte )
- Write byte on UART
- Go to top
This procedure assumes that the transmit bit never resets once it is set.
Is this true?
Other Ideas
-
Conjunction detection and buffer in the Notifier
-
Write the UART in the Server
-
Disable and enable Xmit interrupt in the kernel
Providing I/O for the train controller
Receiving
As Above
Transmitting
For transmitting three conditions must be set
- Byte available to transmit
- Holding register empty
- CTS asserted
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 only guarantee is that the character has been
added to a buffer of characters to be transmitted
You will probably want something more complex in addition to Get and
Put.
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.
How ahould we handle the train controller
Bandwidth of communication with the train controller will probably
be the limiting factor in your trains project.
-
Use it wisely, which means as little as possible.
-
Any time you can substitute computation for communication you should
do so.
-
Communication with the train controller occurs in muli-byte messages.
-
It makes no sense to pass around half a message.
-
Reduce the number of system calls.
-
Minimizes bugs that occur when putting parts of messages together.
-
Convert input bytes into messages as early as possible.
-
Unpack output messages into bytes as late as possible.
Return to: