CS452 - Real-Time Programming - Spring 2009
Lecture 15 - Interrupt Handling
Practical Detail
Interrupt Servicing
How to do it
- Find source of the interrupt
- see below for different methods
- Save state of interrupted task
- integrate information from user mode and irq mode
- Restore kernel state
- now executing in svc mode
- EITHER, process interrupt in kernel
- acquire volatile data from device
- turn off interrupt source
- set up return value for AwaitEvent
- schedule
- exit from kernel
movs, or equivalent, moves SPSR to
CPSR
- goes to user mode
- turns on interrupts
OR, process interrupt in notifier
- exit, without scheduling, to notifier in svc mode
- acquire volatile data from device
- turn off interrupt source
- turn on interrupts & return to user mode in one instruction
Your code should operate correctly if there is another interrupt waiting
which is taken immediately after interrupts are enabled.
Four Interrupt Servicing Methods
Non-nested
- sequential
- test interrupt sources in PIC in order of priority
- keep interrupts disabled until interrupt handling is complete
Nested
- multiple interrupts without priority
- if another interrupt arrives during interrupt servicing
- it is handled within the current handler
- i.e. interrupts are re-enabled as fast as possible
Prioritized
- Software
- identify priority of interrupt
- mask off all but higher priorities in PIC
- re-enable interrupts
- More important interrupts do not wait on the processing of less
important ones
- Can also be done in hardware if the PIC supports it
Vectored
- The fastest and the most tricky
- Trick
- Remapping PIC
0x00000018 ldr pc, [pc, #-0xff0]
0xfffff000 base address of PIC
0xfffff030 vector address in PIC, entry point of kernel for the highest priority interrupt
- How does the address get there?
- kernel has one entry point for each interrupt source
- sixteen interrupt sources can be prioritized
- in order 0 to 15.
- each has two registers
- VICVectAddrX : vector to be put into vector
- VICVectCntlX: control register
- bits [0-4]: interrupt source
- bit 5: enable/disable
- read PIC at offset
0x00000030 to get highest
priority address
- write PIC at offset
0x00000030 to update priority
hardware (interrupt service is complete)
- Another trick
- You will never use
r13_irq
- Put
0x800b0030 in it at initialization
- At
0x00000018 put ldr pc,[r13]
ARM Specific
Two controllers, nested
- VICINTSOURCE[0-31] to primary
- VICINTSOURCE[32-63] to secondary
- You care about
- VICINTSOURCE4: timer counter 1
- VICINTSOURCE5: timer counter 2
- VICINTSOURCE[23,24]: UART1 [receive, transmit]
- VICINTSOURCE[25,26]: UART2 [receive, transmit]
- VICINTSOURCE36: watchdog timer
- VICINTSOURCE51: timer counter 3
- VICINTSOURCE52: UART1 general
- VICINTSOURCE54: UART2 general
Registers at
- primary: 0x800b0000
- secondary: 0x800c0000
47 registers per controller
- 11: chip control
- 16: vector addresses
- 16: vector control
- 4: chip id
Priority
- FIQ-configured interrupts (not vectored)
- IRQ-configured vectored interrupts
- IRQ-configured non-vectored interrupts
Return to: