前言
在前面分析了中断的基本原理后,就可以写一个内核中断程序来体验以下,也可以借此程序继续深入来了解内核中断的执行过程
一.内核中断程序 :
我们还是来看一看成程序:
在看程序之前,要熟悉如何进行模块编程,和了解module_pararm()的用法。如果不熟悉的话请大家看,module_param()的学习 和Linux内核模块编程 ,在此不作解释。
1.程序interrupt.c
1 /*
2 *file name :interrupt.c
3 *atuthor : john
4 */
5 #include
6 #include
7 #include
8 #include
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
6 #include
7 #include
8 #include
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);
40 module_exit(myirq_exit);
41 module_param(interface,charp,0644);
42 module_param(irq,int,0644);
43
2.Makefile的编写
1 obj-m:=tiger.o
2
3 CURRENT_PATH:=$(shell pwd)
4 VERSION_NUM:=$(shell uname -r)
5 LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM)
6
7
8 all :
9 make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules
10 clean:
11 make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean
1 obj-m:=tiger.o
2
3 CURRENT_PATH:=$(shell pwd)
4 VERSION_NUM:=$(shell uname -r)
5 LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM)
6
7
8 all :
9 make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules
10 clean:
11 make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean
(程序的调试,加载和运行,在此不进行说明)
3.首先我们来分析下内核加载模块
在内核加载模块中最重要的的action就是注册中断处理程序。很明显,这一动作是通过request_irq()函数来完成的。
int request_irq