Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between FIQ and IRQ interrupt system?

I want to know the difference between FIQ and IRQ interrupt system in any microprocessor, e.g: ARM926EJ.

like image 377
Renjith G Avatar asked Jun 10 '09 06:06

Renjith G


People also ask

What is the difference between IRQ and FIQ?

FIQs have higher priority than IRQs in two ways: FIQs are serviced first when multiple interrupts occur. Servicing a FIQ causes IRQs to be disabled, preventing them from being serviced until after the FIQ handler has re-enabled them. This is usually done by restoring the CPSR from the SPSR at the end of the handler.

What is FIQ IRQ?

Description In an ARM-based system, two levels of interrupt are available: fast interrupt request (FIQ) for fast, low-latency interrupt handling, and interrupt request (IRQ) for general interrupts.

What is the IRQ used for?

In a computer, an interrupt request (or IRQ) is a hardware signal sent to the processor that temporarily stops a running program and allows a special program, an interrupt handler, to run instead.


2 Answers

ARM calls FIQ the fast interrupt, with the implication that IRQ is normal priority. In any real system, there will be many more sources of interrupts than just two devices and there will therefore be some external hardware interrupt controller which allows masking, prioritization etc. of these multiple sources and which drives the interrupt request lines to the processor.

To some extent, this makes the distinction between the two interrupt modes redundant and many systems do not use nFIQ at all, or use it in a way analogous to the non-maskable (NMI) interrupt found on other processors (although FIQ is software maskable on most ARM processors).

So why does ARM call FIQ "fast"?

  1. FIQ mode has its own dedicated banked registers, r8-r14. R14 is the link register which holds the return address(+4) from the FIQ. But if your FIQ handler is able to be written such that it only uses r8-r13, it can take advantage of these banked registers in two ways:
    • One is that it does not incur the overhead of pushing and popping any registers that are used by the interrupt service routine (ISR). This can save a significant number of cycles on both entry and exit to the ISR.
    • Also, the handler can rely on values persisting in registers from one call to the next, so that for example r8 may be used as a pointer to a hardware device and the handler can rely on the same value being in r8 the next time it is called.
  2. FIQ location at the end of the exception vector table (0x1C) means that if the FIQ handler code is placed directly at the end of the vector table, no branch is required - the code can execute directly from 0x1C. This saves a few cycles on entry to the ISR.
  3. FIQ has higher priority than IRQ. This means that when the core takes an FIQ exception, it automatically masks out IRQs. An IRQ cannot interrupt the FIQ handler. The opposite is not true - the IRQ does not mask FIQs and so the FIQ handler (if used) can interrupt the IRQ. Additionally, if both IRQ and FIQ requests occur at the same time, the core will deal with the FIQ first.

So why do many systems not use FIQ?

  1. FIQ handler code typically cannot be written in C - it needs to be written directly in assembly language. If you care sufficiently about ISR performance to want to use FIQ, you probably wouldn't want to leave a few cycles on the table by coding in C in any case, but more importantly the C compiler will not produce code that follows the restriction on using only registers r8-r13. Code produced by a C compiler compliant with ARM's ATPCS procedure call standard will instead use registers r0-r3 for scratch values and will not produce the correct cpsr restoring return code at the end of the function.
  2. All of the interrupt controller hardware is typically on the IRQ pin. Using FIQ only makes sense if you have a single highest priority interrupt source connected to the nFIQ input and many systems do not have a single permanently highest priority source. There is no value connecting multiple sources to the FIQ and then having software prioritize between them as this removes nearly all the advantages the FIQ has over IRQ.
like image 96
manav m-n Avatar answered Sep 23 '22 13:09

manav m-n


FIQ or fast interrupt is often referred to as Soft DMA in some ARM references.
Features of the FIQ are,

  1. Separate mode with banked register including stack, link register and R8-R12.
  2. Separate FIQ enable/disable bit.
  3. Tail of vector table (which is always in cache and mapped by MMU).

