
Regulator(稳压器)子系统是Linux内核中用于管理系统中各种电压和电流调节器的框架。这些调节器可能位于PMIC(电源管理集成电路)上,或者作为独立的硬件组件存在。Regulator子系统的主要目的是提供一种统一的接口,以控制电源的开关、电压和电流。这对于电源管理至关重要,尤其是在移动设备中,可以有效地节省功耗。
核心知识:
Regulator(稳压器):一个提供电源输出的硬件单元,可以是开关电源或线性稳压器。
Consumer(消费者):使用稳压器供电的设备或子系统。消费者可以通过regulator子系统请求打开或关闭电源,或者调整电压。
Driver(驱动):控制特定稳压器硬件的驱动程序,通常由芯片厂商提供。
Machine(机器):板级特定代码,用于配置稳压器与消费者之间的关系,例如在设备树中指定。
Consumer(消费者) → Regulator Framework(框架) → Driver(驱动) → Hardware Regulator(硬件)电压和电流控制:可以调整稳压器的输出电压和电流限制。
开关控制:打开或关闭稳压器。
电源管理:与其他内核子系统(如时钟、CPU频率调整等)协同工作,实现动态电压和频率调整(DVFS)等高级电源管理功能。
保护机制:例如过流保护、过温保护等。
在设备树中,你可以指定regulator的初始参数,以及消费者如何连接到regulator。
/* 定义调节器节点 */vdd_core: regulator@0 { compatible = "regulator-fixed"; regulator-name = "vdd-core"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <900000>; regulator-boot-on; /* 启动时开启 */ regulator-always-on; /* 始终开启 */};/* 消费者引用 */camera { compatible = "vendor,camera-module"; vdd-supply = <&vdd_core>; /* 引用调节器 */ enable-gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;};消费者(例如一个设备驱动)可以通过regulator API来请求和控制稳压器。
基本步骤:
a. 获取regulator句柄。
b. 使能regulator(打开电源)。
c. 根据需要调整电压或电流。
d. 使用完毕后,关闭regulator。
#include<linux/regulator/consumer.h>structregulator *vdd_reg;/* 获取调节器 */vdd_reg = devm_regulator_get(&pdev->dev, "vdd");if (IS_ERR(vdd_reg)) {return PTR_ERR(vdd_reg);}/* 设置电压 */regulator_set_voltage(vdd_reg, 1800000, 1800000); /* 1.8V *//* 使能调节器 */ret = regulator_enable(vdd_reg);if (ret) { dev_err(&pdev->dev, "Failed to enable regulator\n");}/* 禁用调节器 */regulator_disable(vdd_reg);/* 设置工作模式(正常/低功耗) */regulator_set_load(vdd_reg, 50000); /* 设置50mA负载 */值得注意: 在消费者驱动中,可以通过regulator_get(dev, "vdd")来获取这个regulator,注意字符串"vdd"需要与设备树中引用的名字匹配(通常是去掉"-core"后缀的部分,但实际取决于驱动如何解析)。
# 查看所有调节器cat /sys/kernel/debug/regulator/regulator_summary# 查看具体调节器状态cat /sys/class/regulator/regulator.0/namecat /sys/class/regulator/regulator.0/statecat /sys/class/regulator/regulator.0/voltage# 用户空间控制echo 1800000 > /sys/class/regulator/regulator.0/voltageecho"disabled" > /sys/class/regulator/regulator.0/state如果你需要为一个稳压器硬件编写驱动,你需要实现一个regulator驱动,并向regulator子系统注册。
基本步骤:
a. 定义regulator描述符(struct regulator_desc)和操作(struct regulator_ops)。
b. 在驱动中注册regulator。
/* 驱动实现示例 */staticconststructregulator_opsmy_regulator_ops = { .enable = my_regulator_enable, .disable = my_regulator_disable, .set_voltage = my_regulator_set_voltage, .get_voltage = my_regulator_get_voltage,};staticconststructregulator_descmy_regulator_desc = { .name = "my-regulator", .id = 0, .ops = &my_regulator_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE,};staticintmy_regulator_probe(struct platform_device *pdev){structregulator_configconfig = { }; config.dev = &pdev->dev; config.init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); regulator = devm_regulator_register(&pdev->dev, &my_regulator_desc, &config);return0;}这里整理下常用的一些API函数,不同内核版本会有一些差异,不过大同小异。
regulator_get() | |
regulator_put() | |
regulator_enable() | |
regulator_disable() | |
regulator_set_voltage() | |
regulator_get_voltage() | |
regulator_set_current_limit() | |
regulator_set_mode() | |
regulator_is_enabled() |
devm_regulator_get() 自动管理资源如果遇到问题排查方法如下:
/sys/kernel/debug/regulator/Regulator 子系统是 Linux 电源管理还是蛮重要的,用得好的话可以有效提高系统的稳定性和能效。
小哥搜集了一些嵌入式学习资料,公众号内回复【1024】即可找到下载链接!
推荐好文点击蓝色字体即可跳转
☞专辑|Linux应用程序编程大全 ☞ 专辑|学点网络知识 ☞ 专辑|手撕C语言 ☞ 专辑|手撕C++语言
☞ 专辑|经验分享 ☞ 专辑|从单片机到Linux ☞ 专辑|电能控制技术 ☞ 专辑|嵌入式必备数学知识 ☞ MCU进阶专辑
☞ 经验分享