在编写驱动程序时,需要对驱动里的某些变量进行读写,或函数调用,再或者驱动某个开关量。可通过sysfs接口创建驱动对应的属性,便可以在用户空间通过sysfs接口的show和store函数与硬件交互;

DEVICE_ATTR宏定义在include/linux/device.h中

1、函数原型是:

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

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

DEVICE_ATTR 宏声明有四个参数,分别是名称(_name)、权限位(_mode:一般使用S_IRUGO | S_IWUSR或者0664)、读函数(_show)、写函数(_store)。其中读函数和写函数是读写功能函数的函数名。调用DEVICE_ATTR生成的对应的文件在/sys/devices/目录中对应的device下面。

 

2、代码主要实现过程如下:

//读函数的封装定义,自己根据需要添加相应的操作,cat   test_czd 此时可以读出该接口的信息,也就是执行test_czd_show这个函数
 

static ssize_t test_czd_show(struct device *dev,struct device_attribute *attr, char *buf)

{

       return sprintf(buf, "%s\n", "czd:test code");

}

//写函数的封装定义,自己根据需要添加相应的操作,echo 1 > test_czd 这样就执行test_czd_store

static ssize_t test_czd_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)

{

     return count;

}

//创建设备节点文件test_czd,一般读写我会赋值 0666 ,static DEVICE_ATTR(test_czd, 0666, test_czd_show, test_czd_store);

static DEVICE_ATTR(test_czd, S_IRUGO | S_IWUSR, test_czd_show, test_czd_store);

 

//当你想要实现的接口名字是test_czd的时候,需要实现结构体struct attribute *dev_attrs[],其中成员变量的名字必须是&dev_attr_test_czd.attr

static struct attribute *dev_attrs[] = {

            &dev_attr_test_czd.attr,

            NULL,

    };

 

//然后再封装

static struct attribute_group dev_attr_group = {

            .attrs = dev_attrs,

    };

 

//然后在probe函数中调用,创建接口sysfs:

sysfs_create_group(&client->dev.kobj, &dev_attr_group);

 

//在remove函数中调用,在remove中移除接口sysfs

sysfs_remove_group(&client->dev.kobj, &dev_attr_group);

 

 

注:Mode是权限位,在kernel/include/uapi/linux/stat.h;

 

 1 #define S_IRWXU 00700 //用户可读写和执行
 2 #define S_IRUSR 00400//用户可读
 3 #define S_IWUSR 00200//用户可写
 4 #define S_IXUSR 00100//用户可执行
 5  
 6 #define S_IRWXG 00070//用户组可读写和执行
 7 #define S_IRGRP 00040//用户组可读
 8 #define S_IWGRP 00020//用户组可写
 9 #define S_IXGRP 00010//用户组可执行
10  
11 #define S_IRWXO 00007//其他可读写和执行
12 #define S_IROTH 00004//其他可读
13 #define S_IWOTH 00002//其他可写
14 #define S_IXOTH 00001//其他可执行
Logo

更多推荐