以下是一個非常簡單的Linux字符設備驅動 *^_^*
【驅動程序myChrDrv.c】
[code]#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> static int myChrDrv_open(struct inode *inod, struct file *fp) { printk(KERN_INFO "myChrDrv_open()\n"); return 0; } static int myChrDrv_close(struct inode *inod, struct file *fp) { printk(KERN_INFO "myChrDrv_close()\n"); return 0; } static struct file_operations fops = { .open = myChrDrv_open, .release = myChrDrv_close, }; static int __init myChrDrv_init(void) { printk(KERN_INFO "myChrDrv_init()\n"); int ret; // 創建並向內核注冊字符設備simple_chrdev ret = register_chrdev(250, "simple_chrdev", &fops); return 0; } static void __exit myChrDrv_exit(void) { printk(KERN_INFO "myChrDrv_exit()\n"); unregister_chrdev(250, "simple_chrdev"); } module_init(myChrDrv_init); module_exit(myChrDrv_exit); MODULE_LICENSE("Dual BSD/GPL");【驅動程序Makefile】
[code]obj-m += myChrDrv.o #CROSS_COMPILE = /usr/local/arm/arm-2010.09/bin/arm-none-linux-gnueabi- #CC = $(CROSS_COMPILE)gcc #KDIR := /home/walle/arm/arm_os/kernel/linux-3.10.10 KDIR := /lib/modules/`uname -r`/build default: $(MAKE) -C $(KDIR) M=`pwd` modules clean: $(MAKE) -C $(KDIR) M=`pwd` modules clean【應用程序app.c】
[code]#include <stdio.h> #include <fcntl.h> int main(int argc, char *argv[]) { int fd; fd = open("/dev/simple_chrdev", O_RDWR); if(fd < 0){ printf("open /dev/simple_chrdev failed.\n"); return -1; } printf("open /dev/simple_chrdev successed.\n"); close(fd); return 0; }執行命令 make,編譯生成驅動模塊 myChrDrv.ko。
執行命令 insmod myChrDrv.ko,加載驅動模塊。 執行命令 lsmod,確認模塊加載成功,輸出如下:
[code]Module Size Used by myChrDrv 12478 0或執行命令 cat /proc/modules | grep myChrDrv,輸出如下:
[code]myChrDrv 12478 0 - Live 0xf8d28000 (O)執行命令 dmesg | tail,查看模塊初始化打印信息,輸出如下:
[code][850978.514035] myChrDrv_init()執行命令 gcc app.c -o app,編譯生成應用程序 app。
執行命令 ./app,運行 app,出錯:
[code]open /dev/simple_chrdev failed.
雖然驅動程序初始化函數中有“register_chrdev(250, “simple_chrdev”, &fops);”,函數 register_chrdev 的作用是申請主設備號250、綁定操作相關函數 fops、向內核注冊設備名為 simple_chrdev 的設備。顯然此時系統中並不存在 /dev/simple_chrdev,因此需要執行命令“mknod /dev/simple_chrdev c 250 0”手動創建該設備節點。
mknod 的格式是:mknod [OPTION]… NAME TYPE [MAJOR MINOR]。命令中的“c”表示字符設備;“250”是主設備號,與驅動程序中手動申請的主設備號一致;“0”是次設備號,這裡也可以不設為0,只需要主設備號對應得上就行,因為主設備號指定的是驅動,次設備號指定的是具體設備。
另外文件“/dev/simple_chrdev”要與 app.c 中 open 函數打開的文件一致,所以如果 open 指定的文件是“hello”,mknod 命令創建“hello”即可。這裡之所以用“/dev/simple_chrdev”主要是為了讓它看起來像一個設備。
OK,我們執行命令 ls -l /dev/simple_chrdev,確認設備節點創建成功,輸出如下:
[code]crw-r--r-- 1 root root 250, 0 5月 18 22:34 /dev/simple_chrdev
再次執行命令 ./app,運行 app,成功:
[code]open /dev/simple_chrdev successed.
執行命令 dmesg | tail,查看驅動程序打印信息,輸出如下:
[code][854089.294682] myChrDrv_open() [854089.294855] myChrDrv_close()
可以看到,應用程序 app 的 open 和 close 函數最終調用了驅動程序 myChrDrv 的 open 和 release 函數。
執行命令 rmmod myChrDrv,卸載 myChrDrv 驅動。 執行命令 dmesg | tail,查看驅動程序打印信息,輸出如下:
[code][854555.685634] myChrDrv_exit()執行命令 rm /dev/simple_chrdev,移除設備節點。
Linux字符設備驅動的初體驗完畢 *>_<*