linux中断号指的是什么

本篇内容主要讲解“linux中断号指的是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux中断号指的是什么”吧!

linux中断号是系统分配给每个中断源的代号,以便识别和处理;在采用向量中断方式的中断系统中,CPU必须通过它才可以找到中断服务程序的入口地址,实现程序的转移。

中断号与中断编程:

1、中断号

  中断号是系统分配给每个中断源的代号,以便识别和处理。在采用向量中断方式的中断系统中,CPU必须通过它才可以找到中断服务程序的入口地址,实现程序的转移。

  在ARM裸机中实现中断需要配置:

 I/O口为中断模式,触发方式,I/O口中断使能<br> 设置GIC中断使能,分发配置,分发总使能,CPU外部中断接口使能,中断优先级<br>

  在linux内核中实现中断,只需要知道:

中断号是什么,怎么得到中断号<br>中断处理方法<br>

 2、获取中断号的方法:

/arm/boot/dts/exynos4412-fs4412.dts<br>

  1)看原理图,芯片手册找到中断源对应的中断号SPI Port  No

  linux中断号指的是什么

  linux中断号指的是什么

  2)进入设备树,在arch/arm/boot/dts/exynos4x12-pinctrl.dtsi

<pre>gpx1: gpx1 {                     gpio-controller;                     #gpio-cells = ;                     interrupt-controller;  //中断控制器                     interrupt-parent = ;  //继承于gic                     interrupts = , , , ,                                  , , , ;                     #interrupt-cells = ; //子继承的interrupts的长度             };</pre>

  括号中的24、 25等对应于SPI Port No,以上是系统中已经定义好的节点

在编程中,需要定义自己的节点,用来描述按键,打开可编辑的设备树文件:

arch/arm/boot/dts/exynos4412-fs4412.dts,进入文件。

  3)定义节点,描述当前设备用的中断号

1 key_int_node{<br>2             compatible = "test_key";<br>3             interrupt-parent = ;  //继承于gpx1<br>4             interrupts = ;      //2表示第几个中断号,4表示触发方式为下降沿5         };               //interrupts里长度由父母的-cell决定<br>

  再举个栗子,设置k4 --- GPX3_2(XEINT26) 的节点,中断号

<pre>1 key_int_node{ 2              compatible = "test_key"; 3              interrupt-parent = ;  //继承于gpx3 4              interrupts = ;      //2表示第2个中断号,4表示触发方式为下降沿 5          };</pre>

linux中断号指的是什么

    中断号的定位方法:

    看I/O引脚,GPX1_2,中断号就是GPX1里面的第2个

  4)编译设备树:make dtbs

    更新设备树文件: cp  -raf arch/arm/boot/dts/exynos4412-fs4412.dtb   /tftpboot/

    查看定义的节点:在根目录的 proc/device-tree/目录下  

linux中断号指的是什么  

3、实现中断处理方法

  在驱动中通过代码获取到中断号,并且申请中断

  先看一下中断相关的函数:

<pre>1 a,获取到中断号码:  2     int get_irqno_from_node(void)  3     {  4         // 获取到设备树中的节点  5         struct device_node *np = of_find_node_by_path("/key_int_node");  6         if(np){  7             printk("find node okn");  8         }else{  9             printk("find node failedn"); 10         } 11  12         // 通过节点去获取到中断号码 13         int irqno = irq_of_parse_and_map(np, 0); 14         printk("irqno = %dn", irqno); 15          16         return irqno; 17     } 18 b,申请中断 19 int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char * name, void * dev) 20     参数1: irq     设备对应的中断号 21     参数2: handler     中断的处理函数 22             typedef irqreturn_t (*irq_handler_t)(int, void *); 23     参数3:flags     触发方式 24             #define IRQF_TRIGGER_NONE    0x00000000  //内部控制器触发中断的时候的标志 25             #define IRQF_TRIGGER_RISING    0x00000001 //上升沿 26             #define IRQF_TRIGGER_FALLING    0x00000002 //下降沿 27             #define IRQF_TRIGGER_HIGH    0x00000004  // 高点平 28             #define IRQF_TRIGGER_LOW    0x00000008 //低电平触发 29     参数4:name     中断的描述,自定义,主要是给用户查看的 30             /proc/interrupts 31     参数5:dev     传递给参数2中函数指针的值 32     返回值: 正确为0,错误非0 33  34  35     参数2的赋值:即中断处理函数 36     irqreturn_t key_irq_handler(int irqno, void *devid) 37     { 38         return IRQ_HANDLED; 39     } 43      44 c, 释放中断: 45         void free_irq(unsigned int irq, void *dev_id) 46         参数1: 设备对应的中断号 47         参数2:与request_irq中第5个参数保持一致</pre>

代码实现获取中断号,并注册中断,按下按键引发中断,打印信息

1 #include <br> 2 #include <br> 3 #include <br> 4 #include <br> 5 #include <br> 6 #include <br> 7 #include <br> 8 #include <br> 9 #include <br>10 #include <br>11 <br>12 int irqno;    //中断号<br>13 <br>14 <br>15 irqreturn_t key_irq_handler(int irqno, void *devid)<br>16 {<br>17     printk("----------%s---------",__FUNCTION__);<br>18     return IRQ_HANDLED;<br>19 }<br>20 <br>21 <br>22 //获取中断号<br>23 int get_irqno_from_node(void)<br>24 {<br>25     //获取设备树中的节点<br>26     struct device_node *np = of_find_node_by_path("/key_int_node");<br>27     if(np){<br>28         printk("find node successn");<br>29     }else{<br>30         printk("find node failedn");<br>31     }<br>32 <br>33     //通过节点去获取中断号<br>34     int irqno = irq_of_parse_and_map(np, 0);<br>35     printk("iqrno = %d",irqno);<br>36 <br>37     return irqno;<br>38 }<br>39 <br>40 <br>41 <br>42 static int __init key_drv_init(void)<br>43 {<br>44     //演示如何获取到中断号<br>45     int ret;<br>46     <br>47     irqno = get_irqno_from_node();<br>48 <br>49     ret = request_irq(irqno, key_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, <br>50         "key3_eint10", NULL);<br>51     if(ret != 0)<br>52     {<br>53         printk("request_irq errorn");<br>54         return ret;<br>55     }<br>56     <br>57     return 0;<br>58 }<br>59 <br>60 static void __exit key_drv_exit(void)<br>61 {<br>62     free_irq(irqno, NULL);  //free_irq与request_irq的最后一个参数一致<br>63 }<br>64 <br>65 <br>66 <br>67 module_init(key_drv_init);<br>68 module_exit(key_drv_exit);<br>69 <br>70 MODULE_LICENSE("GPL");<br>key_drv.c<br>

key_drv.c

测试效果:

linux中断号指的是什么

按键按下,打印信息,但出现了按键抖动

cat /proc/interrupt

linux中断号指的是什么

  4、 中断编程 --- 字符设备驱动框架

<pre>// 1,设定一个全局的设备对象 key_dev = kzalloc(sizeof(struct key_desc),  GFP_KERNEL); // 2,申请主设备号 key_dev->dev_major = register_chrdev(0, "key_drv", &key_fops); // 3,创建设备节点文件 key_dev->cls = class_create(THIS_MODULE, "key_cls"); key_dev->dev = device_create(key_dev->cls, NULL, MKDEV(key_dev->dev_major,0), NULL, "key0"); // 4,硬件初始化:         a.地址映射         b.中断申请</pre>

  5、驱动实现将硬件所产生的数据传递给用户

  1)硬件如何获取数据

<pre>key: 按下和抬起: 1/0读取key对应的gpio的状态,可以判断按下还是抬起      读取key对应gpio的寄存器--数据寄存器  //读取数据寄存器int value = readl(key_dev->reg_base + 4) & (1event.value = 0;<br>在xxx_read中奖数据传递给用户<br>     ret = copy_to_user(buf, &key_dev->event,  count);<br></pre>