在ARM64架构的Linux内核中,中断处理是操作系统响应硬件事件的关键机制。以下是中断处理的一般使用方法和步骤:
中断控制器初始化:
arch/arm64/kernel/setup.c
文件中完成,通过调用gic_init()
来设置中断控制器。中断请求(IRQ)分配:
request_irq()
函数来请求一个中断号(IRQ)。这个函数需要传递中断号、中断处理函数、中断类型(如共享或独占)和上下文数据等参数。中断处理函数:
irqreturn_t irq_handler(unsigned int irq, void *dev_id)
。中断处理函数注册:
request_irq()
函数会返回一个错误码,如果成功,返回0。中断处理函数的执行:
中断结束:
irq_set_affinity()
设置中断的CPU亲和性,以便在多核系统中正确分配中断处理任务。释放中断:
free_irq()
函数释放之前请求的中断号。中断处理的同步:
local_irq_disable()
)和启用中断(使用local_irq_enable()
)。中断处理的优化:
中断处理的调试:
irq_affinity_hint()
和irq_affinity_hint_handler()
来设置中断的CPU亲和性提示,这有助于在多核系统中优化中断处理。interrupt-parent = <&gic>;
i2c4: i2c@ffa30000 {
compatible = "rockchip,rk3562-i2c", "rockchip,rk3399-i2c";
reg = <0x0 0xffa30000 0x0 0x1000>;
clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
clock-names = "i2c", "pclk";
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
};
static int lpc32xx_ts_probe(struct platform_device *pdev)
{
...
irq = platform_get_irq(pdev, 0);
...
error = request_irq(tsc->irq, lpc32xx_ts_interrupt,
0, pdev->name, tsc);
...
}
bq25700: bq25700@6b {
compatible = "ti,bq25703";
reg = <0x6b>;
interrupt-parent = <&gpio1>;
interrupts = <RK_PA1 IRQ_TYPE_LEVEL_LOW>;
};
static int i2c_gpio_fi_act_on_scl_irq(struct i2c_gpio_private_data *priv,
irqreturn_t handler(int, void*))
{
int ret, irq = gpiod_to_irq(priv->scl);
...
ret = request_irq(irq, handler, IRQF_TRIGGER_FALLING,
"i2c_gpio_fault_injector_scl_irq", priv);
...
}