早期基于2440&linux-2.6.36的添加软中断的例子
步骤:
1>在软中断定义的枚举类型列表中加入自已的软中断号MY_SOFTIRQ
具体到linux-2.6.36/include/linux/interrupt.h的第376行的枚举列表。其中已经有10项,在NR_SOFTIRQS之前加入MY_SOFTIRQ就可以了。make编译后使用新内核
2>注册软中断
如:open_softirq(MY_SOFTIRQ, my_softirq_action)
对2.6.36内核,在使用前需用EXPORT_SYMBOL_GPL(open_softirq)导出此函数。
3>在中断处理程序中触发软中断
如:raise_softirq(MY_SOFTIRQ)
同样,使用前要用EXPORT_SYMBOL_GPL(raise_softirq)导出此函数。
下面是在s3c2440上实现的一个例子。其中GPF0设为中断EINT0, 在EINT0的中断处理函数中触发软中断。
test.c
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/irq.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zl");
void my_softirq_action(struct softirq_action *data)
{
printk("my softirq atcion ok!\n");
return;
}
static irqreturn_t irq_handle(int irq, void *dev_id, struct pt_regs *regs)
{
int flag;
raise_softirq(MY_SOFTIRQ); //触发软中断
printk("irq %s ok.\n", dev_id);
return 0;
}
int test_init(void)
{
int ret = 0;
open_softirq(MY_SOFTIRQ, my_softirq_action); //注册软中断
set_irq_type(IRQ_EINT0, IRQ_TYPE_EDGE_RISING); //EINT0中断设为上升沿中断
ret = request_irq(IRQ_EINT0, irq_handle, IRQF_SHARED, "my irq", "123"); //注册EINT0中断
if (ret) {
printk("request irq failed.\n");
return -EBUSY;
}
return ret;
}
void test_exit(void)
{
free_irq(IRQ_EINT0, "123");
}
module_init(test_init);
module_exit(test_exit);
Makefile
KERNEL = /media/STUDY/linux/kernel/my2440-2.6.36
#KERNEL = /lib/modules/$(shell uname -r)/build
default:
make -C $(KERNEL) M=$(shell pwd) modules
clean:
make -C $(KERNEL) M=$(shell pwd) modules clean
modules_install:
make -C $(KERNEL) M=$(shell pwd) modules_install INSTALL_MOD_PATH=/home/zl/s3c2440_nfs
depmod -a -b /home/zl/s3c2440_nfs 2.6.13-ZL2440
obj-m += test.o
make后插入生成的test.ko模块。按下GPF0所在的按键,终端会有输出:
my softirq atcion ok!
irq 123 ok.
my softirq atcion ok!
irq 123 ok.
...