使用指南

快速开始

以 RTC 为唤醒源,配置应用进入 PG(电源门控)并被唤醒,需三步。

1. 打开 Kconfig 选项

CONFIG_PM=y

# 空闲线程栈需要放大,否则睡眠路径会栈溢出
CONFIG_IDLE_STACK_SIZE=4096

# 唤醒源设备本身也要使能
CONFIG_RTC=y
CONFIG_RTC_ALARM=y
CONFIG_RTC_AMEBA=y

2. 在 overlay 中把设备标记为唤醒源

&rtc {
   status = "okay";
   wakeup-source;
};

3. 在应用中配置该设备

低功耗框架仅使能设备的唤醒能力,设备本身仍需正常初始化与配置, 如 RTC 设置 alarm、GPIO 配置中断。

应用无需显式请求睡眠,默认的 Residency Based 策略在空闲时长足够时自动 选择状态,判定依据见 低功耗状态的选择。串口日志出现 APPG 与 APPW 表示完成一次 PG 睡眠与唤醒,标记含义见 日志判读。

备注

Zephyr 仅在由 Zephyr 侧引导程序(MCUboot 或 //ns 切分编译的 TF-M BL2) 启动时接管 AP 唤醒源的使能。使用 ameba-loader 时由 KM0 固件负责, 此时上述 DTS 属性不生效。

配置细节

其他唤醒源的 Kconfig

# timer(counter) 作为唤醒源
CONFIG_COUNTER=y

# GPIO 作为唤醒源
CONFIG_GPIO=y

其他唤醒源的 DTS

&gpiob {
   status = "okay";
   wakeup-source;
};

&timer0 {
   status = "okay";
   wakeup-source;
};

节点还需具备 wakeup-source-id 属性(该唤醒源对应的硬件事件 ID), 通常已在 SoC 的 dtsi 中给出。

备注

仅添加 wakeup-source 而节点没有 wakeup-source-id 时, 该唤醒源不会被使能,且无任何报错。

警告

ameba counter 驱动只支持相对 alarm。设置 COUNTER_ALARM_CFG_ABSOLUTE 会返回 -ENOTSUP,alarm 不会被装载,表现为无法唤醒且无报错。

警告

counter_cancel_channel_alarm() 不停止计数器。按 Zephyr counter API 语义, counter_start() 请求的是自由运行,取消 alarm 不撤销它;而标记了 wakeup-source 的节点在启动时即已在 PMC 侧装载,PMC 是否唤醒 AP 与该外设自身中断是否屏蔽无关。

唤醒源使用完毕后须显式 counter_stop(),RTC 以 mask = 0 调用 rtc_alarm_set_time() 关闭 alarm。否则残留唤醒源持续产生唤醒事件, 表现为后续睡眠请求不进入 PG。

低功耗状态的选择

默认使用 Residency Based 策略:框架比较预期空闲时长与各状态声明的 min-residency-us + exit-latency-us,选出满足条件的最深状态,应用无需显式 请求进入某个状态。详见 概述 。

预期空闲时长 由内核给出,等于距下一个已注册 timeout 到期的时间 (z_get_next_timeout_expiry()),不可直接配置。应用侧能左右它的是自身行为: k_msleep() 的时长、定时器周期、以及是否有线程在频繁唤醒。

阈值 在各 SoC 的 dtsi 中以 power-states 节点声明,当前默认值:

状态

power-state-name

min-residency-us

exit-latency-us

CG

suspend-to-idle

3000

2000

PG

suspend-to-ram

5000

2500

即空闲时长需达到 5 ms 才会选择 PG,3 ms 至 5 ms 之间选择 CG,不足 3 ms 仅执行 WFI。三颗 SoC 的默认值一致。板级 dts 通过 cpu-power-states 声明哪些状态对该 CPU 可用,当前为 <&pm_cg &pm_pg>。

应用可在 overlay 中覆盖这些值,例如降低 PG 门槛:

&pm_pg {
   min-residency-us = <2000>;
};

备注

exit-latency-us 描述的是硬件唤醒开销,应与实测值相符;调小它会使框架 在空闲时长不足时仍选择该状态,导致唤醒开销占比过高。调整门槛通常只需改 min-residency-us。

若需临时限制可用状态(例如禁止进入 PG),使用 Zephyr 的 pm_policy_state_lock_get() / pm_policy_state_lock_put()。

各 SoC 支持范围

RTL8721F:

支持 CG(PM_STATE_SUSPEND_TO_IDLE)与 PG(PM_STATE_SUSPEND_TO_RAM)。

引导方式:MCUboot、//ns 切分编译(TF-M BL2)、ameba-loader 均支持。

//ns 配置下 secure 世界跨 PG 保留,唤醒后 secure session 状态 (如 volatile key)继续有效。

运行 PM 测试

zephyr/tests/boards/realtek/pm 覆盖系统时基、内核超时唤醒、CG/PG 下的多种 唤醒源以及连续多次 PG。

west twister -p rtl8721f_evb/rtl8721f/ns -T zephyr/tests/boards/realtek/pm

支持的 target:

rtl8721f_evb/rtl8721f/mcuboot
rtl8721f_evb/rtl8721f/ns
rtl872xda_evb/rtl8721dx/mcuboot
rtl872xda_evb/rtl8721dx/ns
rtl8730e_evb/rtl8730e

备注

ameba-loader 变体不在其中:该配置下由 KM0 固件装载唤醒源,测试无法自行装载, AP 会永久断电。该场景的示例见 applications/amebaloder_pm_system_manage。

若只需一个可直接运行的示例而非测试套件,见 applications/mcuboot_pm_system_manage,依次由 RTC、counter、GPIO 唤醒。

日志判读

一次完整的 PG 睡眠与唤醒如下:

<inf> soc_pm: call pm_state_set: 4
APPG
NPPG
NPPW
APPW
<inf> soc_pm: [pm_state_exit_post_ops] AP wake: 4
Wake up by: rtc@4080aa00.

各标记含义:

标记

含义

pm_state_set: N

进入状态 N(2 为 CG,4 为 PG)

APPG / APCG

AP 进入 PG / CG

NPPG / NPCG

NP 进入 PG / CG

NPPW / NPCW

NP 唤醒

APPW / APCW

AP 唤醒

pm_state_exit_post_ops

唤醒后处理完成

AP 进入而 NP 未跟随(只有 APPG 没有 NPPG)表示 NP 侧未就绪, 此时 AP 会退出本次睡眠。

常见问题

现象

检查方向

无 pm_state_set 日志

策略层未选中任何状态。空闲时长不足

min-residency-us + exit-latency-us,或有残留唤醒源持续产生事件

有 APPG 但无 NPPG

NP 侧未就绪,AP 退出本次睡眠

睡下去不唤醒

唤醒源未真正装载。检查节点是否同时具备 wakeup-source 与

wakeup-source-id、是否使用了不支持的绝对 alarm、 以及引导方式是否为 ameba-loader

唤醒后 uptime 不前进

时间补偿依赖常开的 timer0(TIM0)。应用将其作为 counter 设备

接管并停止或复位后,补偿失效