high priorized isr in arm 7

i_stolze wrote on Friday, July 24, 2009:

I’m using FreeRTOS 5.3 on a TMS470 (ARM7). I want to use FIQ (high piorized interrupt) which can interrupt normal IRQs using portSAVE_CONTEXT() and portRESTORE_CONTEXT() and can interrupt the OS-ISR vPortYieldProcessor(). In the FIQ is no context switch. possible or desired.
I have used  __attribute__ ((interrupt (“FIQ”))) of the arm-elf-gcc (GCC) 4.1.2 (WinARM 4/2007)for the fiq, but i have some trouble on starting the application. After some (10 to 50) reboots the application runs fine. I’m not able to determine the reason for reboots exactly, but I gues the reason is the register saving and restoring of the fiq.
The gcc generates following code for the FIQ: 

sub    lr, lr, #4
stmfd    sp!, {r0, r1, r2, r3, lr}
bl    RtiTimer2Isr
ldmfd    sp!, {r0, r1, r2, r3, pc}^

What’s wrong?

rtel wrote on Saturday, July 25, 2009:

The FIQ mode has some registers all to itself, the compiler should know which to save and restore but the __attribtute__ features of GCC are notoriously problematic.

As an aside, check the definitions of portENABLE_INTERRUPTS and portDISABLE_INTERRUPTS (or what ever is used to disable and enable interrupts in critical sections) to ensure it only manipulates the IRQ bit and not the FIQ bit.


incrediball wrote on Sunday, July 26, 2009:

I didn’t trust the interrupt attributes when I did this after reading about all the problems that others had with them so I coded the entry and exit code myself. This is what I did and it seems to work well:

Firstly use __attribute__((naked)) to ensure there is no automatic entry & exit code.

Entry code:

    // Save context for FIQ interrupt. Left in FIQ mode with F & I bits set (all interrupts disabled)
    asm volatile (
        "stmfd    sp!, {r0-r7,lr}"        // store unbanked registers and lr

Exit code:
    asm volatile (
        "ldmia    sp!, {r0-r7,lr}    \n\t"        // restore unbanked registers and lr
        "subs        pc, lr, #4"                        // Restore the Program Counter using the LR_fiq directly into the PC

The whole function is expected to run in ARM mode.

Make sure you have defined a stack and a vector for the FIQ interrupt in your startup code. Richard’s tip about disabling/enabling interrupts and critical sections is important since you probably don’t want high latencies. The FIQ should be able to interrupt critical sections but make sure the FIQ does not interact with FreeRTOS or anything else that the critical sections are supposed to protect.