电源管理架构
SoC 搭载了先进的电源管理控制器(Power Management Controller,PMC),可灵活控制芯片不同电源域的上电时序,实现性能与功耗的最佳平衡。
SoC 的数字系统中一般包含三个核心电源域:AON 域、SYSON 域和 SOC 域。不同省电模式下,各电源域的关断策略存在差异。
Ameba 系列 SoC 的电源域和唤醒源如下所示:
低功耗模式
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 规范中定义的 WiFi STA 省电模式包括以下关键特性:
在未发送或接收数据时,进入休眠状态。
定期唤醒以接收 AP 的 Beacon 帧。
利用 Beacon 中的 TIM(Traffic Indication Map, 流量指示映射)进行数据管理。
站点休眠期间无法接收任何数据帧,因此 AP 需缓存待传数据帧,STA 需周期性唤醒检测信标帧。
省电模式时序图
基于上述标准 IEEE 802.11 省电机制,Ameba IC 提供三种 WiFi 省电模式:
模式 |
全称 |
描述 |
---|---|---|
LPS |
传统省电模式 |
在WiFi连接状态下,在活跃和休眠状态之间切换,并定期打开或关闭收发器以实现省电。 |
WoWLAN |
无线局域网唤醒 |
允许SoC系统在保持WiFi连接的同时进入睡眠模式。 系统可通过单播数据包、广播/组播数据包(可选)以及AP断连事件被唤醒。 |
IPS |
非活动省电模式 |
在未连接时实现完全断电状态。 |
WiFi 省电模式进入和退出条件:
模式 |
用户配置项 |
进入和退出条件 |
---|---|---|
LPS |
wifi_user_config.lps_enable |
在WiFi连接状态下,根据流量低于或高于设定阈值时,自动进入或退出LPS模式。 |
WoWLAN |
默认支持 |
在WiFi连接状态下,随AP(application processor)休眠或活跃模式自动进入或退出WoWLAN模式。 |
IPS |
wifi_user_config.ips_enable |
WiFi连接或断开时进入或退出。 |
唤醒源
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
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 字节)的部分会丢失。