转自:http://blog.chinaunix.net/uid-14825809-id-2381330.html

1.中断的注册与释放:

在 , 实现中断注册接口:

  1. int request_irq(unsigned int irq,irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name,void *dev_id);
  2. void free_irq(unsigned int irq, void *dev_id);

函数参数说明

unsigned int irq:所要注册的中断号
irqreturn_t (*handler)(int, void *, struct pt_regs *):中断服务程序的入口地址。
unsigned long flags:与中断管理有关的位掩码选项,有三组值:
1. SA_INTERRUPT :快速中断处理程序,当使用它的是后处理器上所有的其他中断都被禁用。
2. SA_SHIRQ :该中断是在设备之间可共享的
3. SA_SAMPLE_RANDOM :这个位表示产生的中断能够有贡献给 /dev/random 
和 /dev/urandom 使用的加密池.(此处不理解) 
const char *dev_name:设备描述,表示那一个设备在使用这个中断。

void *dev_id:用作共享中断线的指针. 它是一个独特的标识, 用在当释放中断线时以及可能还被驱动用来指向它自己的私有数据区(来标识哪个设备在中断) 。这个参数在真正的驱动程序中一般是指向设备数据结构的指针.在调用中断处理程序的时候它就会传递给中断处理程序的void *dev_id。(这是我的理解)如果中断没有被共享, dev_id 可以设置为 NULL, 但是使用这个项指向设备结构不管如何是个好主意. 我们将在"实现一个处理"一节中看到 dev_id 的一个实际应用。

中断号的查看可以使用下面的命令:“cat /proc/interrupts”。

/proc/stat 记录了几个关于系统活动的低级统计量, 包括(但是不限于)自系统启动以来收到的中断数. stat 的每一行以一个文本字串开始, 是该行的关键词; intr 标志是我们在找的.

第一个数是所有中断的总数, 而其他每一个代表一个单个 IRQ 线, 从中断 0 开始. 所有的计数跨系统中所有处理器而汇总的. 这个快照显示, 中断号 4 已使用 1 次, 尽管当前没有安装处理. 如果你在测试的驱动请求并释放中断在每个打开和关闭循环, 你可能发现 /proc/stat 比 /proc/interrupts 更加有用.

以下是一个统计中断时间间隔的中断服务程序。

  1. irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  2. {
  3. static long mytime=0;
  4. static int i=0;
  5. struct net_device *dev=(struct net_device *)dev_id;
  6. if(i==0){
  7. mytime=jiffies;
  8. }else
  9. if(i<20){
  10. mytime =jiffies- mytime;
  11. printk("Request on IRQ %d time %d\n",irq , mytime);
  12. mytime=jiffies;
  13. printk("Interrupt on %s -----%d \n",dev->name,dev->irq);
  14. }
  15. i++;
  16. return IRQ_HANDLED;
  17. }

这个函数实现的只是对两次发生中断的时间间隔的统计,时间单位是毫秒

函数参数说明:int irq :在这里很明显传递过来的是中断号

void *dev_id :这个传递来的是设备的id号,可以根据这个设备id号得到相应设备的数据结构,进而的到相应设备的信息和相关数据。下面以提取网路数据为例来说明一下。

struct net_device *dev=( struct net_device *)dev_id; (这里的dev_id的值是注册中断的时候宏传递过来的,是注册中断函数的最后一个参数。特别说明)

在这之后就可以用dev->name; dev->irq;等得到网络设备的信息了,当然提取ip数据报还得进行一些其它的工作。

struct pt_regs *regs :它指向一个数据结构,此结构保存的是中断之前处理器的寄存器和状态。主要用在程序调试。

关于中断处理函数的返回值:中断程序的返回值是一个特殊类型—irqreturn_t。但是中断程序的返回值却只有两个—IRQ_NONE和IRQ_HANDLED。

/* irqreturn.h */

#ifndef _LINUX_IRQRETURN_H

#define _LINUX_IRQRETURN_H

typedef int irqreturn_t;

/*

* For 2.4.x compatibility, 2.4.x can use

*

* typedef void irqreturn_t;

* #define IRQ_NONE

* #define IRQ_HANDLED

* #define IRQ_RETVAL(x)

*……此处我删去了部分关紧要的内容

* To mix old-style and new-style irq handler returns.

*

* IRQ_NONE means we didn't handle it.

* 中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号.

*此时返回次值

* IRQ_HANDLED means that we did have a valid interrupt and handled it.

* 接收到了准确的中断信号,并且作了相应正确的处理

* IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)

*/

#define IRQ_NONE (0)

#define IRQ_HANDLED (1)

#define IRQ_RETVAL(x) ((x) != 0) //这个宏只是返回0或非0

#endif

以上是在linux/irqreturn.h中的内容,我加了一定的注释.我想是可以说明问题的

编写中断处理程序:
中断处理程序声明:

  1. static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs)

说明:
该类型与request_irq()参数中的handler所要求的参数类型相匹配。
int irq :中断号;
void *dev_id :与request_irq()的参数dev_id一致,可以根据这个设备id号得到相应设备的数据结构,进而的到相应设备的信息和相关数据;
struct pt_regs *regs :它指向一个数据结构,此结构保存的是中断之前处理器的寄存器和状态。主要用在程序调试,一般忽略。
返回值:中断程序的返回值是一个特殊类型——irqreturn_t。但是中断程序的返回值却只有两个值IRQ_NONE和IRQ_HANDLED。
    IRQ_NONE:中断程序接收到中断信号后发现这并不是注册时指定的中断原发出的中断信号;
    IRQ_HANDLED:接收到了准确的中断信号,并且作了相应正确的处理。
亦可以使用宏IRQ_RETVAL(x),若x为非0值,该宏返回IRQ_HANDLED,否则返回IRQ_NONE。

查看中断号:
命令:cat /proc/interrupts

============================================================================
在 2.4 内核和 2.6内核中都使用 request_irq() 函数来注册中断服务函数。在 2.4 内核中,需要包含的头文件是 #include ,2.6 内核中需要包含的头文件则是
 #include 。函数原型如下:

  • 2.4 内核

int request_irq (unsigned int irq, void (*handler)(intvoid *, struct pt_regs *), unsigned long frags, const char *device, void *dev_id);

  • 2.6 内核

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);

参数说明

在发生对应于第 1个参数 irq 的中断时,则调用第 2 个参数 handler 指定的中断服务函数(也就是把 handler() 中断服务函数注册到内核中 )。

第 3 个参数 flags 指定了快速中断或中断共享等中断处理属性。在 2.6 教新的内核里(我的是 2.6.27 ~ 2.6.31 ),在 linux/interrupt.h 中定义操作这个参数的宏如下:

引用
/*
* 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

早期一点的 2.6 内核这里一般以 SA_ 前缀开头,如:
SA_INTERRUPT   表示禁止其他中断;(对应于 IRQF_DISABLED )
SA_SHIRQ             表示共享相同的中断号 (对应于 IRQF_SHARED )
SA_SAMPLE_RANDOM   此宏会影响到 RANDOM 的处理( 对应于 IRQF_SAMPLE_RANDOM )。

第 4 个参数 name 通常是设备驱动程序的名称。改值用在 /proc/interrupt 系统 (虚拟) 文件上,或内核发生中断错误时使用。

第 5 个参数 dev_id 可作为共享中断时的中断区别参数,也可以用来指定中断服务函数需要参考的数据地址。

返回值
函数运行正常时返回 0 ,否则返回对应错误的负值。

示例代码片段

引用
irqreturn_t xxx_interrupt (int irq, void *dev_id)
{
        ...

return (IRQ_HANDLED);
}

int xxx_open (struct inode *inode, struct file *filp)
{
        if (!request_irq (XXX_IRQ, xxx_interruppt, IRQF_DISABLED, "xxx", NULL)) {

/*正常注册*/
        }

return (0);
}

【作者】张昺华
【出处】http://www.cnblogs.com/sky-heaven/
【博客园】 http://www.cnblogs.com/sky-heaven/
【新浪博客】 http://blog.sina.com.cn/u/2049150530
【知乎】 http://www.zhihu.com/people/zhang-bing-hua
【我的作品---旋转倒立摆】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【我的作品---自平衡自动循迹车】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

