在linux驱动中,经常会使用到sysfs节点,便于调试或者提供接口给应用。
一、无总线的字符设备驱动
##_ATTR不止一种形式,还有DEVICE_ATTR、DRIVER_ATTR、BUS_ATTR、CALSS_ATTR。
static ssize_t ##_store(struct class *cls,struct class_attribute *attr,const char *_buf,size_t _count)
static ssize_t ##_show(struct class *cls,struct class_attribute *attr,const char *_buf)
static struct class_attribute test_attrs[]=
{
_ATTR(test, 0220, ##_show, ##_stroe),
_ATTR_NULL,
}
static struct calss test_demo_class =
{
.name = “test-demo”,
.owner = THIS_MODULE,
.calss_attrs = test_attrs,
}
static int test_demo_probe(struct platform_device *pdev)
{
calss_register(&test_demo_class);
}
或者
static struct class *my_class;
static CLASS_ATTR(test,0666,NULL,##_store);
static int **_probe(struct platform_device *pdev)
{
my_class = class_create(THIS_MODULE,“test-demo”);
device_create(my_class,NULL,MKDEV(_major,_minor),NULL,“test-demo”);
class_create_file(my_class,&class_attr_test); //创建/dev/class/test-demo目录
}
class_create()函数创建一个类存放在sysfs下面,
然后通过device_create()函数在/dev目录下创建相应的设备节点。
这样,加载模块的时候,用户空间中的udev会自动响应 device_create()函数,
去/sysfs下寻找对应的类从而创建设备节点。
注销函数:
device_destroy(mydriver_class,MKDEV(_major,_minor));
class_destroy(my_class);
二、总线设备驱动
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的形式。
#define DEVICE_ATTR(_name, _mode, _show, store)
struct device_attribute dev_attr**_name = __ATTR(_name, _mode, _show, _store)
_name:名称,也就是将在sys fs中生成的文件名称。
_mode:上述文件的访问权限
_show:显示函数,cat该文件时,此函数被调用。
_store:写函数,echo内容到该文件时,此函数被调用。
1.device_create_file
直接在probe函数中调用device_create_file创建属性节点。
(1)DEVICE_ATTR(test, 0664, test_show, test_store);
(2)
static int test_demo(struct *platform_device *pdev)
{
…
device_create_file(&pdev->dev, &dev_attr_test);
…
}
2.sysfs_create_group
sysfs_create_group可以用于一次创建多个属性节点。
(1)初始化device_attribute,可创建多个节点
DEVICE_ATTR(test1, 0664, test_show, test_store);
(2)定义属性结构体数组
static struct attribute *test_attrs[] = {
&dev_attr_test1.attr,
&dev_attr_test2.attr,
&dev_attr_test3.attr,
NULL, //必须要以NULL结尾
};
(3)定义attribute属性结构体数组到组属性中
static const struct attribute_group test_attr_grp = {
.attrs = test_attrs,
};
(4)创建sysfs接口
sysfs_create_group(&pdev->dev.kobj,&dev_attr_test);