应用程序和驱动的简易交互方式的实现

来源:互联网 发布:淘宝网支持的网上银行 编辑:程序博客网 时间:2024/06/05 13:32

应用程序和驱动的简易交互方式的实现

一般应用程序要操作设备, 都需要相应的设备驱动程序配合才行, 因为在应用层一般都把设备当成一个文件来操作, 所以,如果要给设备发送特殊的命令,一般要用ioctl函数才行,这也就要求驱动必须实现ioctl的接口,实际上,驱动也可以简单的把相关的命令或属性注册到sysfs下,这样应用程序就只要读写相关属性就能间接控制设备了,这样应用层就只要使用cat, echo 等命令,而不用专门写程序调用ioctl函数了。

 

Sysfs简介:

sysfs 是 Linux 内核中设计较新的一种虚拟的基于内存的文件系统,它的作用与 proc 有些类似,但除了与 proc 相同的具有查看和设定内核参数功能之外,还有为 Linux 统一设备模型作为管理之用。相比于 proc 文件系统,使用 sysfs 导出内核数据的方式更为统一,并且组织的方式更好,它的设计从 proc 中吸取了很多教训。

sysfs 文件系统总是被挂载在 /sys 挂载点上。虽然在较早期的2.6内核系统上并没有规定 sysfs 的标准挂载位置,可以把 sysfs 挂载在任何位置,但较近的2.6内核修正了这一规则,要求 sysfs 总是挂载在 /sys 目录上;针对以前的 sysfs 挂载位置不固定或没有标准被挂载,有些程序从 /proc/mounts 中解析出 sysfs 是否被挂载以及具体的挂载点,这个步骤现在已经不需要了。请参考附录给出的 sysfs-rules.txt 文件链接。

sysfs 与 proc 相比有很多优点,最重要的莫过于设计上的清晰。一个 proc 虚拟文件可能有内部格式,如 /proc/scsi/scsi ,它是可读可写的,(其文件权限被错误地标记为了0444 !,这是内核的一个BUG),并且读写格式不一样,代表不同的操作,应用程序中读到了这个文件的内容一般还需要进行字符串解析,而在写入时需要先用字符串格式化按指定的格式写入字符串进行操作;相比而言, sysfs 的设计原则是一个属性文件只做一件事情, sysfs 属性文件一般只有一个值,直接读取或写入。整个 /proc/scsi 目录在2.6内核中已被标记为过时(LEGACY),它的功能已经被相应的 /sys 属性文件所完全取代。新设计的内核机制应该尽量使用 sysfs 机制,而将 proc 保留给纯净的“进程文件系统”。

 

驱动使用Sysfs流程:

1.      创建属性,

一般用宏 DEVICE_ATTR来创建,原型是

#define DEVICE_ATTR(_name, _mode, _show, _store)     \

         structdevice_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

函数宏DEVICE_ATTR内封装的是__ATTR(_name,_mode,_show,_stroe)方法,_show表示的是读方法,_stroe表示的是写方法。

当然_ATTR不是独生子女,他还有一系列的姊妹__ATTR_RO宏只有读方法,__ATTR_NULL等等, 如对设备的使用  DEVICE_ATTR  ,对总线使用  BUS_ATTR  ,对驱动使用 DRIVER_ATTR  ,对类别 (class) 使用  CLASS_ATTR,  这四个高级的宏来自于<include/linux/device.h> 

DEVICE_ATTR  宏声明有四个参数,分别是名称、权限位、读函数、写函数。其中读函数和写函数是读写功能函数的函数名。


2.      填充结构体struct attribute 变量:

    

    注意, 属性名字, 必须以dev_attr_为前缀, 后跟属性名

 

3.      封装结构体static struct attribute_group

 

4.      注册到sysfs中去

一般在驱动的probe函数中,利用sysfs_create_group(&pdev->dev.kobj,&dev_attr_grp);创建接口

 

5.      实现属性读写函数:

以enable属性为例,读写函数为:

 

通过以上简单的5个步骤,就可以在sysfs相关的目录下查看到接口了。当我们将数据 echo 到属性中时,在上层实际上完成了一次 write 操作,对应到 kernel ,调用了驱动中的 “store”。同理,当我们cat 一个属性时则会调用 “show” 。

 

参考:

http://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/

0 0