转自: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);
}

 

LINUX中断学习笔记【转】的更多相关文章

  1. Linux系统学习笔记:文件I/O

    Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...

  2. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  3. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  4. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  5. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  6. linux 驱动学习笔记01--Linux 内核的编译

    由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...

  7. 20135316王剑桥Linux内核学习笔记

    王剑桥Linux内核学习笔记 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计算机是如何工作的 个人理 ...

  8. Linux命令学习笔记目录

    Linux命令学习笔记目录 最近正在使用,linux,顺便将用到的命令整理了一下. 一. 文件目录操作命令: 0.linux命令学习笔记(0):man 命令 1.linux命令学习笔记(1):ls命令 ...

  9. linux命令学习笔记(25):linux文件属性详解

    Linux 文件或目录的属性主要包括:文件或目录的节点.种类.权限模式.链接数量.所归属的用户和用户组. 最近访问或修改的时间等内容.具体情况如下: 命令: ls -lih 输出: [root@loc ...

随机推荐

  1. 【BZOJ1941】Hide and Seek(KD-Tree)

    [BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...

  2. BZOJ [Ctsc2002] Award 颁奖典礼 解题报告

    [Ctsc2002] Award 颁奖典礼 Description IOI2002的颁奖典礼将在YONG-IN Hall隆重举行.人们在经历了充满梦幻的世界杯之后变得更加富于情趣.为了使颁奖典礼更具魅 ...

  3. 【套题】qbxt国庆刷题班D1

    Day1 事实上D1的题目还是比较简单的= =然而D1T2爆炸了就十分尴尬--错失一波键盘 看题 T1 传送门 Description 现在你手里有一个计算器,上面显示了一个数\(S\),这个计算器十 ...

  4. 中国MOOC_面向对象程序设计——Java语言_第3周 对象容器_1查找里程

    第3周编程题 查看帮助 返回   第3周编程题.注意程序(包括注释)中不能出现汉字. 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后 ...

  5. 淘淘搜索结果中image属性中有多张图片的处理

    solr引擎查询某一个 商品后的结果中,image字段中如果有多张图片路径(用逗号隔开)时,前台会不 显示图片,解决方法如下: package com.taotao.portal.pojo; publ ...

  6. Ubuntu16.04+Cuda8.0+1080ti+caffe+免OpenCV3.2.0+faster-rCNN教程

    一.事先声明:1.Ubuntu版本:Ubuntu使用的是16.04.而不是16.04.1或16.04.2,这三个是有区别的.笔者曾有过这样的经历,Git上一个SLAM地图构建程序在Ubuntu14.0 ...

  7. Nginx配置(一)

    下载源码安装包:http://nginx.org 稳定版Nginx 1.6.2 tengine: 2.1.2 1.安装缺少依赖的包: (yum install jemalloc) yum -y ins ...

  8. 求前n项正整数的倒数和

    求前n项正整数的倒数和 前n项正整数的和是一个发散的序列,学过高等数学的这个都知道.所以它没有一个精确的公式,但是近似的公式是有的: 1 + 1/2 + 1/3 + …… + 1/n ≍ ln n + ...

  9. Chrome控制台报错个人总结(不定时更新)

    最近开始使用Chrome控制台检测代码错误,对于经常碰到的报错做一个汇总,免得每次遇到都要重新想一遍策略,错误原因,重复劳动,浪费时间. 由于不是每个错误都能碰到,以下仅列出个人写代码时经常碰到的报错 ...

  10. [POI2009]WIE-Hexer

    https://www.luogu.org/problem/show?pid=3489 题目描述 Byteasar has become a hexer - a conqueror of monste ...