linux device tree 中断属性

/*
 * 设备树的中断属性
 */
    interrupt-controller    /* 中断控制器 */

    #interrupt-cells        /* 表明引用这个中断控制器的话需要多少个 cell */
        #interrupt-cells=<1>    /* 其它节点要使用这个中断控制器时,只需要一个 cell 来表明使用"哪一个中断" */
        #interrupt-cells=<2>    /* 其它节点要使用这个中断控制器时,第一个 cell 来表明使用"哪一个中断" */
                                /* 另一个 cell 来描述中断,一般是表明触发类型. bits[3] = 0,1,2,4,8 */

    interrupt-parent = <&gpio2>;
    interrupts = <30 0>;

    中断控制器是GPIO2,使用它的30号中断。(30是指30号引脚),0是指触发的方式(上升沿、下降沿等)。

    interrupts = <0 38 1>;
    interrupts = <GIC_SPI 38 1>;
    interrupts = <GIC_PPI 18 1>;

    #define GIC_SPI 0
    #define GIC_PPI 1

    IPI:inter-processer interrupt 中断号 0 ~ 15
    PPI:per processor interrupts 中断号 16 ~ 31
    SPI:shared processor interrupts 中断号 32 ~ 32+224
    SGI:software generated interrupts (SGI).

    第一个参数表示是 IPI、PPI、SPI、SGI 其中的一个
    第二个参数表示:是第一个参数里面的第几个
    第三个参数表示:中断触发的类型。(上升沿、下降沿等)

    interrupts = <GIC_SPI 68 1>;
        表示中断类型为共享处理器中断(SPI),
        中断号为SPI中断类型中的第68号中断号,计算出来的实际中断号即为32+68=100号中断,
        1表示上升沿触发中断。

    中断类型的值:

    #define IRQ_TYPE_NONE        0            /* 内核不改变它,开机或uboot设置它是什么样就什么样 */
    #define IRQ_TYPE_EDGE_RISING    1         /* 上升沿触发 */
    #define IRQ_TYPE_EDGE_FALLING    2        /* 下降沿触发 */
    #define IRQ_TYPE_EDGE_BOTH    (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)    /* 双边沿触发 */
    #define IRQ_TYPE_LEVEL_HIGH    4          /* 电平触发-高电平 */
    #define IRQ_TYPE_LEVEL_LOW    8           /* 电平触发-低电平 */

    一个"interrupts-extended"属性就可以既指定"interrupt-parent",也指定"interrupts"
    interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;

    /* 相关源文件 */
    drivers/irqchip/irq-gic.c

    /* 申请中断,绑定中断处理函数 */
    static inline int __must_check request_irq(unsigned int irq, irq_handler_t handler,
                                unsigned long flags, const char name, void *dev)

        irq : 用于指定"内核中断号",这个参数我们会从设备树中获取或转换得到
        handler: 中断处理函数, irqreturn_t (*irq_handler_t)(int irq, void * dev);

        flags: 设置中断触发方式,该设置会覆盖设备树里面配置的中断触发方式
        name: 中断的名字,中断申请成功后会在"/proc/interrupts"目录下看到对应的文件

        dev: :如果使用了 IRQF_SHARED 宏,则开启了共享中断。"共享中断"指的是多个驱动程序共用同一个中断。
                开启了共享中断之后,中断发生后内核会依次调用这些驱动的"中断服务函数"。
                这就需要在中断服务函数里判断中断是否来自本驱动,这里就可以用 dev 参数做中断判断。
                即使不用 dev 参数判断中断来自哪个驱动,在申请中断时也要加上 dev 参数因为在注销驱动时内核会根据 dev
                参数决定删除哪个中断服务函数

    /* 中断注销函数 */
    void free_irq(unsigned int irq, void *dev)

    /* 通过gpio编号获得中断号 */
    int gpio_to_irq(unsigned int gpio)

    /* 中断使能和禁用 */
    /* 控制某个中断 */
    void enable_irq(unsigned int irq)
    void disable_irq(unsigned int irq)

    /* 控制全局中断 */
    local_irq_enable()
    local_irq_disable()
    local_irq_save(flags)    // 保存当前中断状态,并关闭中断
    local_irq_restore(flags) // 恢复中断,将中断恢复到flags状态

    /* 从设备树里解析出中断号 */
    of_irq_get(dev->of_node, 0)
        i2c : i2c_device_probe() ---> of_irq_get    (drivers/i2c/i2c-core.c)
        spi : spi_drv_probe()    ---> of_irq_get    (drivers/spi/spi.c)

    /* 获得 GPIO 中断号 */
    gpio_to_irq()
    gpiod_to_irq()
    
    /* 获得引脚和 flag */
    gpio_to_desc()
    of_get_gpio_flags()

    /* GPC INTC (General Power Controller, Interrupt Controller) */
    通用电源控制器、中断控制器,提供中断屏蔽、中断状态查询、唤醒功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值