专栏首页韦东山嵌入式韦东山:在Linux设备树(DTS)中指定中断_在代码中获得中断

韦东山:在Linux设备树(DTS)中指定中断_在代码中获得中断

作者:韦东山 全文分为三大部分

1.设备树里中断节点的语法 2.设备树里中断节点的示例 3.在代码中获得中断

参考:

内核Documentation\devicetree\bindings\interrupt-controller\interrupts.txt

1.设备树里中断节点的语法

1.1 设备树里的中断控制器

中断的硬件框图如下:

在硬件上,“中断控制器”只有GIC这一个,但是我们在软件上也可以把上图中的“GPIO”称为“中断控制器”。很了芯片有多个GPIO模块,比如GPIO1、GPIO2等等。所以软件上的“中断控制器”就有很多个:GIC、GPIO1、GPIO2等等。

GPIO1连接到GIC,GPIO2连接到GIC,所以GPIO1的父亲是GIC,GPIO2的父亲是GIC。

假设GPIO1有32个中断源,但是它把其中的16个汇聚起来向GIC发出一个中断,把另外16个汇聚起来向GIC发出另一个中断。这就意味着GPIO1会用到GIC的两个中断,会涉及GIC里的2个hwirq。

这些层级关系、中断号(hwirq),都会在设备树中有所体现。

在设备树中,中断控制器节点中必须有一个属性:interrupt-controller,表明它是“中断控制器”。

还必须有一个属性:#interrupt-cells,表明引用这个中断控制器的话需要多少个cell。

#interrupt-cells的值一般有如下取值:

① #interrupt-cells=<1>

别的节点要使用这个中断控制器时,只需要一个cell来表明使用“哪一个中断”。

② #interrupt-cells=<2>

别的节点要使用这个中断控制器时,需要一个cell来表明使用“哪一个中断”;

还需要另一个cell来描述中断,一般是表明触发类型:

第2个cell的bits[3:0] 用来表示中断触发类型(trigger type and level flags):

1 = low-to-high edge triggered,上升沿触发

2 = high-to-low edge triggered,下降沿触发

4 = active high level-sensitive,高电平触发

8 = active low level-sensitive,低电平触发

示例如下:

vic: intc@10140000 {
  compatible = "arm,versatile-vic";
  interrupt-controller;
  #interrupt-cells = <1>;
  reg = <0x10140000 0x1000>;
};

如果中断控制器有级联关系,下级的中断控制器还需要表明它的“interrupt-parent”是谁,用了interrupt-parent”中的哪一个“interrupts”,请看下一小节。

1.2 设备树里使用中断

一个外设,它的中断信号接到哪个“中断控制器”的哪个“中断引脚”,这个中断的触发方式是怎样的?

这3个问题,在设备树里使用中断时,都要有所体现。

① interrupt-parent=<&XXXX>

你要用哪一个中断控制器里的中断?

② interrupts

你要用哪一个中断?

Interrupts里要用几个cell,由interrupt-parent对应的中断控制器决定。在中断控制器里有“#interrupt-cells”属性,它指明了要用几个cell来描述中断。

比如:

i2c@7000c000 {
  gpioext: gpio-adnp@41 {
    compatible = "ad,gpio-adnp";


    interrupt-parent = <&gpio>;
    interrupts = <160 1>;


    gpio-controller;
    #gpio-cells = <1>;


    interrupt-controller;
    #interrupt-cells = <2>;
  };
......
};

③ 新写法:interrupts-extended

一个“interrupts-extended”属性就可以既指定“interrupt-parent”,也指定“interrupts”,比如:

interrupts-extended = <&intc1 5 1>, <&intc2 1 0>;

2.设备树里中断节点的示例

以100ASK_IMX6ULL开发板为例,在arch/arm/boot/dts目录下可以看到2个文件:imx6ull.dtsi、100ask_imx6ull-14x14.dts,把里面有关中断的部分内容抽取出来。

从设备树反推IMX6ULL的中断体系,如下,比之前的框图多了一个“GPC INTC”:

GPC INTC的英文是:General Power Controller, Interrupt Controller。它提供中断屏蔽、中断状态查询功能,实际上这些功能在GIC里也实现了,个人觉得有点多余。除此之外,它还提供唤醒功能,这才是保留它的原因。

3.在代码中获得中断

之前我们提到过,设备树中的节点有些能被转换为内核里的platform_device,有些不能,回顾如下:

A. 根节点下含有compatile属性的子节点,会转换为platform_device

B. 含有特定compatile属性的节点的子节点,会转换为platform_device

如果一个节点的compatile属性,它的值是这4者之一:“simple-bus”,“simple-mfd”,“isa”,“arm,amba-bus”,

