I am reading about how Interrupts are handled in ARM and came to know whenever any Hardware interrupts comes instruction at an address 0x00000018 is executed which is generally a jump to respected interrupt handler but there could be many interrupt handler for different modules .
Then,how these different handlers are mapped to an address 0x00000018?
Also,how arm cpu comes to know interrupt raise is irq or fiq,who decides it and which device raised the interrupt ,how to map to respected handler for this interrupt.
Can any body point me to a simple interrupt handler code where I can see what all an interrupt handler do ?
An ARM CPU typically has two pins (FIQ and IRQ) that are asserted by devices when they want to generate an interrupt. When this happens, the CPU simply switches modes and jumps to address 0x00000018
.
However, because there are usually more devices than the number of interrupt pins, there's usually an interrupt controller that goes between the CPU and the devices. You can think of this as a hub for connecting more interrupts to the CPU. The interrupt controller can be configured to assert FIQ for certain kinds of interrupts it receives.
The interrupt handler usually asks the interrupt controller which pin caused the interrupt, then calls the appropriate handler.
Here's a stripped down version without error checking of interrupt handler code that I used in a small project.
#include <types.h>
#include <irq.h>
static void (*irq_handlers[32])(void);
void __attribute__((interrupt)) handle_irq() {
int irq = irq_hw_get_and_ack();
if (irq_handlers[irq]) {
irq_handlers[irq]();
}
}
void setup_irq() {
irq_hw_init();
cpu_enable_irq();
}
void irq_request(int irq, void (*func)(void)) {
irq_handlers[irq] = func;
irq_hw_enable(irq);
}
void irq_unrequest(int irq) {
irq_hw_disable(irq);
irq_handlers[irq] = NULL;
}
It has been fairly typical for processors to only have one interrupt. x86 was like that for a while, maybe still is. Arm has traditionally had two, but the newer cores have many now 32, 256, etc.
Where you have a shared interrupt line, as tangrs mentioned you typically have something outside the processor, in the case of arm, within the chip but outside the arm core itself. Something that does have many interrupt inputs and the output or outputs that go to the processors one or few interrupts. When the processors interrupt occurs then you check with this logic/hardware outside the processor/core to see who caused it, and there you go.
it is also not atypical to have nested interrupt controllers, say for example an 8 input with one output. And for some or each of those 8 inputs another 8 to 1 interrupt controller. The software would then need to simply follow the path. check the first level interrupt controller to see which one(s) fired the interrupt, then from there you know the next layer up controller you need to talk to and so on until you isolate the individual interrupt.
Also know and understand that for these shared interrupt systems, it is quite possible to have multiple interrupts happen "at the same time" basically from the time your program starts stopping and the interrupt vector is called, and you do your interrupt startup stuff and eventually read the interrupt status register, more than one can come in. You need to decide how to handle that and depending on the system/logic if you were to return from one of them the others being asserted might bring you back into the interrupt handler, so that impementation would/could be handle only one of the pendings. Other logic might require you to handle all the pendings before you return.
Since arm doesnt necessarily control what is tied to the interrupt or fiq lines you can get all kinds of solutions from various vendors as to how the interrupt system works for a particular arm chip.
User contributions licensed under CC BY-SA 3.0