设备模拟与ISR

2019-04-13 16:53发布

  设备模拟与ISR 实验目的: 1.        编写一个内核模块,模拟设备产生中断 2.        编写另一个内核模块,处理第一个设备产生的中断 实验原理 1.    设备模拟需要编写设备驱动,这就要实现file_operations接口 2.    在模拟设备中使用int指令产生软中断,由ISR模块处理中断 实验内容 1.      模拟出两个字符设备 1)        分别实现字符设备devPK、devGL的驱动,字符设备由一个共享变量char myDeviceChar担当,这个变量在pkISR模块里面声明,其它模块将引用这个设备变量。 2)        实现过程:首先为两个设备创建file_operations变量如下, struct file_operations char_GL_fops = {               .owner   =    THIS_MODULE,               .read    =    glRead,                 .write   =    glWrite,               .open    =    glOpen,               .release =    glRelease,               }; struct file_operations char_PK_fops = {               .owner   =    THIS_MODULE,               .read    =    pkRead,               .write   =    pkWrite,               .open    =    pkOpen,               .release =    pkRelease,               }; 这两个结构的接口函数应该分别在声明之前定义,具体实现参见代码。 3)        注册设备与IRQ         在模块初始化函数中注册, register_chrdev(char_PK_MAJOR,dev_NAME,&char_PK_fops); if(0 != request_irq(5,pkISR,SA_SHIRQ,dev_NAME,dev_NAME))…        相应释放设备与IRQ在模块存在于释放函数中, free_irq(5,dev_NAME); unregister_chrdev(char_PK_MAJOR,dev_NAME);        这里面有几个参数需要说明一下: char_PK_MAJOR是自定义的主设备号,dev_NAME是设备名称,pkISR是设备发生中断时对应的ISR,SA_SA_SHIRQ代表两个字符设备共享同一个IRQ,这里使用的IRQ是5号IRQ。 4)        设备中断的产生:devPK设备的中断在pkRead、pkWrite操作里产生,当设备发生读写操作时即产生一个中断,实现如下, __asm__ __volatile__("int $0x25");      //对应的IRQ是5号 2.      编写ISR模块 ISR模块处理设备发生的中断,在pkISR里,声明并且导出了几个其它模块用到的变量, static int flag = -1; EXPORT_SYMBOL(flag); static char myDeviceChar = ' '; EXPORT_SYMBOL(myDeviceChar); 这里的flag变量用于判断哪个设备发生了何种操作,这个是自定义的。实际应用中的情况不是这样的,但是在模拟情况下采用了这种方法。 相应的,在ISR处理函数里,会打印出相关信息,以显示具体是哪个设备发生了哪类操作,从而达到了处理模拟中断的目的。 3.      模块加载 每个内核模块都有如下注册和撤消函数, module_init(init_name); module_exit(clean_name); 实现编译模块到内核:(Makefile文件: obj-m := file.o) make -C /usr/src/kernels/2.6.23.1-42.fc8-i686 M=$PWD modules 使用insmod 命令注册模块,相应卸载命令是rmmmod. 4.      编写测试模块 测试模块是用户态下的程序test.c,在这个程序里,首先打开设备,然后对设备进行读和写操作。 当然,首先需要注册设备节点,具体操作如下: 以root用户打开终端: mknod /dev/char_devPK c 257 1 mknod /dev/char_devGL c256 1 这里的设备节点名称与设备驱动注册设备使用的名称一致。 当执行测试程序时,查看中断是否发生使用dmeg|tail命令即可。 实验结论 实验发现,两个设备注册的ISR处于一条链上,因为它们注册的是同一个IRQ;当中断发生时,ISR会依次执行,直到得到正确处理,即执行了设备注册的相应的ISR。同时,实现演示出,当设备注册IRQ时,就会调用相应的ISR一次。