当前位置:文档之家› linux中断总结

linux中断总结

1.Linux中断的注册与释放:
在<linux/interrupt.h>, , 实现中断注册接口:
int request_irq(unsigned int irq,irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
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 更加有用.
以下是一个统计中断时间间隔的中断服务程序。

irqreturn_t short_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
static long mytime=0;
static int i=0;
struct net_device *dev=(struct net_device *)dev_id;
if(i==0){
mytime=jiffies;
}else
if(i<20){
mytime =jiffies- mytime;
printk("Request on IRQ %d time %d\n",irq , mytime);
mytime=jiffies;
printk("Interrupt on %s -----%d \n",dev->name,dev->irq);
}
i ;
return IRQ_HANDLED;
}
这个函数实现的只是对两次发生中断的时间间隔的统计,时间单位是毫秒
前言
在前面分析了中断的基本原理后,就可以写一个内核中断程序来体验以下,也可以借此程序继续深入来了解内核中断的执行过程
一.内核中断程序:
我们还是来看一看成程序:
在看程序之前,要熟悉如何进行模块编程,和了解module_pararm()的用法。

如果不熟悉的话请大家看,module_param()的学习和Linux内核模块编程,在此不作解释。

1.程序interrupt.c
1 /*
2 *file name :interrupt.c
3 *atuthor : john
4 */
5 #include<linux/init.h>
6 #include<linux/module.h>
7 #include<linux/kernel.h>
8 #include<linux/interrupt.h>
9
10 MODULE_LICENSE("GPL");
11 static int irq;
12 char *interface;
13 static irqreturn_t myirq_handler(int irq,void *dev);
14
15 static int __init myirq_init(void)
16 {
17 printk("the module is working!\n");
18 printk("the irq is ready for working!\n");
19 if(request_irq(irq,myirq_handler,IRQF_SHARED,interface,&irq)){
20 printk(KERN_ERR "%s interrrupt can't register %d IRQ \n",interface,irq);
21 return -EIO;
22 }
23 printk("%s request %d IRQ\n",interface,irq);
24 return 0;
25 }
26 static irqreturn_t myirq_handler(int irq,void *dev)
27 {
28 printk("%d IRQ is working\n",irq);
29 return IRQ_NONE;
30 }
31 static void __exit myirq_exit(void)
32 {
33 printk("the module is leaving!\n");
34 printk("the irq is bye bye!\n");
35 free_irq(irq,&irq);
36 printk("%s interrupt free %d IRQ\n",interface,irq);
37
38 }
39 module_init(myirq_init);
0 module_exit(myirq_exit);
41 module_param(interface,charp,0644);
42 module_param(irq,int,0644);
43
1 /*
2 *file name :interrupt.c
3 *atuthor : john
4 */
5 #include<linux/init.h>
6 #include<linux/module.h>
7 #include<linux/kernel.h>
8 #include<linux/interrupt.h>
9
10 MODULE_LICENSE("GPL");
11 static int irq;
12 char *interface;
13 static irqreturn_t myirq_handler(int irq,void *dev);
14
15 static int __init myirq_init(void)
16 {
17 printk("the module is working!\n");
18 printk("the irq is ready for working!\n");
19 if(request_irq(irq,myirq_handler,IRQF_SHARED,interface,&irq)){
20 printk(KERN_ERR "%s interrrupt can't register %d IRQ \n",interface,irq);
21 return -EIO;
22 }
23 printk("%s request %d IRQ\n",interface,irq);
24 return 0;
25 }
26 static irqreturn_t myirq_handler(int irq,void *dev)
27 {
28 printk("%d IRQ is working\n",irq);
29 return IRQ_NONE;。

相关主题