1. 课程导论与硬件基础:嵌入式Linux低功耗概览
做嵌入式Linux低功耗优化,说白了就是跟「电」较劲。我入行那会儿,有个产品因为待机功耗超标,客户直接拒收。嗯,从那以后我就明白——功耗不是锦上添花,是生死线。
这一章,我们先搭好知识框架。我会以i.MX8M Plus为例,把SoC功耗架构、PMIC选型这些硬骨头啃下来。你想想看,如果连芯片怎么耗电都不清楚,优化就无从下手。
1.1 嵌入式Linux低功耗:为什么值得你花时间?
先看几个真实场景:
- 电池设备:智能门锁、扫地机器人,续航差就是产品失败
- 散热受限:工业平板、车载中控,功耗高就得降频,性能打折
- 法规门槛:欧洲ErP指令、能源之星,不达标无法上市
我在一个工业HMI项目里遇到过:设备跑Linux,CPU负载才20%,但整机功耗3.5W。客户要求降到2W以内。后来发现,问题出在DDR没进自刷新、PMIC没切低功耗模式。改完直接降到1.8W。
核心观点:低功耗不是「省着用」,而是「不用时彻底关掉」。Linux内核提供了cpuidle、cpufreq、runtime PM、suspend-to-RAM等机制,关键是你得会用。
1.2 主流SoC功耗架构:以i.MX8M Plus为例
i.MX8M Plus是NXP的中高端应用处理器,4个Cortex-A53 + 1个Cortex-M7。它的功耗架构很有代表性。
1.2.1 电源域划分
SoC内部不是铁板一块。i.MX8M Plus把不同模块放在独立的电源域里:
| 电源域 | 包含模块 | 典型电压 | 可关断? |
|---|---|---|---|
| VDD_ARM | Cortex-A53集群、L2缓存 | 0.9V - 1.0V | 是(WFI时自动降) |
| VDD_GPU | GPU 3D/2D | 0.8V - 1.0V | 是(驱动控制) |
| VDD_VPU | 视频编解码单元 | 0.8V - 0.95V | 是(驱动控制) |
| VDD_DRAM | DDR控制器、PHY | 1.1V | 部分(自刷新模式) |
| VDD_SOC | 总线、外设、I/O | 0.8V - 0.9V | 否(常开域) |
我个人习惯,拿到板子第一件事就是看datasheet里的power domain图。搞清楚哪些域可以独立关,哪些必须常开。这决定了你的低功耗策略能走多远。
1.2.2 动态电压频率调整(DVFS)
i.MX8M Plus的A53支持DVFS。Linux内核通过cpufreq驱动,根据负载动态调频调压。
# 查看当前支持的频率档位
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# 输出示例:1200000 1000000 800000 600000 400000
# 设置governor为ondemand
echo ondemand > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
这里有个坑:频率切换太快反而费电。因为每次调频都要重新锁相环,PLL锁定需要几十微秒,期间电流很大。我建议用schedutil governor,它跟调度器配合,切换更平滑。
经验之谈:别迷信「性能模式」。我测过,在轻负载下,performance governor比ondemand多耗电30%以上。用schedutil配合EAS(Energy-Aware Scheduling),效果最好。
1.3 电源管理芯片(PMIC)选型与配置基础
SoC再能省,PMIC不给力也白搭。PMIC负责把电池或外部电源转换成SoC需要的多路电压,同时控制上电时序。
1.3.1 PMIC的核心指标
- 效率:DC-DC转换效率,通常90%以上才算合格。LDO虽然纹波小,但效率低,适合给模拟电路供电。
- 静态电流:PMIC自身消耗的电流。待机时,这个值直接决定整机底电流。
- 上电时序:SoC要求各电源域按特定顺序上电。比如i.MX8M Plus要求VDD_SOC先于VDD_ARM。
- 可编程性:通过I2C/SPI动态调压、关断通道。
1.3.2 常用PMIC对比
| 型号 | 通道数 | 最大效率 | 静态电流 | 接口 | 典型应用 |
|---|---|---|---|---|---|
| BD71847MWV | 7路BUCK + 6路LDO | 95% | 15µA | I2C | i.MX8M系列官方搭档 |
| RK808 | 4路BUCK + 8路LDO | 93% | 20µA | I2C | Rockchip平台常用 |
| AXP803 | 3路BUCK + 11路LDO | 94% | 25µA | I2C | 全志、瑞芯微 |
| TPS65218 | 4路BUCK + 4路LDO | 92% | 12µA | SPI | AM335x、AM437x |
我建议优先选SoC原厂推荐的PMIC。比如i.MX8M Plus配BD71847,上电时序、电压值都调好了,省很多事。自己搭分立方案?我曾经试过,结果上电时序不对,SoC启动到一半就挂,查了三天才找到原因。
1.3.3 PMIC配置示例(BD71847)
BD71847通过I2C配置。Linux内核里有对应的regulator驱动。设备树里这样配:
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = &pinctrl_i2c1;
clock-frequency = <400000>;
status = "okay";
pmic: bd71847@4b {
compatible = "rohm,bd71847";
reg = <0x4b>;
interrupt-parent = <&gpio1>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
regulators {
buck1: BUCK1 {
regulator-name = "buck1";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
// ... 其他通道类似
};
};
};
注意:regulator-always-on和regulator-boot-on别乱加。只有常开域才需要。我见过有人把所有通道都加上,结果系统休眠时PMIC关不掉任何一路,待机功耗直接翻倍。
1.4 知识体系总览
下面这张图,把本章的核心逻辑串起来了。你对照着看,心里就有谱了。
1.5 本章小结
这一章,我们聊了:
- 低功耗优化的三个驱动力:续航、散热、法规
- i.MX8M Plus的电源域划分和DVFS机制
- PMIC选型的关键指标和BD71847配置示例
我个人觉得,最难的不是技术,而是「全局观」。很多人一上来就调内核参数,结果发现硬件上PMIC不支持动态调压,白忙一场。所以,先把硬件架构吃透,后面的事就顺了。
课后动手:拿一块i.MX8M Plus开发板,用cat /sys/kernel/debug/regulator/regulator_summary看看当前各路的电压和状态。再对比datasheet,确认哪些域可以关。这一步做完,你对硬件就有数了。