Linux系统的中断函数记录

文章详细介绍了Linux内核中GPIO中断的注册流程,包括从设备树获取GPIO参数,设置GPIO配置,注册中断服务函数,以及申请和启用中断号。还提到了request_irq函数的使用和中断标志的解释。此外,讨论了设备树在中断配置中的作用,以及中断控制器如GIC的相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、中断的注册流程

        中断的操作流程主要分为两部分:中断资源的注册、中断资源的注销。

        中断的操作一般与硬件有联系,特别是gpio,这里也gpio为例。

(1)从设备树中的结点获得相应的gpio的参数。

/* 设备树中获取按键client端的结点 */
	Input.nd = of_find_node_by_path(BUTTONTREEPATH);
	if(Input.nd == NULL)
	{
		printk("button nod not find\r\n");
		return -EINVAL;
	}


        Input.gpio[i].gpio = of_get_named_gpio(Input.nd, BUTTONGPIONAME, i);
		if(Input.gpio[i].gpio < 0)
		{
			printk("can not get goio%d\r\n",i);
			Input.gpio[i].gpio = -1;
		}else
		{
			printk("gpio:%d\r\n",Input.gpio[i].gpio);
		}


(2)设置gpio的相关配置。

gpio_request(Input.gpio[i].gpio, Input.gpio[i].name);
gpio_direction_input(Input.gpio[i].gpio);

(3)对应gpio的线管中断参数设置。

            Input.gpio[i].irqnum = gpio_to_irq(Input.gpio[i].gpio);

			/* 中断函数相关设置,所有同类型按键调用同一个中断函数 */
			Input.gpio[i].handler = key0_handler;
			Input.gpio[i].event = KEY_0;          /* 事件的类型 */
			printk("get gpio%d irq\r\n" ,Input.gpio[i].gpio);

(4)中断号申请并使能。

ret = request_irq(Input.gpio[i].irqnum, Input.gpio[i].handler,             
                  IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
			      Input.gpio[i].name, &Input.gpio[i]);
			if(ret < 0)
			{
				printk("irq %s request failed!\r\n", Input.gpio[i].name);
				return -EFAULT;
			}else
			{
				printk("request gpio%d irq\r\n" ,Input.gpio[i].gpio);
			}

二、中断的常用函数和关节结构体

①、使能中断,初始化相应的寄存器。
②、注册中断服务函数,也就是向 irqTable 数组的指定标号处写入中断服务函数
②、中断发生以后进入 IRQ 中断服务函数,在 IRQ 中断服务函数在数组 irqTable 里面查找
具体的中断处理函数,找到以后执行相应的中断处理函数。

(1)中断号

        每个中断都有一个中断号,通过中断号即可区分不同的中断
(2)request_irq 函数
        在 Linux 内核中要想使用某个中断是需要申请的,request_irq 函数用于申请中断request_irq 函数可能会导致睡眠因此不能在中断上下文或者其他禁止睡眠的代码段中使用 request_irq 函 数。request_irq 函数会激活(使能)中断,所以不需要我们手动去使能中断,request_irq 函数原型 如下:
int request_irq(unsigned int irq, 
                irq_handler_t handler, 
                unsigned long flags,
                const char *name, 
                void *dev)
函数参数和返回值含义如下:
irq要申请中断的中断号。
handler中断处理函数,当中断发生以后就会执行此中断处理函数。
flags中断标志,可以在文件 include/linux/interrupt.h 里面查看所有的中断标志,这里我们介绍几个常用的中断标志,这些标志可以通过“|”来实现多种组合
中断标志
标志描述
IRQF_SHARED
多个设备共享一个中断线,共享的所有中断都必须指定此标志。
如果使用共享中断的话,request_irq 函数的 dev 参数就是唯一
区分他们的标志。
IRQF_ONESHOT
单次中断,中断执行一次就结束。
IRQF_TRIGGER_NONE
无触发。
IRQF_TRIGGER_RISING
上升沿触发。
IRQF_TRIGGER_FALLING
下降沿触发。
IRQF_TRIGGER_HIGH
高电平触发。
IRQF_TRIGGER_LOW
低电平触发。

 

10 enum irqreturn {
11     IRQ_NONE = (0 << 0),         
12     IRQ_HANDLED = (1 << 0),      //中断处理完成
13     IRQ_WAKE_THREAD = (1 << 1),  //唤醒中断的下半部分的时候使用
14 };
15
16 typedef enum irqreturn irqreturn_t;

 

三、中断的设备树操作

        如果使用设备树的话就需要在设备树中设置好中断属性信息,Linux 内核通过读取设备树
中 的 中断 属性 信息 来配 置中 断。 对于 中断 控制 器 而言 ,设 备树 绑定 信息 参考 文档
Documentation/devicetree/bindings/arm/gic.txt。打开 imx6ull.dtsi 文件,其中的 intc 节点就是
I.MX6ULL 的中断控制器节点,节点内容如下所示:
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 };
第 2 行compatible 属性值为“arm,cortex-a7-gic”在 Linux 内核源码中搜索“arm,cortex-a7-
gic”即可找到 GIC 中断控制器驱动文件。
第 3 行#interrupt-cells #address-cells#size-cells 一样。表示此中断控制器下设备的 cells
大小,对于设备而言,会使用 interrupts 属性描述中断信息,#interrupt-cells 描述了 interrupts
性的 cells 大小,也就是一条信息有几个 cells。每个 cells 都是 32 位整形值,对于 ARM 处理的
GIC 来说,一共有 3 cells,这三个 cells 的含义如下:
        第一个 cells:中断类型,0 表示 SPI 中断,1 表示 PPI 中断。
        第二个 cells:中断号,对于 SPI 中断来说中断号的范围为 0~987,对于 PPI 中断来说中断
号的范围为 0~15
        第三个 cells:标志,bit[3:0]表示中断触发类型,为 1 的时候表示上升沿触发,为 2 的时候
表示下降沿触发,为 4 的时候表示高电平触发,为 8 的时候表示低电平触发。bit[15:8]PPI
断的 CPU 掩码。
第 4 行interrupt-controller 节点为空,表示当前节点是中断控制器。
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>;
10 };
①、#interrupt-cells,指定中断源的信息 cells 个数。
②、interrupt-controller,表示当前节点为中断控制器。
③、interrupts,指定中断号,触发方式等。
④、interrupt-parent,指定父中断,也就是中断控制器。

四、中断的上、下端操作

               内容比较多,这里不在说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值