linux固定中断号如何分配
linux固定中断号如何分配详细介绍
在 Linux 系统中,中断号(IRQ,Interrupt Request)的分配分为 内核空间 和 用户空间 两个层面,其分配机制与具体硬件架构和设备类型密切相关。以下是详细说明:
一、内核空间的中断号分配
1.
静态分配(固定中断号)
- 适用场景:针对硬件特性明确的设备(如传统 ISA 设备、嵌入式系统中的固定外设),驱动程序在注册时需显式指定中断号。
- 接口函数:
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
通过irq参数直接指定中断号,handler为中断处理函数,name为设备名称(如/proc/interrupts中显示的名称)。- 示例(驱动代码片段):c
pdevirq pdev
irq my_irq_handler IRQF_SHARED my_dev
EBUSY
- 中断号范围:
- 传统 x86 架构:
0~15为 ISA 保留中断(如键盘、定时器),16~23为 PCI 设备中断(由 IOAPIC 管理)。 - 嵌入式系统(如 ARM):中断号范围由具体控制器(如 GIC)决定,可通过设备树(DTS)的
interrupts属性显式指定。
- 传统 x86 架构:
2.
动态分配(非固定中断号)
- 适用场景:PCI/USB 等即插即用设备,中断号由硬件自动分配(如 PCI 设备的
INTx中断)。 - 分配流程:
- 设备驱动通过
pci_read_config_dword获取设备的中断引脚(INT_PIN)。 - 内核根据引脚和总线拓扑映射到实际中断号(存储在
struct pci_dev的irq字段)。
- 设备驱动通过
- 特点:中断号在设备枚举时确定,不同系统或重启后可能变化。
3.
设备树(Device Tree)配置
- 在嵌入式系统中,通过 DTS 文件的
interrupts属性指定设备的中断号,例如:dtsmy_device {compatible = "vendor,my-device";
interrupts = <0 3 4>; // 中断号、触发类型(如 IRQ_TYPE_LEVEL_HIGH)、优先级
};
- 驱动通过
of_get_named_gpiod或platform_get_irq解析设备树中的中断配置。
二、用户空间的中断号访问
1.
查看中断号分配
- 通过
/proc/interrupts文件查看系统所有中断号及其对应的设备:bash$ /proc/interruptsCPU0 CPU1 CPU2 CPU3
: IO-APIC-edge timer
: IO-APIC-edge i8042
: IO-APIC-edge rtc0
.
- 通过
/sys/class/interrupts/目录获取设备对应的中断号(动态映射):bash$ /sys/class/interrupts/ my_device
2.
用户空间程序的限制
- 用户空间无法直接分配或修改中断号,只能通过内核提供的接口(如
sys_open打开/dev/interrupts节点,或使用mmap映射中断控制器寄存器)间接操作。 - 如需自定义中断,需编写内核模块(或使用
bpf技术),通过request_irq在内核中注册中断处理函数。
三、注意事项
- 中断号冲突:
- 多个设备共享同一中断号时,需在
request_irq中指定IRQF_SHARED标志,并通过中断处理函数的返回值(IRQ_HANDLED/IRQ_NONE)判断是否为当前设备触发。
- 多个设备共享同一中断号时,需在
- 架构差异:
- x86 架构使用 PIC(可编程中断控制器)或 APIC,ARM 使用 GIC(通用中断控制器),中断号的分配逻辑和范围因架构而异。
- 驱动兼容性:
- 现代驱动应优先使用设备树或动态分配机制,避免硬编码固定中断号(除非硬件特性强制要求)。
总结
Linux 中固定中断号的分配主要通过内核驱动显式指定(如 request_irq 或设备树配置),适用于硬件特性明确的场景。动态分配则由系统自动管理,适用于即插即用设备。用户空间程序不直接参与中断号分配,而是通过内核接口间接使用已分配的中断资源。