低功耗编程接口
睡眠模式配置
pmu_set_sleep_type
项目 |
描述 |
|---|---|
功能 |
设置系统的 Sleep 模式,注意系统默认 Sleep 模式为 PG。 |
参数 |
type:PG 或者 CG |
返回值 |
无 |
pmu_get_sleep_type
项目 |
描述 |
|---|---|
功能 |
获取当前系统的 Sleep 模式。 |
参数 |
无 |
返回值 |
type:PG 或者 CG |
睡眠锁(wakelock)
睡眠锁是一个 32 bit 的变量,每个 bit 代表一个模块的睡眠锁,如果某个模块持有睡眠锁,系统将无法进入 Sleep 模式,只有所有模块的睡眠锁都释放之后(wakelock=0),系统才可能进入 sleep 模式。
睡眠锁可以用于保护某段程序不会走到中间(因等待)误入 sleep 模式。
用户也可以在 PMU_DEVICE 中添加自定义的睡眠锁,但不得修改已经定义好的睡眠锁。
如下是一个睡眠锁定义的实例,注意不同的芯片定义不一样:
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,
};
SDK 定义了 wakelock 和 deepwakelock 两种睡眠锁:
wakelock: 用于 Sleep 模式
当系统启动时,AP 持有 wakelock PMU_OS,NP 持有 wakelock PMU_OS 以及 PMU_AP_RUN,
当 AP 的所有 wakelock 被释放后,AP 向 NP 发送 IPC 然后进入 WFI,
NP 收到 IPC 之后,会对 AP 进行断电 (power-gate) 或关闭时钟 (clock-gate),
然后 NP 释放 PMU_OS 以及 PMU_AP_RUN,让自己也可以进入 Sleep 模式。
deepwakelock: 用于 Deep-Sleep 模式
当系统启动时,AP 持有 deepwakelock PMU_OS,
当 AP 的所有 deepwakelock 被释放后,AP 向 NP 发送 IPC 然后进入 WFI,
NP 收到 IPC 之后,根据状况设置整个系统进入 deep-sleep 模式。
备注
当系统唤醒后,除非重新获取 wakelock,否则会很快再次进入省电模式
请注意使用 pmu_acquire_wakelock 或者 pmu_set_sysactive_time 保护重要的行为
下面介绍用于控制 wakelock 或 deepwakelock 的 API。
pmu_acquire_wakelock
项目 |
描述 |
|---|---|
功能 |
为某个模块获取睡眠锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_release_wakelock
项目 |
描述 |
|---|---|
功能 |
释放某个模块的睡眠锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_acquire_deepwakelock
项目 |
描述 |
|---|---|
功能 |
为某个模块获取深度睡眠锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
pmu_release_deepwakelock
项目 |
描述 |
|---|---|
功能 |
释放某个模块的深度睡眠锁 |
参数 |
nDeviceId:对应模块的设备 ID |
返回值 |
无 |
Active 时间设置
pmu_set_sysactive_time
在某些场景下,系统需要在 Active 状态保持唤醒一段时间以完成特定行为,比如某些行为的结束点有多个分支的情况,这种行为很难被 wakelock 保护。
项目 |
描述 |
|---|---|
功能 |
设置系统保持 Active 状态的持续时间 |
参数 |
timeout:时间(单位:毫秒)
系统将从当前时刻起保持 Active 状态达此时长
|
返回值 |
0 |
备注
当有有多个程序设置 Active 时间的时候,系统会计算一个最大值作为系统可以进入 Sleep 模式的时间。
最大睡眠时间设置
pmu_set_max_sleep_time
项目 |
描述 |
|---|---|
功能 |
设置最大睡眠时间,超时后,系统会被唤醒。 |
参数 |
timer_ms:系统最大睡眠超时时间(单位:毫秒) |
返回值 |
无 |
备注
超时前,系统可能被其他事件唤醒。
此设置仅单次有效,系统唤醒后时间自动清零。
Sleep Hook/Wakeup Hook 注册
用于为 <nDeviceId> 注册 Sleep Hook/Wakeup Hook 函数:
Sleep Hook 函数:系统进入 Sleep 模式前调用
Wakeup Hook 函数:系统唤醒后进入系统线程之前调用
Wakeup Hook 函数的一个典型应用是获取睡眠锁,以防止芯片再次进入休眠模式。
备注
如果 CPU 选择 PG,部分外设会断电,系统醒来后这些外设需要重新初始化才能工作,外设重新初始化可以在 Wakeup Hook 函数中实现。
备注
禁止在 Sleep Hook/Wakeup Hook 函数中使用可能引发 OS 调度的 API(如:
rtos_task_yield、rtos_time_delay_ms、信号量/互斥锁相关操作)禁止在 Sleep Hook 函数中调用
pmu_set_sysactive_time(Wakeup Hook 函数中允许)
pmu_register_sleep_callback
项目 |
描述 |
|---|---|
功能 |
为某个模块注册 Sleep Hook/Wakeup Hook 函数 |
参数 |
- nDeviceId:需要 Sleep Hook/Wakeup Hook 函数的设备 ID
- sleep_hook_fun:Sleep Hook 函数
- sleep_param_ptr:Sleep Hook 函数参数
- wakeup_hook_fun:Wakeup Hook 函数
- wakeup_param_ptr:Wakeup Hook 函数参数
|
返回值 |
无 |
pmu_unregister_sleep_callback
项目 |
描述 |
|---|---|
功能 |
注销某个模块的 Sleep Hook/Wakeup Hook 函数 |
参数 |
- nDeviceId:需要注销 Sleep Hook/Wakeup Hook 函数的设备 ID
- sleep_hook_fun:Sleep Hook 函数
- sleep_param_ptr:Sleep Hook 函数参数
- wakeup_hook_fun:Wakeup Hook 函数
- wakeup_param_ptr:Wakeup Hook 函数参数
|
返回值 |
无 |
进入 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 的睡眠锁和深度睡眠锁进入深度睡眠模式