创建sysfs节点之device_create_file、sysfs_create_group
来源:互联网 发布:vb延时函数 编辑:程序博客网 时间:2024/05/23 17:56
sysfs属性节点可以实现用户空间与硬件交互,如设置管教电平,设置寄存器值等,控制驱动的具体功能。下面是如何在驱动中创建设备属性节点:
一、device_create_file
device_create_file用于在sys下创建设备的属性节点
int device_create_file(struct device *dev, const struct device_attribute *attr)注意:第一个参数为device型,不是cdev,这个参数一般使用device_create()的返回值device_attribute : 使用DEVICE_ATTR(_name, _mode, _show, _store)初始化,注意name的形式
现在就是要创建这个函数需要的两个参数。
1. 初始化属性结构体device_attribute
1).相关结构体
struct attribute { const char *name; // 属性文件的名字 struct module *owner; // 属性文件的所有者 mode_t mode;#ifdef CONFIG_DEBUG_LOCK_ALLOC struct lock_class_key *key; struct lock_class_key skey;#endif};
struct device_attribute { struct attribute attr; // 内置的attribute 结构体 ssize_t (*show)(struct device *dev, struct device_attribute *attr, //属性文件的show方法(也就是读) char *buf); ssize_t (*store)(struct device *dev, struct device_attribute *attr, //属性文件的store方法(也就是写) const char *buf, size_t count);};
2). 初始化device_attribute结构体
- 使用DEVICE_ATTR初始化device_attribute
DEVICE_ATTR(_name, _mode, _show, _store)_name:名称,也就是将在sysfs中生成的文件名称。_mode:上述文件的访问权限,与普通文件相同,UGO的格式。只读0444,只写0222,或者读写都行的0666。_show:显示函数,cat该文件时,此函数被调用。_store:写函数,echo内容到该文件时,此函数被调用
宏定义:
#define DEVICE_ATTR(_name, _mode, _show, _store) \ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)#define __ATTR(_name,_mode,_show,_store) { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, .store = _store,}
可以发现DEVICE_ATTR就是初始化了结构体device_attribute,下面是实例:
static DEVICE_ATTR(demo, (S_IRUGO | S_IWUSR | S_IWGRP),demo_show,demo_store);static DEVICE_ATTR(demo, 0444,demo_show,NULL);
**注意:**mode可以直接定义成只读0444,只写0222,或者读写都行的0666。。
_show和_store函数当没有的时候用NULL赋值,对函数的名称和内容没有具体要求,甚至可以和别的属性相同。
- 直接赋值device_attribute结构体
直接赋值device_attribute结构体代码示例:
static struct device_attribute dev_attr_demo = { .attr = { .name = "demo", .mode = (S_IRUGO | S_IWUSR) }, .show = demo_show, .store = demo_store,};
2. 构建 struct device *dev 参数
1). 没有总线的字符设备驱动
struct class *class_create(struct module *owner, const char *name)
参数:
owner : 一般为 THIS_MODULE
name : 创建的class类名
对应是在/sys/class/下创建类目录
struct class_device *device_create(struct class *cls, struct class_device *parent, dev_t devt, void *drvdata, const char *fmt, ...)struct class: class_create()返回值,必须在本函数调用之前先被创建parent:父节点指针devt:设备号,如果devt不为0,创建设备文件drvdata:被添加到该设备回调的数据fmt:设备名称
对应是在/dev/下创建设备节点
例子:device_create(demo_class, NULL, MKDEV(tmp_major, 0), NULL, "demo");
注意:在删除模块的时候要使用以下两个函数删除创建的文件
device_destroy(struct class *cls, dev_t devt);class_destroy(struct class *cls);注意两个函数的调用顺序
2). platform总线驱动
直接在probe函数中调用device_create_file创建属性节点。
代码示例:
static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, NULL, led_action_store);static int __devinit demo_probe(struct platform_device *pdev){ int ret = 0; /* led gpio init. */ .................. ret = device_create_file(&pdev->dev, &dev_attr_demo); if (ret) return ret; return 0;}
3.代码示例(没有总线的字符设备驱动)
.......................static ssize_t demo_show(struct device *dev, struct device_attribute *attr, char *buf){ sprintf(buf,"read,demo temp is %d\n",temp); /*将“read,demo temp is %d”写入buf中,%d是temp的值*/ return 0;}static ssize_t demo_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t size){ sscanf(buf, "%d", &temp); /*将buf中的值以%d的形式赋值给temp*/ printk(KERN_NOTICE "write,demo temp is %d/n",temp); return size;}/*这里show和store的函数名没有格式要求,可以为NULL,但是函数的参数必须符合格式要求*/static DEVICE_ATTR(demo, (S_IRUGO | S_IWUSR),demo_show,demo_store);.................int demo_init(void) { ................. demo_class = class_create(THIS_MODULE, "demo"); devdemo = device_create(demo_class, NULL, MKDEV(demo_major, 0), NULL, "cdevdemo"); device_create_file(demo,&dev_attr_demo); .....................}
二、sysfs_create_group
sysfs_create_group可以用于一次创建多个属性节点
1. 初始化device_attribute,这里创建多个节点
static DEVICE_ATTR(demo1, (S_IRUGO | S_IWUSR | S_IWGRP),demo_show,demo_store);
2. 定义属性结构体数组
static struct attribute *demo_attrs[] = { &dev_attr_demo1.attr, &dev_attr_demo2.attr, &dev_attr_demo3.attr, NULL, //这里必须要以NULL结尾 }; //末尾有分号
3. 定义attribute属性结构体数组到属性组中
static const struct attribute_group demo_attr_grp = { .attrs = demo_attrs, }
4. 创建sysfs接口
sysfs_create_group(&pdev->dev.kobj,&dev_attr_led);
5. 代码示例:
static DEVICE_ATTR(demo1, (S_IRUGO | S_IWUSR | S_IWGRP),demo_show,demo_store);static DEVICE_ATTR(demo2, (S_IRUGO | S_IWUSR | S_IWGRP),demo_show,demo_store);static DEVICE_ATTR(demo3, (S_IRUGO | S_IWUSR | S_IWGRP),demo_show,demo_store);static struct attribute *demo_attrs[] = { &dev_attr_demo1.attr, &dev_attr_demo2.attr, &dev_attr_demo3.attr, NULL, //这里必须要以NULL结尾 }; //末尾有分号static const struct attribute_group demo_attr_grp = { .attrs = demo_attrs, } static int __devinit demo_probe(struct platform_device *pdev){ int ret = 0; /* led gpio init. */ .................. ret = sysfs_create_group(&pdev->dev.kobj,&demo_attr_grp); if (ret) return ret; return 0;}
6. 删除接口:
sysfs_remove_groupsysfs_create_group(&pdev->dev.kobj,&demo_attr_grp);
- 创建sysfs节点之device_create_file、sysfs_create_group
- linux中sysfs 创建设备节点的方法sysfs_create_group DEVICE_ATTR
- linux sysfs_create_group()创建sysfs接口
- 创建一个简单的device_create_file文件节点
- 创建sysfs节点
- 创建sysfs节点
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- sysfs接口函数DEVICE_ATTR和sysfs_create_group
- DEVICE_ATTR 和 sysfs 的东西 -- sysfs_create_group
- sysfs接口函数DEVICE_ATTR和sysfs_create_group
- Linux那些事儿之我是Sysfs(10)sysfs 创建目录
- Linux那些事儿之我是Sysfs(10)sysfs 创建目录
- Linux那些事儿之我是Sysfs(10)sysfs 创建目录
- Linux那些事儿之我是Sysfs(10)sysfs 创建目录
- C++ string
- Java的运行(基础必备)
- OpenCV-python不懂知识点整理
- 【个人训练】(UVa11129)An antiarithmetic permutation
- 51单片机实验2017年12月4日
- 创建sysfs节点之device_create_file、sysfs_create_group
- [BZOJ1069]-最大土地面积-凸包+旋转卡壳
- FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registe
- 《数据库系统概念》9-附加关系运算
- nodelist 不能使用foreach的解决办法
- mysql+mycat读写分离
- Apache 开启Https双向认证
- 2017noip普及组 T2 librian
- String中的split(正则表达式)