• linux 模型属性attribute


    属性
    几乎在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,保存属性值。

    1. struct kobj_type {//object type,kobj_type是对kobject的特性描述
    2. void (*release)(struct kobject *kobj);//析构函数指针,指向析构函数,该函数在refcount为0时,清理所有”同类“的kobject并释放内存。
    3. const struct sysfs_ops *sysfs_ops;//指针指向”sysfs读写操作函数结构体“
    4. struct attribute **default_attrs;//描述了属于该ktype的kobject的默认属性
    5. const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
    6. const void *(*namespace)(struct kobject *kobj);
    7. };

    ___________________________________________________________

    属性基类和子类定义结构 整理

    1. struct attribute { //属性的通用结构,普通文件是kobject目录的属性展现
    2. const char *name;
    3. umode_t mode;
    4. #ifdef CONFIG_DEBUG_LOCK_ALLOC
    5. bool ignore_lockdep:1;
    6. struct lock_class_key *key;
    7. struct lock_class_key skey;
    8. #endif
    9. };//基类中没有定义 func方法,在子类中定义
    10. ________________________________________________________________
    11. struct bin_attribute {//二进制属性专门设计的,它在sysfs中表现为二进制文件
    12. struct attribute attr;//基类
    13. size_t size;
    14. void *private;
    15. ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
    16. char *, loff_t, size_t);
    17. ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
    18. char *, loff_t, size_t);
    19. int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
    20. struct vm_area_struct *vma);
    21. };
    22. struct property {//设备树中的是以 二进制属性展现的
    23. char *name;
    24. int length;
    25. void *value;
    26. struct property *next;
    27. unsigned long _flags;
    28. unsigned int unique_id;
    29. struct bin_attribute attr;
    30. };
    31. ——————————————————————————————————————————
    32. /* interface for exporting device attributes */
    33. struct device_attribute {//设备属性
    34. struct attribute attr;
    35. ssize_t (*show)(struct device *dev, struct device_attribute *attr,
    36. char *buf);
    37. ssize_t (*store)(struct device *dev, struct device_attribute *attr,
    38. const char *buf, size_t count);
    39. };
    40. Declaring:
    41. DEVICE_ATTR(_name, _mode, _show, _store);
    42. Creation/Removal:
    43. int device_create_file(struct device *dev, const struct device_attribute * attr);
    44. void device_remove_file(struct device *dev, const struct device_attribute * attr);
    45. ————————————————————————————————————————————————————————————
    46. struct bus_attribute {
    47. struct attribute attr;
    48. ssize_t (*show)(struct bus_type *, char * buf);
    49. ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
    50. };
    51. Declaring:
    52. static BUS_ATTR_RW(name);
    53. static BUS_ATTR_RO(name);
    54. static BUS_ATTR_WO(name);
    55. Creation/Removal:
    56. int bus_create_file(struct bus_type *, struct bus_attribute *);
    57. void bus_remove_file(struct bus_type *, struct bus_attribute *);
    58. ——————————————————————————————————————————
    59. Structure:
    60. struct driver_attribute {
    61. struct attribute attr;
    62. ssize_t (*show)(struct device_driver *, char * buf);
    63. ssize_t (*store)(struct device_driver *, const char * buf,
    64. size_t count);
    65. };
    66. Declaring:
    67. DRIVER_ATTR_RO(_name)
    68. DRIVER_ATTR_RW(_name)
    69. Creation/Removal:
    70. int driver_create_file(struct device_driver *, const struct driver_attribute *);
    71. void driver_remove_file(struct device_driver *, const struct driver_attribute *);
    72. ————————————————————————————————————————
    73. struct freq_attr { //cpu freq attr ---子类
    74. struct attribute attr;---基类
    75. ssize_t (*show)(struct cpufreq_policy *, char *);
    76. ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
    77. };

    属性宏定义大量在内核和驱动中使用到,贴出代码,以查阅方便

    1. 基础在定义 include/linux/sysfs.h
    2. #define __ATTR(_name, _mode, _show, _store) { \
    3. .attr = {.name = __stringify(_name), \
    4. .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
    5. .show = _show, \
    6. .store = _store, \
    7. }
    8. #define __ATTR_PREALLOC(_name, _mode, _show, _store) { \
    9. .attr = {.name = __stringify(_name), \
    10. .mode = SYSFS_PREALLOC | VERIFY_OCTAL_PERMISSIONS(_mode) },\
    11. .show = _show, \
    12. .store = _store, \
    13. }
    14. #define __ATTR_RO(_name) { \
    15. .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \
    16. .show = _name##_show, \
    17. }
    18. #define __ATTR_WO(_name) { \
    19. .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \
    20. .store = _name##_store, \
    21. }
    22. #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
    23. _name##_show, _name##_store)
    24. include/linux/device.h是设备属性宏定义
    25. #define DEVICE_ATTR(_name, _mode, _show, _store) \
    26. struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
    27. #define DEVICE_ATTR_RW(_name) \
    28. struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
    29. #define DEVICE_ATTR_RO(_name) \
    30. struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
    31. #define DEVICE_ATTR_WO(_name) \
    32. struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
    33. bus attr属性宏定义也在device.h
    34. #define BUS_ATTR(_name, _mode, _show, _store) \
    35. struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
    36. #define BUS_ATTR_RW(_name) \
    37. struct bus_attribute bus_attr_##_name = __ATTR_RW(_name)
    38. #define BUS_ATTR_RO(_name) \
    39. struct bus_attribute bus_attr_##_name = __ATTR_RO(_name)
    40. driver attr定义也在device.h
    41. #define DRIVER_ATTR(_name, _mode, _show, _store) \
    42. struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store)
    43. #define DRIVER_ATTR_RW(_name) \
    44. struct driver_attribute driver_attr_##_name = __ATTR_RW(_name)
    45. #define DRIVER_ATTR_RO(_name) \
    46. struct driver_attribute driver_attr_##_name = __ATTR_RO(_name)
    47. #define DRIVER_ATTR_WO(_name) \
    48. struct driver_attribute driver_attr_##_name = __ATTR_WO(_name)
    49. class attr定义
    50. #define CLASS_ATTR(_name, _mode, _show, _store) \
    51. struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store)
    52. #define CLASS_ATTR_RW(_name) \
    53. struct class_attribute class_attr_##_name = __ATTR_RW(_name)
    54. #define CLASS_ATTR_RO(_name) \
    55. struct class_attribute class_attr_##_name = __ATTR_RO(_name)

  • 相关阅读:
    数字IC面试总结,看看你掌握几个?
    Mybatis应用场景之动态传参、两字段查询、用户存在性的判断
    安卓手机抓包配置
    【苹果家庭推iMessage位置推】ActiveMQ先前与AMQ.JS(基于旋转)一起使用
    文件路径操作
    中断向量表概述
    面试整理一
    OpenAI政变背后是科学家创始人的悲歌
    直方图均衡化算法
    软件测试之单元测试自动化入门基础
  • 原文地址:https://blog.csdn.net/xuelin273/article/details/127974583