[arm驱动]linux内核中断编程

第一部分获取中断(开启硬件中断)
一、中断的申请注销:
1)中断的申请

1
2
int request_irq(unsigned int irq, irq_handler_t handler,
                         unsigned long irqflags, const char *devname, void *dev_id)

2)中断的注销

1
void free_irq(unsigned int irq, void *dev_id)

3)中断处理函数

1
static irqreturn_t irq_handle(int irq, void *dev__id);

   参数:irq:表示中断号,这个参数还保留由于历史遗留问题,往后可能越来越没用了。由于第二个参数信息更强大
dev__id:就是request_irq()中void *dev_id参数
二、中断申请函数参数

1
2
int request_irq(unsigned int irq, irq_handler_t handler,
                         unsigned long irqflags, const char *devname, void *dev_id)

   1)参数:
   irq:是要申请的硬件中断号。
handler:是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它
    irqflags:是中断处理的属性,
       a)若设置了IRQF_DISABLED,则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;
       b)若设置了    IRQF_SHARED,则表示多个设备共享中断;//在另一篇文章会提到
       c)若设置了IRQF_SAMPLE_RANDOM,表示对系统熵有贡献,对系统获取随机数有好处。
           Tip:(flag是可以通过或的方式同时使用的
   devname:设置中断名称,通常是设备驱动程序的名称  在cat /proc/interrupts中可以看到此名称。
   dev_id:在中断共享时会用到,一般设置为这个设备的设备结构体或者不使用时为NULL。因为在共享中断中同一个中断线(或可以说同一个中断号)可能挂载好几个设备,当使用void free_irq(unsigned int irq, void *dev_id)时,根据irq和dev_id可以找到中断线为irq上的标识为dev_id的某个具体设备。dev_id也经常在不是共享中断中的驱动传递数据

   2)返回值:
   a)request_irq()返回0表示成功;
   b)返回-EINVAL表示无效的参数,如果返回这个值,应该看看传递给request_irq()的参数是否正确;
   c)返回-EBUSY表示中断已经被占用且不能共享;
   d)返回ENOMEM表示内存不足。嵌入式系统由于内存资源有限,经常会发生这样的错误。

   3)扩展---unsigned long irqflags值
   在include\linux\interrupt.h中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
 * These correspond to the IORESOURCE_IRQ_* defines in
 * linux/ioport.h to select the interrupt line behaviour.  When
 * requesting an interrupt without specifying a IRQF_TRIGGER, the
 * setting should be assumed to be "as already configured", which
 * may be as per machine or firmware initialisation.
 */
#define IRQF_TRIGGER_NONE    0x00000000
#define IRQF_TRIGGER_RISING    0x00000001
#define IRQF_TRIGGER_FALLING    0x00000002
#define IRQF_TRIGGER_HIGH    0x00000004
#define IRQF_TRIGGER_LOW    0x00000008
#define IRQF_TRIGGER_MASK    (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE    0x00000010
/*
 * These flags used only by the kernel as part of the
 * irq handling routines.
 *
 * IRQF_DISABLED - keep irqs disabled when calling the action handler
 * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
 * IRQF_SHARED - allow sharing the irq among several devices
 * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
 * IRQF_TIMER - Flag to mark this interrupt as timer interrupt
 * IRQF_PERCPU - Interrupt is per cpu
 * IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
 * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
 *                registered first in an shared interrupt is considered for
 *                performance reasons)
 */
#define IRQF_DISABLED        0x00000020
#define IRQF_SAMPLE_RANDOM    0x00000040
#define IRQF_SHARED        0x00000080
#define IRQF_PROBE_SHARED    0x00000100
#define IRQF_TIMER        0x00000200
#define IRQF_PERCPU        0x00000400
#define IRQF_NOBALANCING    0x00000800
#define IRQF_IRQPOLL        0x00001000


   Tip:下面是老版本(2.4内核irqflags的值),不要在新版本使用。(2.6 内核及2.6以上内核都为新内核)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Migration helpers. Scheduled for removal in 9/2007
 * Do not use for new code !//不要的新版本使用,2.6 内核及2.6以上内核都为新内核
 */
static inline
unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
{
    return flag;
}
#define SA_INTERRUPT        deprecated_irq_flag(IRQF_DISABLED)
#define SA_SAMPLE_RANDOM    deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
#define SA_SHIRQ        deprecated_irq_flag(IRQF_SHARED)
#define SA_PROBEIRQ        deprecated_irq_flag(IRQF_PROBE_SHARED)
#define SA_PERCPU        deprecated_irq_flag(IRQF_PERCPU)
#define SA_TRIGGER_LOW        deprecated_irq_flag(IRQF_TRIGGER_LOW)
#define SA_TRIGGER_HIGH        deprecated_irq_flag(IRQF_TRIGGER_HIGH)
#define SA_TRIGGER_FALLING    deprecated_irq_flag(IRQF_TRIGGER_FALLING)
#define SA_TRIGGER_RISING    deprecated_irq_flag(IRQF_TRIGGER_RISING)
#define SA_TRIGGER_MASK        deprecated_irq_flag(IRQF_TRIGGER_MASK)

三、使用模板
   使用步骤:以外部中断为例
a)定义结构体,相当于定义(void *dev_id)中的(void *)

1
2
3
4
5
struct pin_desc{//声明一个引脚描述的结构体pin_desc
       unsigned int pin;//引脚值,参考数据手册及板子电路原理图
       unsigned int key_val;//值自已随便定义;看自己的项目需要
       //...................
   };

b)实例化结构体,相当于(void *dev_id)中的 dev_id

1
2
3
4
5
struct pin_desc pins_desc[3] = {//实例化结构体,以jz2440按键为列
       {S3C2410_GPF0, 0x01},//S3C2410_GPFn在内核中定义好了
       {S3C2410_GPF2, 0x02},
       {S3C2410_GPG3, 0x03},
   };

c)定义中断处理函数

1
2
3
4
5
static irqreturn_t irq_handle(int irq, void *dev__id){
    struct pin_desc *pindesc = (struct pin_desc *)dev__id;
    //................
    return IRQ_RETVAL(IRQ_HANDLED);//返回IRQ_HANDLED表示中断已经处理
    }

d)申请中断

1
2
3
request_irq(IRQ_EINT0, irq_handle, IRQ_TYPE_EDGE_BOTH, "s2", &pins_desc[0]);//IRQ_EINTn在内核中定义好了
   request_irq(IRQ_EINT2, irq_handle, IRQ_TYPE_EDGE_BOTH, "s3", &pins_desc[1]);
   request_irq(IRQ_EINT11, irq_handle, IRQ_TYPE_EDGE_BOTH, "s4", &pins_desc[2]);

e)释放内存

1
2
3
free_irq(IRQ_EINT0, &pins_desc[0]);
    free_irq(IRQ_EINT2, &pins_desc[1]);
    free_irq(IRQ_EINT11, &pins_desc[2]);


Tip:可以直接将IRQ_EINTn也在pins_desc定义,然后

1
2
3
4
int i = 0;
   for(i = 0; i < 3; i++){
   free_irq(pins_desc[i].irqnum, &pins_desc[i]);
   }

   实例见[arm驱动]Linux内核开发之阻塞非阻塞IO----轮询操作 中的实例(按键中断双边沿触发)



本文转自lilin9105 51CTO博客,原文链接:http://blog.51cto.com/7071976/1392439,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于VCP(Virtual Com Port)拓展的调试经历(一)

* The Overview 前日&#xff0c;接到老板部署的任务&#xff0c;将现有的基于STM32L151与L432的LoRaWAN程序中添加USB CDC(Communication Device Class)功能&#xff0c;并枚举为VCP(Virtual Com Port)用以替代以往的串口打印。很疑惑为什么以前架构代码的时候没有添加进去。。…

leetcode701. 二叉搜索树中的插入操作(dfs)

给定二叉搜索树&#xff08;BST&#xff09;的根节点和要插入树中的值&#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证&#xff0c;新值和原始二叉搜索树中的任意节点值都不同。注意&#xff0c;可能存在多种有效的插入方式&#xff0c;只要树在…

三星s6 android 8.0,再见Android 8.0,三星s6全系列系统都停止了,第一代国王已经倒下了吗?...

对于Android用户而言&#xff0c;最令人兴奋的事情是系统更新&#xff0c;因为该更新意味着更流畅的体验和更加用户友好的功能. 但是&#xff0c;旧的三星S6并不是那么幸运&#xff0c;并且不再错过Android 8.0.三星s6的全系列指的是三星s6&#xff0c;三星s6 edge&#xff0c;…

devise tree_Devise如何确保您的Rails应用密码安全

devise treeby Tiago Alves由蒂亚戈阿尔维斯(Tiago Alves) Devise如何确保您的Rails应用密码安全 (How Devise keeps your Rails app passwords safe) Devise is an incredible authentication solution for Rails with more than 40 million downloads. However, since it ab…

Exchange 2010无法安装问题解决方法

当你在活动目录(AD)森林中安装多台全局编录服务器(GC)之后,默认情况下你会发现在AD站点里面自动生成二条站点连接,从上面的截图可以看到目前在AD森林的Default-First-Site-Name(默认站点)里面有6台GC。 从上面的截图可以看到目前只有一台叫做Sh-Site1GC(全局编录服务器)是处于运…

android edittext 不滚动,EditText 设置可以垂直滑动但是不可输入

一、前言&#xff1a;android:id"id/edtInput"android:layout_width"match_parent"android:layout_height"60dp"android:background"drawable/round_theme_3_gray"android:gravity"top"android:hint"string/please_inp…

snmpd修改端口

http://blog.csdn.net/cau99/article/details/5077239 http://blog.csdn.net/gua___gua/article/details/48547701转载于:https://www.cnblogs.com/diyunpeng/p/6829592.html

leetcode LCP 19. 秋叶收藏集(dp)

小扣出去秋游&#xff0c;途中收集了一些红叶和黄叶&#xff0c;他利用这些叶子初步整理了一份秋叶收藏集 leaves&#xff0c; 字符串 leaves 仅包含小写字符 r 和 y&#xff0c; 其中字符 r 表示一片红叶&#xff0c;字符 y 表示一片黄叶。 出于美观整齐的考虑&#xff0c;小扣…

步进电机 步距角 编码器_我如何迈出了学习编码的第一步

步进电机 步距角 编码器A couple of months ago, I was chatting to a developer at work about how I’ve always wanted to learn to code but never tried.几个月前&#xff0c;我正在与一个开发人员聊天&#xff0c;讨论我一直想学习编码但从未尝试过的方法。 Coding alwa…

第五章:配置使用FastJson返回Json视图

fastJson是阿里巴巴旗下的一个开源项目之一&#xff0c;顾名思义它专门用来做快速操作Json的序列化与反序列化的组件。它是目前json解析最快的开源组件没有之一&#xff01;在这之前jaskJson是命名为快速操作json的工具&#xff0c;而当阿里巴巴的fastJson诞生后jaskjson就消声…

一加6android9玩飞车掉,解锁新速度:一加6T深度评测

解锁新速度&#xff1a;一加6T深度评测2019-11-02 14:28:595点赞2收藏4评论创作立场声明&#xff1a;我们只谈智能硬件&#xff0c;向改变生活的智能硬件Say“嗨”&#xff01;作为安卓旗舰机成员&#xff0c;一加这个品牌在玩机一类的同学手里可是大放光彩&#xff0c;各种刷机…

设计模式(第十七式:迭代器模式)

概念&#xff1a;  迭代器模式&#xff1a;Provide a way to access the elements of an aggregarte object sequentiaally with exposing its underlying representation. 提供一种访问容器对象内每个元素的一种方式&#xff0c;并且不暴露对象的一些内部细节。实现&#xf…

探讨跨域请求资源的几种方式

[转自&#xff1a;http://www.cnblogs.com/dojo-lzz/p/4265637.html] 什么是跨域JSONPproxy代理corsxdr由于浏览器同源策略&#xff0c;凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。具体可以查看下表&#xff08;来源&#xff09; JSONP 这种…

算法训练营 重编码_编码训练营适合您吗?

算法训练营 重编码by Joanna Gaudyn乔安娜高登(Joanna Gaudyn) 编码训练营适合您吗&#xff1f; (Is a Coding Bootcamp something for you?) Coding bootcamps’ popularity is growing. It sounds like a perfect idea to fast-forward your career. But is it really some…

leetcode 771. 宝石与石头(set)

给定字符串J 代表石头中宝石的类型&#xff0c;和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型&#xff0c;你想知道你拥有的石头中有多少是宝石。 J 中的字母不重复&#xff0c;J 和 S中的所有字符都是字母。字母区分大小写&#xff0c;因此"a…

用ntdsutil命令中的restore object 更新版本号

备份域控建立好后&#xff0c;备份域信息&#xff0c;用目录还 原模式&#xff0c;还原域信息&#xff0c;用ntdsutil命令&#xff0c;中的 restore ob ject 更新版本号 本文转自9pc9com博客&#xff0c;原文链接&#xff1a; http://blog.51cto.com/215363/783334 如需…

python处理excel文件(xls和xlsx)

一、xlrd和xlwt 使用之前需要需要先安装&#xff0c;windows上如果直接在cmd中运行python则需要先执行pip3 install xlrd和pip3 install xlwt&#xff0c;如果使用pycharm则需要在项目的解释器中安装这两个模块&#xff0c;File-Settings-Project:layout-Project Interpreter&a…

html块中的内容垂直居中,css如何设置行内元素与块级元素的内容垂直居中

首先我们先了解一下行内元素和块级元素行内元素(内联元素)&#xff1a;没有自己的独立空间&#xff0c;它是依附于其他块级元素存在的&#xff0c;空间大小依附于内容多少。行内元素没有度、宽度、内外边距等属性。块级元素&#xff1a;占据独立的空间&#xff0c;具有宽度&…

Mina、Netty、Twisted一起学(五):整合protobuf

protobuf是谷歌的Protocol Buffers的简称&#xff0c;用于结构化数据和字节码之间互相转换&#xff08;序列化、反序列化&#xff09;&#xff0c;一般应用于网络传输&#xff0c;可支持多种编程语言。protobuf怎样使用这里不再介绍&#xff0c;本文主要介绍在MINA、Netty、Twi…

leetcode 1. 两数之和(map)

给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素不能使用两遍。 示例: 给定 nums [2, 7, 11, 15], target …