带参数的中断程序实例:http://www.kerneltravel.net/?p=133
1。myirq.c
/*myirq.c*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
static int irq;
static char *interface;
module_param(interface,charp,0644);
module_param(irq,int,0644);
//static irq_handler_t myinterrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t myinterrupt(int irq, void *dev_id)
{
static int mycount = 0;
static long mytime = 0;
struct net_device *dev=(struct net_device *)dev_id;
if(mycount==0){
mytime=jiffies;
}
//count the interval between two irqs
if (mycount < 10) {
mytime=jiffies-mytime;
printk("Interrupt number %d — intterval(jiffies) %ld — jiffies:%ld \n", irq,mytime, jiffies);
mytime=jiffies;
//printk("Interrupt on %s —–%d \n",dev->name,dev->irq);
}
mycount++;
return IRQ_NONE;
}
static int __init myirqtest_init(void)
{
printk ("My module worked!\n");
//regist irq
if (request_irq(irq,&myinterrupt,SA_SHIRQ,interface,&irq)) { //early than 2.6.23
//if (request_irq(irq,&myinterrupt,IRQF_SHARED,interface,&irq)) { //later than 2.6.23
printk(KERN_ERR "myirqtest: cannot register IRQ %d\n", irq);
return -EIO;
}
printk("%s Request on IRQ %d succeeded\n",interface,irq);
return 0;
}
static void __exit myirqtest_exit(void)
{
printk ("Unloading my module.\n");
free_irq(irq, &irq); //release irq
printk("Freeing IRQ %d\n", irq);
return;
}
module_init(myirqtest_init);
module_exit(myirqtest_exit);
MODULE_AUTHOR("Helight.Xu");
MODULE_LICENSE("GPL");
2.Makefile
obj-m += myirq.o
#generate the path
CURRENT_PATH:=$(shell pwd)
#the current kernel version number
LINUX_KERNEL:=$(shell uname -r)
#the absolute path
#LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
#这里的内核路径注意根据实际情况修改,确保内核路径指向正确,以下是centos的路径
#LINUX_KERNEL_PATH:=/usr/src/kernels/2.6.32-573.22.1.el6.i686
LINUX_KERNEL_PATH:=/usr/src/kernels/2.6.18-194.el5-i686
#complie object
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#clean
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
3.测试
[root@stu106 irq]# make
[root@stu106 irq]# insmod myirq.ko irq=3 interface=myirq3.
My module worked!
myirq3. Request on IRQ 3 succeeded
[root@stu106 irq]# rmmod myirq.ko
[root@stu106 irq]# dmesg
Unloading my module.
Freeing IRQ 3位于/proc/interrupts文件的输出结果,这个文件存放的是系统中与中断相关的统计信息
irp的序号 各自cpu上发生的中断次数 可编程中断控制器 设备名称(request_irq的dev_name字段)
[root@stu106 irq]# cat /proc/interrupts
CPU0
0: 17252441 IO-APIC-edge timer
1: 4511 IO-APIC-edge i8042
3: 60 IO-APIC-edge myirq3.
4: 6655 IO-APIC-edge serial
6: 5 IO-APIC-edge floppy
7: 0 IO-APIC-edge parport0
8: 1 IO-APIC-edge rtc
9: 0 IO-APIC-level acpi
12: 344020 IO-APIC-edge i8042
15: 173234 IO-APIC-edge ide1
51: 0 IO-APIC-level uhci_hcd:usb1
59: 66574 IO-APIC-level ioc0
67: 38631 IO-APIC-level vmxnet ether
75: 3 IO-APIC-level vmci, Ensoniq AudioPCI
NMI: 0
LOC: 18904116
ERR: 0
MIS: 0
共享中断测试
[root@stu106 irq]# rmmod myirq.ko
[root@stu106 irq]# insmod myirq.ko irq=1 interface=myirq
1是键盘中断
[root@stu106 irq]# cat /proc/interrupts
CPU0
0: 19991537 IO-APIC-edge timer
1: 6977 IO-APIC-edge i8042, myirq
4: 7440 IO-APIC-edge serial
6: 5 IO-APIC-edge floppy
7: 0 IO-APIC-edge parport0
8: 1 IO-APIC-edge rtc
9: 0 IO-APIC-level acpi
12: 380292 IO-APIC-edge i8042
15: 197984 IO-APIC-edge ide1
51: 0 IO-APIC-level uhci_hcd:usb1
59: 70671 IO-APIC-level ioc0
67: 40304 IO-APIC-level vmxnet ether
75: 3 IO-APIC-level vmci, Ensoniq AudioPCI
NMI: 0
LOC: 21616880
ERR: 0
MIS: 0
[root@stu106 irq]# dmesg
My module worked!
myirq Request on IRQ 1 succeeded
Interrupt number 1 — intterval(jiffies) 0 — jiffies:19415118
Interrupt number 1 — intterval(jiffies) 2007 — jiffies:19417126
Interrupt number 1 — intterval(jiffies) 0 — jiffies:19417126
Interrupt number 1 — intterval(jiffies) 0 — jiffies:19417126
Interrupt number 1 — intterval(jiffies) 1 — jiffies:19417127
Interrupt number 1 — intterval(jiffies) 95 — jiffies:19417222
Interrupt number 1 — intterval(jiffies) 0 — jiffies:19417222
Interrupt number 1 — intterval(jiffies) 1 — jiffies:19417223
Interrupt number 1 — intterval(jiffies) 0 — jiffies:19417223
Interrupt number 1 — intterval(jiffies) 615 — jiffies:19417838