Linux字符设备驱动——初体验
2016-05-18 23:05
549 查看
以下是一个非常简单的Linux字符设备驱动 *^_^*
【驱动程序myChrDrv.c】
【驱动程序Makefile】
【应用程序app.c】
执行命令 make,编译生成驱动模块 myChrDrv.ko。
执行命令 insmod myChrDrv.ko,加载驱动模块。
执行命令 lsmod,确认模块加载成功,输出如下:
或执行命令 cat /proc/modules | grep myChrDrv,输出如下:
执行命令 dmesg | tail,查看模块初始化打印信息,输出如下:
执行命令 gcc app.c -o app,编译生成应用程序 app。
执行命令 ./app,运行 app,出错:
虽然驱动程序初始化函数中有“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,确认设备节点创建成功,输出如下:
再次执行命令 ./app,运行 app,成功:
执行命令 dmesg | tail,查看驱动程序打印信息,输出如下:
可以看到,应用程序 app 的 open 和 close 函数最终调用了驱动程序 myChrDrv 的 open 和 release 函数。
执行命令 rmmod myChrDrv,卸载 myChrDrv 驱动。
执行命令 dmesg | tail,查看驱动程序打印信息,输出如下:
执行命令 rm /dev/simple_chrdev,移除设备节点。
Linux字符设备驱动的初体验完毕 *>_<*
【驱动程序myChrDrv.c】
#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】
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】
#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,确认模块加载成功,输出如下:
Module Size Used by myChrDrv 12478 0
或执行命令 cat /proc/modules | grep myChrDrv,输出如下:
myChrDrv 12478 0 - Live 0xf8d28000 (O)
执行命令 dmesg | tail,查看模块初始化打印信息,输出如下:
[850978.514035] myChrDrv_init()
执行命令 gcc app.c -o app,编译生成应用程序 app。
执行命令 ./app,运行 app,出错:
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,确认设备节点创建成功,输出如下:
crw-r--r-- 1 root root 250, 0 5月 18 22:34 /dev/simple_chrdev
再次执行命令 ./app,运行 app,成功:
open /dev/simple_chrdev successed.
执行命令 dmesg | tail,查看驱动程序打印信息,输出如下:
[854089.294682] myChrDrv_open() [854089.294855] myChrDrv_close()
可以看到,应用程序 app 的 open 和 close 函数最终调用了驱动程序 myChrDrv 的 open 和 release 函数。
执行命令 rmmod myChrDrv,卸载 myChrDrv 驱动。
执行命令 dmesg | tail,查看驱动程序打印信息,输出如下:
[854555.685634] myChrDrv_exit()
执行命令 rm /dev/simple_chrdev,移除设备节点。
Linux字符设备驱动的初体验完毕 *>_<*
相关文章推荐
- linux五大搜索命令学习
- 基于AT91SAM9261EK的嵌入式Linux2.6.32+Yaffs2 根文件系统移植成功
- CentOS安装beEF做XSS平台
- 【Linux C】时间转换函数
- linux 拷贝文件内所有文件
- 【Linux C】遍历文件夹下的某种类型的文件
- Centos 7 NS 2.35安装
- Linux下QT5.6打开位置
- centos安装
- Linux常见四种查找命令
- Linux基础篇(一)
- Linux下QWT安装步骤
- linux下搭建dhcp服务器及部署中继代理详解
- 推荐一篇Linux的好文章,大家看看
- linux命令详解(一)
- linux————find的一些简单命令
- LINUX——sort命令
- linux基本命令(28)——tar命令
- Linux配置VNC报错Could not init font path element built-ins, removing from list!
- RedHat-如何在linux系统中设置静态ip地址及设置主机名