对内核模块添加sysfs属性

1. 添加 sysfs 支持

如果你正在开发的设备驱动程序中需要与用户层的接口,一般可选的方法有:

1.注册虚拟的字符设备文件,以这个虚拟设备上的 read/write/ioctl 等接口与用户交互;但 read/write 一般只能做一件事情, ioctl 可以根据 cmd 参数做多个功能,但其缺点是很明显的: ioctl 接口无法直接在 Shell 脚本中使用,为了使用 ioctl 的功能,还必须编写配套的 C语言的虚拟设备操作程序, ioctl 的二进制数据接口也是造成大小端问题 (big endianlittle endian)32/64位不可移植问题的根源;

2.注册 proc 接口,接受用户的 read/write/ioctl 操作;同样的,一个 proc 项通常使用其 read/write/ioctl 接口,它所存在的问题与上面的虚拟字符设备的的问题相似;

3.注册 sysfs 属性;

最重要的是,添加虚拟字符设备支持和注册 proc 接口支持这两者所需要增加的代码量都并不少,最好的方法还是使用 sysfs 属性支持,一切在用户层是可见的透明,且增加的代码量是最少的,可维护性也最好;方法就是使用 <include/linux/device.h> 头文件提供的这四个宏,分别应用于总线/类别/驱动/设备四种内核数据结构对象上:

#define BUS_ATTR(_name, _mode, _show, _store)   /

struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)

 

#define CLASS_ATTR(_name, _mode, _show, _store)                 /

struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)

 

#define DRIVER_ATTR(_name, _mode, _show, _store)        /

struct driver_attribute driver_attr_##_name =           /

        __ATTR(_name, _mode, _show, _store)

 

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

struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

 

总线(BUS)和类别(CLASS)属性一般用于新设计的总线和新设计的类别,这两者一般是不用的;因为你的设备一般是以PCI等成熟的常规方式连接到主机,而不会去新发明一种类型;使用驱动属性和设备属性的区别就在于:看你的 sysfs 属性设计是针对整个驱动有效的还是针对这份驱动所可能支持的每个设备分别有效。

从头文件中还可以找到 show/store 函数的原型,注意到它和虚拟字符设备或 proc 项的 read/write 的作用很类似,但有一点不同是 show/store 函数上的 buf/count 参数是在 sysfs 层已作了用户区/内核区的内存复制,虚拟字符设备上常见的 __user 属性在这里并不需要,因而也不需要多一次 copy_from_user/copy_to_user, show/store 函数参数上的 buf/count 参数已经是内核区的地址,可以直接操作

 

2. 案例文件

2.1. 功能分析

1.demo.ko按一定的时间间隔不断的产生各种级别的日志

 

2.我们新增了attr.hattr.c源文件,并且基本不修改demo.cdemo.h的情况下让demo.ko支持sysfs

所作修改是:在demo的初始化函数中调用demo_attr_install,在demo的退出函数中调用demo_attr_uninstall

 

3.从函数demo_attr_show到各个属性自定义的show函数其实就是面向对象中的多态

 

4.添加sysfs支持后的好处就是可以在用户态下直接跟demo.ko交互,比如

修改打印日志的级别,

echo 101 > /sys/demo/loglevel

修改打印时间间隔,

echo 3000 > /sys/demo/interval

 

5.attr.c / attr.h中的框架可重用

添加一个新的属性,只需要

使用DEMO_ATTR宏定义一个属性

如果该属性支持读,则添加实现ssize_t (*show)(char *buf);

如果该属性支持写,则添加实现ssize_t (*store)(const char *buf, size_t count);

 

其余的代码都不需要改动,都是公共代码。

2.2. attr.h文件

 

2.3. demo.h文件

 

2.4. demo.c文件

 

2.5. attr.c文件

 

3. 参考资料

/Documentation/kobject.txt

/Documentation/filesystems/sysfs.txt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值