免费国外网站/网络做推广公司
1. 什么是 sysfs伪文件系统?
sysfs
是 Linux 内核提供的 伪文件系统,用于向用户空间暴露内核对象的信息和控制接口。它是 procfs
的补充,主要用于管理 设备、驱动、内核子系统 等信息,使用户可以通过文件操作(如用户空间中的open函数、write函数、read函数、 cat
命令、echo
命令)与内核交互【对文件的操作其实直接转换为调用相应的内核函数】,而无需编写内核代码。
- 挂载位置:通常挂载在
/sys
目录下。 - 作用:
- 提供系统信息(如 CPU、设备、驱动程序、总线)。
- 提供设备控制接口(如 GPIO、PWM、I2C、SPI 等)。
- 支持热插拔设备管理(如 USB、PCI、SATA 设备)。
sysfs伪文件系统实际上和设备文件很类似,它们都是用户空间与内核空间交互的媒介,不同的是设备文件是内核空间中驱动程序中的概念,而sysfs伪文件系统则是内核空间中别的需要向用户空间暴露的内核对象的信息和控制接口。所以它的使用实际上和设备文件很类似。
在终端中使用sysfs伪文件系统时,表面上我们是在用相关函数或cat
、echo
命令进行读或写相关的文件,实际上会转换为对某个内核函数的调用。具体的例子见本篇博文后面列出的“一个实际的例子分析”
而在程序代码中使用sysfs伪文件系统时,就和操作设备文件差不多。具体的例子见 https://blog.csdn.net/wenhao_ir/article/details/145459006【搜索“led_init(void)”】
2. sysfs 的目录结构
sysfs 目录下的结构主要分为以下几部分:
/sys/├── block/ # 块设备(如磁盘、分区)├── bus/ # 设备总线(如 i2c, usb, spi, pci, platform)├── class/ # 设备类(如 gpio, net, tty, input)├── devices/ # 设备层次结构├── firmware/ # 固件接口├── kernel/ # 内核参数├── module/ # 加载的内核模块└── power/ # 电源管理
3. sysfs 目录详解
(1)/sys/class/
-
组织 设备 按类别分类(如 GPIO、网络、输入设备)。
-
例子:
ls /sys/class/
输出:
gpio/ net/ input/ sound/ thermal/ tty/ usb_device/
-
GPIO 设备(使用 sysfs 方式操作 GPIO)
echo 131 > /sys/class/gpio/export # 申请 GPIO 131 echo out > /sys/class/gpio/gpio131/direction # 设置方向 echo 1 > /sys/class/gpio/gpio131/value # 设为高电平
我后面会对这三句命令作详细解释,其实就是以这三句命令活生生地展现 sysfs 伪文件系统是怎么实现与内核的交互的。
-
网卡信息
ls /sys/class/net/ eth0 lo wlan0
cat /sys/class/net/eth0/address
# 查看 MAC 地址cat /sys/class/net/eth0/statistics/rx_bytes
# 接收的字节数
(2)/sys/bus/
-
组织 设备按总线分类(如 PCI、USB、I2C、SPI)。
-
例子:
ls /sys/bus/
输出:
i2c/ pci/ platform/ scsi/ spi/ usb/
/sys/bus/i2c/devices/
# I2C 设备/sys/bus/usb/devices/
# USB 设备/sys/bus/pci/devices/
# PCI 设备
-
示例:列出所有 USB 设备
ls /sys/bus/usb/devices/
(3)/sys/devices/
-
按 设备拓扑结构 组织设备信息(如
/sys/devices/pci0000:00/0000:00:1f.2/
)。 -
例子:
ls /sys/devices/
system/ virtual/ pci0000:00/
-
查看 CPU 信息
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
(4)/sys/module/
- 显示 已加载的内核模块 及其参数。
- 例子:
ls /sys/module/
cat /sys/module/gpio/parameters/
cat /sys/module/usbcore/parameters/autosuspend
(5)/sys/kernel/
-
提供与 内核相关的配置信息。
-
例子:
ls /sys/kernel/
debug/ security/ tracing/
-
查看系统调试信息
cat /sys/kernel/debug/gpio
4. sysfs 的工作机制
- sysfs 由
kobject
和kset
组成:kobject
代表 内核对象(如设备、驱动)。kset
是kobject
的集合(如devices
、bus
)。
- 设备驱动注册时,sysfs 自动创建目录和文件。
- 用户空间可以通过
cat
、echo
直接访问内核数据。
示例:
设备驱动代码:
static struct class *my_class;
my_class = class_create(THIS_MODULE, "my_device");
device_create(my_class, NULL, MKDEV(200, 0), NULL, "mydev0");
sysfs 生成的目录:
/sys/class/my_device/mydev0/
5. sysfs 的优缺点
优点 | 缺点 |
---|---|
允许用户空间与内核交互 | 只能操作文本,效率低 |
结构清晰,按类别组织 | 不适用于高频操作 |
可用于设备驱动调试 | 已被 libgpiod 等替代 |
6. sysfs 与 udev、procfs 的区别
文件系统 | 作用 | 特点 |
---|---|---|
sysfs (/sys/ ) | 设备、驱动、总线信息 | 设备管理,与 kobject 相关 |
procfs (/proc/ ) | 进程、内核信息 | 进程管理,虚拟文件 |
udev (/dev/ ) | 设备文件 | 动态创建 /dev/ 设备节点 |
7. 结论
- sysfs 是 Linux 设备模型的核心部分,用于暴露设备和驱动信息。
- 用户空间可以直接
cat
读取信息,echo
进行控制,简化了驱动开发。 - sysfs 已逐渐被
libgpiod
、udev
替代,但仍然广泛使用,特别是在嵌入式系统中。
8.一个实际的例子分析
我们可以通过下面的三条命令实现将编号为131的GPIO口(GPIO5_IO03)的值设为逻辑1值,如果GPIO没有被标记为低电平有效,则逻辑1值就是物理上的高电平,否则就是物理上的低电平,在这里,我实测了一下,GPIO5_IO03
并没有被标记为低电平有效。即运行完成后在下面的原理图基础上,灯灭了。
echo 131 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio131/direction
echo 1 > /sys/class/gpio/gpio131/value
这三条命令是通过 sysfs 接口 操作 GPIO 口 131,本质上是用户空间通过 echo
命令向 sysfs 伪文件系统写入数据,触发内核的 GPIO 相关操作【实际上就是去调用内核中的相关GPIO子系统的函数】。
在看下面的分析前可以参考下博文 https://blog.csdn.net/wenhao_ir/article/details/145119224 是如何利用GPIO子系统实现LED灯的驱动的,实际上这篇博文中调用的函数也就是下面三条echo
命令触发的内核函数。
1. echo
命令与 sysfs GPIO 实现的关系
echo
命令的作用是 向文件写入内容,但当目标文件是 sysfs 文件时,写入的值会被内核的 GPIO 处理函数拦截,并执行相应的 GPIO 操作。
下面具体分析你的 echo
命令是如何作用到 GPIO 上的:
(1)导出 GPIO
echo 131 > /sys/class/gpio/export
-
作用:请求使用 GPIO 131,让内核创建
/sys/class/gpio/gpio131/
目录。 -
sysfs 机制:
echo 131 > /sys/class/gpio/export
相当于向export
文件 写入131
。- 内核中的
export_store()
处理该写入,并调用gpio_request(131, NULL)
申请 GPIO 资源。 - 申请成功后,内核会创建
/sys/class/gpio/gpio131/
目录,用于控制 GPIO 131。
-
相关的内核代码(在
drivers/gpio/gpiolib-sysfs.c
中):static ssize_t export_store(struct class *class,struct class_attribute *attr,const char *buf, size_t count) {int gpio;int ret;ret = kstrtoint(buf, 0, &gpio);if (ret)return ret;ret = gpio_request(gpio, NULL);if (ret)return ret;return count; }
(2)设置 GPIO 方向
echo out > /sys/class/gpio/gpio131/direction
-
作用:设置 GPIO 131 为 输出模式。
-
sysfs 机制:
echo out > /sys/class/gpio/gpio131/direction
相当于向direction
文件 写入字符串"out"
。gpio_direction_output(131, 0)
被调用,将 GPIO 131 配置为 输出模式(初始值 0)。- 内核 GPIO 驱动最终会调用
gpio_chip->direction_output()
这个函数,该函数是具体的 GPIO 控制器驱动 提供的,执行底层的寄存器操作,配置 GPIO 方向。
-
相关的内核代码(在
drivers/gpio/gpiolib-sysfs.c
中):static ssize_t direction_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count) {struct gpio_desc *desc = dev_get_drvdata(dev);if (!strncmp(buf, "out", 3))gpiod_direction_output(desc, 0);elsegpiod_direction_input(desc);return count; }
(3)设置 GPIO 输出值
echo 1 > /sys/class/gpio/gpio131/value
-
作用:设置 GPIO 131 输出 高电平(1)。
-
sysfs 机制:
echo 1 > /sys/class/gpio/gpio131/value
向value
文件 写入"1"
。gpio_set_value(131, 1)
被调用,更新 GPIO 131 的输出电平。- 底层驱动(
gpio_chip->set()
)负责具体的寄存器操作,将 GPIO 置高。
-
相关的内核代码(在
drivers/gpio/gpiolib-sysfs.c
中):static ssize_t value_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count) {struct gpio_desc *desc = dev_get_drvdata(dev);int value;if (buf[0] == '0')value = 0;elsevalue = 1;gpiod_set_value(desc, value);return count; }
2. sysfs GPIO 实现的局限
虽然 sysfs 提供了一种 简单的方式 来访问 GPIO,但它有以下局限性:
- 效率低:sysfs 通过文件操作控制 GPIO,比
ioctl
或mmap
慢。 - 无法高效处理中断:sysfs 方式不适合监听 GPIO 变化(如按键)。
- 已被
libgpiod
取代:新版本的 Linux 内核推荐使用libgpiod
(基于ioctl
的 GPIO 操作)。
3. 结论
🔹 sysfs 方式是 Linux 早期的 GPIO 控制方法,echo
命令本质上是向 sysfs 伪文件系统写入数据,触发内核调用 GPIO 操作函数。
🔹 每个 echo
命令最终都会调用 gpiolib
提供的 API,如 gpio_request()
、gpio_direction_output()
和 gpio_set_value()
,再由底层 GPIO 驱动完成实际的硬件操作。
🔹 sysfs 方式简单直观,但不适用于高效 GPIO 访问,现代 Linux 推荐使用 libgpiod
代替 sysfs GPIO
。(实际上在Linux 5.10以上版本中已经把sysfs
这种对GPIO的操作方式废弃了)
比如上面的三条命令等效于下面这条gpiod API
的命令:
gpioset gpiochip0 131=1
相关文章:

