23-Feb-07
23-Feb-07 (1)
23-Feb-07 (2)
CEG2400 - Microcomputer Systems
Lecture 7: Interrupts
Philip Leong
ARM Exceptions
23-Feb-07 (3)
23-Feb-07 (4)
Exceptions and Modes
Exceptions arise whenever the normal flow of a program has to be halted temporarily
For example to service an interrupt from a peripheral.
Exception Entry
When handling an exception, the ARM7TDMI:
Preserves the address of the next instruction in the appropriate Link Register Copies the CPSR into the appropriate SPSR Forces the CPSR mode bits to a value which depends on the exception Forces the PC to fetch the next instruction from the relevant exception vector It may also set the interrupt disable flags to prevent otherwise unmanageable nestings of exceptions. If the processor is in THUMB state when an exception occurs, it will automatically switch into ARM state when the PC is loaded with the exception vector address.
ARM supports 7 types of exception and has a privileged processor mode for each type of exception. ARM Exception vectors
Address 0x00000000 0x00000004 0x00000008 0x0000000C 0x00000010 0x00000014 0x00000018 0x0000001C Reset Undefined instruction Software Interrupt Abort (prefetch) Abort (data) Reserved IRQ FIQ Exception Mode in Entry Supervisor Undefined Supervisor Abort Abort Reserved IRQ FIQ
23-Feb-07 (5)
23-Feb-07 (6)
Entry/Exit Actions
Reset
When the processors Reset input is asserted
CPSR Supervisor + I + F PC 0x00000000
Entry/Exit Actions
Data Abort
Data access memory abort, invalid data
LR_abt Aborted Instruction + #8, SPSR_abt CPSR PC 0x00000010, CPSR Abort + I Return with : SUBS pc, lr, #4 or SUBS pc, lr, #8
Undefined Instruction
If an attempt is made to execute an instruction that is undefined
LR_undef Undefined Instruction Address + #4 PC 0x00000004, CPSR Undefined + I Return with : MOVS pc, lr
Software Interrupt
Enters Supervisor mode
LR_svc SWI Address + #4, SPSR_svc CPSR PC 0x00000008, CPSR Supervisor + I Return with : MOV pc, lr
Prefetch Abort
Instruction fetch memory abort, invalid fetched instruction
LR_abt Aborted Instruction Address + #4, SPSR_abt CPSR PC 0x0000000C, CPSR Abort + I Return with : SUBS pc, lr, #4
23-Feb-07
23-Feb-07 (7)
23-Feb-07 (8)
Entry/Exit Actions
Interrupt Request
Externally generated by asserting the processors IRQ input
LR_irq PC - #4, SPSR_irq CPSR PC 0x00000018, CPSR Interrupt + I Return with : SUBS pc, lr, #4
r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12
Recall registers
General registers and Program Counter
User32 / System FIQ32 r0 r1 r2 r3 r4 r5 r6 r7 r8_fiq r9_fiq r10_fiq r11_fiq r12_fiq r13_fiq r14_fiq r15 (pc) Supervisor32 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13_svc r14_svc r15 (pc) Abort32 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13_abt r14_abt r15 (pc) IRQ32 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13_irq r14_irq r15 (pc) Undefined32 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13_undef r14_undef r15 (pc)
Fast Interrupt Request
Externally generated by asserting the processors FIQ input
LR_fiq PC - #4, SPSR_fiq CPSR PC 0x0000001C, CPSR Fast Interrupt + I + F Return with : SUBS pc, lr, #4 Handler @0x1C speeds up the response time
r13 (sp) r14 (lr) r15 (pc)
Program Status Registers
cpsr cpsr sprsr_fiq spsr_fiq cpsr spsr_svc cpsr spsr_abt cpsr sprsr_fiq spsr_irq cpsr spsr_undef sprsr_fiq
23-Feb-07 (9)
23-Feb-07 (10)
Recall program status regs
31 28 8 4 0
Mode bits
N Z CV
I F T
Mode
Copies of the ALU status flags (latched if the instruction has the "S" bit set).
Condition Code Flags N = Negative result from ALU flag. Z = Zero result from ALU flag. C = ALU operation Carried out V = ALU operation oVerflowed
Interrupt Disable bits. I = 1, disables the IRQ. F = 1, disables the FIQ. T Bit (Architecture v4T only) T = 0, Processor in ARM state T = 1, Processor in Thumb state
23-Feb-07 (11)
23-Feb-07 (12)
Exception Handler
On completion, the exception handler:
Restores any saved registers Copies the SPSR back to the CPSR Moves the LR, minus an offset where appropriate, to the PC
Registers in use
r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 (sp) r14 (lr) r15 (pc) cpsr
User to FIQ mode
Registers in use
User Mode
FIQ Mode
r0 r1 r2 r3 r4 r5 r6
How do we do (2) and (3)?
If we restore CPSR first, banked LR no longer accessible If we restore PC first, execution returns to the instruction before exception Entry/exit actions slides earlier give a special form of the instruction that does both (2) and (3)
r8_fiq r9_fiq r10_fiq r11_fiq r12_fiq r13_fiq r14_fiq
EXCEPTION
r8 r9 r10 r11 r12 r13 (sp) r14 (lr)
r7 r8_fiq r9_fiq r10_fiq r11_fiq r12_fiq r13_fiq r14_fiq r15 (pc)
Return address calculated from User mode PC value and stored in FIQ mode LR
spsr_fiq
cpsr spsr_fiq
User mode CPSR copied to FIQ mode SPSR
23-Feb-07
23-Feb-07 (13)
23-Feb-07 (14)
FIQ vs IRQ latency
FIQ
Fast interrupt that has a latency of 12 cycles Note that it is the last entry in the exception vector table: the interrupt handler can be directly placed at 0x1c (or a jump can be made as for the other entries)
Recall software interrupt
31 28 27 24 23 0
IRQ
Latency of 25 cycles
Cond
1 1 1 1
Comment field (ignored by Processor)
Condition Field
In effect, a SWI is a user-defined instruction. It causes an exception trap to the SWI hardware vector (thus causing a change to supervisor mode, plus the associated state saving), thus causing the SWI exception handler to be called. The handler can then examine the comment field of the instruction to decide what operation has been requested. By making use of the SWI mechansim, an operating system can implement a set of privileged operations which applications running in user mode can request. See Exception Handling Module for further details.
23-Feb-07 (15)
23-Feb-07 (16)
Hardware Interrupts
Internal: originate from on-chip peripherals or software ARM has fast and normal interrupt inputs
Timer/Counter
Counter overflow
Model Summary
Our interrupt model is that we receive either an FIQ or IRQ and the processor saves the PC & CPSR to the appropriate LR and SPSR and jumps to the exception vector The ISR processes the interrupt
Clear the interrupt source Do some work e.g. update counters, save data etc Return from the interrupt
ADC
End of conversion
USART
End of transmission
IRQ ARM7TDMI Processor
FIQ
Source: http://www.at91.com/selftraining/ppt%20files/ARM7TDMI-based/AT91%20Interrupt%20Handling.ppt
23-Feb-07 (17)
23-Feb-07 (18)
Polling
Up till now, we have controlled I/O devices by polling while (device_addr & 0x50) /* do nothing */ ; send_data(); Polling does not allow for processor to do other things while it tests the devices status register
Could be doing other things
Using Exceptions
23-Feb-07
23-Feb-07 (19)
23-Feb-07 (20)
Interrupts
More efficient scheme: jump to an interrupt service routine (otherwise known as an exception) when a device changes status Other times can be doing other things
Main loop : Instruction 1 Instruction 2 Instruction 3 Instruction 4 Instruction 5
IRQ_Handler
An interrupt service routine (ISR) or IRQ_Handler must
Save registers that it will destroy Do its work Clear interrupt source
i.e. notify hardware that the interrupt has been serviced
Return from interrupt
Interrupt routine : Instruction A Instruction B Instruction C Return from interrupt
ISRs are very easy to get wrong and symptoms are normally non-deterministic!
Source: http://www.at91.com/selftraining/ppt%20files/ARM7TDMI-based/AT91%20Interrupt%20Handling.ppt
23-Feb-07 (21)
23-Feb-07 (22)
MRS/MSR
MRS and MSR read and write the CPSR & SPSRs Commonly used to change processor mode and to enable/disable interrupts, when the core is in a privileged mode (i.e. not User mode). Status registers are split into four 8-bit fields that can be individually written: Control (c) bits 0-7 5 processor mode bits, I & F interrupt disable bits, and the T bit on ARMv4T. Extension (x) bits 8-15 Reserved for future use (unused in Arch 3, 4 & 4T) Status (s) bits 16-23 Reserved for future use (unused in Arch 3, 4 & 4T) Flags (f) bits 24-31 NZCV flags (28-31) and 4 bits (24-27) reserved for future use MRS(cond) Rd, CPSR MRS(cond) Rd, SPSR MSR(cond) CPSR_fields, Rm MSR(cond) SPSR_fields, Rm MSR(cond) CPSR_fields, #immediate MSR(cond) SPSR_fields, #immediate where 'fields' can be any combination of "cxsf". e.g. MSR CPSR_c, #0x1F ; go to System mode, IRQ & FIQ enabled
Enable Interrupts
Enable interrupts by clearing FIQ and IRQ bits in the CPSR. To enable interrupts and enter supervisor mode
MSR cpsr_c,#0x13;
Setting up the SP for various modes can be done in several ways. Set SP for IRQ mode (SP_irq). After setting the SP_irq, the mode is switched back to Supervisor Mode.
MRS R0, CPSR BIC R1, R0,#0x1F ORR R1, R1,#0x12 MSR cpsr_c, R1 LDR SP, =0x4.. MSR cpsr_c, R0 ; current mode in R0 ; clear mode bits ; make it IRQ mode ; change to IRQ mode ; set the stack pointer ; back to previous mode (supervisor)
23-Feb-07 (23)
23-Feb-07 (24)
VIC
ARM only allows two interrupt sources (FIQ and IRQ)
Most applications require more
VIC Categories
Interrupt sources can be assigned one of 3 categories:
FIQ (best possible latency if only one source for this) vectored IRQ only 16 of the 32 can be of this category. An ISR address can be stored in the VIC non-vectored IRQ
The vectored interrupt controller (VIC) is a peripheral that expands this to
32 interrupt request inputs 16 vectored IRQ interrupts 16 priority levels dynamically assigned to interrupt requests Software interrupt generation Described in Ch 5 of http://www.nxp.com/acrobat_download/usermanuals/UM10120_ 1.pdf
The above categories are in decreasing priority
23-Feb-07
23-Feb-07 (25)
23-Feb-07 (26)
Internal Peripherals
VIC Registers
1 means true 0=IRQ 1 = FIQ
23-Feb-07 (27)
23-Feb-07 (28)
VIC Registers
VIC Registers
23-Feb-07 (29)
23-Feb-07 (30)
VICSoftInt
Ex: Setting type and Enabling Interrupts
Program UART0 and SPI0 as vectored IRQs (UART0 being on the higher level than SPI0), while UART1 and I2C are generating non-vectored IRQs First set which are IRQ/FIQ
; SPI0, I2C, UART1 and UART0 are IRQ => bit10, bit9, bit7 and bit6=0 VICIntSelect = 0x0000 0440
Enable them
; SPI0, I2C, UART1 and UART0 are enabled interrupts => bit10, bit9, bit 7 and bit6=1 VICIntEnable = 0x0000 06C0
23-Feb-07
23-Feb-07 (31)
23-Feb-07 (32)
Ex: Setting Vectors
; holds address at what routine for servicing non-vectored IRQs (i.e. UART1 and I2C) starts VICDefVectAddr = 0x... VICVectAddr0 = 0x... ; holds address where UART0 IRQ service routine starts VICVectAddr1 = 0x... ; holds address where SPI0 IRQ service routine starts
Vector Control Reg
23-Feb-07 (33)
23-Feb-07 (34)
Ex: Setting Priority
VICVectCntlx assigns ; interrupt source with index 6 (UART0) is enabled as
; the one with priority 0 (the highest) VICVectCntl0 = 0x0000 0026 ; interrupt source with index 10 (SPI0) is enabled as the one with priority 1 VICVectCntl1 = 0x0000 002A
Ex: Execution vector
After the programming, any IRQ on UART0, SPI0, UART1 or I2C will cause jump to IRQ vector (0x18)
Could put LDR pc, [pc,#-0xFF0] instruction there This instruction loads PC with the address that is present in VICVectAddr (0xFFFFF030) register! Because pc=0x18+8=0x20 and -0xff0= 0xFFFFF00F+1=0xFFFFF010)
This single instruction handles all 32 possible interrupt sources!
23-Feb-07 (35)
23-Feb-07 (36)
Updating VIC Hardware
Interrupts are prioritized by the VIC. Need to allow it to update at the end of the ISR
Interrupt Example
http://www.nxp.com/acrobat_download/ap plicationnotes/AN10254_2.pdf Timer1 is configured to trigger an IRQ interrupt and the code runs from Flash
23-Feb-07
23-Feb-07 (37)
23-Feb-07 (38)
Interrupt vector table
This code should be linked to 0x0. Here the interrupt vectors are provided for the ARM core. ; --------------------------------------------------------; Assembler Directives ; --------------------------------------------------------AREA IVT, CODE ; New Code section CODE32 ; ARM code IMPORT start ; start symbol not ; defined in this ; section Entry ; Defines entry point ; --------------------------------------------------------LDR PC, =start LDR PC, Undefined_Addr LDR PC, SWI_Addr LDR PC, Prefetch_Addr LDR PC, Abort_Addr ; At 0x14 the user should insert a signature (checksum). DCD . LDR PC, [PC, #-0xFF0] LDR PC, FIQ_Addr Undefined_Addr DCD Undefined_Handler SWI_Addr DCD SWI_Handler Prefetch_Addr DCD Prefetch_Handler Abort_Addr DCD Abort_Handler FIQ_Addr DCD FIQ_Handler ; --------------------------------------------------------; Exception Handlers ; --------------------------------------------------------; The following dummy handlers do not do anything useful in ; this example.They are set up here for completeness. Undefined_Handler B Undefined_Handler SWI_Handler B SWI_Handler Prefetch_Handler B Prefetch_Handler Abort_Handler B Abort_Handler FIQ_Handler B FIQ_Handler END
Startup code
; --------------------------------------------------------; Assembler Directives ; --------------------------------------------------------AREA asm_code, CODE ; New Code section CODE32 ; ARM code IMPORT __main ; main not defined ; in this section EXPORT start ; global symbol ; referenced in ; ivt.s ; --------------------------------------------------------start ; Enable interrupts MSR cpsr_c,#0x13 ; Set SP for Supervisor mode. Depending upon ; the stack the application needs this value ; needs to be set. LDR SP,=0x4 .. ; Setting up SP for IRQ mode. Change mode to ; IRQ before setting SP_irq and then ; move back again to Supervisor mode MRS R0, CPSR BIC R1, R0,#0x1F ORR R1, R1,#0x12 MSR cpsr_c, R1 LDR SP, =0x4.. MSR cpsr_c, R0 ; Jump to C code LDR lr, =__main MOV pc, lr END
23-Feb-07 (39)
23-Feb-07 (40)
Initialize (in C)
/* Function declarations */ __irq void IRQHandler(void); void feed(void); void Initialize(void); #include"LPC2___.h" int main() { /* Initialize the system */ Initialize(); /* Start timer */ T1_TCR=0x1; while(1) { } } /****************************************************** **** Initialize ******************************************************* ***/ void Initialize() { /* Setting Multiplier and divider values */ PLLCFG=0x25; feed(); /* Enabling the PLL */ PLLCON=0x1; feed(); /* Wait for the PLL to lock to set frequency */ while(!(PLLSTAT & PLOCK)){} /* Connect the PLL as the clock source */ PLLCON=0x3; feed(); /* Enabling MAM and set number of clocks used for Flash memory fetch */ MAMCR=0x2; MAMTIM=0x4; /* * Setting peripheral Clock (pclk) * to System Clock (cclk) */ VPBDIV=0x1; /* Initialize GPIO */ IODIR=0xFFFF; IOSET=0xFFFF; /* Initialize Timer 1 */ T1_TCR=0x0; T1_TC=0x0; T1_PR=0x0; T1_PC=0x0; /* End user has to fill in the match value */ T1_MR0=0x..; /* Reset and interrupt on match */ T1_MCR=0x3; /* Initialize VIC */ VICINTSEL=0x0; /* Timer 1 selected as IRQ */ VICINTEN= 0x20;/* Timer 1 interrupt enabled */ VICCNTL0= 0x25; /* Address of the ISR */ VICVADDR0=(unsigned long)IRQHandler; } void feed() { PLLFEED=0xAA; PLLFEED=0x55; }
23-Feb-07 (41)
23-Feb-07 (42)
Actual ISR
/********************************************************** Timer 1 ISR **********************************************************/ __irq void IRQHandler() {
/* * The ISR code. The * interrupt cleared in Timer1, a write must * be performed on the VIC Vector Address Register to * update VIC priority hardware. Here the user could * blink a few LEDs or toggle some port pins as an * indication of being in the ISR */
ISR in assembly
STMDB SP!,{R0-R1} ; save R0 and R1 ; T1IR=0x1; MOV R0,#0x00000001 LDR R1,[PC,#0x001C] STR R0,[R1] ; VICVectAddr=0xff; MOV R0,#0x000000FF MOV R1,#0x00000000 STR R0,[R1,#-0x0FD0] LDMIA SP!,{R0-R1} SUBS PC,LR,#0x00000004 ; return from subroutine
T1_IR=0x1; VICVADDR=0xff; }