本系列图文教程均以全志H3开发板为实验板设计,字符设备驱动开发是最基础的驱动开发。其本质是按字节进行读写操作,读写数据是分先后顺序的。LED、按键、IIC、SPI、USB等等都是字符设备,驱动加载成功以后会在“/dev”目录下生成相应的文件,应用程序通过对“/dev/xxx进行操作即可实现对硬件的控制”。应用程序中的每一个系统调用,都在驱动程序中有相应的驱动函数,Linux内核文件中存在着一个内核驱动操作函数集合,以结构体file_operations展现。
(资料图)
编写驱动需要注册两种操作函数,加载和卸载。module_init 函数用来向 Linux 内核注册一个模块加载函数,参数 xxx_init 就是需要注册的具体函数,当使用“insmod”命令加载驱动的时候,xxx_init 这个函数就会被调用。module_exit()函数用来向 Linux 内核注册一个模块卸载函数,参数 xxx_exit 就是需要注册的具体函数,当使用“rmmod”命令卸载具体驱动的时候 xxx_exit 函数就会被调用。驱动编译完成后是.ko文件,使用insmod和modprobe加载驱动模块。
对于字符设备驱动而言,当驱动模块加载成功以后需要注册字符设备,同样,卸载驱动模块的时候也需要注销掉字符设备。注册和注销函数原型如下所示:
static inline int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)static inline void unregister_chrdev(unsigned int major, const char *name)
最后我们需要在驱动中加入 LICENSE 信息和作者信息,其中 LICENSE 是必须添加的,否则的话编译的时候会报错,作者信息非必须。
添加函数为:
MODULE_LICENSE()MODULE_AUTHOR()
Linux如何判断当下的设备就是程序想要调用的那一个呢,通过设备号对设备进行唯一匹配。有动态和静态两种分配方式,我们先讲解旧的驱动设备注册方式(静态),也就是使用register_chrdev函数注册设备。其三个参数分别是主设备号(手动分配),设备名称(字符串),函数集合指针结构体。主设备号的可选范围是0-4095,所以使用之前先查看开发板的Linux系统还有哪些设备号没有用,使用命令cat /proc/devices查看。
最后就是完整的编写驱动和应用程序,驱动程序完成设备打开,读写操作,使用一个虚拟读写设备做一个简单的例子。借助copy_to_user(将内核态数据复制到用户态)和printk函数(内核态)完成模拟。
共分以下几步
•编写驱动程序(对printk的解释内核态,设备注册等)
•编写App程序(open等函数)
•编译驱动程序成.ko 测试(编写Makefile文件)
•编译App
•下载到TF的rootfs分区下
•找到相应文件夹下加载模块insmod **.ko
•查看系统中的所有设备cat /proc/devices
•创建设备节点文件mknod /dev/chrdevbase c 200 0 然后再执行上一步查看设备是否多了chrdevbase
c表示字符设备,200是主设备号,0是次设备号
•如果App要读写chrdevbase设备,直接操作/dev/chrdevbase就可以
读操作测试./chrdevbaseApp /dev/chrdevbase 1
标签: