linux 内核 --- 中断子系统

ARM芯片有硬件中断号,比如0~15是SGI中断

linux内核规定了软件中断号及软件中断号的功能;不直接使用ARM芯片的硬件中断号是因为linux内核是适配多架构操作系统,比如有些芯片硬件中断号20是GPIO中断,有些芯片是25;linux统一规定了某个中断号对应GPIO中断。这样就存在硬件中断号和软件中断号的映射(IRQ domain)

下面除非特别说明,否则出现的中断号都是软件中断号

 

相关API

request_irq() // 注册中断,第一个参数就是软件中断号

freee_irq() // 注销中断

 

代码分析

总体流程

触发中断,硬件会根据触发的中断类型自动做一些事情

下图是IRQ中断,跳转到中断代码之前,CPU自动完成的操作

把进中断前的 CPSR 保存到 SPSR_irq,返回地址保存到 LR_irq;

设置CPSR.M = '10010',进入IRQ模式(类似于CM3 的 Thread 模式和 Handler 模式)

设置CPSR.I = '1',关闭 IRQ 中断

跳转到 IRQ 中断函数

跳转到 vector_irq,vector_irq 是用宏实现的,接着执行 __irq_usr

__irq_usr() ---> irq_handler() ---> handle_arch_irq() == gic_handle_irq() ---> handle_domain_irq() ---> handle_irq_desc() ---> generic_handle_irq_desc()

gic 初始化(gic_irq_domain_map())的时候,会设置 desc 的 handle_irq,对于 IRQ 中断,就是 handle_fasteoi_irq()。最后在 __handle_irq_event_percpu() 执行 request_irq() 设置的中断服务函数 action->handler()

 

request_irq()

每个中断号都对应一个 struct irq_desc 实例,request_irq() 的目的就是填写对应中断号的 struct irq_desc,比如填写中断服务函数。

当触发中断时,就可以根据中断号取出对应的中断服务函数执行。

 

posted @ 2023-10-05 00:27  流水灯  阅读(76)  评论(0编辑  收藏  举报