The last feature also gives a slight advantage over an IRQ which must branch.

A speed demo in 'C'

Some have quoted the difficulty of coding in assembler to handle the FIQ. gcc has annotations to code a FIQ handler. Here is an example,

void  __attribute__ ((interrupt ("FIQ"))) fiq_handler(void) {     /* registers set previously by FIQ setup. */     register volatile char *src asm ("r8");  /* A source buffer to transfer. */     register char *uart asm ("r9");          /* pointer to uart tx register. */     register int size asm ("r10");           /* Size of buffer remaining. */     if(size--) {         *uart = *src++;     } } 

This translates to the following almost good assembler,

00000000 <fiq_handler>:    0:   e35a0000        cmp     sl, #0    4:   e52d3004        push    {r3}            ; use r11, r12, etc as scratch.    8:   15d83000        ldrbne  r3, [r8]    c:   15c93000        strbne  r3, [r9]   10:   e49d3004        pop     {r3}            ; same thing.   14:   e25ef004        subs    pc, lr, #4 

The assembler routine at 0x1c might look like,

   tst     r10, #0    ; counter zero?    ldrbne  r11, [r8]  ; get character.    subne   r10, #1    ; decrement count    strbne  r11, [r9]  ; write to uart    subs    pc, lr, #4 ; return from FIQ. 

A real UART probably has a ready bit, but the code to make a high speed soft DMA with the FIQ would only be 10-20 instructions. The main code needs to poll the FIQ r10 to determine when the buffer is finished. Main (non-interrupt code) may transfer and setup the banked FIQ registers by using the msr instruction to switch to FIQ mode and transfer non-banked R0-R7 to the banked R8-R13 registers.

Typically RTOS interrupt latency will be 500-1000 instructions. For Linux, it maybe 2000-10000 instructions. Real DMA is always preferable, however, for high frequency simple interrupts (like a buffer transfer), the FIQ can provide a solution.

As the FIQ is about speed, you shouldn't consider it if you aren't secure in coding in assembler (or willing to dedicate the time). Assembler written by an infinitely running programmer will be faster than a compiler. Having GCC assist can help a novice.

Latency

As the FIQ has a separate mask bit it is almost ubiquitously enabled. On earlier ARM CPUs (such as the ARM926EJ), some atomic operations had to be implemented by masking interrupts. Still even with the most advanced Cortex CPUs, there are occasions where an OS will mask interrupts. Often the service time is not critical for an interrupt, but the time between signalling and servicing. Here, the FIQ also has an advantage.

Weakness

The FIQ is not scalable. In order to use multiple FIQ sources, the banked registers must be shared among interrupt routines. Also, code must be added to determine what caused the interrupt/FIQ. The FIQ is generally a one trick pony.

If your interrupt is highly complex (network driver, USB, etc), then the FIQ probably makes little sense. This is basically the same statement as multiplexing the interrupts. The banked registers give 6 free variables to use which never load from memory. Register are faster than memory. Registers are faster than L2-cache. Registers are faster than L1-cache. Registers are fast. If you can not write a routine that runs with 6 variables, then the FIQ is not suitable. Note: You can double duty some register with shifts and rotates which are free on the ARM, if you use 16 bit values.

Obviously the FIQ is more complex. OS developers want to support multiple interrupt sources. Customer requirements for a FIQ will vary and often they realize they should just let the customer roll their own. Usually support for a FIQ is limited as any support is likely to detract from the main benefit, SPEED.

Summary

Don't bash my friend the FIQ. It is a system programers one trick against stupid hardware. It is not for everyone, but it has its place. When all other attempts to reduce latency and increase ISR service frequency has failed, the FIQ can be your only choice (or a better hardware team).

It also possible to use as a panic interrupt in some safety critical applications.

like image 25
artless noise Avatar answered Sep 23 '22 13:09

artless noise