Linux 的 sysfs 伪文件系统介绍【用户可以通过文件操作与内核交互(如调用内核函数),而无需编写内核代码】
1. 什么是 sysfs伪文件系统? sysfs 是 Linux 内核提供的 伪文件系统,用于向用户空间暴露内核对象的信息和控制接口。它是 procfs 的补充,主要用于管理 设备、驱动、内核子系统 等信息,使用户可以通过文件操作(如用户空…...

每日一题洛谷P5721 【深基4.例6】数字直角三角形c++
#include<iostream> using namespace std; int main() {int n;cin >> n;int t 1;for (int i 0; i < n; i) {for (int j 0; j < n - i; j) {printf("%02d",t);t;}cout << endl;}return 0; }...

计算机网络笔记再战——理解几个经典的协议1
目录 前言 从协议是什么出发 关于TCP/IP协议体系 几个传输方式的分类 地址 网卡 中继器(Repeater) 网桥(Bridge) 路由器(Router) 网关 前言 笔者最近正在整理(笔者开的坑不少…...

ElasticSearch学习笔记-解析JSON格式的内容
如果需要屏蔽其他项目对Elasticsearch的直接访问操作,统一由一个入口访问操作Elasticsearch,可以考虑直接传入JSON格式语句解析执行。 相关依赖包 <properties><elasticsearch.version>7.9.3</elasticsearch.version><elasticsea…...

浅谈密码相关原理及代码实现
本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时,需自行确保其行为符合所在国家或地区的法律法规。 开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或…...

Spring Boot常用注解深度解析:从入门到精通
今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…...

can not add outlook new accounts on the outlook
link : Reference url...

私有化部署 DeepSeek + Dify,构建你的专属私人 AI 助手
私有化部署 DeepSeek Dify,构建你的专属私人 AI 助手 概述 DeepSeek 是一款开创性的开源大语言模型,凭借其先进的算法架构和反思链能力,为 AI 对话交互带来了革新性的体验。通过私有化部署,你可以充分掌控数据安全和使用安全。…...

【Elasticsearch】post_filter
post_filter是 Elasticsearch 中的一种后置过滤机制,用于在查询执行完成后对结果进行过滤。以下是关于post_filter的详细介绍: 工作原理 • 查询后过滤:post_filter在查询执行完毕后对返回的文档集进行过滤。这意味着所有与查询匹配的文档都…...

验证工具:GVIM和VIM
一、定义与关系 gVim:gVim是Vim的图形界面版本,提供了更多的图形化功能,如菜单栏、工具栏和鼠标支持。它使得Vim的使用更加直观和方便,尤其对于不习惯命令行界面的用户来说。Vim:Vim是一个在命令行界面下运行的文本编…...

如何优化垃圾回收机制?
垃圾回收机制 掌握 GC 算法之前,我们需要先弄清楚 3 个问题。第一,回收发生在哪里?第二,对象在 什么时候可以被回收?第三,如何回收这些对象? 回收发生在哪里? JVM 的内存区域中&…...

beyond the ‘PHYSICAL‘ memory limit.问题处理
Container [pid5616,containerIDcontainer_e50_1734408743176_3027740_01_000006] is running 507887616B beyond the ‘PHYSICAL’ memory limit. Current usage: 4.5 GB of 4 GB physical memory used; 6.6 GB of 8.4 GB virtual memory used. Killing container. 1.增大map…...

Day36【AI思考】-表达式知识体系总览
文章目录 **表达式知识体系总览**回答1:**表达式知识体系****一、三种表达式形式对比****二、表达式转换核心方法****1. 中缀转后缀(重点)****2. 中缀转前缀** **三、表达式计算方法****1. 后缀表达式计算(栈实现)****…...

段错误(Segmentation Fault)调试
1. 使用 GDB(GNU Debugger) GDB 是一个强大的调试工具,可以帮助你逐步执行程序并检查变量状态。 编译时添加调试信息: gcc -g your_program.c -o your_program启动 GDB: gdb ./your_program运行程序: …...

每日Attention学习19——Convolutional Multi-Focal Attention
每日Attention学习19——Convolutional Multi-Focal Attention 模块出处 [ICLR 25 Submission] [link] UltraLightUNet: Rethinking U-shaped Network with Multi-kernel Lightweight Convolutions for Medical Image Segmentation 模块名称 Convolutional Multi-Focal Atte…...

LeetCode题练习与总结:三个数的最大乘积--628
一、题目描述 给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。 示例 1: 输入:nums [1,2,3] 输出:6示例 2: 输入:nums [1,2,3,4] 输出:24示例 3&a…...

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭版系统 带F9 Colorful一键恢复功能
Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭中文版系统 带F9 Colorful一键恢复功能 自动重建COLORFUL RECOVERY功能 带所有随机软件和机型专用驱动 支持机型:隐星P15 TA 24 文件下载:asusoem.cn/745.html 文件格式:ISO 系统版本&…...

第二篇:多模态技术突破——DeepSeek如何重构AI的感知与认知边界
——从跨模态对齐到因果推理的工程化实践 在AI技术从单一模态向多模态跃迁的关键阶段,DeepSeek通过自研的多模态融合框架,在视觉-语言-语音的联合理解与生成领域实现系统性突破。本文将从技术实现层面,解构其跨模态表征学习、动态融合机制与…...

CTreeCtrl 设置图标
mfc界面修改真难受 使用CTreeCtrl 进行设置导航视图时,有时候需要设置图标,一般使用如下代码 m_TreeViewImages.DeleteImageList();UINT uiBmpId IDB_ICONLIST_TREE;CBitmap bmp; if (!bmp.LoadBitmap(uiBmpId)) return;BITMAP bmpObj; bmp.GetBitmap…...

在JAX-RS中获取请求头信息的方法
在JAX-RS中获取请求头信息的方法 HeaderParam注解,可以直接将请求头中的特定值注入到方法参数中,代码示例: import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.core.Response;Path(&q…...

Java 面试之结束问答
技术优化 线程池优化 设置最大线程数设置最小核心线程数设置额外线程存活时间选择线程池队列选择合适的线程池选择合适的饱和策略 锁优化 尽量不要锁住方法缩小同步代码块,只锁数据锁中尽量不要再包含锁将锁私有化,在内部管理锁进行适当的锁分解 HT…...

柔性数组与c/c++程序中内存区域的划分
1.柔性数组 1.1柔性数组的定义 柔性数组是指在结构体中定义的,其大小在编译时未确定,而在运行时动态分配的数组。这种数组允许结构体的大小根据需要动态变化。语法如下: struct D {int a;int arry1[0]; };struct F {int a;int arry2[]; };…...

mini-lsm通关笔记Week2Day7
项目地址:https://github.com/skyzh/mini-lsm 个人实现地址:https://gitee.com/cnyuyang/mini-lsm 在上一章中,您已经构建了一个完整的基于LSM的存储引擎。在本周末,我们将实现存储引擎的一些简单但重要的优化。欢迎来到Mini-LSM的…...

Typora免费使用
一.下载地址 https://typoraio.cn/ 二.修改配置文件 1.找到安装路径下的LicenseIndex.180dd4c7.4da8909c.chunk.js文件 文件路径为:安装路径\resources\page-dist\static\js\LicenseIndex.180dd4c7.4da8909c.chunk.js 将js中的 e.hasActivated"true"e.hasActiva…...

AI驱动的无线定位:基础、标准、最新进展与挑战
1. 论文概述 研究目标:本论文旨在综述AI在无线定位领域的应用,包括其基础理论、标准化进展、最新技术发展,以及面临的挑战和未来研究方向。主要发现: AI/ML 技术已成为提升无线定位精度和鲁棒性的关键手段,特别是在 3GPP 标准的推动下。论文系统性地分析了 AI 在 LOS/NLOS…...

苹果再度砍掉AR眼镜项目?AR真的是伪风口吗?
曾经,AR游戏一度异常火热,宝可梦go让多少人不惜翻墙都要去玩,但是也没过去几年,苹果被曝出再度砍掉了AR眼镜项目,面对着市场的变化,让人不禁想问AR真的是伪风口吗? 一、苹果再度砍掉AR眼镜项目&…...

18 大量数据的异步查询方案
在分布式的应用中分库分表大家都已经熟知了。如果我们的程序中需要做一个模糊查询,那就涉及到跨库搜索的情况,这个时候需要看中间件能不能支持跨库求交集的功能。比如mycat就不支持跨库查询,当然现在mycat也渐渐被摒弃了(没有处理笛卡尔交集的…...

DRM系列八:Drm之DRM_IOCTL_MODE_ADDFB2
本系列文章基于linux 5.15 在上一篇文章DRM系列七:Drm之DRM_IOCTL_MODE_CREATE_DUMB获取buf的handle和pitch之后,接着使用ioctl(fd, DRM_IOCTL_MODE_ADDFB2, &fb_cmd)创建一个新的帧缓冲区对象(framebuffer object),并将帧缓冲区对象与显…...

软件测试用例篇
设计测试用例是测试面试的必考题,务必好好学 1. 测试用例 测试用例的概念 测试⽤例(Test Case)是为了实施测试而向被测试的系统提供的⼀组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素。 设计测试⽤…...

PopupMenuButton组件的功能和用法
文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容,本章回中将介绍PopupMenuButton组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧,…...