LINUX中断学习笔记【转】相关推荐

  1. 操作系统进程学习(Linux 内核学习笔记)

    操作系统进程学习(Linux 内核学习笔记) 进程优先级 并非所有进程都具有相同的重要性.除了大多数我们所熟悉的进程优先级之外,进程还有不同的关键度类别,以满足不同需求.首先进程比较粗糙的划分,进程可 ...

  2. linux系统管理学习笔记之八---进程与作业的管理

    linux系统管理学习笔记之八---进程与作业的管理 2010-01-05 13:00:42 标签:linux 进程 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

  3. Linux命令学习笔记

    Linux命令学习笔记 1 前言 1.1 系统版本 1.2 终端切换 1.3 快捷键 1.4 帮助文档 1.5 关机重启 2 目录命令 2.1 当前目录 pwd 2.2 切换目录 cd 2.3 查看目 ...

  4. linux pipe 命名管道,linux 进程学习笔记-named pipe (FIFO)命名管道

    与"无名管道"不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如"/tmp/my_fifo",其对应到磁盘上的一个管道文件,如果我们用f ...

  5. Linux基本命令学习笔记--文件查看、下载、查找

    1.Linux基本命令学习笔记–(文件查看) cat -整个查看 -n:行号 >(创建.覆盖) >>(追加)a.txt<<EOF:编写内容 内容 EOF (定格写:结束) ...

  6. linux系统管理学习笔记之三----软件的安装

    linux系统管理学习笔记之三----软件的安装 2009-12-29 19:10:02 标签:linux 系统管理 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

  7. linux系统管理学习笔记之一-------linux解压缩命令

    linux系统管理学习笔记之一-------linux解压缩命令 2009-12-29 11:52:55 标签:linux tar [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接 ...

  8. linux系统管理学习笔记之八---linux文件与目录的管理及权限

    linux系统管理学习笔记之八---linux文件与目录的管理及权限 2010-01-05 09:00:49 标签:权限 管理 文件目录 linx [推送到技术圈] 版权声明:原创作品,允许转载,转载 ...

  9. 韩顺平Linux教程学习笔记

    Linux系统学习笔记   新装了deepin v23系统,结果磁盘没设置好,玩崩了,百度半天修复不了,看看韩顺平老师的Linux操作课程,做做笔记(只记录对自己有用的).   B站网址 基础篇·Li ...

最新文章

  1. 万字长文,别再说你不懂Linux内存管理了(合辑),30 张图给你安排的明明白白...
  2. 2020-07-01 CVPR2020 表示学习论文讨论(2) 笔记
  3. Java EE业务处理流程与XML的引入
  4. 针对Hybrid A*论文解析(5)中的方法的一些验证
  5. Qt4_实现其他菜单
  6. 使用WMI筛选器管理组策略应用
  7. 如何避免循环中“突兀”的break和continue
  8. CGContextRef:mask和layer绘图
  9. android应用程序开发另解及Android SDK工具集的另类用法 .
  10. fir.im分发平台安卓苹果应用下载二维码合并步骤
  11. python数据分析-互联网常见9种数据分析方法
  12. PGP加密软件使用教程-云安全技术
  13. 张萌韩墨羽——Toolbar和DrawerLayout+SlideMenu 2种方式实现抽屉侧滑
  14. 使用OBS屏幕录制时色彩错误问题解决方案
  15. Power bi 4.19 龙卷风图
  16. Linux基础-Swap分区
  17. xgboost缺失值处理
  18. ESP通过乐为物联控制灯,微信发送数值,ESP上传传感器数据
  19. rsync不覆盖已经存在文件的方法
  20. java 向word中添加excel附件并向excel单元格中加入图片并压缩图片并根据图片动态控制单元格高度宽度

热门文章

  1. Python调用外部程序——os.system()和subprocess.call()
  2. NODEJS项目实践0.4 [domain,pm2,log4js,md5]
  3. sql server两种分页方法
  4. 2、onclickListener冲突
  5. 网络与服务器编程框架库 acl_3.0.13 发布
  6. [转载]中国工商银行软件开发部门职业发展
  7. 测试工具/PostMan
  8. 使用主机ip地址绑定GooglAppEngine站点
  9. 计算机意外地重新启动或遇到错误。windows安装无法继续。若要安装windows 请单击 确定 重新启动计算机...
  10. 【SICP练习】111 练习3.24