背景

相关文章:1、sysfs与kobject基类

下面内容基本上参考(有删改):https://blog.csdn.net/qb_2008/article/details/6846412

API

attribute

// include/linux/sysfs.h
#include <linux/sysfs.h>
struct attribute {
/* 属性名称 */
const char *name;
/* 访问权限 */
umode_t mode;
// ...
}; struct attribute_group {
const char *name;
umode_t (*is_visible)(struct kobject *,
struct attribute *, int);
struct attribute **attrs;
struct bin_attribute **bin_attrs;
}; struct bin_attribute {
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);
};

之前说过普通文件是kobject目录的属性展现。

struct attribute:就是属性的通用结构,其它部分在使用时还可以把struct attribute内嵌到更大的属性结构中。

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

struct attribute_group:提供一组属性的集合,这样集中管理attribute与`bin_attribute``更为方便。

静态初始化属性的宏

#define __ATTR(_name, _mode, _show, _store) {               \
.attr = {.name = __stringify(_name), .mode = _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) #define __ATTR_NULL { .attr = { .name = NULL } }

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

属性读写方法sysfs_ops

#include <linux/sysfs.h>
struct sysfs_ops {
/* 读取该 sysfs 文件时该方法被调用 */
ssize_t (*show)(struct kobject *, struct attribute *, char *);
/* 写入该 sysfs 文件时该方法被调用 */
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};

show()方法在读操作时被调用。它会拷贝由attr提供的属性值到buffer指定的缓冲区中,缓冲区大小为PAGE_SIZE字节;在x86体系中,PAGE_SIZE为4096字节。该函数如果执行成功,则将返回实际写入buffer的字节数。如果失败,则返回负的错误码。

store()方法在写操作时调用,它会从buffer中读取size大小的字节,并将其存放如attr表示的属性结构体变量中。缓冲区的大小总是为PAGE_SIZE和更小些。该函数如果执行成功,则将返回实际从buffer中读取的字节数。如果失败,则返回负数的错误码。

工作队列延迟调度

int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner);

sysfs_schedule_callback()会创建一个工作队列,稍后调用func(data)。

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

本来自己无法删除自己,现在可以了。

目录操作

int __must_check sysfs_create_dir(struct kobject *kobj);
void sysfs_remove_dir(struct kobject *kobj); int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
int __must_check sysfs_move_dir(struct kobject *kobj,
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对应的目录下。

属性

通用属性

int __must_check sysfs_create_file(struct kobject *kobj,
const struct attribute *attr);
int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
mode_t mode);
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对应的属性文件。

二进制属性

int __must_check sysfs_create_bin_file(struct kobject *kobj,
struct bin_attribute *attr);
void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);

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

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

批量操作

int __must_check sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp);
int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp);
void sysfs_remove_group(struct kobject *kobj,
const struct attribute_group *grp);
int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
void sysfs_remove_file_from_group(struct kobject *kobj,
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中删除。

阻塞IO

void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
void sysfs_notify_dirent(struct sysfs_dirent *sd);

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

软链接

int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
const char *name);
int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
struct kobject *target,
const char *name);
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的软链接文件。

生命周期管理

struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
const unsigned char *name);
struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
void sysfs_put(struct sysfs_dirent *sd);

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

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

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

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

其他

初始化函数

int __must_check sysfs_init(void);

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

调试

void sysfs_printk_last_file(void);

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

Linux 内核:sysfs 有关的API的更多相关文章

  1. LInux内核分析--使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    实验者:江军 ID:fuchen1994 实验描述: 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3 ...

  2. Linux内核 GPIO操作部分API

    内核中关于GPIO的操作API主要集中在<linux/of_gpio.h>和<linux/gpio.h>中,前者主要是GPIO直接与设备树相关的操作,在Linux 设备树操作A ...

  3. linux内核sysfs详解【转】

    转自:http://blog.csdn.net/skyflying2012/article/details/11783847 "sysfs is a ram-based filesystem ...

  4. Linux 内核sysfs 文件系统符号连接

    sysfs 文件系统有通常的树结构, 反映它代表的 kobjects 的层次组织. 但是内核中对象 间的关系常常比那个更加复杂. 例如, 一个 sysfs 子树 (/sys/devices )代表所有 ...

  5. 20135239 益西拉姆 linux内核分析 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    https://drive.wps.cn/preview#l/759e32d65654419cb765da932cdf5cdc 本次直接在wps上写的,因为不能连同图片一起粘贴过来,一个一个粘比较费时 ...

  6. Linux内核kobject结构体分析

    1.前言 Linux内核中有大量的驱动,而这些驱动往往具有类似的结构,根据面向对象的思想,可以将共同的部分提取为父类,而这个父类就是kobject,kobject结构体中包含了大量设备的必须信息,而三 ...

  7. 芯灵思Sinlinx A64开发板Linux内核定时器编程

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 Linux 内核定时器是内 ...

  8. 全志A33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  9. 芯灵思SinlinxA33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  10. Linux内核驱动之GPIO子系统API接口概述

    1.前言 在嵌入式Linux开发中,对嵌入式SoC中的GPIO进行控制非常重要,Linux内核中提供了GPIO子系统,驱动开发者在驱动代码中使用GPIO子系统提供的API函数,便可以达到对GPIO控制 ...

随机推荐

  1. github只下载某个文件或文件夹(使用GitZip插件)

    安装GitZip插件 (此安装过程需要梯子(不懂"梯子",百度一下就明白)) 1. 打开插件管理页面 方法一:打开Chrome浏览器(Edge浏览器同理),在Chrom地址栏输入c ...

  2. 004—Orcad创建简单分裂元件

    004-Orcad创建简单分裂元件 以TPS545为例,先查看datasheet,管脚图,PCB封装.新建库,设置名称和part的数量,然后添加管脚,设定管脚属性.电源管脚要勾选Pin Visble. ...

  3. VSCode+VUE+ESLint以达到保存自动格式化

    首先打开VSCode在.eslintrc.js中加入以下代码(不知道怎么找可以ctrl+shift+p进行搜索),添加 vscode 终端启动服务 // 添加⾃定义规则 'prettier/prett ...

  4. python 简明笔记

    python 简明笔记 基础内置类型 数值类型 字面量 3.14e-10 3.14E-10 3.14e+10 #八进制 0o123 #十六进制 0xabf #二进制 0b10101 #进制转换函数 # ...

  5. GitHub总是打不开

    终极解决方案 http://tool.chinaz.com/dns?type=1&host=github.com&ip= github.com vim /etc/hosts 添加下面内 ...

  6. keepalived(3)- keepalived+nginx实现WEB负载均衡高可用集群

    目录 1. keepalived+nginx实现WEB负载均衡高可用集群 1.1 需求和环境描述 1.2 WEB集群部署 1.3 负载均衡集群部署 1.4 keepalived部署 1.5 测试监控的 ...

  7. postgresql 主键id配序列

    一.手动创建序列 1.表格id字段,设置主键(PRIMARY KEY),类型为int4 2.创建序列 CREATE SEQUENCE public.moni_wzhour_warn_id_seq IN ...

  8. AIRIOT物联网低代码平台如何配置三菱PLC驱动?

    三菱PLC驱动配置使用三菱Melsec协议(MC协议)从三菱PLC读取数据,仅支持以太网方式.三菱PLC都可以通过此协议访问,但是需要对PLC进行设置. AIRIOT物联网低代码平台如何配置三菱PLC ...

  9. 如何部署ASP.NET Core到Linux服务器

    如何部署ASP.NET Core 到Linux服务器 我们开发的最终目的,是将开发后的东西发布网络上,以便自己及其他人使用. 本篇博客介绍如果在 linux 上部署 ASP.NET Core应用,使用 ...

  10. 自定义Naive UI的数据表格Data Table中按钮Button图标

    在Naive UI官网中详细介绍了[数据表格 Data Table](数据表格 Data Table - Naive UI)的使用方式 { title: "Action", key ...