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

SAM7X calling function from interrupt

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

I am trying to use a timer interrupt to "Set up" a function call. INstead of setting a flag in the interrupt and then polling that flag I would like the interrupt to call a function as soon as teh interrupt is done, but not during the interrupt.

I tried setting a software (swi) interrupt to fire during the timer interupt, but the problem was that it called the software int immediatley during the timer IRQ and not after. I thought the swi was a lower priotrity int then the timer IRQ (set to priority 7), But I guess not...am I wrong????

Is ther a way to do this?
Possibley use a lower priority IRQ to call a function by "Setting" that IRQ during a higher priority IRQ ?
Parents
  • Note: This was originally posted on 6th November 2008 at http://forums.arm.com

    Hello there,

    It sounds like you're trying to set up a delayed function call such that your interrupt handler doesn't take very long (and thus doesn't affect the latency of other interrupts too much). Is that assumption correct? It sounds like an OS in which the task scheduler is run on a timer tick.

    There are a number of ways that you can achieve what you're trying to do. A common solution to this problem is to have a DFC (delayed function call) queue. When an interrupt is triggered, your interrupt routine will clear the interrupt and do any necessary maintenance, then add a task to the queue which processes the data. Be careful with this, as the queue can potentially fill up if your timer tick is too fast for your DFC to keep up, so you'll have to tune your system somehow (whether by hand or automatically at run-time).

    Alternatively, if you simply want to have nested interrupts you can switch to system mode in the interrupt handler (for example). You'll need to be careful with processor state (such as the stack pointer) here.

    A note about SWI and SVC:

    A SWI is not really an interrupt, but is more like an exception. It cannot be masked, and is always triggered by an explicit instruction, rather than by an external event of some kind. In fact, the "SWI" instruction has changed and is now called "SVC" in order to reflect this. I think "SVC" stands for "supervisor call"; it allows user-mode code to call functions in supervisor mode via a fixed exception handler (to allow security restrictions to be enforced).

    Note that most assemblers will generally accept either SWI or SVC instructions, but for all intents and purposes they are one and the same and assemble to the same code.

    If you trigger a SVC (SWI) during an IRQ (or FIQ), it will immediately call the SVC handler, just as if an abort or other exception had occurred. If an undefined instruction was encountered during your interrupt routine, you wouldn't expect the core to handle it after the interrupt routine completes, would you? Well, it's the same effect here.

    A note about interrupts:

    The ARM7 core only knows about two interrupts: IRQs and FIQs. It has no notion of interrupt priority, as that is dealt with in the interrupt controller and that is not part of the core. Typically, the interrupt controller will issue the highest priority interrupt to the core, but once an interrupt is running the core will not stop it to service a higher-priority one. You can set up nested interrupts by explicitly unmasking interrupts during your routine, but it's not usually worthwhile and I don't think that's what you're trying to do. (Nesting FIQs into IRQs is probably more common, but that's much easier to do as the core banks the stack pointer and processor state for you.)

    One way to achieve what you're trying to do with the SVC is to trigger another interrupt during your interrupt routine; this will execute once you return, but higher-priority interrupts will execute first. Judging by what you've said, I don't think that's really what you're trying to achieve.

    ----

    There's a lot of information there, but interrupt handling is quite a complex topic. If you could provide more information about exactly what you're aiming to do I might be able to provide more specific information, but it's useful to understand how these things work.
Reply
  • Note: This was originally posted on 6th November 2008 at http://forums.arm.com

    Hello there,

    It sounds like you're trying to set up a delayed function call such that your interrupt handler doesn't take very long (and thus doesn't affect the latency of other interrupts too much). Is that assumption correct? It sounds like an OS in which the task scheduler is run on a timer tick.

    There are a number of ways that you can achieve what you're trying to do. A common solution to this problem is to have a DFC (delayed function call) queue. When an interrupt is triggered, your interrupt routine will clear the interrupt and do any necessary maintenance, then add a task to the queue which processes the data. Be careful with this, as the queue can potentially fill up if your timer tick is too fast for your DFC to keep up, so you'll have to tune your system somehow (whether by hand or automatically at run-time).

    Alternatively, if you simply want to have nested interrupts you can switch to system mode in the interrupt handler (for example). You'll need to be careful with processor state (such as the stack pointer) here.

    A note about SWI and SVC:

    A SWI is not really an interrupt, but is more like an exception. It cannot be masked, and is always triggered by an explicit instruction, rather than by an external event of some kind. In fact, the "SWI" instruction has changed and is now called "SVC" in order to reflect this. I think "SVC" stands for "supervisor call"; it allows user-mode code to call functions in supervisor mode via a fixed exception handler (to allow security restrictions to be enforced).

    Note that most assemblers will generally accept either SWI or SVC instructions, but for all intents and purposes they are one and the same and assemble to the same code.

    If you trigger a SVC (SWI) during an IRQ (or FIQ), it will immediately call the SVC handler, just as if an abort or other exception had occurred. If an undefined instruction was encountered during your interrupt routine, you wouldn't expect the core to handle it after the interrupt routine completes, would you? Well, it's the same effect here.

    A note about interrupts:

    The ARM7 core only knows about two interrupts: IRQs and FIQs. It has no notion of interrupt priority, as that is dealt with in the interrupt controller and that is not part of the core. Typically, the interrupt controller will issue the highest priority interrupt to the core, but once an interrupt is running the core will not stop it to service a higher-priority one. You can set up nested interrupts by explicitly unmasking interrupts during your routine, but it's not usually worthwhile and I don't think that's what you're trying to do. (Nesting FIQs into IRQs is probably more common, but that's much easier to do as the core banks the stack pointer and processor state for you.)

    One way to achieve what you're trying to do with the SVC is to trigger another interrupt during your interrupt routine; this will execute once you return, but higher-priority interrupts will execute first. Judging by what you've said, I don't think that's really what you're trying to achieve.

    ----

    There's a lot of information there, but interrupt handling is quite a complex topic. If you could provide more information about exactly what you're aiming to do I might be able to provide more specific information, but it's useful to understand how these things work.
Children
No data