做嵌入式开发的同学,几乎每天都会和“电源”打交道——LDO稳压器、PMIC、电压电流调节,这些名词天天见,但你真的懂它们在Linux内核里是怎么被管理的吗?

很多人调试LDO驱动时一头雾水,改个电压配置无从下手;看内核代码时,对着一堆regulator相关结构体直呼“看不懂”。其实核心问题就一个:没吃透Regulator子系统。
更多内容可以加入Linux系统知识库套餐(教程+视频+答疑)
加我微信领取Linux大全课程大额优惠劵:

今天就用最通俗的比喻、最干货的拆解,从基础概念到核心API,再到内部数据结构,把Regulator子系统讲明白,不管你是刚入门的驱动新手,还是需要做技术选型的工程师,都能看完就用!
前置知识点:LDO(低压差线性稳压器)是嵌入式设备中最常用的电源器件,能在输入输出电压差值极低的情况下稳定工作,而所有LDO的驱动,都依赖Linux Regulator子系统实现统一管理。


先抛核心定义:Regulator子系统是Linux内核提供的一套标准接口,用于统一控制所有电压、电流稳压器(比如LDO、DCDC),核心目的只有一个——动态调节电源输出,节省功耗、延长设备续航(尤其适用于电池供电设备)。
简单说,它就像一个“电源总管家”,不管你是LDO还是PMIC里的稳压器,不管是电压可调还是电流可控,都要归它管,统一提供“开启/关闭、调电压、调电流”的接口,避免每个驱动都重复写一套电源控制逻辑。
搞懂这3个名词,就掌握了Regulator子系统的一半:
Regulator(稳压器):电源的“供给端”,比如LDO、DCDC,负责把输入电压转换成设备需要的稳定输出电压/电流,核心能力是“可开启/禁用、可调节”(部分仅支持开关)。
PMIC(电源管理IC):“集成式电源管家”,本质是一个芯片,里面集成了多个Regulator,还可能包含其他电源管理功能(比如休眠、唤醒),是嵌入式设备中最常见的电源方案。
Consumer(消费者):电源的“使用端”,也就是被Regulator供电的设备(比如CPU、LCD、RTC、传感器)。分为两种:
静态消费者:只需要“有电/没电”,不需要改电压/电流(比如简单的LED灯);
动态消费者:需要根据工作状态调整电压/电流(比如CPU,高频时要高电压,低频时降电压省电)。
补充一句:Regulator子系统的核心价值,就是实现“供给端”和“使用端”的解耦——消费者不用关心自己用的是哪个Regulator、怎么调节,只要调用统一接口,就能拿到稳定电源;开发者也不用为每个设备单独写电源控制代码,极大提升驱动复用性和稳定性。
对于驱动开发者来说,最常用的就是“消费者视角”的API——如何获取电源、开启/关闭电源、调节电压/电流。这些API都定义在drivers/regulator/core.c,记住这4组,就能应对80%的开发场景。

消费者要使用电源,首先要“申请”——通过regulator_get获取Regulator句柄;不用时要“归还”——通过regulator_put释放,避免资源泄露。

// 1. 获取Regulator(dev:消费者设备指针;"Vcc":电源ID,对应设备树配置)struct regulator *regulator = regulator_get(dev, "Vcc");// 2. 释放Regulator(不用时调用,通常在driver的remove函数中)regulator_put(regulator);
注意:这两个函数通常成对出现,分别在驱动的probe(设备探测)和remove(设备卸载)函数中调用。
获取句柄后,通过以下API控制电源的开启、关闭,以及查询状态:

// 1. 开启Regulator(给消费者供电)int ret = regulator_enable(regulator);// 2. 判断Regulator是否已开启(返回>0表示已开启)int is_en = regulator_is_enabled(regulator);// 3. 关闭Regulator(停止供电,注意:若有其他消费者共享,不会立即关闭)ret = regulator_disable(regulator);// 4. 紧急情况:强制关闭Regulator(不管是否有其他消费者,慎用!)ret = regulator_force_disable(regulator);
关键提醒:Regulator支持“共享”——如果多个消费者共用一个Regulator,只有当所有消费者都调用regulator_disable(引用计数为0),Regulator才会真正关闭。
对于CPU、SD卡等动态消费者,需要根据工作状态调整电压,核心API是regulator_set_voltage,支持设置“最小可接受电压”和“最大可接受电压”,内核会自动匹配最合适的电压。

// 设置电压(参数:regulator句柄、最小电压uV、最大电压uV)int ret = regulator_set_voltage(regulator, 1800000, 2000000); // 1.8V~2.0V// 查询当前输出电压(返回值为当前电压,单位uV)int voltage = regulator_get_voltage(regulator);
示例:CPUfreq驱动(CPU调频),就是通过这个API,在CPU高频时调高压、低频时调低压,实现“调频省电”。
有些消费者(比如LCD背光、USB设备)需要限制最大电流,避免功耗过高或损坏设备,核心API是regulator_set_current_limit。
// 设置电流限制(参数:regulator句柄、最小电流uA、最大电流uA)int ret = regulator_set_current_limit(regulator, 50000, 100000); // 50mA~100mA// 查询当前电流限制(返回值为当前最大电流,单位uA)int current = regulator_get_current_limit(regulator);
示例:LCD背光驱动,通过调整电流限制,改变背光亮度;USB驱动会将电流限制设为500mA,符合USB供电标准。
很多人看Regulator子系统源码时,被一堆结构体搞懵——regulator_dev、regulator_desc、regulator_ops,其实它们的关系很简单,用“大学管理系统”来比喻,瞬间就能理解:

把整个Regulator子系统,想象成一所大学,所有建筑(设备)都需要用电,而Regulator就是“供电系统”,各个结构体对应大学的不同角色:

regulator_map(全局链表):大学的“总资产登记表”,记录学校所有供电设备(PMIC/Regulator)的位置和信息,方便“管理层”(内核)快速查找。
regulator_dev(调节器设备):具体的“教学楼”(比如第一实验楼),是供电系统的核心载体,每个Regulator硬件对应一个regulator_dev,所有供电操作都围绕它进行。
regulator_desc(调节器描述符):教学楼的“建筑设计说明书”,是静态不变的——比如这栋楼是“LDO类型”(供电类型)、有多少个电闸(支持的电压等级)、能不能远程控制(regmap配置),在“楼建好”(设备注册)时就确定。
regulator_ops(调节器操作集):教学楼的“物业管理团队”,定义了所有可操作的行为——比如“打开总电源”(.enable)、“关闭总电源”(.disable)、“调节电压”(.set_voltage),不同的“教学楼”(Regulator)可能有不同的“物业团队”(操作集)。
regulator_config(调节器配置):校长办公室下达的“启用指令”,是动态的——比如这栋楼初始状态是通电还是断电、供电要遵守哪些安全规范(constraints)、“遥控器”(regmap)交给哪个部门保管,在“楼启用”(注册Regulator)时配置。
regulation_constraints(调节器约束):政府和安全部门制定的“安全规范”——比如这栋楼电压不能超过2.0V、电流不能超过100mA、休眠时要断电,避免硬件损坏。
regulator(调节器消费者):楼里的“租户”(比如301实验室),也就是具体使用电源的设备——向学校“申请用电”(regulator_get)、提出用电需求(比如需要1.8V电压、一直通电)、不用时“退租”(regulator_put)。
理解了角色,再看它们的关系和使用流程,就非常简单了,分两步:
开发者提供“建筑设计说明书”(regulator_desc)和“物业团队”(regulator_ops);
探测到硬件后,准备“启用指令”(regulator_config),包含“安全规范”(regulation_constraints)和“遥控器”(regmap);
调用regulator_register,内核创建“教学楼”(regulator_dev),并登记到“总资产表”(regulator_map)中,完成注册。
消费者(设备驱动)通过regulator_get,向“管理层”(内核)申请“用电凭证”(regulator句柄);
拿到凭证后,调用regulator_enable、regulator_set_voltage等API,实现“用电、调电”;
不用电时,调用regulator_put释放凭证,完成“退租”。
核心设计思想:面向对象——regulator_dev是“基类”(教学楼),regulator_desc和regulator_ops是“静态属性和方法”(说明书和物业),regulator_config是“构造参数”(启用指令),regulator是“客户端句柄”(租户凭证),分层清晰,便于扩展和维护。

看到这里,相信你已经对Regulator子系统有了清晰的认知,最后用3句话总结,帮你快速巩固:
Regulator子系统是Linux内核的“电源总管家”,统一管理所有稳压器,实现供给端和使用端解耦,核心是“标准化接口+分层设计”;
消费者驱动常用4组API:获取/释放(regulator_get/put)、开启/关闭(regulator_enable/disable)、调电压(regulator_set_voltage)、调电流(regulator_set_current_limit),直接复制就能用;
核心结构体用“大学管理”比喻:regulator_map是资产表、regulator_dev是教学楼、regulator是租户,理解角色关系,就能轻松看懂源码。
对于嵌入式开发者来说,吃透Regulator子系统,不仅能快速调试LDO、PMIC相关驱动,还能在技术选型、竞品分析时,精准判断电源管理方案的优劣(比如功耗控制、扩展性),提升项目交付效率。
后续会更新Regulator子系统的实操案例(比如LDO驱动开发、设备树配置),关注我,嵌入式电源管理不迷路~
💬 互动提问:你在调试Regulator相关驱动时,遇到过最头疼的问题是什么?评论区留言,一起交流解决方案!