"); //-->
当驱动程序开发完成之后,一般都会先自行进行测试,这样就会提前发现一些问题,从而提高整体效率。那么本篇文章就简单介绍下如何对一个驱动程序进行测试,并梳理应用程序打开设备文件调用驱动的整个过程。
1. 安装驱动程序并手动创建设备节点安装驱动并查看是否成功安装
创建设备节点与设备驱动挂钩
sudo mknod /dev/hello c 255 0
当我们执行insmod命令后驱动就被安装到了内核中,但是用户空间却无从访问,要想访问驱动,必须先创建设备节点与设备驱动相关联,通过设备节点来访问驱动,设备节点其实就是个文件,文件类型是c – 七大文件类型中的字符设备文件。
/dev/hello:要创建的设备节点的名字及路径,一般都在/dev目录下创建。
c: 表示要创建一个字符设备。
255 0:主设备号和次设备号,表示创建的这个设备节点和对应设备号是(255,0)的这个设备驱动关联,这样访问这个设备节点的时候就可以根据设备号唯一确定一个设备了。
2. 写应用测试程序驱动是运行在内核中的,那么我们写的驱动,调用的接口肯定是内核源码库里面的,写应用程序肯定是调用的标准库函数,入口也是我们常说的mian函数了,这点一定不要弄混了。
首先打开设备文件
使用系统调用open函数打开设备节点“/dev/hello”,这个时候内核会根据设备节点对应的设备号去内核查找对应的设备驱动,并调用设备驱动里面的文件操作集合(fops)里面的.open函数,即hello_open函数。
读设备
当通过系统调用read函数对设备进行读操作时,会调用驱动的hello_read函数,hello_read函数会将内核空间的数据cp给buf传递回来。
写设备
当通过系统调用write函数对设备进行写操作时,会调用驱动的hello_write函数,hello_write函数会将用户空间保存在buf中的数据cp到内核空间。最后别忘了close(fd)关闭设备文件。
测试
使用gcc(如果在目标板上运行就用交叉编译工具链)编译应用程序生成可执行文件,直接执行即可。
查看内核驱动的log,调用过程一目了然。
3. 图析应用程序调用驱动过程在看框图之前,先介绍两个重要的结构体,在写驱动的时候,实现open和close函数都有两个重要的参数struct inode和struct file结构体。
inode结构体
一切皆文件,用户在文件系统下看到和操作的都是文件,但是这个文件对应在内核中是以一个inode结构体的形式存在的,当我们在文件系统下用touch或者mknod等命令创建文件时,内核都会创建唯一一个与之对应的inode结构体,保存这个文件的基本信息,当我们用户操作这个文件的时候,操作系统(内核)其实操作的是对应的inode结构体,会将我们的访问需求转换为对某个方法的调用,根据你打开的文件的类型进行不同的操作。
file结构体
操作系统将用户对某个文件的访问的需求转换为对某个方法的调用,内核根据你打开的文件的类型进行不同的操作,当用户打开某个文件时,实际上内核操作的是这个文件对应的inode结构体,同时内核会创建一个file结构体与之对应,这个file结构体里面保存了当前用户对这个文件的操作信息(操作的哪个文件:inode;以什么方式打开的,R/W/RW等:f_flags)
总结
也就是说,inode结构体和文件是一一对应的关系,每个文件在内核系统中都有一个唯一的inode结构体与之对应。只有在用户对文件进行打开操作的时候,内核空间才会创建一个file结构体,那么当多个用户对同一个文件进行打开时,就会创建多个file结构体,分别保存每个用户的操作,file结构体和文件是多对一的关系。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。