。一旦被激活,则可以传递给用户插卡操作信息,在用户应用软件中可立即调用读函数进行读卡操作。这样就实现了对卡的实时操作监控。
(5)模块注销函数的实现
static void_exit
remove_ic(void){
m8xx_timer_stop();
cpm_free_handler(CPMVEC_TIMERl);
unregister_chrdev(majorl,“IC”);
}
这个函数也是模块驱动开发中必不可少的函数之一,用于模块卸载时进行资源的释放,并注销此模块。如上函数所示,首先进行了中断的停止、释放中断资源,同时进行了字符设备的注销。
(6)设备读、写、监控等子函数
用来实现对卡的操作,主要是通过实现卡的各种操作时序。也即在ic_fop s结构体中定义的4个操作函数:icopen用于打开卡设备,进行一些数据的初始化操作;icread()用于插卡操作时读取卡数据;icwrite()用于写卡;icpoll()用于实现卡的实时监控。
综上所述,卡驱动模块的基本实现原理是:申请中断资源,当有插卡操作发生时,引发中断,进行读卡操作。在拔卡操作时也能引发中断,同时进行相应数据处理。同时提供poll()函数接口,用户可采用此函数对设备进行监控,从而实现有卡操作发生时马上进行卡数据的更新。
注:驱动程序源码见本刊网站WWW.dpj.tom.cn。5 驱动模块开发的编译调试 以开发平台和编译器为例编写简单的makefile文件为:
CC=ppc 8xx_gcc
DD=.nostdinc.DMODULE-D_KERNEL_I/mykeme Finclude.Wall-Wstrict-prototypes-Wno-trigraphs-02-fomit-frame-pointer-fno-strict-aliasing-fno-common-I/mykernel/arch/ppc-fsigned-char-resort-float-pipe-ffixed-r2-Wno-uninitialized-mmultiple-mstring-fno-builtin-I/Opt/hardhat/devkit/ppc/8xx/target/usr/lib/gcc-lib/powerpc-hardhat-linux/3.2.1/include ie.o:ic.C
$(CC)$(DD)-C ic.c
install:
make ic.o
clean:
rn*o
执行命令make install,便可以实现驱动模块的动态编译。
内核提供了两个应用程序insmod和rmmod来实现内核模块的动态加载和去除。在模块编译当前目录下执行命令
mknod/dev/charmodule c2540
建立与此设备模块对应的设备文件节点。c表示为字符设备,254表示主设备号,0表示子设备号。
执行命令insmod ic.o,可实现模块动态加载;而命令rmmod ic可实现模块的动态去除。
6 驱动模块的静态编译进内核
①将模块驱动源文件拷贝进/drivers/char/目录下;
②修改/drivers/char/Makefile文件,添加obj-$(CONFIG_MYMODULE)+=ic.o
③在/drivers/char/config.in文件中添加config CONFIG_MYMODULE
bool “IC”CONFIG_MYMODULE
④进入编译内核目录,执行make menuconfig。
在character devices 目录下即可见到IC选项。选择,然后执行编译命令,即可编入内核或仅编译模块:
make mrproper
make menuconfig
make CROSS_COMPILE=ppc_8xx-gcc
make modules CROSS_COMPILE=ppc_8xx-gcc
即可只编译内核。在源文件目录下可见到ic.o。
7 总结
用基本的字符设备实现IC卡设备的驱动模块开发。内核驱动模块的开发是与硬件直接接触的。针对硬件的不同,其内部处理方法也千变万化。对于内核模块开发,最有效的学习途径和最好的学习文档就是Linux的内核源代码。同时,加入一些Linux的邮件开发组也将获益匪浅。