ST AN1776 Application note

AN1776
APPLICATION NOTE
INTERRUPT HANDLING FOR STR7 MICROCONTROLLERS
by MCD Application Team

INTRODUCTION

An exception occurs when the normal flow of a program has to be halted temporarily. The rea­sons for an exception to occur can be due to an interrupt from a hardware peripheral, a coding error or incompatibility or even a user-defined exception. In each of these cases, the exception needs to be 'handled'. This means, the normal program execution needs to be paused, and the processor needs to be directed to a specially written section of code which performs a se­ries of predetermined actions. The process of performing these special actions is called ex­ception handling. This document gives a description of the use of the STR7 interrupt controller (EIC), as well as how to configure the EIC to be able to handle IRQ and FIQ exception, and therefore how it can be customized for your own application requirements.
All examples provided with this application note are developed with RVDK 2.1 for ST and op­timized for the STR710-Demoboard.
This document assumes that the reader is familiar with the ARM7TDMI core and ARM assem­bler. For more details on the ARM core architecture, refer to the ARM Developer Suite Guide and the ARM Technical Reference Manual. These documents are available from the ARM website.
AN1776/1105 1/13
1
INTERRUPT HANDLING FOR STR7 MICROCONTROLLERS

1 EXCEPTION ENTRY AND EXIT

1.1 ENTERING AN EXCEPTION

This first section of this application note gives an introduction to Exception Handling by de­scribing the basic default configuration of the ARM processors.
When an exception occurs, the ARM processor switches automatically to the ARM state and to the exception mode, copies the Current Program Status Register (CPSR) into SPSR_<mode> (where SPSR is the Saved Program Status Register, here in a particular mode), saves the return address in to LR_<mode>, sets the appropriate CPSR bits. The re­turn address is stored in the Link Register, LR_<mode> to ensure that normal execution can resume following the exception handling. Finally, the Program Counter (PC) is set to the vector address to where the exception can be handled.
After handling the exception, the reverse process needs to be applied where CPSR is restored from SPSR_<mode> and the PC is restored from LR_<mode>.
Remember that exception handling can only be exited in ARM state, so if previously in Thumb state, prior to exit the exception, the core should switch states to ARM.

1.2 LEAVING AN EXCEPTION

To return from an exception, a data procession instruction is used however the exact instruc­tion depends on the exception being handled.
In the ARM state, the use of the S bit normally sets the conditional flag. However, when in priv­ileged modes, with the S bit set and the PC as the destination register, the instruction will up­date the PC and copy the SPSR_<mode> into the CPSR. Finally, still in privileged mode, LDM can be used with the ^ qualifier if LR_<mode> is adjusted before being stacked.
For SWI and Undefined exception handlers
MOVS pc, lr
For FIQ, IRQ and Prefect Abort exception handlers
SUBS pc, lr, #4
For Data Abort exception handlers
SUBS pc, lr, #8
LDM can be used with the ^ qualifier if LR adjusted before being stacked
LDMFD sp!,{pc}^
2/13
2
INTERRUPT HANDLING FOR STR7 MICROCONTROLLERS

2 EXCEPTION PRIORITIES

It is important to remember that several exceptions can occur simultaneously. However, all ex­ceptions are assigned priorities and are served in a predefined order.
The exception with the highest priority is Reset. Next, in order of decreasing priority, there is the Data Abort, FIQ (Fast), IRQ (Normal), Prefetch Abort, SWI, and finally the Undefined in­struction with the lowest priority.

3 EXCEPTION VECTORS

The Reset Vector is at address 0x0000. This is followed by the undefined instruction vector, the SWI vector, the Prefetch Abort vector, Data abort vector, IRQ vector and FIQ vector.
The exception vector should contain a valid instruction to branch to the exception handler.
A branch instruction (B Exception_Handler) or data instruction (LDR pc,[pc,#offset]) may be used to jump to the exception handler.
The B instruction can be used if the exception handler is within 32MByte of the exception vector. The LDR pc,[pc,#offset] instruction loads a content of a memory to the PC, this memory points the exception handler. This memory location is pointed to by the contents of the program counter content plus an offset. This is done this way since the exception handler is outside the 32 Mbytes branch instruction range. Note also that the offset has to be within a 4Kbyte boundary, however, this is not a problem since this address itself doesn't need to con­tain any code.
The other method of accessing the exception handler is by using the MOV instruction. When the MOV PC instruction is used, only an appropriate address boundary can be used.
Specially for FIQ exception, since the FIQ vector is the last vector in the table, the handler can be written directly starting from the FIQ vector. This is quite normal for the FIQ handler, since it allows for it to be executed immediately, as fast as possible, without having to jump else­where.

4 ARM OR THUMB ?

It may be necessary to have an application which contains a mixture of ARM and Thumb code. When an exception occurs, the processor will switch the state automatically to ARM. This is because the instruction held in the vector table associated with the exception vector must be an ARM instruction. This vector instruction will jump the program counter to an exception han­dler. Once the execution of this exception handler has finished, the processor returns to exe­cute the application in the state it was originally running in, either ARM or Thumb.
3/13
INTERRUPT HANDLING FOR STR7 MICROCONTROLLERS
Note that the exception handler itself can be written in either ARM or Thumb instruction code. Any exception handler code written with the Thumb instruction set will return the processor to ARM state as the program counter will have to back to the original application code (i.e. main loop) with ARM instructions.

5 INTERRUPT HANDLING

This section of the application note gives an introduction to interrupt handling from the periph­erals. In particular, the IRQ and FIQ interrupt modes are discussed. Many of the peripherals can be configured to generate interrupts in certain circumstances, for example a Timer might be set up to trigger an interrupt after a certain amount of time, periodically. How this Timer in­terrupt is handled by the exception handler is to be decided by the user-defined section of the handler of the code.
The ARM core has two levels of external interrupt handling, IRQ and FIQ, however the STR7 microcontrollers have a large number of interrupt sources. To manage all of the peripheral in­terrupts together with their priorities, the STR7 family of microcontrollers includes an En­hanced Interrupt Controller. The EIC has hardware handling of multiple interrupt channels, in­terrupt priority and automatic vectorization.

5.1 FIQ INTERRUPTS VERSUS IRQ INTERRUPTS

FIQ interrupts have a higher priority than IRQs which means that they will be serviced first when situations arise with both IRQ and FIQ events simultaneously. Servicing an FIQ will dis­able an IRQ and therefore IRQs will not be serviced until the FIQ handler completely exits.
FIQ interrupts are designed to be run as quickly as possible. The handler for FIQ can be placed directly at the end of the exception vectors table since the vector is the last in the table. A jump to another address therefore is not necessary and can be run immediately. In addition, FIQ mode has an additional 5 banked registers which means that there is less time wasted saving the non-banked registers before serving the FIQ exception handling and restoring them before exiting the exception.

5.2 SIMPLE INTERRUPT HANDLED IN C

The following example shows a simple interrupt handler written in C. In addition, the related assembly code is shown, compiled with and without __irq.
Note that the assembly code differs between one compiler to another.
__irq void IRQHandler (void) { u16 *IRQChannel = (u32 *)0xFFFFF804 if (* IRQChannel == 0) // which interrupt was it Channel0_IRQHandler(); // process the interrupt // insert checks for other interrupt sources here
4/13
Loading...
+ 9 hidden pages