Hi,
I'm trying to get an idea of the best (only?) way to implement interrupt nesting (i.e. a lower priority ISR being interrupted by a higher priority one). I'm using only the VIC IRQ of an STR91 device (i.e no FIQ). Using UV3 & RealView. Having reviewed what I've read here, it seems that I need to:
1) Upon ISR entry, save the current context 2) Enter supervisor mode in order to... 3) ...re-enable interrupts (allowing pre-emption) 4) Process ISR 5) Revert to user mode 6) Restore context 7) Leave ISR
Q1. Is the only way to enter supervisor mode via an SWI? Q2.Would all my ISR's requiring pre-emption (not all would) have to be encased in an asm wrapper? Q3. Are there some 'intrinsics' that can be used for this purpose? (I'm having difficulty finding a definitive list of them) Q4. Is my understanding correct?
Any clarification/recommendations on this would be appreciated.
Thanks
Dave
David, I think you can find your answer here: http://www.keil.com/support/docs/3353.htm
I've had a look, and am trying to adapt the example given:
Add the following assembler wrapper (in a separate assembly module) to the interrupt function: PRESERVE8 AREA NEST_IRQ, CODE, READONLY ARM IMPORT eint1_srv EXPORT eint1_irq eint1_irq PUSH {R0-R3,R12,LR} ; save register context MRS LR, SPSR ; Copy SPSR_irq to LR PUSH {LR} ; Save SPSR_irq MSR CPSR_c, #0x1F ; Enable IRQ (Sys Mode) PUSH {LR} ; Save LR BL eint1_srv POP {LR} ; Restore LR MSR CPSR_c, #0x92 ; Disable IRQ (IRQ Mode) POP {LR} ; Restore SPSR_irq to LR MSR SPSR_cxsf, LR ; Copy LR to SPSR_irq ; VICVectAddr = 0; ; Acknowledge Interrupt MOV R0,#0 STR R0,[R0,#-0xFD0] POP {R0-R3,R12,LR} ; restore register context SUBS R15,R14,#0x0004 ; return from interrupt END
I'm struggling to adapt the asm relating to reading the relevant VIC current vector address (which I guess is here)
VICVectAddr = 0; ; Acknowledge Interrupt MOV R0,#0 STR R0,[R0,#-0xFD0]
I'm not to clear what's actually happening here- what I need to do amounts to the VIC1->VAR = 0 statement in 'C', which amounts to a write to 0xFC00.0030 on the STR91x device.
How do I adapt what's in this example to do this?
David, please refer to documentation related to ARM9 interrupt handling. note that upon an IRQ, the ARM9 always jumps to 0x18, where an instruction to jump to a address specified at 0xFFFFFF030 (filled by the VIC) is located. that is what you see happening in that snippet of code. handling a FIQ happens by jumping to 0x1C where your ISR is located.