interrupt结构体和相关函数
学习资料来源于:韦东山第三期,侵联删
可以从request_irq函数一路分析,interrupt相关结构体如下:
![0](https://img2024.cnblogs.com/blog/3261801/202404/3261801-20240401023110409-164652267.png)
Linux中有一个中断数据,对于每一个硬件中断,都有一个数组项,这个数组就是irq_desc数组
当调用request_irq、request_threaded_irq注册中断处理函数时,内核就会构造一个irqaction结构体。在里面保存name、dev_id等,最重要的是handler、thread_fn、thread。
在irq_data结构体中,irq是软件中断号,hwirq是硬件中断号
irq_domain_ops.xlate用来解析设备树的中断属性,提取出hwirq/type等信息
irq_domain_ops.map将hwirq转换成irq
irq_data.irq转换为irq_data.hwirq:
irq_to_desc 是 Linux 内核中的一个函数,用于根据中断号获取对应的中断描述符。中断描述符包含了与中断相关的各种信息,例如中断处理函数、中断共享状态等。
这个函数的原型定义在 include/linux/irqdesc.h 头文件中,通常在中断处理程序中使用。其用法如下:
struct irq_desc *irq_to_desc(unsigned int irq); // 参数说明 irq 是中断号,函数返回对应中断号的中断描述符指针,类型为 struct irq_desc *。通过这个指针,可以获取中断描述符的各种信息,进而进行中断处理等操作。
获取中断号:
对于platform设备驱动:
struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num); // 参数说明 type:IORESOURCE_MEM/IORESOURCE_REG/IORESOURCE_IRQ num:这类资源中的哪一个
使用demo如下:
#include <linux/platform_device.h> struct resource *res; int irq; // 假设 platform_dev 是一个 platform_device 结构的指针 res = platform_get_resource(platform_dev, IORESOURCE_IRQ, 0); if (res) { irq = res->start; printk(KERN_INFO "Interrupt number: %d\n", irq); } else { printk(KERN_ERR "Failed to get IRQ resource\n"); }
也可使用platform_get_irq获取中断号
int platform_get_irq(const struct platform_device *pdev, unsigned int num); // 参数和返回值说明 pdev 是指向平台设备结构的指针, num 是中断号的索引,用于指定设备可能的中断号。 如果中断号存在,则返回该中断号;如果中断号不存在,则返回一个负值。
非platform设备驱动可使用of_irq_get获取
int of_irq_get(const struct device_node *dev, int index) // 参数和返回值说明 dev 是指向设备节点的指针, index 是中断号的索引,用于指定设备可能的中断号。 如果中断号存在,则返回该中断号;如果中断号不存在或者出错,则返回一个负值。
对于GPIO中断可使用gpio_to_irq或gpiod_to_irq获得中断号:
int gpio_to_irq(unsigned int gpio); // 参数和返回值说明 gpio 是 GPIO 引脚的编号。该函数将给定的 GPIO 引脚映射到相应的中断号,并返回该中断号。 如果无法将 GPIO 引脚映射到中断号,则返回一个负值。
中断申请和中断下半部函数可见: