属性
几乎在Linux设备模型的每一层都提供了添加属性的函数。属性由attribute结构表示,其成员包括
name 属性名
mode 属性权限
设备、驱动、总线和类的属性结构分别是device_attribute、driver_attribute、bus_attribute和class_attribute。其成员包括
attr attribute结构
show 显示回调函数
store 存储回调函数
为了方便属性的创建,内核提供了如下的宏
XXX_ATTR_RW 创建可读可写属性
XXX_ATTR_RO 创建只读属性
XXX_ATTR_WO 创建只写属性
可使用如下函数向设备、驱动、总线或类添加 / 删除属性
xxx_create_file() 创建属性文件
xxx_remove_file() 移除属性文件
属性组
多个属性可以组成属性组,这样就可以利用前面提到的属性组相关函数来一次性添加多个属性。属性组由attribute_group结构表示。其主要成员包括
name 属性组名称(可选)
attrs 指向属性数组指针,以NULL结尾
内核提供了ATTRIBUTE_GROUPS宏以简化属性组的创建
——————————————————————————————————————
基类 子类初步整理
属性对应sysfs中的一个文件,那么在sysfs中,为什么会有attribute的概念呢?sysfs中的目录描述了kobject,而kobject是特定数据类型变量(如struct device)的体现。因此kobject的属性,就是这些变量的属性。它可以是任何东西,名称、一个内部变量、一个字符串等等。而attribute,在sysfs文件系统中是以文件的形式提供的,即:kobject的所有属性,都在它对应的sysfs目录下以文件的形式呈现。这些文件一般是可读、写的,而kernel中定义了这些属性的模块,会根据用户空间的读写操作,记录和返回这些attribute的值。
总之,所谓的attibute,就是内核空间和用户空间进行信息交互的一种方法。例如某个driver定义了一个变量,却希望用户空间程序可以修改该变量,以控制driver的运行行为,那么就可以将该变量以sysfs attribute的形式开放出来。
属性分为普通属性和二进制属性
1.普通属性
struct attribute { //属性的通用结构,普通文件是kobject目录的属性展现
name,属性的名字,对应sysfs中文件的名字。
mode,应用于属性(文件)的保护位,与文件的权限相同
}
2.二进制属性
struct bin_attribute {
attr,包含的普通属性。
size,二进制属性的最大长度,如果没有最大值可以设为0。
private,私有数据,与linux中大部分私有数据的用途一样,用于传递私有数据结构。
read()、write()、mmap(),操作二进制属性的函数。
}
二进制属性不能作为默认属性被设置,只能显式地创建。
使用该attribute生成的sysfs文件,只能用字符串的形式读写。
而struct bin_attribute在struct attribute的基础上,增加了read、write等函数,因此它所生成的sysfs文件可以用任何方式读写。固件一般使用bin_attribute属性
3.属性组
struct attribute_group{
name,属性组的名字,不为空的话对应一个sysfs的文件夹。
attrs,属性组里的普通属性列表。
bin_attrs,属性组里的二进制属性列表。
is_visible(),返回组中属性的读写权限。
4. sysfs_ops--kobject的ktype,目录的属性读写接口,attribute的属性接口调用首先需要
目录的通过sysfs_ops进行读写。
show,显示属性值。
store,保存属性值。
- struct kobj_type {//object type,kobj_type是对kobject的特性描述
- void (*release)(struct kobject *kobj);//析构函数指针,指向析构函数,该函数在refcount为0时,清理所有”同类“的kobject并释放内存。
- const struct sysfs_ops *sysfs_ops;//指针指向”sysfs读写操作函数结构体“
- struct attribute **default_attrs;//描述了属于该ktype的kobject的默认属性
- const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
- const void *(*namespace)(struct kobject *kobj);
- };
___________________________________________________________
属性基类和子类定义结构 整理
- struct attribute { //属性的通用结构,普通文件是kobject目录的属性展现
- const char *name;
- umode_t mode;
- #ifdef CONFIG_DEBUG_LOCK_ALLOC
- bool ignore_lockdep:1;
- struct lock_class_key *key;
- struct lock_class_key skey;
- #endif
- };//基类中没有定义 func方法,在子类中定义
-
-
-
- ________________________________________________________________
-
-
- struct bin_attribute {//二进制属性专门设计的,它在sysfs中表现为二进制文件
- struct attribute attr;//基类
- size_t size;
- void *private;
- ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
- char *, loff_t, size_t);
- ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
- char *, loff_t, size_t);
- int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
- struct vm_area_struct *vma);
- };
-
-
- struct property {//设备树中的是以 二进制属性展现的
- char *name;
- int length;
- void *value;
- struct property *next;
- unsigned long _flags;
- unsigned int unique_id;
- struct bin_attribute attr;
- };
-
- ——————————————————————————————————————————
-
-
- /* interface for exporting device attributes */
- struct device_attribute {//设备属性
- struct attribute attr;
- ssize_t (*show)(struct device *dev, struct device_attribute *attr,
- char *buf);
- ssize_t (*store)(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count);
- };
-
- Declaring:
- DEVICE_ATTR(_name, _mode, _show, _store);
-
-
- Creation/Removal:
- int device_create_file(struct device *dev, const struct device_attribute * attr);
- void device_remove_file(struct device *dev, const struct device_attribute * attr);
-
-
- ————————————————————————————————————————————————————————————
- struct bus_attribute {
- struct attribute attr;
- ssize_t (*show)(struct bus_type *, char * buf);
- ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
- };
-
- Declaring:
- static BUS_ATTR_RW(name);
- static BUS_ATTR_RO(name);
- static BUS_ATTR_WO(name);
-
-
- Creation/Removal:
- int bus_create_file(struct bus_type *, struct bus_attribute *);
- void bus_remove_file(struct bus_type *, struct bus_attribute *);
-
- ——————————————————————————————————————————
-
-
- Structure:
- struct driver_attribute {
- struct attribute attr;
- ssize_t (*show)(struct device_driver *, char * buf);
- ssize_t (*store)(struct device_driver *, const char * buf,
- size_t count);
- };
-
-
- Declaring:
- DRIVER_ATTR_RO(_name)
- DRIVER_ATTR_RW(_name)
-
-
- Creation/Removal:
- int driver_create_file(struct device_driver *, const struct driver_attribute *);
- void driver_remove_file(struct device_driver *, const struct driver_attribute *);
-
-
- ————————————————————————————————————————
- struct freq_attr { //cpu freq attr ---子类
- struct attribute attr;---基类
- ssize_t (*show)(struct cpufreq_policy *, char *);
- ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
- };
-
属性宏定义大量在内核和驱动中使用到,贴出代码,以查阅方便
- 基础在定义 include/linux/sysfs.h
-
- #define __ATTR(_name, _mode, _show, _store) { \
- .attr = {.name = __stringify(_name), \
- .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
- .show = _show, \
- .store = _store, \
- }
-
- #define __ATTR_PREALLOC(_name, _mode, _show, _store) { \
- .attr = {.name = __stringify(_name), \
- .mode = SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\
- .show = _show, \
- .store = _store, \
- }
-
- #define __ATTR_RO(_name) { \
- .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \
- .show = _name##_show, \
- }
-
- #define __ATTR_WO(_name) { \
- .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \
- .store = _name##_store, \
- }
-
- #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
- _name##_show, _name##_store)
-
-
-
-
- include/linux/device.h是设备属性宏定义
-
- #define DEVICE_ATTR(_name, _mode, _show, _store) \
- struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
- #define DEVICE_ATTR_RW(_name) \
- struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
- #define DEVICE_ATTR_RO(_name) \
- struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
- #define DEVICE_ATTR_WO(_name) \
- struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
-
-
- bus attr属性宏定义也在device.h
- #define BUS_ATTR(_name, _mode, _show, _store) \
- struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
- #define BUS_ATTR_RW(_name) \
- struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
- #define BUS_ATTR_RO(_name) \
- struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
-
- driver attr定义也在device.h
- #define DRIVER_ATTR(_name, _mode, _show, _store) \
- struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store)
- #define DRIVER_ATTR_RW(_name) \
- struct driver_attribute driver_attr_##_name = __ATTR_RW(_name)
- #define DRIVER_ATTR_RO(_name) \
- struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
- #define DRIVER_ATTR_WO(_name) \
- struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
-
- class attr定义
- #define CLASS_ATTR(_name, _mode, _show, _store) \
- struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)
- #define CLASS_ATTR_RW(_name) \
- struct class_attribute class_attr_##_name = __ATTR_RW(_name)
- #define CLASS_ATTR_RO(_name) \
- struct class_attribute class_attr_##_name = __ATTR_RO(_name)