Interrupt-Driven IO
Interrupt Service Routine (ISR)
Info
An interrupt service routine (ISR) (handler) performs I/O instead of the main program doing polling
Steps
- Write ISR (keep as short as possible)
- Store IRS address in the vector table (since we made a custom handler)
- Enable IRQss at the device
- Run the main program
- Whenever an IRQ is received, the ISR is run by the IC to do the IO
Example - ADC Interrupts
See ARM V7 Assembly
Note that ADC generates IRQ22
ADINTEN EQU 0x4003400C ; ADC Interrupt Enable
ADDR EQU 0x40034010
SAMPLES SPACE 100 ; Each integer is 4 bytes, we can fit 25 integers here
POINTER DCD SAMPLES ; Creates 1-word variable in memory,
; initialized with the address of the first slot in SAMPLES
(See Directives#Data Reservation Directives)
- Write ISR
ISR
MOV32 R0, #ADDR
MOV32 R1, #POINTER ; R1 <- pointer to current sample array address
LDR R2, [R1] ; Loaded samples pointer
LDR R3, [R0] ; Reads sample (also clears IRQ)
AND R3, #0x000FFFD ; Grab bits 4-15
LSR R3, #4
STR R3, [R2], #4 ; Store to array
STR R2, [R1] ; Update pointer (registers don't persist)
BX LR ; Return from exception
- Store the ISR address in the vector table
(since we are using IRQ22 and vector 16 is IRQ0)
MOV32 R0, #ISR ; or LDR R0, =ISR or ADR
MOV R1, #38 * 4 ; or ADR R0, ISR
; Vector table entries are 4 bytes
STR R0, [R1]
- Enable the IRQ on the device (device specific)
MOV32 R0, #ADINTEN
MOV R1, #1
STR R1, [R0] ; Sets bit 0 to 1 which enables the IRQ