This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Setting up IRQ in ARM

Hi everyone

I am new to ARM and really wanted to learn about various aspects of ARM Programming .

I have basic understanding of x86 Assembly.

So,what Specifically I wanted to know is what happens when an external device triggers an interrupt .

Let me put my basic understanding on the same, which I learnt in last few days

Offset Handler
===============
00 Reset
04 Undefined Instruction
08 Supervisor Call (SVC)
0C Prefetch Abort
10 Data Abort
14 (Reserved)
18 Interrupt (IRQ)
1C Fast Interrupt (FIQ)

Whenever Interrupt comes instruction at address 18 is executed

So is it true that it is first instruction executed when interrupts comes??

Or as I read somewhere whenever interrupts comes first it moves from user mode to IRQ mode and cpsr is copied to spsr_IRQ but it happen without an instruction .

After that current instruction is replaced with a blx 0x18

How and where we do need to set the stack for different mode e.g for IRQ mode and Supervisior mode??

In the brancged code


IRQ_HANDLER:

SUB lr, lr, #4

STMFD !sp {r14}

bl IRQ_handler_to_specific_device ;it will branch to actuall hander code.

LDMFD r13!,{r14}
mov pc, r14


Is it all We need to do for setting up Basic IRQ handling ?


Also,how PIC/CPU comes to know that interrupt is coming from which device?


Thanks

Amit Singh Tomar.


"ARM is taking over the world"

  • Getting interrupts right on ARM can be a little fiddly - you have to get quite a lot of things right, and do them in the correct order. I would highly recommend the ARM System Developers Guide as it walks through a lot of the OS-like behaviors.

    http://books.google.co.uk/books/about/ARM_System_Developer_s_Guide.html?id=vdk4ZGRqMskC&redir_esc=y

    Also note that the Cortex-M series does things totally differently with a simpler interrupt model and much more of the low level interrupt handling done in hardware.

    To answer your questions ...

    So is it true that it is first instruction executed when interrupts comes??


    Yes.


    How and where we do need to set the stack for different mode e.g for IRQ mode and Supervisior mode??


    Stacks need to be setup when your OS boots, before the first interrupt happens.


    Is it all We need to do for setting up Basic IRQ handling ?

    No. Most of the ARM registers are shared with the context of the application which was running when the system was interrupted, so you need to stack off these registers before the main part of the interrupt handler runs, or you may corrupt state. You also have to restore them at the end before you return.

    You also need a special return instruction which will restore the SPSR into the CPSR - you can't just "mov pc, r14". This link may help, although it only gives the bare essentials:

    ARM Compiler toolchain Developing Software for ARM Processors: Return from an exception handler


    Also,how PIC/CPU comes to know that interrupt is coming from which device?

    Depends on implementation. Some devices provide a vector-based interrupt handler so the device can jump directly to the correct handler, others require the interrupt handler to query the interrupt controller to find out which line was activated.

    HTH,
    Pete

  • Hi Amit,

    A couple of other things worth noting on top of what Pete has said if you want your IRQ_handler_to_specific_device to be written in C:

    1.You'd need to think about pushing r0-r3 and r12 as these may be corrupted by the called function (based on the AAPCS) - Pete alluded to this

    2. You'll need to make sure the stack is 8-byte aligned prior to the BL

    Also note, by default, the IRQ is non-reentrant. This means if you have multiple interrupt sources you'll need to poll them to find the actual source (ineffienent).

    You can play games to support reentrant IRQs by swapping to the SVC mode before reenabling the I-bit but this gets even more messy.

    Alternatively your device may have (probably has) an external interrupt controller or vectored interrupt controller to help support and prioritise multiple IRQs. Most ARMv7-A cores will probably use the ARM GIC for interrupt control which handles multiple interrupt sources and maps them onto the IRQ (especially in multi-core where you might want to select which external int is mapped to which cores IRQ).

  • Thanks Niall for your reply

    But I really can't think why r0-r3 and r12 need to be pushed and where/when it need to pushed.

    Also,would you please provde any link where a simple IRQ handler is written in assembly.

    I really not sure what exact has to be there to handle a irq interrupt 

  • Hi Tomar,

    You've had some great replies so far. Hope they've been useful.

    You need to push r0-r3,r12 because the AAPCS (Procedure Call Standard for the ARM Architecture) says that a called function may corrupt these registers. Since an interrupt handler is not allowed to corrupt any registers, if you call another function in your handler, you need to preserve these registers before doing so.


    For details of how to write an interrupt handler in assembler, have a look at this section of the compiler documentation ARM Information Center

    Hope this helps

    Chris

  • Absolute minimum handler:

    IRQ_handler

         SUB       lr, lr, #4       ; modify LR

         SRSFD     #0x12!           ; store SPSR and LR to IRQ mode stack

        PUSH      {r0-r3, r12}     ; store AAPCS registers on to the IRQ mode stack

         BL        IRQ_handler_to_specific_device

         POP       {r0-r3, r12}     ; restore registers

         RFEFD     sp!              ; and return from the exception using pre-modified LR

    * Note this does not handle stack alignment

  • Yes, Tomar, you could use those instructions to manage the stack alignment. You would need to remember to "undo" any change you have made to the stack pointer before returning from the handler, though. You can do this by simply adding back the value in r4.

    In the SRSFD instruction, 0x12 is the mode number of the IRQ mode (i.e. the value in the mode field of CPSR which specifies IRQ mode) so this is what specifies use of the IRQ stack. You are right that there is no real need to save SPSR if you are not expecting any further interrupts. So you could just push LR at this point. I think we would say, though, that SRS/RFE is a more modern pair of instructions these days!

  • Thanks Chris, your comments are indeed quite useful !!!

  • Absoultey thanks to you Niall.

    This is exactly what I am looking for

    I guess I can manage Stack alignment using below instructions


    and r4, sp, #4

    sub sp, sp, r4

    Only one doubt I do want to get cleared

    SRSFD #0x12!

    Is this Instruction is really required?

    Since we are not expecting any other interrupts here and it just a simple IRQ handler(not the nested one)

    So,why we do require to save the SPSR here.

    Also,I don't know how SRSED works, I mean how it pushes the SRSR and LR to IRQ mode stack

    Is #012 is base address of IRQ mode stack?