ST AN3129 APPLICATION NOTE

AN3129
Application note
Real-time performance using FIQ interrupt handling
in SPEAr MPUs
Introduction
This application note provides information for software developers on how to use the (FIQ) (fast interrupt request) mechanism with Linux in the SPEAr embedded MPU family.
Section 1 describes the interrupt logic on SPEAr platform.
Section 2 provides a detailed introduction to the FIQ interrupt handling hardware
mechanism and interrupt latency in the Linux kernel.
Section 3 describes the FIQ interrupt handler software.
Section 4 gives the results of interrupt latency measurements performed with Linux running
on a SPEAr evaluation board.
January 2010 Doc ID 16927 Rev 1 1/12
www.st.com
SPEAr interrupt logic AN3129
Interrupt logic
Interrupt sources
Vectored
interrupt
controller
ARM
FIQ
IRQ

1 SPEAr interrupt logic

SPEAr is a family of embedded MPUs based on the ARM core. The embedded MPU uses the PL190 vectored interrupt controller (VIC) IP. Together they provide facilities to use fast interrupts as highest priority interrupts. Fast interrupt features are supported by both the ARM core and the VIC. This VIC IP can be configured to select any hardware source to interrupt ARM core as either IRQ or FIQ.

Figure 1. SPEAr platform interrupt logic

The order of priority for hardware interrupts (from higher to lower) is as follows:
1. Fast interrupt request (FIQ) interrupts
2. Vectored IRQ interrupts
3. Non-vectored IRQ interrupts.
FIQs are intended for fast, low-latency interrupt handling. In FIQ mode, the ARM core uses seven 32-bit banked registers, which enable the VIC to process interrupts as quickly as possible.
Multiple interrupts can be handled as FIQs, but in this case the IRQ vector needs to be loaded in the program counter (PC). In order to reduce interrupt latency, it is advised to use a single FIQ source, because the ISR can be directly executed without determining the source of the interrupt.
As the Linux kernel never disables FIQs they have ultimate priority over anything else in the system. When using an FIQ, the FIQ latency will be the time it takes the CPU to enter your FIQ function. Moreover an FIQ can preempt Linux kernel code and IRQ handlers and it can also be used for faster response to interrupts.
Note: The use of an FIQ in place of an IRQ does not require any hardware (wiring) modifications
on the SPEAr board. The VIC has a 32-bit register (VICINTSELECT) which can toggle an IRQ source to raise an FIQ instead of the default mechanism of IRQ.
2/12 Doc ID 16927 Rev 1
AN3129 Linux kernel IRQ handling latency
Interrupt IRQ handler
Interrupt
latency
Interrupt disabling in Kernel
OR
other interrupt handler
Interrupt
handler
duration

2 Linux kernel IRQ handling latency

In a Linux kernel based system, interrupt latency may occur in the following cases:
Interrupt latency for top half,
Various sections where IRQs are disabled

Figure 2. IRQ handling latency in Linux Kernel

An FIQ is a highest priority interrupt and preempts both of these sources of latency. It can preempt IRQ top half handlers as well as Linux kernel code sections where IRQs are disabled. Further to this, the FIQ handler can not be preempted by other IRQs. This ensures that the platform has predictable worst case timings for FIQ handler latency making FIQ suitable for real-time systems.
The FIQ handler can not permit tasks that require other IRQs to be active, including the timer. This also makes it suitable for real-time systems but imposes the following limitations:
Kernel mode APIs and device driver framework can not be used inside the FIQ handler.
These APIs available for Linux driver development may internally rely upon timers, schedulers, spinlocks, etc. for functioning. Linux code also needs to guard against multiple access to objects by spinlocks or other relevant mechanisms. FIQ ISRs can come in the middle of anything and have to get out quickly again too. So unless it is a simple macro, you can not use any Linux APIs in the FIQ ISR.
Page faults have to be avoided inside the handler (the memory used in the handler
should be already allocated and initialized). In case that a page fault occurs inside the FIQ handler, it can not be recovered by the kernel and it would lead to a kernel crash.
Doc ID 16927 Rev 1 3/12
FIQ handler environment AN3129

3 FIQ handler environment

The FIQ registration, the ISR function and the runtime environment of a FIQ handler are different from a standard IRQ handler. A working example of an FIQ handler can be found in latency measurement module in Section 4: IRQ latency measurement.

3.1 FIQ registration

For FIQ registration ‘set_fiq_handler’ API is used.
The two arguments of this API are:
Function pointer
Size of handler function in bytes
This handler function is copied to the FIQ vector reserved area. The FIQ vector area is last in the memory area reserved for interrupt vectors. About five hundred (500) bytes are available in this area for copying the ISR.
In the SPEAr Linux Support Package (LSP), the following API must be used to select the configuration of the IRQ source:
vic_unmask_irq(int number) – enables interrupt source on VIC as IRQ
vic_select_fiq(int number) – selects interrupt source on VIC as FIQ instead of IRQ

3.2 FIQ mode registers setup

When the FIQ handler runs, it utilizes FIQ mode-specific registers (r8-r14) and general mode registers (r0-r7). This set of FIQ mode registers is exclusive to FIQ mode and not available to other handlers.
To pass any information to the FIQ handler, the FIQ mode registers have to be set using the call: ‘set_fiq_regs’.

3.3 Return from FIQ mode

To return from FIQ mode on completion of the code, use the following assembly instruction:
subs pc, lr, #4;
This command restores the instruction pointer to the original location it was before FIQ arrived.

3.4 FIQ ISR in C

Writing the FIQ handler function in ARM assembly language can be cumbersome, so it is highly recommended to use C language instead. This is especially true for large functions when the handler function is larger than the maximum size available for FIQ vector (500 bytes). In such cases branching to the C function can be possible. This involves saving of the register context (r0-r12 general mode registers) and initialization of the function frame pointer.
4/12 Doc ID 16927 Rev 1
Loading...
+ 8 hidden pages