如何使用sysfs来排查驱动问题

原理性内容参考:

Linux文件管理源码相关总结-CSDN博客

/sys概览

先看下sys目录内容:

一般就是这些内容,各个系统可能不太一样,我们暂时熟悉一些通用的目录即可。

/sys/devices

这是整个 /sys 里最核心、最真实的目录

/sys/devices 是内核把整个硬件拓扑结构,1:1 映射成文件目录给你看。

它不是按功能分类,而是按 "谁挂在谁下面" 的真实硬件层级展示。

比如:

复制代码
主板 -> 总线 -> 控制器 -> 设备 -> 引脚/时钟/寄存器

在 sysfs 里就是一层层目录。

/sys/devices

  • 真实硬件拓扑
  • 按 "物理连接关系" 组织
  • 驱动开发、硬件排查用

也看下有哪些子目录:

我们主要讲一些重点的通用的,个别不一致的目录可能是不同的系统或者用户自定义的。

逐类拆解:每个目录是什么、从哪来、干嘛用

1. 核心硬件拓扑类(真实物理设备)

目录名 含义 来源 核心用途
platform 平台总线设备根目录 设备树 / 平台设备注册 你之前看的 ff634480.pwmpinctrl@ff634480所有片上外设、平台驱动都在这里,是嵌入式驱动调试的核心目录
system 系统级核心设备 CPU / 内核架构 存放 CPU、时钟、中断控制器、总线等系统核心硬件 ,比如 cpu@0timerinterrupt-controller
armv8_pmuv3 ARMv8 架构性能监控单元(PMU) CPU 内核自带 用于 CPU 性能计数、功耗监控、perf 工具采样,是 ARM 架构的标准硬件调试单元

2. 功能 / 子系统类(按功能分类的设备)

目录名 含义 来源 核心用途
iio:device0 工业 I/O 子系统设备 IIO 驱动 用于传感器(ADC、陀螺仪、温湿度、红外等),你的红外设备如果走 IIO 框架,就会在这里生成设备节点,方便用户态读取数据
virtual 虚拟设备根目录 内核虚拟驱动 存放无物理硬件对应 的虚拟设备,比如 gpiochip(GPIO 控制器虚拟节点)、loop 设备、veth 网卡等

3. 调试 / 追踪类(内核调试工具)

目录名 含义 来源 核心用途
uprobe / breakpoint / kprobe / software / tracepoint 内核追踪 / 探针设备 ftrace/kprobe 子系统 都是 Linux 内核动态追踪(ftrace)的底层设备节点,用于:• kprobe:内核函数探针• uprobe:用户态函数探针• tracepoint:静态追踪点• breakpoint:硬件断点• software:软件事件(如调度、内存)perf、ftrace 工具的底层都依赖这些设备

三、根目录的设计逻辑(为什么这么分?)

核心原则:按「设备类型 + 归属」分层,完全对应 Linux 设备模型

  1. **真实物理硬件 → platform/system/armv8_pmuv3**对应你板子上的真实芯片外设、CPU 核心,是设备的「真身」。
  2. **功能子系统 → iio:device0**按功能归类,方便应用层统一访问,比如所有传感器都走 IIO 框架。
  3. **虚拟设备 → virtual**内核模拟的设备,无物理硬件对应。
  4. 调试工具 → 各类探针目录内核给开发者提供的动态追踪、性能调试接口,属于调试专用。

devices/platform/ (平台总线)

概况

  • 内容CPU 直接寻址 的板载设备(无传统总线)。
    • 嵌入式 / ARM 开发板的绝大多数设备(UART、I2C、SPI、GPIO)
    • x86 主板控制器(RTC、电源管理、温度传感器)
  • 用途:嵌入式开发、底层硬件调试、设备树(DT)相关设备。

你调试驱动 90% 都在 platform 目录里

看下里面的内容:

这些奇怪命名(比如 ff634480.pwmfixed-regulator0)** 到底是怎么来的?

这些名字不是随便起的 ,而是由 设备树(Device Tree) + 内核驱动规则 共同决定的。

我把命名规则总结为 "三大来源",你对照着看就能完全明白:


1. 第一类:地址.编号 形式(最常见)

格式寄存器地址 + 序号例子ff634480.pwmff634480.gpioff634480.ir

怎么来的?

  1. 来自设备树的 reg 属性 :设备树节点里有一段地址,比如 reg = <0x0 0xff634480 0x100>;。内核在加载时,会把这个物理地址作为设备的唯一标识。
  2. 自动追加序号 :如果同一块地址上挂载了多个子设备(比如一个引脚控制器里有 PWM、GPIO 等),内核会自动生成 .0.1.2 这样的编号。

2. 第二类:功能名 + 编号

格式设备类型 + 数字例子fixed-regulator0usbphy0serial0

怎么来的?

  1. 来自设备树的 compatible 兼容字符串 :比如设备树里写了 compatible = "regulator-fixed";,内核就知道这是个固定电压调节器 ,就会把它归类叫 fixed-regulator
  2. 自动计数 :系统中可能有多个固定调节器,内核就按顺序编号 fixed-regulator0fixed-regulator1...

3. 第三类:自定义名字(特殊)

格式任意名字例子aml_wifiblejtagvout

怎么来的?

  1. 来自设备树节点的 labelname :如果设备树节点里明确写了 label = "aml_wifi"; 或者节点名就叫 wifi,内核就会直接用这个名字。
  2. 厂商自定义 :厂商(比如 Amlogic 你用的平台)为了好记,会给设备起特定的名字。

你的截图分析

  • aml_wifi:Amlogic 厂商定制的 WiFi 设备。
  • ble:蓝牙模块。
  • jtag:调试接口。
  • vout:视频输出。

4. 为什么你会看到 waiting_for_supplier

你截图里最后有个 waiting_for_supplier,这其实是设备树依赖关系的显示:

  • 含义 :这个设备正在等待它的供电设备(regulator)准备好。
  • 场景 :比如红外设备(ir)需要 fixed-regulator0 供电,如果电源还没输出,这里就会显示 waiting_for_supplier
  • 解决:这说明你的红外驱动加载了,但是电源还没起来,属于正常启动过程,或者检查一下 regulator 配置。

总结(一句话记住)

这些名字都是 ** 设备树(DTB)** 在启动时,按物理地址、功能类型、厂商命名自动生成的 "身份证"。

  • 地址.编号 = 物理硬件映射
  • 功能名+编号 = 设备功能分类
  • 自定义名 = 设备树节点起的名字

你现在看你的红外设备(假设叫 ir),它应该就在这个列表里,如果没看到,说明设备树可能没生效或者命名被隐藏了。
一些iic spi设备,在devices里面也有吗,一般在哪个子目录下?

一、核心结论:I2C/SPI 设备肯定在 /sys/devices,位置分两种

1. 物理总线视角(真实硬件拓扑,真身目录)

I2C/SPI 是硬件总线控制器 ,设备会挂在对应总线控制器的父目录下,这是设备的「真身」。

典型路径(Amlogic 晶晨平台,和你当前环境完全匹配)

复制代码
# I2C 设备真身路径
/sys/devices/platform/ff805000.i2c/i2c-0/          # 第0路I2C总线
/sys/devices/platform/ff805000.i2c/i2c-1/          # 第1路I2C总线
# 总线下面就是挂在这条总线上的具体I2C设备
/sys/devices/platform/ff805000.i2c/i2c-0/0-0048/   # I2C地址0x48的设备

# SPI 设备真身路径
/sys/devices/platform/ff800000.spi/spi_master/spi0/  # 第0路SPI总线
/sys/devices/platform/ff800000.spi/spi_master/spi0/spi0.0/  # SPI0.0设备(片选0)

命名规则(一眼识别)

  • I2C 总线目录i2c-<总线号>(如 i2c-0i2c-1
  • I2C 设备目录<总线号>-<7位I2C地址>(如 0-0048 = 总线 0,地址 0x48)
  • SPI 总线目录spi_master/spi<总线号>(如 spi_master/spi0
  • SPI 设备目录spi<总线号>.<片选号>(如 spi0.0 = 总线 0,片选 0)

2. 总线视角(软链接,方便统一查看)

内核会在 /sys/bus/ 下生成软链接,指向 /sys/devices 里的真身,方便你按总线分类查看:

复制代码
# I2C 总线视角
/sys/bus/i2c/devices/0-0048 -> ../../devices/platform/ff805000.i2c/i2c-0/0-0048/

# SPI 总线视角
/sys/bus/spi/devices/spi0.0 -> ../../devices/platform/ff800000.spi/spi_master/spi0/spi0.0/

注意:这只是软链接,真实数据都在 /sys/devices,修改属性只改真身目录即可。


二、I2C/SPI 设备在 /sys/devices 里的完整层级(以 Amlogic 为例)

1. I2C 层级结构

复制代码
/sys/devices/
└── platform/
    └── ff805000.i2c/          # I2C控制器(物理地址0xff805000,来自设备树)
        ├── i2c-0/             # 第0路I2C总线
        │   ├── 0-0048/        # 总线0上,地址0x48的I2C设备(真身)
        │   ├── 0-0050/        # 总线0上,地址0x50的I2C设备
        │   └── ...
        └── i2c-1/             # 第1路I2C总线
            └── 1-0060/        # 总线1上,地址0x60的I2C设备

2. SPI 层级结构

复制代码
/sys/devices/
└── platform/
    └── ff800000.spi/          # SPI控制器(物理地址0xff800000,来自设备树)
        └── spi_master/
            ├── spi0/          # 第0路SPI总线
            │   ├── spi0.0/    # SPI0,片选0的设备
            │   ├── spi0.1/    # SPI0,片选1的设备
            │   └── ...
            └── spi1/          # 第1路SPI总线
                └── spi1.0/    # SPI1,片选0的设备

三、怎么快速找到你的 I2C/SPI 设备?(直接复制用的命令)

1. 找所有 I2C 总线和设备

复制代码
# 1. 列出所有I2C总线控制器(看真身)
ls /sys/devices/platform/*i2c*

# 2. 列出所有I2C总线下的设备
ls /sys/devices/platform/*i2c*/i2c-*

# 3. 快速查看所有I2C设备(总线+地址)
ls /sys/bus/i2c/devices/

# 4. 查看某个I2C设备的详细信息(以0-0048为例)
cat /sys/bus/i2c/devices/0-0048/uevent
cat /sys/bus/i2c/devices/0-0048/name

2. 找所有 SPI 总线和设备

复制代码
# 1. 列出所有SPI总线控制器(看真身)
ls /sys/devices/platform/*spi*

# 2. 列出所有SPI总线下的设备
ls /sys/devices/platform/*spi*/spi_master/spi*/spi*.*

# 3. 快速查看所有SPI设备
ls /sys/bus/spi/devices/

# 4. 查看某个SPI设备的详细信息(以spi0.0为例)
cat /sys/bus/spi/devices/spi0.0/uevent
cat /sys/bus/spi/devices/spi0.0/modalias

i2c spi这些是真实总线,platform是虚拟总线,为啥也放在platform下,不是对应不上吗?

这问题问到 Linux 设备模型最精髓的地方 了!你直觉完全没错:I2C、SPI 是真实硬件总线,platform 是虚拟总线 ,但它们确实就应该放在 /sys/devices/platform/ 下面,一点都不矛盾。

我用最清晰、最本质的方式给你讲透,保证你以后再也不晕。


一句话核心结论

I2C/SPI 控制器本身,是挂在 CPU 内部总线(APB/AHB)上的 "片上外设", Linux 对这类无法自动枚举的片上外设,统一用 platform 总线管理。

所以:

  • I2C/SPI 控制器 = platform 设备
  • 挂在 I2C/SPI 上的传感器 = I2C 设备 / SPI 设备

这是两层结构,不是同一层!


两层结构彻底讲清(非常关键)

第一层:I2C/SPI 控制器 是 platform 设备

CPU 内部:

  • I2C 控制器
  • SPI 控制器
  • UART
  • PWM
  • GPIO
  • IR 红外控制器
  • 时钟控制器
  • 电源控制器

它们全都 ** 直接连在 CPU 内部总线(AHB/APB)** 上。

Linux 对这类:

  • 内存映射寄存器(有 reg 属性)
  • 不能自动枚举(不像 PCI/USB 插上去就能发现)
  • 需要设备树描述

统一归类为:platform 设备

所以它们在:

复制代码
/sys/devices/platform/ff805000.i2c
/sys/devices/platform/ff800000.spi

第二层:I2C/SPI 总线上的外设 才是真实 I2C/SPI 设备

比如:

  • 触摸屏
  • 陀螺仪
  • 温湿度传感器
  • 音频 codec
  • 红外传感器

它们真的挂在 I2C/SPI 物理总线上,所以它们的目录在:

复制代码
/sys/devices/platform/ff805000.i2c/i2c-0/0-0048
                                      ↑
                            这才是真实 I2C 设备

结构是:

复制代码
platform(虚拟)
  ↓
I2C 控制器(platform 设备)
  ↓
i2c-0(真实 I2C 总线)
  ↓
0-0048(真实 I2C 设备)

总线控制器 ≠ 总线本身控制器挂在哪层,不影响总线本身类型


为什么 Linux 要这么设计?

因为:

  • ARM / 嵌入式 SoC 内部外设太多
  • 全都接在 AHB/APB 上
  • 没有统一标准枚举方式
  • 只能靠设备树告诉内核 "这里有个控制器"

Linux 为了统一管理,发明了 platform 虚拟总线,专门收纳这类片上控制器。


最终总结(最精炼)

  • I2C/SPI 控制器 是 platform 设备→ 所以在 /sys/devices/platform/xxx.i2c

  • I2C/SPI 总线上的传感器 才是真实 I2C/SPI 设备→ 在 i2c-0/0-0048spi0.0

platform 管的是 "控制器",不是 "总线"。 I2C/SPI 管的是 "外设",不是 "控制器"。

两层完全不冲突,是标准 Linux 模型。
每个目录里面一般有哪些文件?(重点)

进任意一个设备目录,比如:

你会看到固定几样东西:

  • driver → 软链接,指向绑定的驱动(有没有 probe 成功看这个)

  • of_node → 设备树节点(compatible、reg 都在这里)

  • uevent → 设备信息(主次设备号、驱动名)

  • power → 电源管理

  • subsystem → 属于哪个子系统

  • input→ 输入子系统设备节点,说明该设备是输入设备(比如红外遥控器、按键),ls input/ 能看到 event0 等输入节点,对应 /dev/input/eventX,用于调试输入上报

  • 驱动自己创建的属性文件(如 status、enable 等)

devices/system/ (系统核心设备)

概述

  • 内容非外设的核心硬件
    • system/cpu/ :CPU 核心、频率、缓存、在线状态(online 文件)
    • system/node/:NUMA 节点
    • system/clocksource/:时钟源
  • 用途:CPU 性能调试、电源管理、系统监控。

devices/virtual/ (虚拟 / 伪设备)

概述

  • 内容非物理存在 的逻辑设备:
    • virtual/net/lo:本地回环网卡
    • virtual/mem/ :内存设备(null, zero, random
    • virtual/block/loop[0-9]:回环块设备
  • 用途:网络配置、内存设备操作、挂载镜像文件。

/sys/class

按 "功能类" 归类设备

  • 同类设备放一起,不管在哪条总线
  • 比如:gpio pwm tty net block input pinctrl

例:

复制代码
/sys/class/gpio/
/sys/class/pwm/
/sys/class/input/

相对好理解

/sys/bus

总线信息

  • platform、i2c、spi、pci、usb
  • 每个总线下面有:devices drivers

你写 platform 驱动,就在:

复制代码
/sys/bus/platform/devices/
/sys/bus/platform/drivers/

相对好理解

/sys/bus/platform/driversdevices

这两个目录是 Linux platform 总线的核心入口,专门用来管理平台设备和驱动的绑定关系,是嵌入式驱动调试的「黄金入口」。


一、核心定位:两个目录的本质区别

目录 本质 核心作用
/sys/bus/platform/devices/ 所有 platform 设备的软链接集合 按总线视角,统一展示所有平台设备(真身都在 /sys/devices/platform/ 下)
/sys/bus/platform/drivers/ 所有 platform 驱动的目录集合 展示所有已加载的平台驱动,管理驱动与设备的绑定 / 解绑

二、/sys/bus/platform/devices/ 详解

1. 内容本质

里面全是软链接 ,100% 指向 /sys/devices/platform/ 下的真实设备目录,不占用额外空间。比如你截图里的红外设备,会在这里生成一个同名软链接:

plaintext

复制代码
/sys/bus/platform/devices/ff634480.ir -> ../../devices/platform/ff634480.ir/

2. 核心用途

  • 快速遍历所有平台设备 :不用逐层翻 /sys/devices/platform/,直接 ls 就能看到所有平台设备
  • 验证设备是否被内核识别:设备出现在这里 = 设备树加载成功、设备注册成功
  • 批量查看设备状态 :比如 ls /sys/bus/platform/devices/*ir* 快速定位红外设备

3. 常用命令

复制代码
# 列出所有平台设备
ls /sys/bus/platform/devices/

# 快速查找红外相关设备
ls /sys/bus/platform/devices | grep -i ir

# 查看设备的驱动绑定状态(和真身目录完全一致)
ls -l /sys/bus/platform/devices/ff634480.ir/driver

三、/sys/bus/platform/drivers/ 详解

1. 内容本质

里面是每个已加载的 platform 驱动的独立目录,每个目录对应一个内核驱动模块。比如你的红外驱动加载后,会在这里生成:

复制代码
/sys/bus/platform/drivers/ir_driver/

2. 每个驱动目录里的核心文件

进入任意驱动目录(如 ir_driver),会看到标准文件:

  • bind / unbind可写文件,手动绑定 / 解绑设备(调试神器)
  • uevent:驱动的环境变量信息
  • module:软链接,指向 /sys/module/ir_driver/(驱动模块信息)
  • 已绑定的设备软链接:比如 ff634480.ir,说明该驱动已经和这个设备绑定成功

3. 核心用途

  • 验证驱动是否加载成功:驱动目录出现在这里 = 模块已加载、probe 函数执行
  • 手动绑定 / 解绑设备:强制驱动和设备重新匹配,调试驱动加载问题
  • 查看驱动绑定的所有设备ls /sys/bus/platform/drivers/ir_driver/ 直接看到所有绑定的设备

/sys/module

所有内核模块信息 加载后的 .ko 都会在这里出现:

复制代码
/sys/module/xxx_driver/

能看到:

  • 加载状态
  • 参数
  • 引用计数

/sys/firmware

固件 / 设备树相关

复制代码
/sys/firmware/devicetree/base/

可以直接看当前内核用的设备树,检查节点是否存在。

注意,设备树是按层级来的,上层一般是目录,然后逐级往下。

/sys/kernel

内核内部信息,最重要的就是:

复制代码
/sys/kernel/debug/  ← 你刚才问的 debugfs
/sys/kernel/irq/

debugfs参考:

Linux中驱动有问题如何排查(一)-CSDN博客

那irq呢?

/sys/kernel/irq/ 是 Linux sysfs 下用于系统中断(IRQ)信息查询 的标准化目录,提供了比 /proc/interrupts 更结构化、更易于程序解析的中断状态视图。

一、目录结构

/sys/kernel/irq/ 下为 ** 每个有效的中断号(IRQ)** 创建一个子目录,目录名即中断号。

复制代码
/sys/kernel/irq/
├── 0/
├── 1/
├── 4/
├── 32/
└── ... (其他中断号目录)

二、每个中断目录(如 /sys/kernel/irq/32/)下的核心文件

1. actions

  • 内容:逗号分隔的设备名列表,表示该中断被哪些设备占用。
  • 示例eth0, ohci_hcd:usb1
  • 用途:快速定位中断归属。

2. chip_name

  • 内容 :中断控制器名称(如 GIC, IO-APIC, PCI-MSI)。
  • 用途:判断中断类型(硬件总线 / 消息信号中断)。

3. hwirq

  • 内容:硬件层面的原始中断号。
  • 用途:内核中断号(VIRQ)与硬件中断号(HWIRQ)映射关系调试。

4. type

  • 内容 :中断触发方式。
    • edge:边沿触发
    • level:电平触发
  • 用途:驱动 / 硬件中断配置校验。

5. wakeup

  • 内容yesno
  • 用途:标识该中断能否唤醒休眠系统。

6. per_cpu_count/

  • 子目录 :内含 cpu0, cpu1 ... 等文件。
  • 内容 :每个文件记录对应 CPU 核心处理该中断的总次数
  • 用途 :精确分析中断在多核间的分布,定位中断负载不均问题。

三、与 /proc/irq/ 的核心区别

  • /sys/kernel/irq/
    • 定位只读 、结构化、机器友好的状态查询接口。
    • 内容chip_name, hwirq, per_cpu_count 等底层硬件信息。
  • /proc/irq/<IRQ>/
    • 定位可读写 、面向用户的配置与控制接口。
    • 内容smp_affinity (CPU 亲和性), affinity_hint, spurious (伪中断计数)。

四、常用操作示例

复制代码
# 1. 查看中断32的归属设备
cat /sys/kernel/irq/32/actions

# 2. 查看中断32的控制器类型
cat /sys/kernel/irq/32/chip_name

# 3. 查看中断32在各CPU上的计数
cat /sys/kernel/irq/32/per_cpu_count/cpu0
cat /sys/kernel/irq/32/per_cpu_count/cpu1

总结

  • /sys/kernel/irq/中断(硬件信息、统计)。
  • /proc/irq/中断(亲和性、开关)。

/sys/block

/sys/block:块设备的「快捷入口」

1. 本质是什么

/sys/block所有块设备(硬盘、U 盘、SD 卡、eMMC、loop 设备等)的统一视图入口 ,里面全是软链接 ,指向 /sys/devices/ 下对应设备的真实目录。

2. 里面有什么

每个子目录对应一个块设备,比如:

复制代码
/sys/block/
├── sda/       # SATA硬盘 / U盘
├── mmcblk0/   # eMMC / SD卡
├── loop0/     # 回环设备
└── nvme0n1/   # NVMe固态硬盘

每个目录里包含块设备的核心属性:

  • size:设备总大小(扇区数,512 字节 / 扇区)
  • queue/:IO 队列参数(调度器、队列深度、缓存等)
  • dev:主次设备号(major:minor)
  • device/:软链接,指向 /sys/devices/ 下的真实硬件控制器目录

3. 核心用途

  • 快速查看所有块设备 :不用逐层翻 /sys/devices/,直接 ls /sys/block 就能看到所有存储设备
  • 查看块设备参数 :比如 cat /sys/block/sda/size 算硬盘容量,cat /sys/block/sda/queue/scheduler 查看 IO 调度器
  • 调试存储性能:修改队列参数、调整缓存、排查 IO 问题
  • 区分真实硬件 vs 虚拟设备sda/mmcblk0 是真实硬件,loop0 是虚拟回环设备

4. 常用命令

复制代码
# 列出所有块设备
ls /sys/block/

# 查看sda的总容量(扇区数 × 512字节)
cat /sys/block/sda/size

# 查看当前IO调度器
cat /sys/block/sda/queue/scheduler

# 查看设备主次设备号
cat /sys/block/sda/dev

/sys/dev

/sys/dev:设备号的「快捷入口」

1. 本质是什么

/sys/dev按「主次设备号(major:minor)」索引的设备视图入口 ,里面全是软链接 ,指向 /sys/devices/ 下对应设备的真实目录。

2. 里面有什么

按设备号分两级目录:

复制代码
/sys/dev/
├── block/       # 块设备号索引
│   └── 8:0/    # 对应sda(major 8, minor 0)
└── char/        # 字符设备号索引
    └── 1:3/    # 对应/dev/null(major 1, minor 3)

比如 /sys/dev/block/8:0 就是 /sys/block/sda 的软链接,指向同一个真实设备目录。

3. 核心用途

  • 通过设备号快速定位设备 :已知 major:minor,直接找到对应设备
  • 统一管理块 / 字符设备 :块设备在 block/ 子目录,字符设备在 char/ 子目录
  • 调试设备节点 :排查 /dev 下设备文件与真实硬件的对应关系
  • udev 规则开发:udev 会通过这个目录匹配设备号,创建设备文件

4. 常用命令

复制代码
# 查看sda对应的设备号
cat /sys/block/sda/dev
# 输出:8:0

# 通过设备号反向找设备
ls -l /sys/dev/block/8:0
# 输出:../../devices/pci0000:00/14.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda

/sys 到底怎么用

驱动开发时,/sys 到底怎么用?(最实用部分)

我给你列驱动开发天天用的操作

1. 看驱动有没有匹配成功

复制代码
ls /sys/bus/platform/drivers/你的驱动名/

里面有设备名 = 匹配成功

2. 看设备是否存在

复制代码
ls /sys/devices/platform/你的设备名

3. 操作 GPIO(不用写应用,直接调试)

复制代码
cd /sys/class/gpio

echo 100 > export    # 导出GPIO
echo out > direction # 设为输出
echo 1 > value       # 输出高电平

4. 看中断被触发了多少次

复制代码
cat /sys/kernel/irq/45/irq_count

5. 看设备树节点是否生效

复制代码
ls /sys/firmware/devicetree/base/ir@xxx

6. 看引脚配置(pinctrl)

复制代码
cat /sys/kernel/debug/pinctrl/.../pinconf-pins

7. 看时钟是否打开

复制代码
cat /sys/kernel/debug/clk/clk_summary

8. 看设备是否被正确绑定

复制代码
cat /sys/devices/platform/xxx/driver_override

四、/sys 对驱动开发的意义(超级重要)

1. 驱动状态可视化probe 成没成?匹配没匹配?时钟开没开?引脚对不对?不用读 dmesg 大海捞针,直接看 /sys。

2. 不用写应用就能调试硬件GPIO、PWM、LED、REGULATOR 都能直接 echo/cat 调试。

3. 快速定位问题

  • 设备没出现 → 设备树或设备注册问题
  • 驱动目录空 → 匹配失败(compatible 错)
  • gpio 导出失败 → 被占用或引脚复用错

4. 驱动可以自己在 /sys 创建设备属性让应用层读状态、设参数:

复制代码
device_create_file(dev, &dev_attr_xxx);

应用就能:

复制代码
cat /sys/devices/.../xxx

五、最简单总结(你记住这个就够)

/sys 就是内核的 "设备浏览器"。

  • /sys/class → 按功能分类
  • /sys/devices → 真实硬件结构
  • /sys/bus → 总线与驱动匹配
  • /sys/module → 模块信息
  • /sys/kernel/debug → 调试状态

驱动开发时: 看设备、看驱动、看引脚、看时钟、调 GPIO,全部靠 /sys。

相关推荐
丶伯爵式1 小时前
Ubuntu 新装后常用设置
linux·运维·ubuntu
哼?~1 小时前
Socket编程准备
linux·网络
羌俊恩2 小时前
Vim modeline 命令执行漏洞(CVE-2026-34714)修复指导
linux·编辑器·vim·漏洞·cve-2026-34714
wang09072 小时前
Linux性能优化之中断
linux·运维·性能优化
bukeyiwanshui2 小时前
20260410 系统启动原理
linux
huanmieyaoseng10032 小时前
Linux 安装配置 Tomcat超详细2026新(附安装包)
linux·运维·tomcat
charlie1145141912 小时前
嵌入式Linux模块学习——insmod 底层全流程解剖:从用户命令到内核内存
linux·c·嵌入式linux
Bert.Cai2 小时前
Linux cat命令详解
linux·运维
零二年的冬3 小时前
epoll详解
java·linux·开发语言·c++·链表