电源管理架构
SoC 搭载了先进的电源管理控制器(Power Management Controller,PMC),可灵活控制芯片不同电源域的上电时序,实现性能与功耗的最佳平衡。
SoC 的数字系统中一般包含三个核心电源域:AON 域、SYSON 域和 SOC 域。不同省电模式下,各电源域的关断策略存在差异。
Ameba 系列 SoC 的电源域和唤醒源如下所示:
备注
RTC power domain 是 RTL8721F 特有的 power domain。本文介绍的所有工作模式中,RTC 同 AON domain 工作状态相同, 因此不做区分。
低功耗模式
Ameba SoC 支持两种低功耗模式:
睡眠(Sleep)模式
时钟门控模式(Clock Gating,CG):关闭 SOC 域的时钟,保留其供电
电源门控模式(Power Gating,PG):关闭 SOC 域的电源
深度睡眠(Deep-Sleep)模式:关闭 SYSON 域和 SOC 域的供电。深度睡眠模式比睡眠模式关闭更多电源域,因此功耗更低。
Tickless 是 FreeRTOS 的低功耗功能,当系统空闲时会暂停 CPU(不关闭时钟和电源)。睡眠模式流程和深度睡眠模式流程均基于 Tickless 实现。
下表详细解释了各个模式的电源域工作状态及特点:
模式 |
AON 域 |
SYSON 域 |
SOC 域 |
描述 |
---|---|---|---|---|
Tickless |
ON |
ON |
ON |
|
Sleep |
ON |
ON |
|
|
Deep-Sleep |
ON |
OFF |
OFF |
|
FreeRTOS Tickless
FreeRTOS 的 Tickless 低功耗特性通过优先级最低的空闲任务实现,当系统没有其他运行任务时触发。
备注
低功耗应用必须启用 configUSE_TICKLESS_IDLE 配置项,因为睡眠模式基于 Tickless 机制实现。
与原生 FreeRTOS 不同,不依赖 xExpectedIdleTime 进行唤醒。
空闲任务中的 FreeRTOS Tickless
上图展示了空闲任务的代码流程。在空闲任务中,系统会检查睡眠条件(包括唤醒锁状态、系统活跃时间等,详见章节 唤醒锁 API 和 pmu_set_sysactive_time),以决定是否进入睡眠模式。
当条件不满足时:CPU 执行 ARM WFI (等待中断)指令,使处理器挂起直至中断触发。通常由 SysTick 中断恢复运行,此模式称为 软件 Tickless。
当条件满足时:执行函数
freertos_pre_sleep_processing()
进入睡眠模式或深度睡眠模式
备注
即使设置了 FreeRTOS 时间控制机制(如软件定时器或 vTaskDelay),只要空闲任务被执行且满足条件,系统仍会进入睡眠模式。
Wi-Fi 低功耗
IEEE 802.11 省电管理允许 STA 自主进入睡眠状态,其核心规则为:
STA 必须在特定时间戳保持唤醒状态,其余时间可进入睡眠状态
WLAN 驱动通过获取唤醒锁(Wakelock)阻止系统在需保持活跃时进入睡眠模式
当允许休眠时,WLAN 驱动释放唤醒锁
站点休眠期间无法接收任何数据帧,因此 AP 需缓存待传数据帧,STA 需周期性唤醒检测信标帧。

