最近几天我正在研究很多关于linux第10章的书ldd3。我有一些疑问请澄清一下。有些是我的分析,如果他们错了,请建议。
对于ARM,有一个中断向量表地址 - IRQ中断 - 0x00000018 然后,芯片制造商可以为USART,SPI,I2C,外部中断等硬件提供单独的中断线 - 并将它们复用到ARM的单个IRQ线。 并有(自己选择的)寄存器来确定哪一个触发了中断。
此外,如果有一个中断线可用于GPIO引脚电平变化中断。 如下所示,链路的单个中断线可以由不同设备驱动程序的许多处理程序共享。
fiq & irq handler -- arm 通常,中断控制器是一个硬件单元,它将许多中断线复用在一起,为CPU产生单线。发生中断时,控制器会断言IRQ线。 CPU停止执行并跳过IRQ向量(位置变化)到中断处理程序。中断处理程序读取中断控制器上的寄存器以确定中断线,并调用正确的中断处理程序然后清除中断 - 允许另一个中断发生。
http://www.makelinux.net/ldd3/chp-10-sect-2 此链接中描述了如何注册中断处理程序。
https://unix.stackexchange.com/questions/47306/how-does-the-linux-kernel-handle-shared-irqs Linux为同一共享行调用所有intruppt处理程序。
我的问题是作为设备驱动程序的程序员我只调用.... request_irq()。
谁提供通用的代码 - IRQ中断@ 0x00000018地址 - 正在读取供应商特定的寄存器以确定哪个中断线引发了IRQ。 然后告诉linux功能 - 调用为该IRQ线路注册的所有共享中断处理程序?
芯片组的GCC编译器启动代码是否为我们工作?
答案 0 :(得分:6)
实际的中断处理由linux/arch/arm/kernel/entry-armv.S设置。然后,在解码和运行中断处理程序时涉及长链代码。
实际的request_irq是通用代码,它设置了linux/include/linux/irqdesc.h中定义的“描述符”irq_desc。
在电路板的特定设置中配置“哪个中断是哪个”的实际处理。我在这里给出一个omap2 / omap3板的例子(随机选择,因为我使用过这些板,但不是在Linux中): linux/arch/arm/mach-omap2/irq.c
我希望这会有所帮助。
答案 1 :(得分:1)
在entry-armv.S文件中,您可以找到填写IRQ行的代码,如下所示:
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro irq_handler
get_irqnr_preamble r5, lr
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, BSYM(1b)
bne asm_do_IRQ
宏get_irqnr_and_base
是特定于机器的,因此包含在文件arch / arm / mach_ / include / entry-macro.S中。
您可以看到,这个宏以不同的方式为不同的基于arm的机器实现。这就是基于不同的HW来识别IRQ线的方法。