CS452 - Real-Time Programming - Spring 2012

Lecture 13 - Hardware Interrupts

Public Service Annoucements

  1. Assignment 3

Hardware Interrupts

Vectored Operation

General Idea

The standard way of programming the ICU requires the kernel to query the ICU. Sometimes (!), this is unacceptably inefficient. Then, you have another alternative, vectored interrupts.

Relevant registers:

  1. there are 16 pairs that you write
    Register Name Offset R/W Description Comments
    VICxVectAddry 0x100+4y R/W Vector address for interrupt y Entry point of ISR for interrupt y
    VICxVectCntly 0x200+4y R/W Control register for interrupt y Bit[0-4]: interrupt source for interrupt y
    Bit[5]: enable vectored interrupt y

  2. There is one pair used by the program
    Register Name Offset R/W Description
    VICxVectAddr 0x030 R/W Read: address of vector for highest priority interrupt

    Write: service complete, enable priority hardware

    VICxDefVectAddr 0x034 R/W Default vector address

Procedure

Initialization

  1. Write kernel entry point into VICxDefVectAddr
  2. If desired write special entry point into VICxVectAddry
  3. When ready to accept interrupts write source and enable into VICxVectCntly

When an interrupt occurs

  1. Read VICxVectAddr to find address
  2. Move result to PC
        ldr   pc, #<VicVectAddr>

    (Note that this is similar to the instruction in 0x014. Could we do it all in one?)

  3. Before interrupts are re-enabled write VICxVectAddr to start priority hardware

Answer to question.

Look carefully at what's in 0x18


Clock Server

Primitives

int Time( )
int Delay( int ticks )
int DelayUntil( int ticks )

Implementation

main( ) {
    notifier = Create( HIGHEST, ... );
    time = 0
    Send( notifier, &evtType, ... );
    FOREVER {
        Receive( &requester, &request, ... );
        switch ( request.type ) {
        case NOTIFIER:
            Reply( notifier, ... )
            time++;
            break;
        case TIME_REQUEST:
            Reply( requester, time,... )
            break;
        case DELAY_REQUEST: 
            Add requester to list of suspended tasks
            break;
        }
        Check list of suspended tasks and reply
    }
}

Comments:

  1. You need a common request type, or possibly a union.
  2. You should notice a typical server pattern.
  3. It's normal to sort the list of suspended tasks. Why?

HALT versus an Idle Task

What do you do when there are no tasks to run?


Serial I/O

See pdf.

FIFO

Why do FIFOs exist in UARTS?

The Big Blunder

To use the FIFO effectively you must be able to turn off the transmitter & receiver independently.

But look at UARTE in UARTxCtrl

The Little Blunder

`It is assumed that various configuration registers for the UART are not written more than once in quick succession, in order to insure proper synchronization of configuration information across the implementation. Such registers include UART1Ctrl and UART1LinCtrlHigh. ... In between the two writes, at least two UARTCLK periods must occur. Under worst case conditions, at least 55 HCLK periods must separate the two writes. The simplest way to due [sic] this is separate the two writes by 55 NOPs.'

Why does this occur?

Why doesn't anybody care?

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

Three inputs to the PIC

  1. Transmit
  2. Receive
  3. Combined

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


Return to: