sysfs是用于表现设备驱动模型的文件系统,它基于ramfs。要学习linux的设备驱动模型,就要先做好底层工作,总结sysfs提供给外界的API就是其中之一。sysfs文件系统中提供了四类文件的创建与管理,分别是目录、普通文件、软链接文件、二进制文件。目录层次往往代表着设备驱动模型的结构,软链接文件则代表着不同部分间的关系。比如某个设备的目录只出现在/sys/devices下,其它地方涉及到它时只好用软链接文件链接过去,保持了设备唯一的实例。而普通文件和二进制文件往往代表了设备的属性,读写这些文件需要调用相应的属性读写。

sysfs是表现设备驱动模型的文件系统,它的目录层次实际反映的是对象的层次。为了配合这种目录,linux专门提供了两个结构作为sysfs的骨架,它们就是struct kobject和struct kset。我们知道,sysfs是完全虚拟的,它的每个目录其实都对应着一个kobject,要想知道这个目录下有哪些子目录,就要用到kset。从面向对象的角度来讲,kset继承了kobject的功能,既可以表示sysfs中的一个目录,还可以包含下层目录。对于kobject和kset,会在其它文章中专门分析到,这里简单描述只是为了更好地介绍sysfs提供的API。

sysfs模块提供给外界的接口完全展现在include/linux/sysfs.h中。

[cpp] view plaincopyprint?
  1. struct attribute {
  2. const char      *name;
  3. struct module       *owner;
  4. mode_t          mode;
  5. };
  6. struct attribute_group {
  7. const char      *name;
  8. mode_t          (*is_visible)(struct kobject *,
  9. struct attribute *, int);
  10. struct attribute    **attrs;
  11. };

之前说过普通文件是kobject目录的属性展现。struct attribute就是属性的通用结构,其它部分在使用时还可以把struct attribute内嵌到更大的属性结构中。struct attribute_group是提供一组属性的集合,这样集中的管理更为方便。

[cpp] view plaincopyprint?
  1. #define __ATTR(_name,_mode,_show,_store) { \
  2. .attr = {.name = __stringify(_name), .mode = _mode },   \
  3. .show   = _show,                    \
  4. .store  = _store,                   \
  5. }
  6. #define __ATTR_RO(_name) { \
  7. .attr   = { .name = __stringify(_name), .mode = 0444 }, \
  8. .show   = _name##_show,                 \
  9. }
  10. #define __ATTR_NULL { .attr = { .name = NULL } }
  11. #define attr_name(_attr) (_attr).attr.name

以上的宏是为了静态初始化属性时更为方便,我们简单将其忽略。

[cpp] view plaincopyprint?
  1. struct bin_attribute {
  2. struct attribute    attr;
  3. size_t          size;
  4. void            *private;
  5. ssize_t (*read)(struct kobject *, struct bin_attribute *,
  6. char *, loff_t, size_t);
  7. ssize_t (*write)(struct kobject *, struct bin_attribute *,
  8. char *, loff_t, size_t);
  9. int (*mmap)(struct kobject *, struct bin_attribute *attr,
  10. struct vm_area_struct *vma);
  11. };

struct attribute是通用的属性结构,而struct bin_attribute就是为二进制属性专门设计的,它在sysfs中表现为二进制文件,大多数是设备配置参数的映射。struct bin_attribute恰恰就是把struct attribute内嵌到更大结构的样例。

[cpp] view plaincopyprint?
  1. struct sysfs_ops {
  2. ssize_t (*show)(struct kobject *, struct attribute *,char *);
  3. ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
  4. };

struct sysfs_ops中包含show和store两个函数指针,它们分别在sysfs文件读和文件写时调用。

[cpp] view plaincopyprint?
  1. int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
  2. void *data, struct module *owner);

sysfs_schedule_callback()会创建一个工作队列,稍后调用func(data)。本来sysfs中的属性读写函数是无法删除属性文件或者kobject目录的,因为调用函数时是加锁的,要删除也需要加锁。但这里可以通过工作队列回调的方式实现。

[cpp] view plaincopyprint?
  1. int __must_check sysfs_create_dir(struct kobject *kobj);
  2. void sysfs_remove_dir(struct kobject *kobj);
  3. int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
  4. int __must_check sysfs_move_dir(struct kobject *kobj,
  5. struct kobject *new_parent_kobj);

sysfs_create_dir()创建一个kobject对应的目录,目录名就是kobj->name。

sysfs_remove_dir()删除kobj对应的目录。删除一个目录也会相应地删除目录下的文件及子目录。

sysfs_rename_dir()修改kobj对应目录的名称。

sysfs_move_dir()将kobj对应的目录移到new_parent_kobj对应的目录下。

[cpp] view plaincopyprint?
  1. int __must_check sysfs_create_file(struct kobject *kobj,
  2. const struct attribute *attr);
  3. int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
  4. mode_t mode);
  5. void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);

sysfs_create_file()在kobj对应的目录下创建attr对应的属性文件。

sysfs_chmod_file()修改attr对应的属性文件的读写权限。

sysfs_remove_file()在kobj对应的目录下删除attr对应的属性文件。

[cpp] view plaincopyprint?
  1. int __must_check sysfs_create_bin_file(struct kobject *kobj,
  2. struct bin_attribute *attr);
  3. void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);

sysfs_create_bin_file()在kobj目录下创建attr对应的二进制属性文件。

sysfs_remove_bin_file()在kobj目录下删除attr对应的二进制属性文件。

[cpp] view plaincopyprint?
  1. int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
  2. const char *name);
  3. int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
  4. struct kobject *target,
  5. const char *name);
  6. void sysfs_remove_link(struct kobject *kobj, const char *name);

sysfs_create_link()在kobj目录下创建指向target目录的软链接,name为软链接文件名称。

sysfs_create_link_nowarn()与sysfs_create_link()功能相同,只是在软链接文件已存在时不会出现警告。

sysfs_remove_link()删除kobj目录下名为name的软链接文件。

[cpp] view plaincopyprint?
  1. int __must_check sysfs_create_group(struct kobject *kobj,
  2. const struct attribute_group *grp);
  3. int sysfs_update_group(struct kobject *kobj,
  4. const struct attribute_group *grp);
  5. void sysfs_remove_group(struct kobject *kobj,
  6. const struct attribute_group *grp);
  7. int sysfs_add_file_to_group(struct kobject *kobj,
  8. const struct attribute *attr, const char *group);
  9. void sysfs_remove_file_from_group(struct kobject *kobj,
  10. const struct attribute *attr, const char *group);

sysfs_create_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。如果文件已存在,会报错。

sysfs_update_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。文件已存在也不会报错。sysfs_update_group()也用于group改动影响到文件显示时调用。

sysfs_remove_group()在kobj目录下删除一个属性集合,并删除集合中的属性文件。

sysfs_add_file_to_group()将一个属性attr加入kobj目录下已存在的的属性集合group。

sysfs_remove_file_from_group()将属性attr从kobj目录下的属性集合group中删除。

[cpp] view plaincopyprint?
  1. void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
  2. void sysfs_notify_dirent(struct sysfs_dirent *sd);

sysfs_notify()和sysfs_notify_dirent()都是用来唤醒在属性文件上调用select()或poll()而阻塞的用户进程。

[cpp] view plaincopyprint?
  1. struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
  2. const unsigned char *name);
  3. struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
  4. void sysfs_put(struct sysfs_dirent *sd);

sysfs_get()增加目录或文件的引用计数。

sysfs_put()减少目录或文件的引用计数,并在降为零时删除相应的文件或目录,这种删除又会减少上层目录的引用计数。

sysfs_get_dirent()是增加目录parent_sd中名为name的目录或文件的引用计数。

虽然同样是引用计数,同样在降为零时有删除动作,但却并非使用kref。这种操作更多地继承了文件系统管理时的传统。

[cpp] view plaincopyprint?
  1. void sysfs_printk_last_file(void);
  2. int __must_check sysfs_init(void);

sysfs_printk_last_file()是在sysfs崩溃时打印最后一个访问到的文件路径。

sysfs_init()是在sysfs模块初始化时调用的。

这两个函数都与我们没有什么关系。

sysfs API总结相关推荐

  1. linux下的gpio转串口驱动,X-026-KERNEL-Linux gpio driver的移植之gpio range

    X-026-KERNEL-Linux gpio driver的移植之gpio range 作者:wowo 发布于:2017-9-27 22:27 分类:X Project 1. 前言 我们在[1][2 ...

  2. 编译linux内核3.0系统出现的警告信息(原创)

    编译linux内核3.0系统出现的警告信息(原创) 余超   yuchao86@gmail.com [yuchao@yuchao-Latitude-E5410 linux-3.0]$gcc --ver ...

  3. linux cpufreq framework(3)_cpufreq core

    1. 前言 前文(Linux cpufreq framework(2)_cpufreq driver)从平台驱动工程师的角度,简单的介绍了编写一个cpufreq driver的大概步骤.但要更深入理解 ...

  4. sata3.0 linux内核,编译Linux内核3.0系统出现的警告信息

    [www.linuxidc.com @linux linux-3.0]$gcc --version gcc (GCC) 4.6.1 Copyright © 2011 Free Software Fou ...

  5. 【Linux kernel/cpufreq】framework ----big Little driver

    Linux kernel支持ARM big·Lttile框架的解决方案 一般ARM SOC包含能效和性能两个cluster,共8个 core,可以把这8个core统统开放给kernel,让kernel ...

  6. <Linux> Linux Power Management Overview

    Overview Generic PM 传统意义上的Power Management,如Power On/Off, Restart, Suspend to RAM/Disk等. Clock Frame ...

  7. GPIO及中断API函数

    #include <linux/gpio.h> // 标准 GPIO_API    int gpio_request(unsigned gpio, const char *label); ...

  8. 【Python7】csv/excel/matplotlib,排序/树遍历,线/进程,文件/xml操作,百度人脸API,aiohttp/hal/restful/curl

    文章目录 1.csv 2.excel 3.matplotlib 4.时间复杂度 5.顺序表/链表 6.六种排序 6.1 选择 6.2 插入 6.3 希尔 6.4 冒泡 6.5 快排 6.6 归并 7. ...

  9. linux 内核设备管理模型sysfs(进阶篇)

    <linux 内核设备管理模型sysfs(入门篇)>讲述了内核设备管理模型sysfs的基础管理单元kobject和kset,但是在实际过程中很少有驱动工程师有机会直接操作上述结构,linu ...

最新文章

  1. bmaplib vue 调用_Vue-cli3/4中使用AMap、BMap
  2. SSM项目搭建一(终)
  3. 三角形周长最短问题_谈“最短”
  4. 03_Android项目中读写文本文件的代码
  5. 计算机网络实验中S1是啥意思,某计算机A需要访问域名www.yy.com,它首先向本域DNS服务器S1查询,.._简答题试题答案...
  6. 用Python分析了20万场吃鸡数据,有不少有趣的发现
  7. 第十八期:闲鱼上哪些商品抢手?Python分析后告诉你
  8. 用python写WordCount的MapReduce代码
  9. Qt 学习之路 2 --- 读书笔记
  10. 【论文概述】AVOD (2018)
  11. 计算机数字雨教程视频,股票配资火爆cmd什么意思(cmd命令数字雨)
  12. 通过DSP采集AD7606的转换结果
  13. 优酷发布2018世界杯战略 视频云将提供全程技术保障
  14. 还在为微信朋友圈的大量广告而苦恼吗?一文教你如何清除微信朋友圈的广告!!!
  15. ffmpeg 实现音频aac编码
  16. 麦克风阵列matlab,matlab关于麦克风阵列仿真的问题
  17. java获取前五分钟时间,java计算下一个整5分钟时间点
  18. 【开源项目】X-TRACK源码分析
  19. 【展讯】安卓修改音量等级曲线
  20. net slim 分割_如何用TensorFlow和TF-Slim实现图像标注、分类与分割

热门文章

  1. 徐州事业单位计算机软件类,徐州计算机办公应用软件
  2. python 任务调度 celery_python任务调度模块celery(二)
  3. 返回值类型与函数类型不匹配_golang基础语法,定义函数类型 为已存在的数据类型起别名...
  4. java bidi_Java Bidi createLineBidi()用法及代码示例
  5. python中比较重要的几个函数_【python】python re模块中几个比较重要的函数
  6. oracle的catalog,Oracle Rman Catalog的创建方法和备份原理
  7. java创建数组大小为n_如何通过提供大小在Kotlin中创建一个像Java一样的数组?
  8. java的static块执行时机
  9. “有一个产品经理的女朋友是什么体验?”
  10. 最好用的 Python 虚拟环境,没有之一