| |||||
Technical Support Support Resources
Product Information | CARM: NESTING INTERRUPTSInformation in this article applies to:
QUESTIONThe classic ARM architecture only provides two interrupts (IRQ and FIQ). The Vectored Interrupt Controller or Advanced Interrupt Controller provides interrupt priorities and interrupt nesting for the standard interrupt, but it requires that you set the I bit in the CPSR. In this context I have the following questions:
ANSWERIt should be noted that good programming technique implies that you keep interrupt functions very short. When you are using short interrupt functions, interrupt nesting becomes unimportant. When you are using an Real-Time Operating System (such as Advanced RTX), the stack usage of user tasks becomes unpredictable when you allow interrupt nesting. However, if you still need interrupt nesting in your application, you may implement it as described below:
You may nest interrupts by using the macros IENABLE and IDISABLE at beginning and end of an interrupt service routine.
#define IENABLE /* Nested Interrupts Entry */ \
__asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ \
__asm { STMFD SP!, {LR} } /* Save SPSR_irq */ \
__asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ \
__asm { STMFD SP!, {LR} } /* Save LR */ \
#define IDISABLE /* Nested Interrupts Exit */ \
__asm { LDMFD SP!, {LR} } /* Restore LR */ \
__asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ \
__asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ \
__asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ \
The usage is as shown below:
void interrupt_srv (void) __irq {
IENABLE; // allow nested interrupts
... // interrupt code
IDISABLE; // disable interrupt nesting
}
Depending on interrupt controller, it might be required to clear the interrupt source and acknowledge the interrupt. So in reality an implementation might look like the following example:
/* External Interrupt 1 Service */
void eint1_srv (void) __irq {
EXTINT = 2; // Clear EINT1 interrupt flag
IENABLE; // allow nested interrupts
delay ();
++intrp_count; // increment interrupt count
IDISABLE; // disable interrupt nesting
VICVectAddr = 0; // Acknowledge Interrupt
}
MORE INFORMATION
SEE ALSOFORUM THREADSThe following Discussion Forum threads may provide information related to this topic.
Last Reviewed: Thursday, March 31, 2005 | ||||
| |||||