CS452 - Real-Time Programming - Winter 2018

Lecture 15 - UART Interrupts

Public Service Annoucements

  1. Due date for kernel4: 16 February, 2018.
  2. March break open house: March 10.
  3. Exam scheduled for Monday, April 23.
  4. See pdf.

Serial I/O

Serial I/O Interrupts

Five interrupts in the device

These interrupts are separately enabled and disabled.

  1. Transmit
  2. Receive
  3. Modem status
  4. Receive timeout
  5. Combined

Registers of the UART

Offset Register Function
0x00 data Write: data to transmit.
Read: received data.
0x04 Receive status Write: clear status.
Read: overrun, framing, etc
0x08 Line control high bits/frame, fifo enable, stop bits, etc.
0x0c Line control mid bits/sec: [15:8]
0x10 Line control low bis/sec: [7:0]
0x14 Interrupt/UART enable
0x18 Modem status register. CTS, etc., read only
0x1c Interrupt Status Register. Write: clear modem interrupt
Read: interrupt status.

Three inputs to the PIC

For each UART:

  1. Transmit
  2. Receive
  3. Combined

Easy way to use interrupts

Enable only the combined interrupt; read UART register to decide which interrupt(s) are asserted.

Note that the event, which is the kernel entity, is an abstraction of the hardware interrupt. There is no need for there to be a one-to-one correspondence between hardware interrupt and event. In this style of handling a UART there is one interrupt source which is resolved by the kernel into four separate interrupt events.

Think of the receive and transmit parts of the UART as separate state machines


Implementation of Serial I/O

Assume.

To identify the current interrupt

Read UARTxIntIDIntClr at 0x800[bc]001c

Providing I/O for the terminal

Initialization

  1. Enable RcvRdy, XmitRdy interrupts in UART.
  2. Enable combined interrupt in ICU

Receiving

Notifier EVT_BL on RcvRdy event

  1. Interrupt occurs, AwaitEvent returns with received byte.
  2. Notifier sends byte to server
  3. Server replies,
  4. Notifier returns to the EVT_BL state
  5. After a while server runs again
  6. Server checks GetQ
  7. If ( ! GetQ_Empty )
  8. Else put byte in RcvQ

When server receives Get request from client

  1. Server checks RcvQ
  2. If ( ! RcvQ_Empty )
  3. Else put client in GetQ

Transmitting

Transmitting is a little more tricky because two conditions must be met.

  1. Byte available to transmit
  2. Transmit holding register empty

Assume we put conjunction detection in the server

When server receives Put request from client

  1. Is Notifier ready?
  2. If ( Ready ) Reply( notifier, byte ); Reply( client, ... )
  3. Else insert byte in XmitQ; Reply( client, ... )

When server receives Ready request from Notifier

  1. If ( XmitQEmpty ) Mark notifier ready
  2. 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?

  1. Enable XmitRdy interrupt
  2. byte = AwaitEvt( XmitRdy )
  3. Disable XmitRdy interrupt in UART
  4. Send( server, ready, byte )
  5. Write byte on UART
  6. Go to top

This procedure assumes that the transmit bit never resets once it is set. Is this true?

Conjunction detection and buffer could just as easily be in the Notifier

Providing I/O for the train controller

Receiving

As Above

Transmitting

For transmitting three conditions must be set

  1. Byte available to transmit
  2. Holding register empty
  3. CTS asserted

Return to: