当前位置: 首页 > news >正文

理解字符设备、设备模型与子系统:以 i.MX8MP 平台为例

视频教程请关注 B 站:“嵌入式 Jerry”


Linux 内核驱动开发中,很多人在接触字符设备(char device)、设备模型(device model)和各种子系统(subsystem)时,往往会感到概念混杂,边界模糊。本文将从 Linux 驱动体系架构的演化入手,结合 NXP 的 i.MX 8M Plus EVK 平台(下文简称 i.MX8MP-EVK),深入讲解这三者的关系、用途与实际代码的融合方式,帮助你彻底理解这些核心概念。


在这里插入图片描述

一、历史与基础概念

1.1 字符设备(Character Device)

字符设备是 Linux 设备类型之一,另一种是块设备(Block Device)。字符设备以字节为单位进行读写,接口类似于普通文件,通过 read()write()ioctl() 等系统调用进行操作。

  • 常见字符设备:串口(serial)、GPIO、I2C、PWM、Watchdog 等。
  • 管理结构:主要由 struct file_operationsstruct cdev 控制,最终通过 register_chrdev_region()cdev_add() 注册到系统。

1.2 设备模型(Device Model)

Linux 为了实现设备与驱动的自动匹配、热插拔管理、sysfs 显示,设计了一套统一的设备模型架构,包括以下关键结构:

  • struct device
  • struct driver
  • struct bus_type
  • struct class

这套模型抽象了“设备是如何插到系统里的、驱动如何找到设备、如何在用户空间体现出设备结构”等问题。

设备模型的意义在于:“它是一种运行时的驱动与设备匹配与管理框架”。

1.3 子系统(Subsystem)

“子系统”是指内核中具有统一接口规范的功能模块,例如:

  • I2C 子系统
  • SPI 子系统
  • PWM 子系统
  • regulator 子系统
  • input 子系统
  • sound 子系统

每个子系统背后都有一个核心的框架代码,并暴露出标准接口(如 struct pwm_chipstruct i2c_driver 等),驱动开发者按照接口标准进行设备适配即可。

子系统的意义在于:“统一了设备驱动的行为规范和上层调用方式,是设备模型的具体实现与应用场景”。


二、三者关系的准确理解

我们通过一个类比来帮助你理解三者关系:

类别类比解释实际作用
字符设备老式收音机,直接接电可用最基本的驱动编程方式
设备模型家庭电网管理系统让每台收音机能统一开关、统一命名、自动识别
子系统不同的电台频道系统(如 FM/AM)为收音机统一音频标准接口、设置方法等

正确理解:

  • 设备模型并不是“设备驱动的替代品”,而是驱动与设备的匹配系统。
  • 字符设备可裸用,也可嵌入子系统内部。
  • 子系统是专用领域的模型扩展,基于设备模型构建的统一抽象。

三、实战解析:以 i.MX8MP 的 PWM 驱动为例

NXP 的 pwm-imx27 驱动是一个非常典型的子系统 + 设备模型驱动的代表。下面我们从设备树、驱动代码到字符接口逐步解析。

3.1 设备树定义(设备描述)

arch/arm64/boot/dts/freescale/imx8mp-evk.dts 中:

&pwm1 {pinctrl-names = "default";pinctrl-0 = <&pinctrl_pwm1>;status = "okay";
};

说明:pwm1 控制器启用,绑定了特定管脚。

3.2 驱动注册过程(platform_device + pwm_chip)

驱动源码文件:drivers/pwm/pwm-imx27.c

注册入口:

static struct platform_driver imx_pwm_driver = {.driver = {.name = "pwm-imx27",.of_match_table = pwm_imx27_dt_ids,},.probe = pwm_imx27_probe,
};
module_platform_driver(imx_pwm_driver);

核心结构:

struct pwm_imx27_chip {struct pwm_chip chip; // 属于PWM子系统的驱动注册入口...
};

pwm_chip 是子系统定义的结构体,其 ops 字段中定义了 .apply.get_state 等操作接口。

然后调用:

return devm_pwmchip_add(&pdev->dev, &imx->chip);

此函数实际上完成了驱动注册到子系统 + 注册 sysfs 接口 + device model 挂载等多个功能。

3.3 sysfs 与字符设备的区别

尽管 pwm-imx27 没有 register_chrdevcdev_add,但它通过子系统自动创建了 sysfs 接口,例如:

