分享

ubuntu 内核模块编译——中断

 无衍 2011-09-17

ubuntu 内核模块编译——中断

 45人阅读 评论(0) 收藏 举报

ubuntu 内核模块编译——中断

                                                                                                                                                                                               author:suzhaoda

        首先,要声明两个变量 ,用两个模块参数 interface  irq 来指明我们要使用的接口 ,并使用 module_param()(注意:MODUL_PARM()函数在2.6.1以后的版本不是用了) 和 MODULE_PARM_DESC 来捕获参数.

        函数 request_irq() 将您的函数添加到选定的 IRQ 行的处理程序列表.定义:

int request_irq(unsigned int irq,
void (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
const char *devname,
void *dev_id);

irq                是中断号。

handler      是一个指针,指向处理中断的函数。

irqflags        使用RQF_SHARED就可以了, 表明我们的处理程序支持与其他处理程序共享 IRQ。

devname   是设备的简称,显示在 /proc/interrupts 列表中。我们将使用 interface 变量中的值,它是作为模块参数接收到的。

dev_id         是设备 ID。这个参数通常设置为 NULL,但是,如果需要共享 IRQ,以使得稍后那个 IRQ 被free_irq() 释放时,正确的设备会被放开,

那么它需要是 non-NULL 的。由于它是 void * ,所以它可以指向任何内容,不过,通常的做法是传递驱动程序的设备结构体。

在此,我们将使用一个指向 irq 变量的指针。

如果成功,request_irq() 将返回 0。

       其余要做的全部事情就是编写 myinterrupt() 处理程序函数。它的声明已经间接通过 request_irq() 的参数说明了:

void (*handler)(int, void *, struct pt_regs *) 

第一个参数是中断号,

第二个参数是在 request_irq 中所使用的设备 ID,

第三个参数持有一个指向某个结构体的指针,结构体中容纳的是在服务那个中断之前的处理器寄存器和状态。

这个函数需要返回某些内容。由于这不是一个真正的驱动程序,而只是研究中断,所以应该返回 IRQ_NONE 
通过返回 IRQ_HANDLED ,我们可以宣称这是设备的真正驱动程序,不需要任何其他驱动程序来处理这个中断。

程序代码:
/*myirqtest*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("SUZHAODA");
MODULE_DESCRIPTION("Myirqtest");

static int irq;
static char *interface = NULL;

/*
*MODULE_PARM(name,type)
*The first parmeters is the parameters name,
*The second parmeters is the data type.
*/

module_param(interface,charp,0644);
MODULE_PARM_DESC(interface, "A network interface");
module_param(irq,int,0644);
MODULE_PARM_DESC(irq,"The IRQ of the network interface");


/*
*irq function define
*The first parmeters is irq number.
*The function handler is pointer which point to the interrupt function.
*The parmeter irqflags = SA_SHIRQ,it represent that the interrupt funciton 
*support the shared IRQ
*The parmeter devname is the device name.
*The last parmeter is the device ID.We usally set it NULL
*/
/*int request_irq(unsigned int irq,
void (*handler)(int,void *,struct pt_regs *),
unsigned long irqflags,
const char *devname,
void *dev_id);
*/

static irqreturn_t myinterrupt(int irq,
void *dev_id,
struct pt_regs *regs)
{
static int mycount = 0;
if(mycount < 10)
{
printk("Interrupt!/n");
mycount++;
}
return IRQ_NONE;
}

static int __init myirqtest_init(void)
{
if(request_irq(irq,&myinterrupt,IRQF_SHARED,interface,&irq))
{
printk(KERN_ERR "myirqtest:cannot register IRQ %d/n",irq);
return -EIO;
}
printk("Requst on IRQ %d succeeded/n",irq);
return 0;
}
/*
*if succeed, return 0
*/

static void __exit myirqtest_exit(void)
{
free_irq(irq,&irq);
printk("freeing IRQ %d/n",irq);
return;
}

module_init(myirqtest_init);
module_exit(myirqtest_exit);


makefile:
obj-m := myirqtest.o
KERNELDIR := /lib/modules/$(shell uname -r)/build

default:
make -C $(KERNELDIR) M=$(shell pwd) modules

clean:
rm -rf *.o *.mod.c *.ko *.symvers *.markers *.orders


最后:
在终端输入sudo make
                     sudo insmod **.ko interface=** irq=**
                     dmesg
就会看到结果。
上述**:是你要替换的地方;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多