CS452 - Real-Time Programming - Winter 2018
Lecture 11 - Hardware Interrupts
Public Service Annoucements
- Due date for kernel3: Monday, 5 February, 2018.
Hardware Interrupts
The Hardware in the Trains Lab
32-bit Timer
Base address: 0x80810080
The four registers of the timer.
Offset |
Function |
R/W |
Bits |
Comments |
0x0 |
Timer3Load |
R/W |
32: <Load/Reload Value> |
|
0x4 |
Timer3Value |
R |
32:<Current value> |
Set when Load is written,
even when counting |
0x8 |
Timer3Control |
R/W |
32:the lowest order bits are <CLKSEL>xx<MODE><ENABLE> |
<CLKSEL>: 0, 2KHz clock; 1, 508KHz clock
<MODE>: 0, count once; 1, count continuously
<ENABLE>: 0, counting off; 1, counting on
No bit for turning interrupts off and on
|
0xc |
Timer3Clear |
W |
32: |
Writing anything clears the interrupt |
Why are there four registers and not three?
What is a Hardware Interrupt?
In the CPU
A hardware interrupt is an input signal to the CPU from the outside
world, usually signifying that a device needs attention. Here is the
sequence of events when it occurs.
-
(-2) Interrupt asserted at IRQ input, combinational logic.
-
(0) Interrupt latched:
-
two instructions complete
-
two instructions aborted
-
PC gets 0x18
-
SPSR_irq gets CPRS
-
CPSR rewritten
-
No instruction fetched.
-
(1) Link register set; instruction in 0x18 fetched.
-
(2) Adjust partial execution.
-
(5) PC set to kernel entry.
-
(6) Fetch instruction at kernel entry.
A chart of the pipeline: eleven (11) cycles
920T pipeline
PC for fetch\Cycle |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
|
IRQ Assert |
|
IRQ Ack |
|
|
|
|
|
-8 |
Execute |
Data |
Write back |
|
|
|
|
|
|
-4 |
Decode |
Execute |
Data |
Write back |
|
|
|
|
|
|
0 (PC at IRQ Assert) |
Fetch |
Decode |
Execute |
Link |
Adjust |
|
|
|
|
|
|
+4 |
|
Fetch |
Decode |
|
|
|
|
|
|
|
|
+8 |
|
|
No Fetch |
|
|
|
|
|
|
|
|
0x18 |
|
|
|
Fetch |
Decode |
Execute |
Data |
Write back |
|
|
|
kernel entry |
|
|
|
|
|
|
|
|
Fetch |
Decode |
Execute |
In the Interrupt Control Unit (ICU)
The input signal (IRQ pin) is created by the ICU, a component
separate from the CPU, but located on the same chip as the CPU.
In the Cirrus EP9302 the ICU is an ARM part, the PL190.
-
An ICU has many inputs, each hard-wired to a specific device.
This is typical for computers that interact heavily with the
external world. In general, interrupts occur frequently and
the average amount of computing per interrupt is small. Try
listing the interrupt sources in your mobile phone.
-
The EP9302 ICU consists of two PL190s for a total of 64 inputs.
Most of them are used talking to devices on the EP9302.
-
Several interrupts may be present when an interrupt occurs.
This is uncommon, but the arrival of one or more interrupts
while an interrupt is being handled is more common than you
think. Suppose your CPU usage is only 10%.
-
The kernel consumes about half of the CPU usage. It is
running about 5% of the time.
-
About 5% of interrupts occur while interrupts are
disabled. About 0.25% of interrupts already have one
deferred interrupt when they arrive.
-
How often do interrupts occur?
-
20,000 per second when interacting with the terminal,
-
500 per second when interacting with the train,
-
100 per second when interacting with the timer.
5% of 20,000 is 1,000 per second; 0.25% of 20,000 is
50 per second; 0.0125% of 20,000 is 2.5 per second, or
150 per minute.
Notice how lumpy is the execution profile of of a program.
-
When more than one interrupt is present,
-
One is chosen, by a priority mechanism, which may be implemented in
-
software: the kernel knows priorities, chooses the
highest priority one using software
-
hardware: the kernel programs its priorities into
the ICU. But it's not always possible to avoid
using software completely.
The improvement in performance by using hardware priority
is very small. Use it only when the interrupt rate is
very fast.
-
Software can override priority mechanism in ICU (not
recommended)
-
The time of an interrupt is not correlated with the time
of any other interrupt.
Clearing one interrupt often exposes another one.
In the Peripheral Hardware
-
Several interrupts exist in each UART
-
ORed in peripheral hardware
-
ORed in glue hardware
-
Rare that peripheral devices have a priority mechanism
-
Clearing one interrupt can expose another one
When two interrupts are present
There may be several interrupts present when interrupt
processing starts.
-
Software in the kernel determines their relative priorities,
which is up to you.
-
The highest priority interrupt is serviced.
-
Only one interrupt is serviced per pass through the kernel.
Why? A new interrupt, of higher priority than the non-serviced
interrupts may have arrived during processing of any interrupt.
It's necessary to give an interrupt window for it to enter
the CPU, and the easiest way of doing so is to context switch
out of the kernel.
How does the transition from handling the first interrupt to
processing the second occur?
-
Kernel executes with interrupts disabled
-
Context switch into user task turns on interrupts
-
Before fetching the first user task instruction the instruction
fetch procedure is followed
-
If IRQ asserted, re-initiate interrupt processing
Context Switches for Interrupts
Difference from Software Interrupts
It is impossible to predict where they occur
-
You may have made some assumptions about when they can occur
Assymmetry between User Task and Kernel
Scratch registers of the user task must be saved.
Scratch registers of the kernel need not be saved.
-
assuming that you do not let the optimizer loose on your
context switch.
Four link registers must be put in the correct places.
- One to return from interrupt
-
In the IRQ mode link register when the interrupt handling
code starts,
-
It must be moved to svc mode because that's where it will
be needed for a future context switch. (Don't just assume
that your kernel will crash before the future context
switch. That's an example of a self-fulfilling prediction.)
-
One allowing the interrupting task to return from the function
that was executing when it was interrupted.
-
When the interrupt occurs it is in the link register of
usr mode.
-
It must be saved in a way that gets it back on the usr
mode link register when the interrupted task is next
scheduled.
-
One allowing IRQ mode code to return from whatever function
it is executing when the interrupt occurs.
-
One allowing code executing in svc mode to return from whatever
function called it.
Helpful Features of the ICU
Because the ICU was designed by programmers it
has a few features that are helpful to programmers
-
Several places where you can read state
-
Several places where you can block interrupt flow
-
Trigger hardware interrupt from software
-
What makes interrupts hard is that you are doing two
semi-hard things at once
-
Making the hardware produce the interrupt
-
Responding to the interrupt
-
This allows you to separate them in developing/debugging
The Hardware in the Trains Lab
32-bit Timer
Base address: 0x80810080
The four registers of the timer.
Offset |
Function |
R/W |
Bits |
Comments |
0x0 |
Timer3Load |
R/W |
32: <Load/Reload Value> |
|
0x4 |
Timer3Value |
R |
32:<Current value> |
Set when Load is written,
even when counting |
0x8 |
Timer3Control |
R/W |
32:the lowest order bits are <CLKSEL>xx<MODE><ENABLE> |
<CLKSEL>: 0, 2KHz clock; 1, 508KHz
<MODE>: 1, count continuously; 0, count once
<ENABLE>: Clock turned on
No bit for turning interrupts off and on
|
0xc |
Timer3Clear |
W |
32: |
Writing anything clears the interrupt |
Interrupt Control Unit (ICU)
The actual device is the ARM PL190, and there are two of them
in the SoC. In the Cirrus documentation they are called VIC1
and VIC2.
The logic in this design is completely asynchronous, so it functions
when the CPU clock is turned off.
-
Important (= essential) for low power operation.
All input signals are
- active high
-
level sensitive
-
the other way of doing it is edge sensitive
Base addresses
-
VIC1:
0x800B0000
-
VIC2:
0
x800C0000
Basic Operation
VIC powers up with
- all vectored interrupts disabled.
- all interrupts giving IRQ
- all interrupts masked
Most likely you will change only the last of them.
Procedure
Initialization
-
leave protection off, unless you are in doubt about your
partner's ethics or competence.
-
enable in VICxIntEnable only when you are ready to handle the
interrupt
On an interrupt, the kernel
- reads the VICxIRQStatus register,
- chooses which interrupt to handle and
- clears the interrupt source in the device.
For debugging
- Use VICxSoftInt and VICxSoftIntClear to turn interrupt sources off and
on in software
Hardware Definitions
Registers for Basic Operation
Register Name |
Offset |
R/W |
Description |
VICxIRQStatus |
0x00 |
RO |
One bit for each interrupt source
1 if interrupt is asserted and enabled
|
VICxFIQStatus |
0x04 |
RO |
As above for FIQ |
VICxRawIntr |
0x08 |
RO |
As above but not masked |
VICxIntSelect |
0x0c |
R/W |
0: IRQ, 1: FIQ |
VICxIntEnable |
0x10 |
R/W |
0: Masked, 1: Enabled |
VICxIntEnClear |
0x14 |
WO |
Clears bits in VICxIntEnable |
VICxSoftInt |
0x18 |
R/W |
Asserts interrupt from software |
VICxSoftIntClear |
0x1c |
WO |
Clears interrupt from software |
VICxProtection |
0x20 |
R/W |
Bit 0 enables protection from user mode access |
VICxVectAddr |
0x30 |
R/W |
Enables priority hardware
See documentation.
|
Helpful Features of the ICU
- Several places where you can read state
- Several places where you can block interrupt flow
- Trigger hardware interrupt from softwareonce
- What makes interrupts hard is that you are doing two semi-hard
things at once
- Making the hardware produce the interrupt
- Responding to the interrupt
- Software interrupt generation allows you to separate them in
developing/debugging
Non-vectored Operation
Initialization
- Enable interrupt in device
- Enable interrupt in ICU
- Enable interrupt in CPU, by MOVS
Normal operation
When a hardware interrupt occurs you find yourself in IRQ
mode. How do you you are in IRQ mode?
-
Read the PSR.
-
Put something special in the SP_irq
Next, you
-
Remember that you started in IRQ mode.
-
Switch to svc mode.
-
Do the context switch.
-
Look at the active interrupt sources; decide which one you
will service; turn it off.
-
Find which task is blocked waiting for the interrupt.
-
Set up its return value, and make it ready.
Tasks waiting on interrupts are normally high priority, and
usually run right away.
If a second interrupt occurs immediately
-
The CPU checks AND( IRQ, NOT( IRQ disabled bit set in CPSR ) )
before each instruction fetch.
-
If it is asserted an IRQ exception is taken in place of next
instruction fetch.
-
Possibly, zero instructions of the active task are executed.
-
Make sure that this case works
- Context switch into kernel
- Turn off interrupt in device
-
Do you need to turn off the interrupt in the ICU?
Return to: