07、PWM 子系统框架
PWM子系统的架构分为四个清晰的层级,从上到下分别是:
用户空间
这是应用程序运行的区域,用户通过这里直接与PWM功能交互。内核空间
这一层包含三个核心模块:- 设备驱动层:直接控制硬件设备,将软件指令转化为具体操作。
- 核心层:作为中间管理者,协调不同驱动层的协作。
- 适配器驱动层:负责连接不同硬件接口或总线,适配不同设备需求。
硬件层
最底层是实际的PWM硬件设备,如芯片或电路模块。
简单来说:用户程序通过上层调用→内核空间三层协作处理→最终驱动底层硬件工作。
一、驱动文件
最重要的文件:
- pwm-rockchip.c
- core.c
- sysfs.c
对应功能宏控:
obj-$(CONFIG_PWM) += core.o
obj-$(CONFIG_PWM_SYSFS) += sysfs.o
obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
2
3
二、结构体抽象
以下是更直白简洁的解释:
2.1 PWM控制器(pwm_chip)
作用:struct pwm_chip
是管理一个PWM控制器的结构体,负责将硬件PWM功能封装成通用接口,方便系统调用。
核心功能:
- 提供硬件操作函数(如初始化、开关PWM等)。
- 隐藏硬件细节,统一接口。
- 存储控制器配置信息。
关键字段:
struct pwm_chip {
struct device *dev; // 对应的设备
const struct pwm_ops *ops; // 硬件操作函数集合(如enable/disable)
int base; // 该控制器管理的PWM起始编号
unsigned int npwm; // PWM通道总数
struct pwm_device *pwms; // 管理的所有PWM设备列表
// 其他字段用于设备树解析
};
2
3
4
5
6
7
8
2.2 PWM通道(pwm_device)
作用:struct pwm_device
是具体的PWM设备实例,对应一个硬件PWM通道,是用户操作PWM的接口。
核心功能:
- 存储设备名称、状态、硬件通道号等信息。
- 关联到对应的PWM控制器(pwm_chip)。
- 存储配置参数和实时状态。
关键字段:
struct pwm_device {
const char *label; // 设备名称(如"pwm-0")
unsigned int hwpwm; // 硬件通道编号(如通道0、通道1)
struct pwm_chip *chip; // 对应的控制器
struct pwm_args args; // 用户传入的参数(周期、极性)
struct pwm_state state; // 当前运行状态(周期、占空比等)
};
2
3
4
5
6
7
2.3 参数传递(pwm_args)
作用:struct pwm_args
用于传递PWM的初始配置参数。
核心功能:
- 存储用户设置的PWM周期和极性。
- 常用于设备树配置或系统接口(如sysfs)。
关键字段:
struct pwm_args {
u64 period; // PWM周期(纳秒,如1000000ns=1ms)
enum pwm_polarity polarity; // 极性:高电平有效(PWM_POLARITY_NORMAL)或低电平有效(PWM_POLARITY_INVERTED)
};
2
3
4
2.4 当前状态(pwm_state)
作用:struct pwm_state
记录PWM的实时运行状态。
核心功能:
- 存储周期、占空比、极性等关键参数。
- 标记PWM是否启用。
关键字段:
struct pwm_state {
u64 period; // 当前周期(纳秒)
u64 duty_cycle; // 占空比(纳秒,如period=1ms,duty_cycle=500000ns则占空比50%)
enum pwm_polarity polarity; // 当前极性
bool enabled; // 是否启用(true=开启,false=关闭)
};
2
3
4
5
6
:::
总结关系
pwm_chip:管理整个PWM控制器(如管理多个通道)。
pwm_device:对应一个硬件通道,是用户直接操作的PWM设备。
pwm_args:用户传入的参数(如设置周期)。
pwm_state:记录当前运行的PWM参数和状态。
简单来说:
控制器(pwm_chip)管理多个通道(pwm_device),通道通过参数(pwm_args)配置,最终状态保存在(pwm_state)中。 :::
三、PWM 核心层 :core.c
Linux内核的PWM核心模块就像中间桥梁,连接着上层应用和底层硬件控制器。它的工作方式很简单:
- 设备管理
PWM核心通过一个统一的结构体(pwm_device)来记录每个PWM设备的信息,比如设备名称、所属的控制器等。这样上层应用(比如驱动程序或用户程序)只需要通过这个标准化的接口,就能方便地操作所有PWM设备,不需要关心底层硬件差异。 - 参数设置
当需要调整PWM参数时,比如设置周期、占空比或高低电平顺序,上层只需调用pwm_config接口。这个接口会把用户设定的参数转换成底层硬件能识别的格式,然后交给对应的控制器驱动去具体执行设置。 - 开关控制
要开启或关闭PWM信号输出时,上层调用pwm_enable或pwm_disable函数。核心模块会直接通知底层硬件驱动,让对应的PWM通道真正开始或停止发送脉冲信号。
::: 简单来说:
硬件厂商只需把自己的PWM控制器驱动注册到核心模块,填好设备信息并实现基础操作函数。而使用PWM的其他程序或应用,只需要通过pwm_device这个统一接口,就能像操作标准化设备一样控制所有PWM硬件。 :::
四、PWM sysfs 接口
PWM核心层是Linux系统中管理脉冲宽度调制(PWM)设备的核心模块。它为应用程序提供了简单直接的文件接口,方便用户通过修改系统文件来控制PWM参数:
- 周期设置:修改
/sys/class/pwm/pwmX/period
文件可调整PWM信号的周期 - 占空比设置:通过
/sys/class/pwm/pwmX/duty_cycle
文件设置脉冲宽度 - 极性控制:
/sys/class/pwm/pwmX/polarity
文件用于切换高低电平输出方向 - 开关控制:写入
/sys/class/pwm/pwmX/enable
文件可快速开启或关闭PWM输出
这些功能通过简单的文件读写操作即可实现,无需深入调用复杂的内核函数。PWM核心层统一管理所有PWM设备,提供标准化接口,并支持电源管理等高级功能,极大简化了PWM设备的使用难度。
后续章节将详细讲解两种PWM控制方式:通过内核API函数编程操作,以及通过上述系统文件的直接操作方法。
五、PWM 适配器驱动层 :pwm-rockchip.c
PWM适配器驱动层是连接PWM硬件和上层软件的关键桥梁,它的主要作用是:
- 隐藏硬件细节 通过标准化接口(如pwm_chip)将不同PWM芯片的底层操作统一起来。上层软件只需调用简单函数就能控制PWM,无需关心具体芯片的寄存器或电路设计。
- 适配不同硬件 为每种PWM芯片编写专属的驱动程序,把通用控制指令(如"设置占空比50%")转换成对应芯片能识别的硬件操作。这样核心层就能同时支持各种品牌的PWM芯片。
- 初始化硬件 在系统启动时自动完成PWM硬件的准备工作,包括:
- 配置时钟频率
- 设置GPIO引脚功能
- 启动电源供应
- 校准硬件参数 确保PWM模块处于待命状态随时可用
- 管理设备状态 实时记录PWM设备的运行状态,比如:
- 当前输出频率
- 是否处于启用状态
- 最近的参数设置 这些信息会同步给上层软件,帮助系统准确控制PWM输出,避免重复配置或错误操作。
这种分层设计就像翻译官一样,让上层软件能用统一的"普通话"指令,就能驱动不同品牌的PWM硬件设备,既方便又可靠。