那么它的子结点(需含compatile属性)也可以转换为platform_device。

C. 总线I2C、SPI节点下的子节点:不转换为platform_device

某个总线下到子节点,应该交给对应的总线驱动程序来处理, 它们不应该被转换为platform_device。

3.1 对于platform_device

一个节点能被转换为platform_device,如果它的设备树里指定了中断属性,那么可以从platform_device中获得“中断资源”,函数如下,可以使用下列函数获得IORESOURCE_IRQ资源,即中断号:

/**
* platform_get_resource - get a resource for a device
* @dev: platform device
* @type: resource type   // 取哪类资源?IORESOURCE_MEM、IORESOURCE_REG
*                      // IORESOURCE_IRQ等
* @num: resource index  // 这类资源中的哪一个?
*/
struct resource *platform_get_resource(struct platform_device *dev,
              unsigned int type, unsigned int num);

3.2 对于I2C设备、SPI设备

对于I2C设备节点,I2C总线驱动在处理设备树里的I2C子节点时,也会处理其中的中断信息。一个I2C设备会被转换为一个i2c_client结构体,中断号会保存在i2c_client的irq成员里,代码如下(drivers/i2c/i2c-core.c):

对于SPI设备节点,SPI总线驱动在处理设备树里的SPI子节点时,也会处理其中的中断信息。一个SPI设备会被转换为一个spi_device结构体,中断号会保存在spi_device的irq成员里,代码如下(drivers/spi/spi.c):

3.3. 调用of_irq_get获得中断号

如果你的设备节点既不能转换为platform_device,它也不是I2C设备,不是SPI设备,那么在驱动程序中可以自行调用of_irq_get函数去解析设备树,得到中断号。

3.4. 对于GPIO

参考:

drivers/input/keyboard/gpio_keys.c

可以使用gpio_to_irq或gpiod_to_irq获得中断号。

举例,假设在设备树中有如下节点:

gpio-keys {
    compatible = "gpio-keys";
    pinctrl-names = "default";


    user {
        label = "User Button";
        gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
        gpio-key,wakeup;
        linux,code = <KEY_1>;
    };
};

那么可以使用下面的函数获得引脚和flag:

button->gpio = of_get_gpio_flags(pp, 0, &flags);

bdata->gpiod = gpio_to_desc(button->gpio);

再去使用gpiod_to_irq获得中断号:

irq = gpiod_to_irq(bdata->gpiod);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【深度】韦东山:一文看看尽linux对中断处理的前世今生

    从2005年我接触Linux到现在15年了,Linux中断系统的变化并不大。比较重要的就是引入了threaded irq:使用内核线程来处理中断。

    韦东山
  • 第五课. 内核中断系统中的设备树

    这节课讲解如何在中断系统中使用设备树,也就是用设备树如何描述中断。 中断体系在4.x内核中变化很大,中断体系又跟pinctrl系统密切相关,pinctrl中又...

    韦东山
  • 第六课:在LCD驱动中使用设备树

    转载请注明文章地址 http://wiki.100ask.org/Linux_devicetree

    韦东山
  • 作画、视物、竖中指 AI的进步让假肢更加智能

    小明评测智能家居网讯:随着科学技术的飞速发展,人们的生活也得到极大的便利。对于身体有残缺的人士而言,假肢可以说是相当重要了。而由于技术在电池、大脑控制机器人和人...

    企鹅号小编
  • 【Vue原理】Diff - 白话版

    终于到了最后一块内容了!今天我们就来简单概括一下 Diff,内容一点都不多哦,全是图片

    神仙朱
  • STM32Cube-05 | 使用EXIT检测按键

    因为没有设置硬件上拉,所以我们配置开启上拉电阻,并设置用户标签为KEY1和KEY2,接下来是最重要的一步:

    Mculover666
  • 一个很easy的脚本--php获取服务器端的相关信息

    存档: 1 <html> 2 <head> 3 <meta http-equiv="content-type" content="...

    Angel_Kitty
  • Java面试必问通信框架NIO,原理详解

    新的输入/输出 (NIO) 库是在 JDK 1.4 中引入的,弥补了原来的 I/O 的不足,提供了高速的、面向块的 I/O。

    李红
  • WCF安全指南

    在2月11日,J.D. Meier在其博客上宣布Patterns & Practices WCF Security Guide发布。J.D. Meier在博客中...

    张善友
  • jQueryUI实现自动完成输入框提示

    在昨天我发表了一个jQueryUI的effect方法,下面我再来给大家介绍一个通过jQueryUI来实现自动完成输入框提示的方法。他需要调用jQuery对象的 ...

    无邪Z

扫码关注云+社区

领取腾讯云代金券