开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
前言
前几篇讲的是驱动结构,是驱动的外壳。
现在讲一下驱动的内容,对外提供的操作接口,涉及到的结构体是 file_operations,定义在 linux/fs.h下。这可以理解为c语言的对象实现方法,其中成员就是对象的操作方法。
其中比较重要的方法有 open,release,read,write,llseek,ioctl。
操作方法
open :这是用户操作驱动时的第一个动作。如果不定义,默认NULL,则用户打开驱动时,驱动得不到系统的通知。可以写一个空函数,打印个日志。
release:和open函数是一对,可以不定义。
read/write:不可置NULL,否则 返回-EINVAL('invalid argument' 无效参数)。成功时返回读或者写成功的数目。
下面是一个简单的读内存的读实例,驱动自己申请一个4k的空间,用于读写操作的缓存空间。
文件已经读到结尾,给用户程序返回0.
返回为正,小于cnt,则多数情况下,程序会继续读取数据;等于cnt,这是最理想的结果,数据返回给用户程序。
如果发生了错误,需要通过返回错误码给用户程序,错误码位于 linux/errno.h。
下面是一个简单的写实例,未考虑超出缓冲区问题。
每次写都是从缓冲区起始点开始写数据。
只是用来测试读写的可用性,所以读写操作逻辑简单,未考虑各类异常。
使用系统命令测试驱动可用性,如下。
可以看出来,echo 程序写入了一次数据,并释放了资源。
cat 读131072字节,第一次读返回4k字节,所以cat程序又读了一次,然后驱动返回0(达到文件结尾),cat程序释放了资源。
llseek:修改当前文件的读写位置,返回当前位置。出错返回负的错误码。如果这个方法置NULL,则内核通过修改filePtr->f_pos(当前文件读写位置)来执行定位,而当前定位由read或者write操作来更新。