arm64架构的linux中断分析(五)中断的使用

发布时间:2024年01月11日

6. 中断的使用方法

在ARM64架构的Linux内核中,中断处理是操作系统响应硬件事件的关键机制。以下是中断处理的一般使用方法和步骤:

  1. 中断控制器初始化

    • 在系统启动时,需要初始化中断控制器(如GIC,Generic Interrupt Controller)。这通常在arch/arm64/kernel/setup.c文件中完成,通过调用gic_init()来设置中断控制器。
  2. 中断请求(IRQ)分配

    • 使用request_irq()函数来请求一个中断号(IRQ)。这个函数需要传递中断号、中断处理函数、中断类型(如共享或独占)和上下文数据等参数。
  3. 中断处理函数

    • 编写一个中断处理函数,这个函数将在中断发生时被调用。中断处理函数通常需要遵循特定的原型,例如irqreturn_t irq_handler(unsigned int irq, void *dev_id)
  4. 中断处理函数注册

    • 在请求中断时,将中断处理函数与中断号关联。request_irq()函数会返回一个错误码,如果成功,返回0。
  5. 中断处理函数的执行

    • 当硬件设备产生中断时,中断控制器会通知CPU,CPU会跳转到中断处理函数执行中断服务例程。
  6. 中断结束

    • 中断处理完成后,需要使用irq_set_affinity()设置中断的CPU亲和性,以便在多核系统中正确分配中断处理任务。
  7. 释放中断

    • 当不再需要中断处理时,使用free_irq()函数释放之前请求的中断号。
  8. 中断处理的同步

    • 在中断处理函数中,可能需要同步操作,如禁用中断(使用local_irq_disable())和启用中断(使用local_irq_enable())。
  9. 中断处理的优化

    • 为了提高中断处理效率,可能需要使用中断共享、快速中断处理(FIQ)等技术。
  10. 中断处理的调试

    • 使用irq_affinity_hint()irq_affinity_hint_handler()来设置中断的CPU亲和性提示,这有助于在多核系统中优化中断处理。

6.1 gic中断使用

6.1.1 设备树的编写

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>;
        };


6.1.2 驱动编写

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);
...
}                            

6.2 gpio中断使用

6.2.1 设备树的编写

        bq25700: bq25700@6b {
                compatible = "ti,bq25703";
                reg = <0x6b>;
                interrupt-parent = <&gpio1>;
                interrupts = <RK_PA1 IRQ_TYPE_LEVEL_LOW>;
        };

6.2.2 驱动编写

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);
...
}

文章来源:https://blog.csdn.net/sinat_22338935/article/details/135140240
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。