本文仅介绍如何在Linux驱动中使用中断
linux中的中断不可嵌套(中断不可打断其他中断)
不宜在中断中做耗时长的事情
耗时的事情应当放在中断下半部中
中断下半部是可以被其他中断打断的, 而且可以用线程来执行
内核对中断下半部有三种方式 1,软中断 2, tasklet(用软中断实现,会被其他中断打断) 3,工作队列(将tasklet丢到工作队列中, 由线程来执行) 4,线程化中断(中断函数线程化)
linux需要读取设备树来得到外设的中断信息
标题如何在设备树中描述中断信息
参考文档
内核Documentation\devicetree\bindings\interrupt-controller\interrupts.txt
- 中断控制器(看得懂dtsi中的中断控制器节点)
中断控制器的参考文档Documentation/devicetree/bindings/arm/gic.txt
设备树中 中断控制器节点中必须有一个属性:interrupt-controller属性 表明它是“中断控制器”。
1 intc: interrupt-controller@00a01000 {
2 compatible = "arm,cortex-a7-gic";
3 #interrupt-cells = <3>;
4 interrupt-controller;
5 reg = <0x00a01000 0x1000>,
6 <0x00a02000 0x100>;
7 };
1 gpio5: gpio@020ac000 {
2 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
3 reg = <0x020ac000 0x4000>;
4 interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
5 <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
6 gpio-controller;
7 #gpio-cells = <2>;
8 interrupt-controller;
9 #interrupt-cells = <2>; //注意这里把cell变成了2 引用这个中断控制器只要两个cell即可
10 };
第一个 cells:中断类型,0表示 SPI中断,1表示 PPI中断。
第二个 cells:中断号,对于 SPI中断来说中断号的范围为 0~987,对于 PPI中断来说中断
号的范围为 0~15。 并不是随便取值, 需要参考芯片手册里gpio对应的中断号
第三个 cells:标志,bit[3:0]表示中断触发类型,
1 = low-to-high edge triggered,上升沿触发
2 = high-to-low edge triggered,下降沿触发
4 = active high level-sensitive,高电平触发
8 = active low level-sensitive,低电平触发
可以或运算同时包含
描述一个外设并应用中断(必须会写)
1 fxls8471@1e {
2 compatible = "fsl,fxls8471";
3 reg = <0x1e>;
4 position = <0>;
5 interrupt-parent = <&gpio5>;
6 interrupts = <0 8>;
7 };
interrupt-parent属性指定用使用哪个中断控制器
interrupts 指定中断号 触发方式
获取设备树中的中断号的函数
对于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);
对于I2C设备、SPI设备
对于I2C设备节点,I2C总线驱动在处理设备树里的I2C子节点时,也会处理其中的中断信息。一个I2C设备会被转换为一个i2c_client结构体,中断号会保存在i2c_client的irq成员里
对于SPI设备节点,SPI总线驱动在处理设备树里的SPI子节点时,也会处理其中的中断信息。一个SPI设备会被转换为一个spi_device结构体,中断号会保存在spi_device的irq成员里文章来源:https://www.toymoban.com/news/detail-435559.html
调用of_irq_get获得中断号
如果你的设备节点既不能转换为platform_device,它也不是I2C设备,不是SPI设备,那么在驱动程序中可以自行调用of_irq_get函数去解析设备树,得到中断号
对于GPIO作为中断
可以使用int gpio_to_irq(unsigned int gpio)
或gpiod_to_irq获得中断号。
通用的获得中断号, 适用任意节点
编写驱动的时候需要用到中断号,我们用到中断号,中断信息已经写到了设备树里面,因
此可以通过 irq_of_parse_and_map函数从 interupts属性中提取到对应的设备号,函数原型如下:
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
dev:设备节点。
index:索引号,interrupts属性可能包含多条中断信息,通过 index指定要获取的信息。文章来源地址https://www.toymoban.com/news/detail-435559.html
到了这里,关于linux驱动之中断(一) --- 设备树中描述中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!