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

Abort some questions of arm interrupt

Note: This was originally posted on 20th June 2008 at http://forums.arm.com

I try to understand arm interrupt,there are some questions I don't know,
  1.   Why the nested interrupt has to switch out of irq mode to svc mode?  I think  it only pushes the r14_irq into the irq stack.
   2.    The basic difference between a reentrant interrupt handler and a nested interrupt han-dler is that the interrupts are reenabled early on in the reentrant interrupt handler, which can reduce interrupt latency.
    I can't understand that ?

   thanks!
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    1. So do  you know where has the example codes to explain them(nested / re-entrant) ?
    2.  As you know, our system has no unbounded stack to keep re-entrant interrupt handler, so what can i do prevent  the  stack overflow ?

    thanks!

    If I recall correctly, a nested interrupt handler allows a higher-priority interrupt to interrupt it. For example, you might want a timer interrupt to have higher priority than a UART interrupt, because what you are doing in the timer requires hard real-time guarantees on latency. In this model, an interrupt cannot interrupt the handler for itself.

    In a re-entrant interrupt routine, a second interrupt of the same type can interrupt processing of the first one. This is rarer, because if the interrupt is that important, you probably need to service the first one anyway. Re-entrant code is more difficult to write and debug, since it will often require access to the same data structures as the interrupted interrupt handler. It also allows unbounded stack growth if the interrupts come in too fast to handle.
  • Note: This was originally posted on 26th June 2008 at http://forums.arm.com

    Sean,

    ...............
    Interrupt nesting: interrupt A can preempt handling of interrupt B; both interrupt A and interrupt B's handlers can be "active" at the same time.

    Re-entrant interrupt: interrupt A can preempt handling of interrupt A; interrupt A's handler can be active concurrently with itself.

    ..................

    hth
    s.

    Hi sim,
        For Interrupt nesting, I don't think interrupt A and interrupt B's handlers can be "active" at the same time. interrupt B must wait for returning by interrupt A if no interrupt occurs.
  • Note: This was originally posted on 27th June 2008 at http://forums.arm.com

    Hi sim,
          I have not use  Cortex-M3 yet, but the Interrupt chaining you said is very interesting. Could you tell me the how to replace the interrupt vector with new handler to run in details?

    Thanks!

    Sean,


    Interrupt chaining: (an overloaded term) means one of two things; firstly checking for a new pending interrupt before returning from interupt context (i.e. a scenario which would could waste time by unstacking and then straight away restacking the same registers); or secondly, linking handlers together (typically by replacing the interrupt vector with the new handler to run, followed by the new handler calling the original handler). I assume you mean the first.


    hth
    s.
  • Note: This was originally posted on 30th June 2008 at http://forums.arm.com

    Hi Sim,
          How about the preformance with the second definition?
    I think this is a good idea to avoid the  re-entrant problem which shares the same structures .  Is it ?



    Sunmoon,

    For the first definition (checking for new interrupts before returning), Cortex-M3 already deals with this automatically in hardware, and will perform a "tail-chain" from the end of one interrupt to the entry of another without performing unstacking and restacking.

    The second definition is less useful on a closed/embedded platform; the typical example of this type of chaining used to be the DOS TSR (terminate and stay resident) handlers for things like adding special key bindings e.g. "holding CTRL+ALT+A+B brings up my special program". In this scenario, the TSR would replace the keyboard interrupt vector with its own address, giving itself the chance to check for the magic keysequence, but would then chain onto the original handler if it didn't find what it was looking for. This kind of system may also exist where multiple peripherals share a single interrupt line/handler.

    Replacing the interrupt vector on Cortex-M3 is simply a matter of changing the pointer value in the vector table in memory, though on most MCUs this would likely also require the vector table to be relocated to RAM first.

    hth
    s.
  • Note: This was originally posted on 23rd June 2008 at http://forums.arm.com

    Hi,

    1- Because you don't know how your irq handler will use the stack. Therefore, you keep your irq mode stack as small as possible (only for your status and lr saves) and do the rest in svc mode which should have the largest (depends on your app.) amount of stack.

    Regards,
    Bekir
  • Note: This was originally posted on 24th June 2008 at http://forums.arm.com

    If I recall correctly, a nested interrupt handler allows a higher-priority interrupt to interrupt it. For example, you might want a timer interrupt to have higher priority than a UART interrupt, because what you are doing in the timer requires hard real-time guarantees on latency. In this model, an interrupt cannot interrupt the handler for itself.

    In a re-entrant interrupt routine, a second interrupt of the same type can interrupt processing of the first one. This is rarer, because if the interrupt is that important, you probably need to service the first one anyway. Re-entrant code is more difficult to write and debug, since it will often require access to the same data structures as the interrupted interrupt handler. It also allows unbounded stack growth if the interrupts come in too fast to handle.
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    I just looked up the difference in "The Definitive Guide to the Cortex M3" (Joseh Yiu, Newnes 2007), and the M3 at least does not allow re-entrant interrupts, although nested interrupts are allowed. This is a consequence of the way the interrupt controller works.

    So if you are planning to use a M3, you do not need to worry.
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    Is that re-entrancy, though? It requires you to finish the service of the original interrupt and return to a lower-priority context. That sounds like interrupt chaining to me.
  • Note: This was originally posted on 30th June 2008 at http://forums.arm.com

    To answer the question in the original post:

    You need to switch to system mode / supervisor mode
    before enabling nested interrupt. Otherwise you might
    lose your LR after a BL instruction. For example, if
    you stay in IRQ state and you execute a BL instruction
    inside the handler, the value of LR is updated. At the
    same time if a new IRQ come in, this overwrite the new
    LR content before you have any chance to save it to
    the stack.

    By switching over to system or supervisor mode, the BL
    instruction will update the LR for system/supervisor mode,
    which will not be overriden when a new IRQ come in. 
    The new IRQ handler can save the LR (and other registers)
    to the stack before switching to system/supervisor mode
    again. This applied to ARM7/ARM9, etc.

    ----

    Regarding reentrant interrupts in ARM7/ARM9, it also
    depends on the interrupt controller. If you are using
    VIC (PL192/PL190), it has priority logic inside which
    will stop reentrant interrupts (similar to the case
    in Cortex-M3).

    ----
    Regarding Cortex-M3:
    Technically it is possible to create re-entry interrupt
    using non-base thread enable and clear the IPSR value
    by a extra layer of exception (and manually manipulate stack
    frames) so that the interrupt masking is removed. But
    this is really a pain to setup. Therefore I wouldn't recommend
    this to anyone  B)
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    Sean,

    For clarity, the definitions I use are as follows;

    Interrupt nesting: interrupt A can preempt handling of interrupt B; both interrupt A and interrupt B's handlers can be "active" at the same time.

    Re-entrant interrupt: interrupt A can preempt handling of interrupt A; interrupt A's handler can be active concurrently with itself.

    Interrupt chaining: (an overloaded term) means one of two things; firstly checking for a new pending interrupt before returning from interupt context (i.e. a scenario which would could waste time by unstacking and then straight away restacking the same registers); or secondly, linking handlers together (typically by replacing the interrupt vector with the new handler to run, followed by the new handler calling the original handler). I assume you mean the first.

    Interrupt nesting on ARM7 typically requires some degree of re-entrancy (ignoring FIQ vs IRQ) due to all handlers hanging off the IRQ vector. Cortex-M3 has greater flexibility in interrupt handling, priorities and number of vectors, so the ability/requirement for re-entrancy is signficiantly less.

    Re-entrancy on ARM7 requires code to exit from the "true" interrupt context and to drop priority, i.e. switch out of IRQ mode, and re-enable interrupts via a small code stub; the same is true for Cortex-M3. Unlike ARM7, the same isn't true for interrupt nesting (ignoring FIQ), if the priority of A is higher than the currently running interrupt B, then A will preempt automatically on Cortex-M3.

    Implementing re-entrancy on Cortex-M3 requires, as I eluded to earlier, the pushing of a thread stack frame containing the ReturnPC of the re-entrant interrupt handler, a suitable Thread xPSR and some initial register values onto the stack, followed by performing an interrupt return to Thread mode. Whilst this part of the code clearly isn't re-entrant, the part "returned" to is. Exiting from a re-entrant handler written like this is less trivial - and left as an exercise for the reader :-)

    hth
    s.
  • Note: This was originally posted on 26th June 2008 at http://forums.arm.com

    Hi sim,
        For Interrupt nesting, I don't think interrupt A and interrupt B's handlers can be "active" at the same time. interrupt B must wait for returning by interrupt A if no interrupt occurs.


    Sorry, I used "active" to mean that an execution context for the two handlers existed concurrently, not that both handlers were actually being simultaneously worked upon; the typical case would be for the highest-prioirty handler to be run to completion before the lower priority one continues, though I could envisage other (more complicated) scenarios.

    hth
    s.
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    "does not allow" is perhaps a little over the top; what the Cortex-M3 hardware does do is perform all of the operations required to enable interrupt nesting with [near] zero effort on the programmer's side. If really desired, interrupt re-entrancy can be performed via the creation of, and return to, an additional (lower-priority) context after setting the non-base-thread enable.

    s.
  • Note: This was originally posted on 25th June 2008 at http://forums.arm.com

    sunmoon,

    NXP have an appnote containing all of this for their ARM7 based LPC2000 series:

    [url="http://www.nxp.com/acrobat_download/applicationnotes/AN10381_1.pdf"]http://www.nxp.com/acrobat_download/applic...s/AN10381_1.pdf[/url]

    hth
    s.
  • Note: This was originally posted on 27th June 2008 at http://forums.arm.com

    Sunmoon,

    For the first definition (checking for new interrupts before returning), Cortex-M3 already deals with this automatically in hardware, and will perform a "tail-chain" from the end of one interrupt to the entry of another without performing unstacking and restacking.

    The second definition is less useful on a closed/embedded platform; the typical example of this type of chaining used to be the DOS TSR (terminate and stay resident) handlers for things like adding special key bindings e.g. "holding CTRL+ALT+A+B brings up my special program". In this scenario, the TSR would replace the keyboard interrupt vector with its own address, giving itself the chance to check for the magic keysequence, but would then chain onto the original handler if it didn't find what it was looking for. This kind of system may also exist where multiple peripherals share a single interrupt line/handler.

    Replacing the interrupt vector on Cortex-M3 is simply a matter of changing the pointer value in the vector table in memory, though on most MCUs this would likely also require the vector table to be relocated to RAM first.

    hth
    s.