Linux驱动开发基础_在设备树中指定中断以及在代码中获得中断

这篇具有很好参考价值的文章主要介绍了Linux驱动开发基础_在设备树中指定中断以及在代码中获得中断。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

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

1.1 设备树里的中断控制器

1.2 设备树里使用中断

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

3 在代码中获得中断

3.1 对于 platform_device 

3.2  对于 I2C 设备、SPI 设备

3.3  调用 of_irq_get 获得中断号

3.4 对于 GPIO 


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

参考文档:内核 Documentation\devicetree\bindings\interrupt-controller\interrupts.txt

1.1 设备树里的中断控制器

中断的硬件框图如下:

of_get_gpio_flags,# Linux驱动--驱动开发基础,Linux驱动

 在硬件上,“中断控制器”只有 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  设备树里中断节点的示例

of_get_gpio_flags,# Linux驱动--驱动开发基础,Linux驱动

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

of_get_gpio_flags,# Linux驱动--驱动开发基础,Linux驱动

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

3 在代码中获得中断

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

  • 根节点下含有 compatile 属性的子节点,会转换为 platform_device 
  • 含有特定 compatile 属性的节点的子节点,会转换为 platform_device 如果一个节点的 compatile 属性,它的值是这 4 者之一:"simple-bus","simple-mfd","isa","arm,amba-bus",  那么它的子结点(需含 compatile 属性)也可以转换为 platform_device。
  • 总线 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): 

of_get_gpio_flags,# Linux驱动--驱动开发基础,Linux驱动

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

of_get_gpio_flags,# Linux驱动--驱动开发基础,Linux驱动

 3.3  调用 of_irq_get 获得中断号

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

3.4 对于 GPIO 

可以使用 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); 文章来源地址https://www.toymoban.com/news/detail-578165.html

到了这里,关于Linux驱动开发基础_在设备树中指定中断以及在代码中获得中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 驱动开发基础知识——LED 模板驱动程序的改造:设备树(十一)

     个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755@qq.com 🦉个人WeChat:Vir2021GKBS 🐼 本文由妄北y原创,首发CSDN 🎊🎊🎊 🐨座右铭:大多数人想要改造这个世界,但却罕有人想改造自己。 专栏导航: 妄北y系列专栏导航: C/C++的基

    2024年02月21日
    浏览(34)
  • 【IMX6ULL驱动开发学习】09.Linux驱动之GPIO中断(附SR501人体红外感应驱动代码)

    Linux驱动的GPIO中断编程主要有以下几个步骤: 1、 通过GPIO号获取 软件中断号 (中断编程不需要设置GPIO输入输出,当然申请GPIO,设置输入也没问题) 参数 含义 gpio GPIO引脚编号 2、 注册 中断处理函数 ,设置中断 触发方式 (上升沿、下降沿等) 参数 含义 irq 软件中断号(通过

    2024年02月11日
    浏览(41)
  • 驱动开发 day8 (设备树驱动,按键中断实现led亮灭)

    //编译驱动  (注意Makefile的编译到移植到开发板的内核)         make arch=arm //清除编译生成文件         make clean ****************************************** //安装驱动         insmod mycdev.ko //卸载驱动         rmmod mycdev   需要在内核路径/arch/arm/boot/dts/  修改 stm32mp157a-fsmp1a-dts 文件 *

    2024年02月14日
    浏览(33)
  • linux驱动之中断(一) --- 设备树中描述中断

    本文仅介绍如何在Linux驱动中使用中断 linux中的中断不可嵌套(中断不可打断其他中断) 不宜在中断中做耗时长的事情 耗时的事情应当放在中断下半部中 中断下半部是可以被其他中断打断的, 而且可以用线程来执行 内核对中断下半部有三种方式 1,软中断 2, tasklet(用软中断实现

    2024年02月03日
    浏览(22)
  • linux驱动开发 - 09_中断

    链接: C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂 在裸机中使用中断需要做一大堆的工作,比如配置寄存器,使能 IRQ 等等。 Linux 内核提供了完善的中断框架,只需要申请中断,然后注册中断处理函数即可,使用非常方便,不需要一系列复杂的寄存器

    2024年02月03日
    浏览(28)
  • <Linux开发>驱动开发 -之-内核定时器与中断

    <Linux开发>驱动开发 -之-内核定时器与中断 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: <Linux开发> -之-系统移植 uboot移植过程详细记录(第一部分) <Linux开发> -之-系统移植 uboot移植过程详细记录(第二部分) <Linux开

    2024年02月08日
    浏览(33)
  • Linux驱动开发笔记(四):设备驱动介绍、熟悉杂项设备驱动和ubuntu开发杂项设备Demo

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/134533533 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… 上一篇:《Linux驱动开发笔记(三

    2024年02月05日
    浏览(37)
  • [驱动开发]Linux内核定时器与中断的简单应用

    首先介绍一下定时器原理。 在linux系统中定时器有分为软定时和硬件定时器。 以海思某款芯片为例,定时器模块又称为Timer模块,主要实现定时、计数功能。 Timer 具有以下特点: 带可编程 8 位预分频器的 32bit/16bit 减法定时器/计数器。 Timer 的计数时钟为 3MHz 时钟。 支持 3 种

    2024年02月20日
    浏览(28)
  • 4、Linux驱动开发:设备-设备号&设备号注册

    🍅点击这里查看所有博文   随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有

    2024年02月15日
    浏览(45)
  • Linux驱动开发实战(一)——设备驱动模型

    在早期的Linux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Linux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。 设备驱动模型

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包