省电模式时序图
SDK 中的实现模式如下:
IEEE 802.11 power management is called LPS, and if NP enters sleep mode when Wi-Fi is in LPS mode, we call it WoWLAN mode.
In WoWLAN mode, a timer with a period of about 102ms will be set in the suspend function. And LP will wake up every 102ms to receive the beacon to maintain the connection.
Except for LPS and WoWLAN, we also have IPS, which can be used when Wi-Fi is not connected. The following tables list all three power-saving modes for Wi-Fi and the relationship between the system power mode and Wi-Fi power mode.
模式 |
Wi-Fi 状态 |
描述 |
SDK |
---|---|---|---|
IPS |
未连线:
|
Wi-Fi 驱动自动关闭 Wi-Fi 模块 |
禁止IPS后,系统平均功耗会大幅增加,不建议禁用 |
LPS |
已连线:
|
LPS 模式用于实现 IEEE 802.11 省电管理 基于信标的 TSF 和 TIM IE 控制射频的开关 |
默认启用 LPS 模式,可通过 API
|
WoWLAN |
已连线:
|
每次信标提前中断时WIFI 会被打开,以接收来自AP router的信标帧 当接收到唤醒数据包时,会唤醒系统并将数据交由网络层处理。 |
默认启用 WoWLAN 模式 |
系统功耗模式和 Wi-Fi 功耗模式之间的关系如下表所示:
系统功耗模式 |
Wi-Fi 功耗模式 |
描述 |
---|---|---|
Active |
IPS |
Wi-Fi 已开启但未建立连接 |
LPS |
Wi-Fi 已连接并进入 IEEE 802.11 省电管理模式 |
|
Sleep |
Wi-Fi 关闭/IPS |
|
WoWLAN |
Wi-Fi 保持关联状态 |
|
Deep-Sleep |
Wi-Fi 关闭 |
需保持 Wi-Fi 持续在线或关联的场景,不推荐使用 Deep-Sleep 模式 |
唤醒源
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
IPC |
√ |
√ |
X |
仅 KM0 可通过 IPC 唤醒 KM4 |
Basic Timer4~7 |
√ |
√ |
X |
|
PMC Timer |
√ |
√ |
X |
仅内部使用 |
UART0~2 |
√ |
√ |
X |
当使用 UART 作为唤醒源时:
|
LOGUART |
√ |
√ |
X |
当使用 LOGUART 作为唤醒源时:
|
GPIO |
√ |
√ |
X |
|
I2C |
√ |
√ |
X |
|
CAP_TOUCH |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
SDIO |
√ |
√ |
X |
|
Key-Scan |
√ |
√ |
X |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
|
AON_TIMER |
√ |
√ |
√ |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
RTC |
√ |
√ |
√ |
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
IWDG |
√ |
√ |
X |
|
IPC |
√ |
√ |
X |
|
Basic Timer |
√ |
√ |
X |
|
UART |
√ |
√ |
X |
|
LOGUART |
√ |
√ |
X |
|
GPIO |
√ |
√ |
X |
|
SPI |
√ |
X |
X |
|
CAP_TOUCH |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
VAD |
√ |
X |
X |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
|
AON_TIMER |
√ |
√ |
√ |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
RTC |
√ |
√ |
√ |
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
IWDG |
√ |
√ |
X |
|
IPC |
√ |
√ |
X |
|
Basic Timer |
√ |
√ |
X |
|
UART |
√ |
√ |
X |
|
LOGUART |
√ |
√ |
X |
|
GPIO |
√ |
√ |
X |
|
SPI |
√ |
X |
X |
|
CAP_TOUCH |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
VAD |
√ |
X |
X |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
|
AON_TIMER |
√ |
√ |
√ |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
RTC |
√ |
√ |
√ |
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
IWDG |
√ |
√ |
X |
|
IPC |
√ |
√ |
X |
|
Basic Timer |
√ |
√ |
X |
|
UART |
√ |
√ |
X |
|
LOGUART |
√ |
√ |
X |
|
GPIO |
√ |
√ |
X |
|
SPI |
√ |
X |
X |
|
CAP_TOUCH |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
VAD |
√ |
X |
X |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
|
AON_TIMER |
√ |
√ |
√ |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
RTC |
√ |
√ |
√ |
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
UART |
√ |
√ |
X |
当使用 UART 作为唤醒源时:
|
IPC |
√ |
√ |
X |
IPC 只能唤醒 CA32 和 KM4,不能唤醒 KM0 |
USB |
√ |
X |
X |
|
SPI |
√ |
X |
X |
当使用 SPI 作为唤醒源,禁止关闭 SOC 域的时钟和电源 |
VAD |
√ |
√ |
X |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
|
CAP_TOUCH |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
RTC |
√ |
√ |
√ |
|
GPIO |
√ |
√ |
X |
|
LOGUART |
√ |
√ |
X |
当使用 LOGUART 作为唤醒源时:
|
Basic Timer |
√ |
√ |
X |
|
IWDG |
√ |
√ |
X |
|
AON_TIMER |
√ |
√ |
√ |
SYSON 电源管理控制器(SYSON PMC)用于控制 LP 的时钟和电源,之后 LP 控制 NP 和 AP 的时钟和电源。
当系统进入睡眠时,CPU 可以选择进入 CG 或 PG 模式,此时 SYSON PMC 保持全功能运行,当有唤醒源触发时负责唤醒 LP。
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
Sleep CG |
Sleep PG |
Deep-Sleep |
限制 |
---|---|---|---|---|
WLAN |
√ |
√ |
X |
|
BT |
√ |
√ |
X |
|
IPC |
√ |
√ |
X |
|
Basic Timer |
√ |
√ |
X |
timer0 ~ timer3可以用作唤醒源 |
UART |
√ |
√ |
X |
UART0~UART3用作唤醒源时:
|
LOGUART |
√ |
√ |
X |
LOGUART用作唤醒源时:
|
GPIO |
√ |
√ |
X |
|
RMII |
√ |
X |
X |
|
CAP-TOUCH |
√ |
√ |
X |
|
CAN |
√ |
X |
X |
仅支持时钟门控,电压需维持在0.8V,且需开启OSC4M |
IWDG |
√ |
√ |
X |
|
ADC |
√ |
√ |
X |
|
SDIO |
√ |
X |
X |
需要PLL 正常工作 |
USB |
√ |
X |
X |
|
AON_TIMER |
√ |
√ |
√ |
|
AON_WAKEPIN |
√ |
√ |
√ |
|
RTC |
√ |
√ |
√ |
|
BOR |
√ |
√ |
√ |
|
PWR_DOWN |
√ |
√ |
√ |
进入 Sleep 模式
睡眠模式基于 FreeRTOS Tickless 模式实现,因此推荐通过释放唤醒锁(Wakelock) 的方式进入睡眠模式。
初始化目标外设
启用和注册外设中断
设置
ambea_sleepcfg.c
文件中的sleep_wevent_config[]
,确保中断注册在sleep_wevent_config[]
选择的相同的 CPU 上对于需要特殊时钟配置的外设,在
ameba_sleepcfg.c
文件中设置ps_config[]
根据需要注册睡眠/唤醒回调函数
通过释放 AP 的唤醒锁进入睡眠模式(启动时 PMU_OS 默认被占用,需在进入睡眠模式前释放)
在系统唤醒后,及时清除外设中断
进入 Deep-Sleep 模式
通过 FreeRTOS Tickless 流程同样可以进入深度睡眠模式。
当系统启动时,应用处理器(AP)自动持有深度唤醒锁 PMU_OS,导致 freertos_ready_to_dsleep()
校验失败,系统默认不在空闲任务中进入深度睡眠模式。
只有当 freertos_ready_to_sleep()
校验通过,才会校验 freertos_ready_to_dsleep()
,因此需同时释放唤醒锁和深度唤醒锁方可进入深度睡眠模式。
配置:
初始化目标外设并启用中断
在
ameba_sleepcfg.c
文件中设置sleep_wakepin_config[]
,使用 AON 唤醒引脚作为唤醒源通过释放 AP 的唤醒锁和深度唤醒锁进入深度睡眠模式
低功耗配置
请参考 开发者配置 章节以获取详细信息.
低功耗相关 API
唤醒锁 API
唤醒锁(Wakelock)是一个 32 位的映射,如果某个模块持有唤醒锁,系统将无法进入睡眠模式。每个模块在唤醒锁位图中都有其对应的位(参见枚举 PMU_DEVICE),用户也可以在枚举中添加自定义的唤醒锁,但不得修改已经定义好的唤醒锁。
Ameba Soc 定义了两种唤醒锁,每种唤醒锁都可以支持 32 个不同的模块:
wakelock:用于睡眠模式,当 wakelock 为 0 时,系统可进入睡眠模式;否则,不允许进入睡眠模式。
deepwakelock:用于深睡眠模式,当 deepwakelock 为 0 时,系统可进入深睡眠模式;否则,不允许进入深睡眠模式。
以下内容展示了系统定义的唤醒锁位图:
enum PMU_DEVICE {
PMU_OS = 0,
PMU_WLAN_DEVICE,
PMU_KM4_RUN,
PMU_WLAN_FW_DEVICE,
PMU_BT_DEVICE,
PMU_DEV_USER_BASE, /*编号 7~31 预留给客户使用*/
PMU_MAX
};
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。
wakelock:当系统启动时,应用核(AP)持有 wakelock PMU_OS,而网络核(NP)则持有 wakelock PMU_OS 以及 PMU_KM4_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,AP 或 NP 才允许进入休眠模式。
睡眠流程:当 AP 的 wakelock PMU_OS 被释放后,AP 会在空闲任务中进入休眠模式,并向 NP 发送 IPC。NP 会对 AP 进行断电(power-gate)或时钟门控(clock-gate),然后释放 PMU_OS 以及 PMU_KM4_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。
deepwakelock: 当系统启动时,应用核持有 deepwakelock PMU_OS。
睡眠条件:当 AP 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 AP 的所有 deepwakelock 被释放后,并在空闲任务中向 NP 发送 IPC。NP 会发送 deep-sleep 请求,最终让芯片进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
enum PMU_DEVICE {
PMU_OS = 0,
PMU_WLAN_DEVICE,
PMU_KM4_RUN,
PMU_KR4_RUN,
PMU_DSP_RUN,
PMU_WLAN_FW_DEVICE,
PMU_BT_DEVICE,
PMU_DEV_USER_BASE = 7, /*编号 7~31 预留给客户使用*/
PMU_MAX = 31,
};
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。wakelock:当系统启动时,应用核(AP)持有 wakelock PMU_OS,而网络核(NP)则持有 wakelock PMU_OS 以及 PMU_KM4_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,AP 或 NP 才允许进入休眠模式。
睡眠流程:当 AP 的 wakelock PMU_OS 被释放后,AP 会在空闲任务中进入休眠模式,并向 NP 发送 IPC。NP 会对 AP 进行断电(power-gate)或时钟门控(clock-gate),然后释放 PMU_OS 以及 PMU_KM4_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。deepwakelock: 当系统启动时,应用核持有 deepwakelock PMU_OS。
睡眠条件:当 AP 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 AP 的所有 deepwakelock 被释放后,并在空闲任务中向 NP 发送 IPC。NP 会发送 deep-sleep 请求,最终让芯片进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
enum PMU_DEVICE {
PMU_OS = 0,
PMU_WLAN_DEVICE,
PMU_KM4_RUN,
PMU_KR4_RUN,
PMU_DSP_RUN,
PMU_WLAN_FW_DEVICE,
PMU_BT_DEVICE,
PMU_DEV_USER_BASE = 7, /*编号 7~31 预留给客户使用*/
PMU_MAX = 31,
};
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。wakelock:当系统启动时,应用核(AP)持有 wakelock PMU_OS,而网络核(NP)则持有 wakelock PMU_OS 以及 PMU_KM4_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,AP 或 NP 才允许进入休眠模式。
睡眠流程:当 AP 的 wakelock PMU_OS 被释放后,AP 会在空闲任务中进入休眠模式,并向 NP 发送 IPC。NP 会对 AP 进行断电(power-gate)或时钟门控(clock-gate),然后释放 PMU_OS 以及 PMU_KM4_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。deepwakelock: 当系统启动时,应用核持有 deepwakelock PMU_OS。
睡眠条件:当 AP 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 AP 的所有 deepwakelock 被释放后,并在空闲任务中向 NP 发送 IPC。NP 会发送 deep-sleep 请求,最终让芯片进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
enum PMU_DEVICE {
PMU_OS = 0,
PMU_WLAN_DEVICE,
PMU_KM4_RUN,
PMU_KR4_RUN,
PMU_DSP_RUN,
PMU_WLAN_FW_DEVICE,
PMU_BT_DEVICE,
PMU_DEV_USER_BASE = 7, /*编号 7~31 预留给客户使用*/
PMU_MAX = 31,
};
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。wakelock:当系统启动时,应用核(AP)持有 wakelock PMU_OS,而网络核(NP)则持有 wakelock PMU_OS 以及 PMU_KM4_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,AP 或 NP 才允许进入休眠模式。
睡眠流程:当 AP 的 wakelock PMU_OS 被释放后,AP 会在空闲任务中进入休眠模式,并向 NP 发送 IPC。NP 会对 AP 进行断电(power-gate)或时钟门控(clock-gate),然后释放 PMU_OS 以及 PMU_KM4_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。deepwakelock: 当系统启动时,应用核持有 deepwakelock PMU_OS。
睡眠条件:当 AP 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 AP 的所有 deepwakelock 被释放后,并在空闲任务中向 NP 发送 IPC。NP 会发送 deep-sleep 请求,最终让芯片进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
enum PMU_DEVICE { PMU_OS = 0, PMU_WLAN_DEVICE = 1, PMU_KM4_RUN = 2, PMU_AP_RUN = 3, PMU_BT_DEVICE = 4, PMU_VAD_DEVICE = 5, PMU_DEV_USER_BASE = 6, /*编号 6~31 预留给客户使用*/ PMU_MAX, };
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。
wakelock:当系统启动时, 当系统启动时,CA32/KM4 持有 wakelock PMU_OS,KM0 持有 wakelock PMU_OS、PMU_KM4_RUN 和 PMU_AP_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,CPU 才允许进入休眠模式。
睡眠流程: 当 CA32 的 wakelock PMU_OS 被释放后,CA32 会在 idle 任务中进入休眠模式,并向 KM0 发送 IPC。KM0 首先对 CA32 进行时钟/电源门控,然后释放 PMU_AP_RUN;如果 KM4 发现 CA32 已经进入休眠模式,则在 idle 任务中释放 PMU_OS,并向 KM0 发送 IPC,KM0 首先对 KM4 进行时钟/电源门控,然后释放 PMU_OS 和 PMU_KM4_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。
deepwakelock: 当系统启动时,CA32 持有 deepwakelock PMU_OS。
睡眠条件:当 CA32 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 CA32 的 deepwakelock PMU_OS 被释放,并且 CA32 所有 wakelock 都被释放后,CA32 允许进入 deep-sleep 模式,并在 idle 任务中向 KM0 发送 IPC。KM0 会发送 deep-sleep 请求,使芯片最终进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
typedef enum { PMU_OS = 0, PMU_WLAN_DEVICE, PMU_CPU0_RUN, PMU_CPU1_RUN, PMU_WLAN_FW_DEVICE, PMU_BT_DEVICE, PMU_FULLMAC_WIFI, PMU_DEV_USER_BASE, /*编号 7~31 预留给客户使用*/ PMU_MAX } PMU_DEVICE;
睡眠模式:通过函数
freertos_ready_to_sleep()
判断 wakelock 是否为 0。
wakelock:当系统启动时,应用核(AP)持有 wakelock PMU_OS,而网络核(NP)则持有 wakelock PMU_OS 以及 PMU_CPU0_RUN。
睡眠条件:只有当所有 wakelock 都被释放后,AP 或 NP 才允许进入休眠模式。
睡眠流程:当 AP 的 wakelock PMU_OS 被释放后,AP 会在空闲任务中进入休眠模式,并向 NP 发送 IPC。NP 会对 AP 进行断电(power-gate)或时钟门控(clock-gate),然后释放 PMU_OS 以及 PMU_CPU0_RUN。
深睡眠模式:通过函数
freertos_ready_to_dsleep()
判断 deepwakelock 是否为 0。
deepwakelock: 当系统启动时,应用核持有 deepwakelock PMU_OS。
睡眠条件:当 AP 的所有 deepwakelock 被释放后,AP 和 NP 才允许进入 deep-sleep 模式。
睡眠流程:当 AP 的所有 deepwakelock 被释放后,并在空闲任务中向 NP 发送 IPC。NP 会发送 deep-sleep 请求,最终让芯片进入 deep-sleep 模式。
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入休眠模式。
下文列示了用于控制唤醒锁或深度唤醒锁的 API。
pmu_acquire_wakelock
项目 |
描述 |
---|---|
功能 |
为某个模块获取唤醒锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_release_wakelock
项目 |
描述 |
---|---|
功能 |
释放某个模块的唤醒锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_acquire_deepwakelock
项目 |
描述 |
---|---|
功能 |
为某个模块获取深度唤醒锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_release_deepwakelock
项目 |
描述 |
---|---|
功能 |
释放某个模块的深度唤醒锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_set_sysactive_time
在某些场景下,系统需要在活跃状态保持唤醒一段时间以完成特定流程。
项目 |
描述 |
---|---|
功能 |
设置系统保持活跃状态的持续时间 |
参数 |
timeout:时间(单位:毫秒) 系统将从当前时刻起保持活跃状态达此时长 |
返回值 |
0 |
睡眠/唤醒回调 API
用于为 <nDeviceId> 注册挂起/恢复回调函数:
挂起回调函数:系统进入睡眠模式前在空闲任务中触发
恢复回调函数:系统唤醒后立即执行
如果在芯片休眠前或唤醒后有相关操作需要处理,可以使用 suspend 和 resume 回调函数。resume 函数的一个典型应用是获取唤醒锁,以防止芯片再次进入休眠模式。此外,如果 CPU 选择 PG(掉电关断),部分外设会断电,因此需要重新初始化。这些操作可以在 resume 函数中实现。
备注
禁止在回调函数中使用可能引发 OS 调度的 API(如:
rtos_task_yield
、rtos_time_delay_ms
、信号量/互斥锁相关操作)禁止在挂起回调函数中调用
pmu_set_sysactive_time
(恢复回调函数中允许)
pmu_register_sleep_callback
项目 |
描述 |
---|---|
功能 |
为某个模块注册挂起/恢复回调函数 |
参数 |
|
返回值 |
无 |
pmu_unregister_sleep_callback
项目 |
描述 |
---|---|
功能 |
注销某个模块的挂起/恢复回调函数 |
参数 |
|
返回值 |
无 |
pmu_set_max_sleep_time
项目 |
描述 |
---|---|
功能 |
设置最大睡眠时间 |
参数 |
timer_ms:系统最大睡眠超时时间(单位:毫秒) |
返回值 |
无 |
备注
超时后,系统不会被唤醒。
超时前,系统可能被其他事件唤醒。
此设置仅单次有效,系统唤醒后时间自动清零。
唤醒原因 API
备注
唤醒时,相应的外设中断会被触发;清除中断时,唤醒原因中的对应位也会被清除。因此,在中断被清除之后,将无法获得唤醒原因。
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
功能 |
获取从深睡眠唤醒的原因 |
参数 |
无 |
返回值 |
|
WAK_STATUS0
以下寄存器可用于获取唤醒原因。
寄存器 |
参数 |
---|---|
WAK_STATUS0 |
|
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
简介 |
获取深度睡眠唤醒原因 |
参数 |
无 |
返回值 |
Bit[0]: CHIP_EN 短按 Bit[1]: CHIP_EN 长按 Bit[2]: BOR Bit[3]: AON 定时器 Bit[5:4]: AON GPIO Bit[8]: RTC |
WAK_STATUS0 & WAK_STATUS1
如下寄存器可用于获取唤醒原因。
Register |
Parameters |
---|---|
WAKE_STATUS0 |
|
WAKE_STATUS1 |
|
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
简介 |
获取深度睡眠唤醒原因 |
参数 |
无 |
返回值 |
Bit[0]: CHIP_EN 短按 Bit[1]: CHIP_EN 长按 Bit[2]: BOR Bit[3]: AON 定时器 Bit[5:4]: AON GPIO Bit[8]: RTC |
WAK_STATUS0 & WAK_STATUS1
如下寄存器可用于获取唤醒原因。
Register |
Parameters |
---|---|
WAKE_STATUS0 |
|
WAKE_STATUS1 |
|
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
简介 |
获取深度睡眠唤醒原因 |
参数 |
无 |
返回值 |
Bit[0]: CHIP_EN 短按 Bit[1]: CHIP_EN 长按 Bit[2]: BOR Bit[3]: AON 定时器 Bit[5:4]: AON GPIO Bit[8]: RTC |
WAK_STATUS0 & WAK_STATUS1
如下寄存器可用于获取唤醒原因。
Register |
Parameters |
---|---|
WAKE_STATUS0 |
|
WAKE_STATUS1 |
|
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
简介 |
获取从深睡眠唤醒原因 |
参数 |
无 |
返回值 |
Bit[0]: CHIP_EN 短按 Bit[1]: CHIP_EN 长按 Bit[2]: BOR Bit[3]: AON Timer Bit[7:4]: AON GPIO Bit[8]: RTC |
WAK_STATUS0
以下寄存器可用于获取唤醒原因。
寄存器 | 参数 |
|
---|---|
WAK_STATUS0 |
|
WAK_STATUS1 |
|
SOCPS_AONWakeReason
项目 |
描述 |
---|---|
功能 |
获取从深睡眠唤醒的原因 |
参数 |
无 |
返回值 |
|
WAK_STATUS0 & WAK_STATUS1
下列寄存器可以获取唤醒原因.
Register |
Parameters |
---|---|
WAK_STATUS0 |
|
WAK_STATUS1 |
|
UART 和 LOGUART
对于需要特定时钟设置的外设,例如 UART 和 LOGUART,其设置流程在以下章节中进行了描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置唤醒源 (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2_BT/WAKE_SRC_UART_LOG) 要唤醒的 CPU( WAKEUP_KM4 或 WAKEUP_KM0),并确保中断注册在要唤醒的 CPU 上。选择时钟源:
XTAL: 在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal, 将 keep_OSC4M_on 设置为 TRUE。OSC2M: 在
ps_config[]
中将 keep_OSC4M_on 设置为 TRUE。
设置工作电压:在
ps_config[]
中将sleep_to_08V
设定为 TRUE 。通过释放 KM4 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒后清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,有以下限制:
Rx 时钟源只能为 OSC2M,且睡眠期间不可关闭 OSC4M。当波特率大于 115200 时,不建议使用 UART 作为唤醒源。
睡前需要调用 API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_OSC_LP)
将时钟切换到 OSC2M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_XTAL_40M)
切换为 XTAL40M Rx 时钟。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分会丢失。
当使用 LOGUART 作为唤醒源时,有以下限制:
若 Rx 时钟源为 OSC2M,睡眠期间不可关闭 OSC4M。
睡前需要调用 API
RCC_PeriphClockSource_LOGUART(LOGUART_CLK_OSC_LP)
将时钟切换到 OSC2M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSource_LOGUART(LOGUART_CLK_XTAL_40M)
切换为 XTAL40M Rx 时钟。
若 Rx 时钟源为 XTAL40M,睡眠期间不可关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分会丢失。
对于需要特定时钟设置的外设,如 UART 和 LOGUART,其设置流程在以下章节中进行描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置唤醒源 (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2/WAKE_SRC_UART3/WAKE_SRC_UART_LOG) 要唤醒的 CPU( WAKEUP_AP 或 WAKEUP_NP),并确保中断注册在要唤醒的 CPU 上。设定时钟源:在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal。通过释放 KM4 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒时清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分将会丢失。
当使用 LOGUART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分将会丢失。
对于需要特定时钟设置的外设,如 UART 和 LOGUART,其设置流程在以下章节中进行描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置唤醒源 (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2/WAKE_SRC_UART3/WAKE_SRC_UART_LOG) 要唤醒的 CPU( WAKEUP_AP 或 WAKEUP_NP),并确保中断注册在要唤醒的 CPU 上。设定时钟源:在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal。通过释放 KM4 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒时清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分将会丢失。
当使用 LOGUART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分将会丢失。
对于需要特定时钟设置的外设,如 UART 和 LOGUART,其设置流程在以下章节中进行描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置唤醒源 (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2/WAKE_SRC_UART3/WAKE_SRC_UART_LOG) 要唤醒的 CPU( WAKEUP_AP 或 WAKEUP_NP),并确保中断注册在要唤醒的 CPU 上。设定时钟源:在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal。通过释放 KM4 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒时清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分将会丢失。
当使用 LOGUART 作为唤醒源时,存在以下限制:
Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分将会丢失。
对于需要特定时钟设置的外设,如 UART 和 LOGUART,其设置流程在以下章节中进行描述。
UART
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置相关唤醒源(WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2/WAKE_SRC_UART_LOG)将要唤醒的 CPU(WAKEUP_AP/WAKEUP_NP/WAKEUP_LP),并确保中断注册在对应的 CPU 上。选择时钟源:
XTAL: 在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal, 将 keep_OSC4M_on 设置为 TRUE。OSC2M: 在
ps_config[]
中将 keep_OSC4M_on 设置为 TRUE。
通过释放 KM4 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒时清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,存在以下限制:
如果 Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
如果 Rx 时钟源为 OSC2M,睡眠期间不要关闭 OSC4M。
睡前需要调用 API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_OSC_LP)
将时钟切换到 OSC2M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_XTAL_40M)
切换为 XTAL40M Rx 时钟。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分将会丢失。
当使用 LOGUART 作为唤醒源时,存在以下限制:
如果 Rx 时钟源为 XTAL40M,睡眠期间不要关闭 XTAL。
如果 Rx 时钟源为 OSC2M,睡眠期间不要关闭 OSC4M。
睡前需要调用 API
RCC_PeriphClockSource_LOGUART(UARTLOG_CLK_OSC_LP)
将时钟切换到 OSC2M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSource_LOGUART(UARTLOG_CLK_XTAL_40M)
切换为 XTAL40M Rx 时钟。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分将会丢失。
对于需要特定时钟设置的外设,例如 UART 和 LOGUART,其设置流程在以下章节中进行了描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]
中设置唤醒源 (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2/WAKE_SRC_UART3/WAKE_SRC_UART_LOG) 要唤醒的 CPU( WAKEUP_AP 或 WAKEUP_NP),并确保中断注册在要唤醒的 CPU 上。选择时钟源:
OSC2M/OSC4M: 在
ps_config[]
中将 keep_osc4m_on_in_sleep 设置为 TRUE。XTAL: 在
ps_config[]
中将 xtal_mode_in_sleep 设置为 XTAL_Normal, keep_osc4m_on_in_sleep 设置为 TRUE。
设置工作电压:在
ps_config[]
中将regu_state_in_sleep
设定为 STATE2_LDOPC_SWRPFM_08 。通过释放 AP 上的唤醒锁进入睡眠模式(PMU_OS 需要被释放,因为系统启动时默认已获取)。
唤醒后清除 UART/LOGUART 中断。
备注
当使用 UART 作为唤醒源时,有以下限制:
如果 Rx 时钟源为 OSC2M,睡眠期间不可关闭 OSC4M。当波特率大于 115200 时,不建议选择该时钟源。
睡前通过 API
RCC_PeriphClockSourceSet(UARTx, OSC2M)
将时钟切换到 OSC2M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSourceSet(UARTx, XTAL)
切换为 XTAL40M Rx 时钟
如果 Rx 时钟源是 XTAL40M,在睡眠期间禁止关闭 XTAL40M 和 OSC4M。
用于唤醒的命令中超出 FIFO 深度(64 字节)的部分会丢失。
当使用 LOGUART 作为唤醒源时,有以下限制:
如果 Rx 时钟源为 OSC2M,睡眠期间不可关闭 OSC4M。
睡前通过 API
RCC_PeriphClockSourceSet(LOGUART, OSC4M)
将时钟切换到 OSC4M。醒后需要更高波特率,可通过 API
RCC_PeriphClockSourceSet(LOGUART, XTAL)
切换为 XTAL40M Rx 时钟
如果 Rx 时钟源为 XTAL40M,睡眠期间不可关闭 XTAL。
用于唤醒的命令中超出 FIFO 深度(16 字节)的部分会丢失。