电源管理架构
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 进行唤醒。
下展示了空闲任务的代码流程。在空闲任务中,系统会检查睡眠条件(包括唤醒锁状态、系统活跃时间等,详见章节 唤醒锁 API 和 pmu_set_sysactive_time),以决定是否进入睡眠模式。
当条件不满足时:CPU 执行 ARM WFI (等待中断)指令,使处理器挂起直至中断触发。通常由 SysTick 中断恢复运行,此模式称为 软件 Tickless。
当条件满足时:执行函数
freertos_pre_sleep_processing()进入睡眠模式或深度睡眠模式。
空闲任务中的 FreeRTOS Tickless
备注
即使设置了 FreeRTOS 时间控制机制(如软件定时器或 vTaskDelay),只要空闲任务被执行且满足条件,系统仍会进入睡眠模式。
Wi-Fi 低功耗
请参考 Wi-Fi 低功耗 章节以获取详细信息。
唤醒源
在不同低功耗模式下,可用于唤醒系统的唤醒源如下表所示:
唤醒源 |
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 模式
睡眠模式基于 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 的唤醒锁和深度唤醒锁进入深度睡眠模式
低功耗配置
github source code
唤醒掩码设置
在睡眠模式下,某些场景仅需唤醒单个 CPU 来执行程序,唤醒掩码模块即用于实现此功能。一般情况下,除了设置唤醒掩码,还需要注册唤醒源中断,以便在唤醒时由特定的 CPU 处理。
通过设置唤醒掩码,可选择仅唤醒某个指定的 CPU。若选择 KM4,需先唤醒 KM0 并由其恢复 KM4 运行。
用户可通过修改 ameba_sleepcfg.c 中的 sleep_wevent_config[] 来选择想要唤醒的目标 CPU。
每个唤醒源的属性可设置为以下值之一:
WAKEUP_KM4:仅唤醒 KM4
WAKEUP_KM0:仅唤醒 KM0
WAKEUP_NULL:禁用该唤醒源
/* 唤醒属性可设置为 WAKEUP_NULL/WAKEUP_KM4/WAKEUP_KM0 */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module Wakeup
{WAKE_SRC_SDIO, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_Keyscan, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_RTC, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_I2C1, WAKEUP_NULL},
{WAKE_SRC_I2C0, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_NULL},
{WAKE_SRC_UART2_BT, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_pmc_timer1, WAKEUP_KM0}, /* Internal use, do not change it */
{WAKE_SRC_pmc_timer0, WAKEUP_KM4}, /* Internal use, do not change it */
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_IPC_KM4, WAKEUP_KM4}, /* IPC can only wake up KM4, do not change it */
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_KM4_WAKE_IRQ, WAKEUP_KM0}, /* Internal use, do not change it */
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_KM0}, /* Wi-Fi wakeup, do not change it */
{WAKE_SRC_WIFI_FISR_FESR_IRQ, WAKEUP_KM0}, /* Wi-Fi wakeup, do not change it */
{0xFFFFFFFF, WAKEUP_NULL},
};
AON 唤醒引脚配置
AON 唤醒引脚是支持睡眠唤醒的外设之一。
SoC 提供两个 AON 唤醒引脚(PB30 和 PB31),需在 ameba_sleepcfg.c 中的 sleep_wakepin_config[] 中配置。
配置属性可选值如下:
DISABLE_WAKEPIN:禁用唤醒
HIGH_LEVEL_WAKEUP:GPIO 高电平触发唤醒
LOW_LEVEL_WAKEUP:GPIO 低电平触发唤醒
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 对应 _PB_30 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 对应 _PB_31 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
备注
默认情况下, sleep_wakepin_config[] 中未启用
AON_WAKEPIN_IRQ,需用户手动激活。唤醒掩码不会在
sleep_wakepin_config[]中被设置。如果需要将唤醒引脚用于睡眠模式,设置sleep_wevent_config[]中的WAKE_SRC_AON_WAKEPIN即可。
时钟和电压配置
XTAL、OSC4M 的状态及睡眠模式电压可通过 ameba_sleepcfg.c 中的 ps_config[] 配置,适用于需要在睡眠模式下保持外设时钟的场景。
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* Keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* Set XTAL mode during sleep mode, see enum xtal_mode_sleep for details */
.sleep_to_08V = FALSE, /* Default sleep to 0.7V, setting this option to TRUE will sleep to 0.8V */
};
睡眠模式配置
应用程序可通过调用函数
pmu_set_sleep_type(uint32_t type)()设置睡眠模式为 CG 或 PG用户可通过调用函数
pmu_get_sleep_type()获取当前 CPU 睡眠模式
备注
KM0 与 KM4 同属一个电源域,因此两者的睡眠模式相同。调用函数
pmu_set_sleep_type()设置 KM4 的睡眠模式,KM0 将自动同步 KM4 的睡眠模式。系统默认睡眠模式为 PG。如需修改睡眠模式,必须在进入睡眠状态前调用函数
pmu_set_sleep_type()。
github source code
唤醒掩码设置
在睡眠模式下,某些场景仅需唤醒单个 CPU 来执行程序,唤醒掩码模块即用于实现此功能。一般情况下,除了设置唤醒掩码,还需要注册唤醒源中断,以便在唤醒时由特定的 CPU 处理。
要启用特定唤醒源,需在 ameba_sleepcfg.c 的 sleep_wevent_config[] 数组中设置对应模块的状态。每个模块可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP。
例如:如果 WAKE_SRC_AON_WAKEPIN 设置为 WAKEUP_NP,表示当系统处于睡眠模式时,一旦发生 AON 唤醒引脚中断,NP 核将被唤醒处理事件。
/* 唤醒属性可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON 唤醒引脚配置
AON 唤醒引脚是支持睡眠唤醒的外设之一。
SoC 提供两个 AON 唤醒引脚(PA0 and PA1),需在 ameba_sleepcfg.c 中的 sleep_wakepin_config[] 中配置。
配置属性可选值如下:
DISABLE_WAKEPIN:禁用唤醒
HIGH_LEVEL_WAKEUP:GPIO 高电平触发唤醒
LOW_LEVEL_WAKEUP:GPIO 低电平触发唤醒
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 对应 _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 对应 _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
备注
默认情况下, sleep_wakepin_config[] 中未启用
AON_WAKEPIN_IRQ,需用户手动激活。唤醒掩码不会在
sleep_wakepin_config[]中被设置。如果需要将唤醒引脚用于睡眠模式,设置sleep_wevent_config[]中的WAKE_SRC_AON_WAKEPIN即可。
时钟和电压配置
XTAL、OSC4M 的状态及睡眠模式电压可通过 ameba_sleepcfg.c 中的 ps_config[] 配置,适用于需要在睡眠模式下保持外设时钟的场景。
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
睡眠模式配置
应用程序可通过调用函数
pmu_set_sleep_type(uint32_t type)()设置睡眠模式为 CG 或 PG用户可通过调用函数
pmu_get_sleep_type()获取当前 CPU 睡眠模式
备注
KR4 与 KM4 同属一个电源域,因此两者的睡眠模式相同。调用函数
pmu_set_sleep_type()设置 AP 的睡眠模式,NP 将自动同步 AP 的睡眠模式。系统默认睡眠模式为 PG。如需修改睡眠模式,必须在进入睡眠状态前调用函数
pmu_set_sleep_type()。
github source code
唤醒掩码设置
在睡眠模式下,某些场景仅需唤醒单个 CPU 来执行程序,唤醒掩码模块即用于实现此功能。一般情况下,除了设置唤醒掩码,还需要注册唤醒源中断,以便在唤醒时由特定的 CPU 处理。
要启用特定唤醒源,需在 ameba_sleepcfg.c 的 sleep_wevent_config[] 数组中设置对应模块的状态。每个模块可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP。
例如:如果 WAKE_SRC_AON_WAKEPIN 设置为 WAKEUP_NP,表示当系统处于睡眠模式时,一旦发生 AON 唤醒引脚中断,NP 核将被唤醒处理事件。
/* 唤醒属性可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON 唤醒引脚配置
AON 唤醒引脚是支持睡眠唤醒的外设之一。
SoC 提供两个 AON 唤醒引脚(PA0 and PA1),需在 ameba_sleepcfg.c 中的 sleep_wakepin_config[] 中配置。
配置属性可选值如下:
DISABLE_WAKEPIN:禁用唤醒
HIGH_LEVEL_WAKEUP:GPIO 高电平触发唤醒
LOW_LEVEL_WAKEUP:GPIO 低电平触发唤醒
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 对应 _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 对应 _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
备注
默认情况下, sleep_wakepin_config[] 中未启用
AON_WAKEPIN_IRQ,需用户手动激活。唤醒掩码不会在
sleep_wakepin_config[]中被设置。如果需要将唤醒引脚用于睡眠模式,设置sleep_wevent_config[]中的WAKE_SRC_AON_WAKEPIN即可。
时钟和电压配置
XTAL、OSC4M 的状态及睡眠模式电压可通过 ameba_sleepcfg.c 中的 ps_config[] 配置,适用于需要在睡眠模式下保持外设时钟的场景。
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
睡眠模式配置
应用程序可通过调用函数
pmu_set_sleep_type(uint32_t type)()设置睡眠模式为 CG 或 PG用户可通过调用函数
pmu_get_sleep_type()获取当前 CPU 睡眠模式
备注
KR4 与 KM4 同属一个电源域,因此两者的睡眠模式相同。调用函数
pmu_set_sleep_type()设置 AP 的睡眠模式,NP 将自动同步 AP 的睡眠模式。系统默认睡眠模式为 PG。如需修改睡眠模式,必须在进入睡眠状态前调用函数
pmu_set_sleep_type()。
github source code
唤醒掩码设置
在睡眠模式下,某些场景仅需唤醒单个 CPU 来执行程序,唤醒掩码模块即用于实现此功能。一般情况下,除了设置唤醒掩码,还需要注册唤醒源中断,以便在唤醒时由特定的 CPU 处理。
要启用特定唤醒源,需在 ameba_sleepcfg.c 的 sleep_wevent_config[] 数组中设置对应模块的状态。每个模块可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP。
例如:如果 WAKE_SRC_AON_WAKEPIN 设置为 WAKEUP_NP,表示当系统处于睡眠模式时,一旦发生 AON 唤醒引脚中断,NP 核将被唤醒处理事件。
/* 唤醒属性可设置为 WAKEUP_NULL/WAKEUP_NP/WAKEUP_AP/WAKEUP_DSP */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_VAD, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_NULL},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_AON_RTC, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_AP},
{WAKE_SRC_UART3, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NULL},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_NP},
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_NP},
{0xFFFFFFFF, WAKEUP_NULL},
};
AON 唤醒引脚配置
AON 唤醒引脚是支持睡眠唤醒的外设之一。
SoC 提供两个 AON 唤醒引脚(PA0 and PA1),需在 ameba_sleepcfg.c 中的 sleep_wakepin_config[] 中配置。
配置属性可选值如下:
DISABLE_WAKEPIN:禁用唤醒
HIGH_LEVEL_WAKEUP:GPIO 高电平触发唤醒
LOW_LEVEL_WAKEUP:GPIO 低电平触发唤醒
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 对应 _PA_0 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 对应 _PA_1 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
};
备注
默认情况下, sleep_wakepin_config[] 中未启用
AON_WAKEPIN_IRQ,需用户手动激活。唤醒掩码不会在
sleep_wakepin_config[]中被设置。如果需要将唤醒引脚用于睡眠模式,设置sleep_wevent_config[]中的WAKE_SRC_AON_WAKEPIN即可。
时钟和电压配置
XTAL、OSC4M 的状态及睡眠模式电压可通过 ameba_sleepcfg.c 中的 ps_config[] 配置,适用于需要在睡眠模式下保持外设时钟的场景。
PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE, /* keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF, /* set xtal mode during sleep mode, see enum xtal_mode_sleep for detail */
};
睡眠模式配置
应用程序可通过调用函数
pmu_set_sleep_type(uint32_t type)()设置睡眠模式为 CG 或 PG用户可通过调用函数
pmu_get_sleep_type()获取当前 CPU 睡眠模式
备注
KR4 与 KM4 同属一个电源域,因此两者的睡眠模式相同。调用函数
pmu_set_sleep_type()设置 AP 的睡眠模式,NP 将自动同步 AP 的睡眠模式。系统默认睡眠模式为 PG。如需修改睡眠模式,必须在进入睡眠状态前调用函数
pmu_set_sleep_type()。
github source code
唤醒掩码设置
在睡眠模式下,某些场景仅需唤醒单个 CPU 来执行程序,唤醒掩码模块即用于实现此功能。一般情况下,除了设置唤醒掩码,还需要注册唤醒源中断,以便在唤醒时由特定的 CPU 处理。
通过设置唤醒掩码,可选择仅唤醒某个指定的 CPU。若选择 KM4,需先唤醒 KM0 并由其恢复 KM4 运行。
用户可通过修改 ameba_sleepcfg.c 中的 sleep_wevent_config[] 来选择想要唤醒的目标 CPU。
每个唤醒源的属性可设置为以下值之一:
WAKEUP_KM4:仅唤醒 KM4
WAKEUP_KM0:仅唤醒 KM0
WAKEUP_NULL:禁用该唤醒源
/* 唤醒属性可设置为 WAKEUP_NULL/WAKEUP_LP/WAKEUP_NP/WAKEUP_AP */
WakeEvent_TypeDef sleep_wevent_config[] = {
// Module wakeup
{WAKE_SRC_nFIQOUT1_OR_nIRQOUT1, WAKEUP_NULL},
{WAKE_SRC_nFIQOUT0_OR_nIRQOUT0, WAKEUP_NULL},
{WAKE_SRC_BT_WAKE_HOST, WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN, WAKEUP_NULL},
{WAKE_SRC_UART2, WAKEUP_NULL},
{WAKE_SRC_UART1, WAKEUP_NULL},
{WAKE_SRC_UART0, WAKEUP_NULL},
{WAKE_SRC_SPI1, WAKEUP_NULL},
{WAKE_SRC_SPI0, WAKEUP_NULL},
{WAKE_SRC_IPC_AP, WAKEUP_AP}, /* do not change it */
{WAKE_SRC_IPC_NP, WAKEUP_NP}, /* do not change it */
{WAKE_SRC_VADBT_OR_VADPC, WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN, WAKEUP_LP},
{WAKE_SRC_BOR, WAKEUP_NULL},
{WAKE_SRC_ADC, WAKEUP_NULL},
{WAKE_SRC_CTOUCH, WAKEUP_NULL},
{WAKE_SRC_RTC, WAKEUP_NULL},
{WAKE_SRC_GPIOC, WAKEUP_NULL},
{WAKE_SRC_GPIOB, WAKEUP_NULL},
{WAKE_SRC_GPIOA, WAKEUP_NULL},
{WAKE_SRC_UART_LOG, WAKEUP_NULL},
{WAKE_SRC_Timer7, WAKEUP_NULL},
{WAKE_SRC_Timer6, WAKEUP_NP},
{WAKE_SRC_Timer5, WAKEUP_NULL},
{WAKE_SRC_Timer4, WAKEUP_NULL},
{WAKE_SRC_Timer3, WAKEUP_NULL},
{WAKE_SRC_Timer2, WAKEUP_NULL},
{WAKE_SRC_Timer1, WAKEUP_NULL},
{WAKE_SRC_Timer0, WAKEUP_NULL},
{WAKE_SRC_WDG0, WAKEUP_NULL},
{WAKE_SRC_AP_WAKE, WAKEUP_NULL},
{WAKE_SRC_NP_WAKE, WAKEUP_NULL},
{WAKE_SRC_AON_TIM, WAKEUP_NULL},
{WAKE_SRC_WIFI_FTSR_MAILBOX, WAKEUP_LP}, /* Wi-Fi wakeup, do not change it */
{WAKE_SRC_WIFI_FISR_FESR, WAKEUP_LP}, /* Wi-Fi wakeup, do not change it */
{0xFFFFFFFF, WAKEUP_NULL}, /* Table end */
};
AON 唤醒引脚配置
AON 唤醒引脚是支持睡眠唤醒的外设之一。
SoC 提供四个 AON 唤醒引脚(PB21、PB22、PB23 和 PB24),需在 ameba_sleepcfg.c 中的 sleep_wakepin_config[] 中配置。
配置属性可选值如下:
DISABLE_WAKEPIN:禁用唤醒
HIGH_LEVEL_WAKEUP:GPIO 高电平触发唤醒
LOW_LEVEL_WAKEUP:GPIO 低电平触发唤醒
/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
// wakepin config
{WAKEPIN_0, DISABLE_WAKEPIN}, /* WAKEPIN_0 对应 _PB_21 */
{WAKEPIN_1, DISABLE_WAKEPIN}, /* WAKEPIN_1 对应 _PB_22 */
{WAKEPIN_2, DISABLE_WAKEPIN}, /* WAKEPIN_2 对应 _PB_23 */
{WAKEPIN_3, DISABLE_WAKEPIN}, /* WAKEPIN_3 对应 _PB_24 */
{0xFFFFFFFF, DISABLE_WAKEPIN},
}
备注
PB23和PB24默认用于 LOGUART 的收发。如果需要将其用作深度睡眠唤醒源,请联系 Realtek。活动模式和睡眠模式的引脚通过 pinmap 控制,必要时修改ameba_pinmapcfg.c中的 pmap_func[] 实现模式切换。默认情况下, sleep_wakepin_config[] 中未启用
AON_WAKEPIN_IRQ,需用户手动激活。唤醒掩码不会在
sleep_wakepin_config[]中被设置。如果需要将唤醒引脚用于睡眠模式,设置sleep_wevent_config[]中的WAKE_SRC_AON_WAKEPIN即可。
时钟和电压配置
XTAL、OSC4M 的状态及睡眠模式电压可通过 ameba_sleepcfg.c 中的 ps_config[] 配置,适用于需要在睡眠模式下保持外设时钟的场景。
PSCFG_TypeDef ps_config = {
.km0_tickles_debug = TRUE,/* if open WIFI FW, should close it, or beacon will lost in WOWLAN */
.km0_pll_off = TRUE,
.km0_audio_vad_on = FALSE,
#if defined(CONFIG_CLINTWOOD ) && CONFIG_CLINTWOOD
.km0_config_psram = FALSE, /* if device enter sleep mode or not, false for keep active */
.km0_sleep_withM4 = FALSE,
#else
.km0_config_psram = TRUE, /* if device enter sleep mode or not, false for keep active */
.km0_sleep_withM4 = TRUE,
#endif
.keep_OSC4M_on = FALSE,
.xtal_mode_in_sleep = XTAL_OFF,
.swr_mode_in_sleep = SWR_PFM,
};
低功耗相关 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,否则会很快再次进入休眠模式。
下文列示了用于控制唤醒锁或深度唤醒锁的 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
如下寄存器可用于获取唤醒原因。
寄存器 |
参数 |
|---|---|
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
如下寄存器可用于获取唤醒原因。
寄存器 |
参数 |
|---|---|
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
如下寄存器可用于获取唤醒原因。
寄存器 |
参数 |
|---|---|
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 |
|
UART 和 LOGUART
对于需要特定时钟设置的外设,例如 UART 和 LOGUART,其设置流程在以下章节中进行了描述。
初始化 UART/LOGUART 并使能其中断。
设定唤醒源:在
sleep_wevent_config[]中设置唤醒源 (UART0/UART1/UART2_BT/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[]中设置唤醒源 (UART0/UART1/UART2/UART3/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[]中设置唤醒源 (UART0/UART1/UART2/UART3/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[]中设置唤醒源 (UART0/UART1/UART2/UART3/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[]中设置相关唤醒源(UART0/UART1/UART2/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 字节)的部分将会丢失。