/sys/class/pwm/pwmchip0/

这意味着控制 PWM 不再依赖传统字符设备节点 /dev/pwm0,而是通过标准 pwm 子系统提供的统一 sysfs 文件操作。


四、对比分析:没有子系统的字符设备

若驱动不走子系统,例如传统的 LED 控制驱动,则需要手动注册字符设备:

register_chrdev_region();
cdev_init();
cdev_add();

并创建 /dev/xxx 节点,再通过 open/read/write/ioctl 实现访问。

优缺点对比

特性传统字符设备子系统驱动(如 PWM)
注册方式register_chrdev + cdevpwmchip_add 等
用户访问方式/dev/xxxsysfs + standard API
是否自动匹配设备
是否统一接口
开发复杂度中等略高(但标准)

五、设备模型:驱动背后的系统机制

Linux 驱动之所以能做到自动识别设备、按需加载驱动,靠的就是设备模型架构。

5.1 总线(bus_type)

  • platform 总线:用于板载设备(PWM、I2C、SPI)
  • usb 总线:用于外设热插拔设备
  • pci 总线:用于 PC 设备识别与枚举

所有子系统最终都依赖某种 bus 类型与设备模型框架。

5.2 匹配过程(match)

设备模型按照:

  • .of_match_table(设备树匹配)
  • .id_table(非设备树匹配)

来完成 devicedriver 的自动匹配与调用 probe。


六、结语与建议

6.1 学习建议

  • 新手建议从字符设备入手,理解基础接口。
  • 进阶阶段要深入了解设备模型与 sysfs 接口。
  • 若目标是嵌入式设备驱动,应熟练掌握子系统开发接口(如 I2C/SPI/PWM 等子系统结构)。

6.2 总结结构图

           +------------------------+|     用户空间接口       |+------------------------+↑+-------------------------+|     sysfs / /dev 节点    |+-------------------------+↑+----------------------------+|  子系统接口(如 PWM/SPI)   |+----------------------------+↑+---------------------------+|  设备模型(device model) |+---------------------------+↑+--------------------------+|   platform/PCI/... bus   |+--------------------------+

附录:i.MX8MP 平台相关驱动推荐阅读

  • drivers/pwm/pwm-imx27.c:PWM 控制器驱动
  • drivers/regulator/pca9450-regulator.c:PMIC 驱动
  • drivers/i2c/busses/i2c-imx.c:I2C 控制器驱动

视频教程请关注 B 站:“嵌入式 Jerry”

相关文章:

  • Redis的数据持久化是怎么做的?
  • 飞算 JavaAI 与 Spring Boot:如何实现微服务开发效率翻倍?
  • dolphinscheduler实现(oracle-hdfs-doris)数据ETL
  • 多态以及多态底层的实现原理
  • 【Dart语言】八、并发
  • 《C++ 模板:泛型编程的核心》
  • 【无人机】使用扩展卡尔曼滤波 (EKF) 算法来处理传感器测量,各传感器的参数设置,高度数据融合、不同传感器融合模式
  • 第十五届蓝桥杯 2024 C/C++组 下一次相遇
  • 逻辑回归:损失和正则化技术的深入研究
  • Git分支管理方案
  • 【Git】Git Revert 命令详解
  • 【springsecurity oauth2授权中心】jwt令牌更换成自省令牌 OpaqueToken P4
  • 前端频繁调用后端接口问题思考
  • 转型探讨:未来投资与布局
  • qt.tlsbackend.ossl: Failed to load libssl/libcrypto.
  • 【springsecurity oauth2授权中心】将硬编码的参数提出来放到 application.yml 里 P3
  • OpenCV --- 图像预处理(六)
  • 25、简述.NET程序集(Assembly)
  • JavaFX实战:从零打造一个功能丰富的“猜数字”游戏
  • ASP.Net Web Api如何更改URL
  • 南国置业:控股股东电建地产拟受让公司持有的房地产开发业务等相关资产和负债
  • 迎接神十九乘组回家,东风着陆场各项工作已准备就绪
  • 北京画院上海“点画”:评论家展场一对一评点
  • 龙头券商哪家强:中信去年营收领跑,中金净利下滑
  • 舞剧《百合花》7月绽放,王安忆:这是送给母亲的一份礼物
  • 甘肃省政府原副省长赵金云严重职务违法被开除公职