LISA PM 组件
LISA PM 是基于 ARCS HAL PM 的系统电源管理组件,负责把应用侧的电源策略、系统睡眠锁、设备 system PM、唤醒原因、睡眠统计、WiFi 省电协同和 AP/CP 双核协同统一到一组 lisa_pm_*() 接口中。
组件由公共接口、核心调度、设备 PM 分发、ARCS SoC 移植层和可选扩展组成,可用于应用侧自动轻睡眠、外设低功耗恢复、WiFi 省电协同以及 AP/CP 双核运行模式。
功能特性
系统策略:通过
lisa_pm_set_system_policy()在ACTIVE和AUTO_LIGHT_SLEEP之间切换。系统睡眠锁:
lisa_pm_lock_acquire()/lisa_pm_lock_release()使用引用计数封装 HALPM_LOCK_APP。设备 system PM:自动发现
lisa_device中挂载的lisa_pm_system_ops_t,统一执行 idle 检查、睡眠前挂起和唤醒后恢复。应用睡眠回调:支持单实例
before_sleep/after_wake,其中after_wake延后到lisa_pm内部任务执行。唤醒原因和统计:把 ARCS AON
PMU_WAKEUP_*映射为lisa_pm_wakeup_cause_t,可选统计睡眠次数、时长和占比。WiFi 省电协同:在
CONFIG_LISA_PM_WIFI=y时提供 WiFi PS 模式和 WiFi PS 锁接口。双核运行模式:AP/CP 两侧均运行固件并初始化
lisa_pm,HAL PM 通过 AMP shared memory 协同进入和退出 light sleep。远端 AP 睡眠锁:在 CP 侧可通过 remote lock MRPC 请求 AP 持有或释放系统睡眠锁。
文件说明
路径 |
说明 |
|---|---|
|
对应用和驱动开放的 LISA PM 公共接口 |
|
系统策略、系统锁、初始化、应用睡眠回调和 after-wake 任务 |
|
system PM 设备发现、复制注册和回调分发 |
|
睡眠统计 hook 实现 |
|
WiFi PS 模式和 WiFi PS 锁封装 |
|
remote lock 公共 wrapper |
|
ARCS SoC porting、snapshot 默认区和 remote lock MRPC 适配 |
|
底层 HAL PM 实现,包含 |
|
设备 PM 描述、wakeup-source vtable 和 PM 版本注册宏 |
配置选项
启用组件:
CONFIG_LISA_PM=y
主要配置:
配置 |
说明 |
|---|---|
|
启用 LISA PM;自动选择 |
|
指定本固件在 HAL PM 中是否是 primary 核;CP 默认 |
|
CP 侧声明 AP 是运行中的 PM 对端核心;打开后不会选择 |
|
启用睡眠统计,默认 |
|
|
|
|
|
|
|
启用 WiFi 省电扩展;依赖 |
|
CP 侧 remote lock client,使用 AP PM lock MRPC 服务 |
|
AP 侧 remote lock server,把远端请求映射为本地 |
|
预留的 Runtime PM 开关;当前 system PM 不依赖它 |
|
存在 ILM 时, |
|
存在 ILM 时, |
双核示例中的典型配置:
# AP remote 固件
CONFIG_ARCS_AP_CORE=y
CONFIG_ARCS_HAL_IPC=y
CONFIG_LISA_PM=y
CONFIG_LISA_PM_CORE_PRIMARY=n
# CP 主固件
CONFIG_ARCS_CP_CORE=y
CONFIG_ARCS_HAL_IPC=y
CONFIG_LISA_PM=y
CONFIG_LISA_PM_CORE_PRIMARY=y
CONFIG_LISA_PM_DUAL_CORE=y
components/lisa_pm/CMakeLists.txt 会根据 CONFIG_LISA_PM_CORE_PRIMARY 导出:
角色 |
编译定义 |
|---|---|
primary 核 |
|
非 primary 核 |
|
API 接口
初始化
int32_t lisa_pm_init(void);
lisa_pm_init() 是幂等入口。当前 ARCS porting 的主要初始化顺序如下:
创建并获取
lisa_pm内部状态锁。调用
vrtc_init(),再调用pm_init()。存在 ILM 时按配置注册默认 snapshot 区域。
将当前系统策略下发给 HAL PM;默认策略是
LISA_PM_SYSTEM_POLICY_ACTIVE。创建 after-wake 队列和
lisa_pm_wake内部任务。CONFIG_LISA_PM_STATS=y时注册统计 hook,占用PM_HOOK_ID_0。注册框架 common hook,占用
PM_HOOK_ID_1。注册 HAL managed device,占用
PM_DEV_ID_UART,其中.on_exit指向lisa_pm_framework_device_on_wake(),.on_wake = NULL。遍历
lisa_device,把带system_ops的设备复制到lisa_pm内部表。初始化当前记录的唤醒原因。
应用不需要在使用 lisa_pm 前显式调用 vrtc_init()。
系统策略
typedef enum {
LISA_PM_SYSTEM_POLICY_ACTIVE = 0,
LISA_PM_SYSTEM_POLICY_AUTO_LIGHT_SLEEP,
} lisa_pm_system_policy_t;
int32_t lisa_pm_set_system_policy(lisa_pm_system_policy_t policy);
lisa_pm_system_policy_t lisa_pm_get_system_policy(void);
在 ARCS 上,策略映射如下:
LISA PM 策略 |
HAL PM 配置 |
|---|---|
|
|
|
|
当前 HAL PM_MODE_LIGHT_SLEEP 使用深睡恢复路径承载自动轻睡语义。除 AON/保留域和 snapshot 覆盖区域外,外设寄存器和普通内存状态需要通过 driver 的 resume_restore() 或应用重配置恢复。
系统睡眠锁
int32_t lisa_pm_lock_acquire(void);
int32_t lisa_pm_lock_release(void);
int32_t lisa_pm_lock_get_count(void);
bool lisa_pm_is_sleep_blocked(void);
锁使用引用计数:计数从 0 到 1 时调用 HAL pm_lock_acquire(PM_LOCK_APP),计数从 1 到 0 时调用 pm_lock_release(PM_LOCK_APP)。计数大于 0 时,HAL pm_can_sleep() 会因为 pm_env.lock_bits != 0 放弃 deep sleep,本轮 idle 只执行普通 WFI。
应用睡眠回调
typedef struct {
void (*before_sleep)(void *user_data);
void (*after_wake)(void *user_data, lisa_pm_wakeup_cause_t cause);
void *user_data;
} lisa_pm_sleep_callback_t;
int32_t lisa_pm_sleep_callback_register(const lisa_pm_sleep_callback_t *callback);
int32_t lisa_pm_sleep_callback_unregister(void);
当前只支持一个应用回调实例。
before_sleep和after_wake可只填一个,但不能同时为NULL。before_sleep运行在 HAL PM enter 关键路径中,必须短小、确定、不可阻塞。after_wake被投递到lisa_pm_wake任务,已离开 PM exit 关键路径,可执行普通任务上下文允许的恢复动作。after_wake投递前会临时直接持有一个 HALPM_LOCK_APP,任务取到消息后先释放该临时锁,再执行用户回调;这个临时锁不计入lisa_pm_lock_get_count()。
唤醒原因
typedef enum {
LISA_PM_WAKEUP_TIMER = 0,
LISA_PM_WAKEUP_RTC,
LISA_PM_WAKEUP_BT,
LISA_PM_WAKEUP_WIFI,
LISA_PM_WAKEUP_GPIO,
LISA_PM_WAKEUP_UNKNOWN,
} lisa_pm_wakeup_cause_t;
lisa_pm_wakeup_cause_t lisa_pm_get_wakeup_cause(void);
ARCS porting 使用 AON PMU_WAKEUP_* ISR 位做归一化映射:WiFi、GPIOB_00…09、Timer、RTC、BT 分别映射到对应的 LISA_PM_WAKEUP_*。注意 PMU_WAKEUP_* 是 AON 唤醒状态位,和 pm_sleep_config_t.wakeup_src_mask 使用的 PM_WAKEUP_* 不是同一个 namespace。
睡眠统计
typedef struct {
uint32_t sleep_count;
uint32_t sleep_abort_count;
uint64_t total_sleep_us;
uint64_t total_active_us;
uint32_t last_sleep_us;
uint32_t max_sleep_us;
uint32_t wakeup_cause_count[LISA_PM_WAKEUP_UNKNOWN + 1];
} lisa_pm_stats_t;
int32_t lisa_pm_get_stats(lisa_pm_stats_t *stats);
int32_t lisa_pm_reset_stats(void);
uint32_t lisa_pm_get_sleep_ratio(void);
lisa_pm_get_sleep_ratio() 返回万分比,例如 5234 表示 52.34%。当前统计由 HAL common hook 更新,sleep_abort_count 字段保留在结构体中,当前实现未在 abort 路径累加。
WiFi 省电扩展
typedef enum {
LISA_PM_WIFI_PS_OFF = 0,
LISA_PM_WIFI_PS_DTIM,
LISA_PM_WIFI_PS_LISTEN,
} lisa_pm_wifi_ps_mode_t;
typedef struct {
uint16_t listen_interval;
} lisa_pm_wifi_ps_config_t;
int32_t lisa_pm_wifi_set_ps_mode(lisa_pm_wifi_ps_mode_t mode,
const lisa_pm_wifi_ps_config_t *config);
lisa_pm_wifi_ps_mode_t lisa_pm_wifi_get_ps_mode(void);
int32_t lisa_pm_wifi_lock_acquire(void);
int32_t lisa_pm_wifi_lock_release(void);
int32_t lisa_pm_wifi_lock_get_count(void);
bool lisa_pm_wifi_is_power_save_blocked(void);
LISA_PM_WIFI_PS_LISTEN 的 listen_interval 有效范围是 1 到 19,未传配置时默认使用 10。对当前 WiFi 库而言,LISTEN 参数必须在 WiFi 发起连接前设置,否则监听周期不会生效。WiFi PS 锁只控制 WiFi 省电,不等同于系统睡眠锁。
远端 AP 睡眠锁
typedef struct {
uint32_t locked;
} lisa_pm_remote_lock_state_t;
int32_t lisa_pm_remote_lock_acquire(void);
int32_t lisa_pm_remote_lock_release(void);
int32_t lisa_pm_remote_lock_get_state(lisa_pm_remote_lock_state_t *state);
这些接口仅在 CONFIG_LISA_PM_REMOTE_LOCK_CLIENT=y 时对 CP 侧开放。ARCS 当前实现通过 AP PM lock MRPC 服务访问 AP 侧 lisa_pm_lock_*(),用于 CP 业务在需要时阻止 AP 进入或停留在低功耗等待路径。
System PM 设备接入
lisa_device 注册
推荐驱动先使用普通设备注册宏完成设备本体注册,再用 LISA_DEVICE_PM_ATTACH() 独立声明 PM 能力:
LISA_DEVICE_REGISTER_DEINIT(name, api_ptr, priv_data_ptr, user_data_ptr,
init_fn, deinit_fn, level, priority);
#if CONFIG_LISA_PM
LISA_DEVICE_PM_ATTACH(name, system_ops, wakeup_ops, ctx);
#endif
LISA_DEVICE_PM_ATTACH() 会生成独立的 lisa_device_pm_t attach 条目,name 必须与前面的设备注册名一致:
typedef struct {
const lisa_pm_system_ops_t *system_ops;
const lisa_pm_wakeup_ops_t *wakeup_ops;
void *ctx;
} lisa_device_pm_t;
system_ops 和 wakeup_ops 是两个独立能力槽位:
字段 |
回答的问题 |
调用方 |
典型内容 |
不负责 |
|---|---|---|---|---|
|
这个设备当前是否允许系统睡眠,以及睡前/醒后如何快速处理 |
|
|
配置唤醒条件、使能唤醒源 |
|
这个设备能否作为唤醒源,以及如何把唤醒条件下发到硬件 |
|
缓存 GPIO/RTC 等唤醒条件、启用/禁用硬件 wakeup |
判断设备是否忙、睡前挂起、醒后恢复 |
两个槽位互不依赖:设备可以只提供
system_ops、只提供wakeup_ops,也可以两个都提供;不支持的能力填NULL。ctx只透传给system_ops回调,通常填设备私有数据指针;wakeup_ops回调直接接收lisa_device_t *dev,再从 device 中取私有数据。CONFIG_LISA_PM=n时,LISA_DEVICE_PM_ATTACH()为空宏,不影响设备本体注册和驱动可用性。lisa_pm_init()会扫描设备自带 PM 描述和独立 PM attach 段,只自动接管system_ops;wakeup-source 的启停由应用通过lisa_device_wakeup_enable()显式控制。LISA_DEVICE_REGISTER_PM()/LISA_DEVICE_REGISTER_PM_DEINIT()仍保留兼容,现有驱动可继续使用。
system_ops 语义
typedef struct {
int32_t (*check_idle)(void *ctx);
int32_t (*prepare_suspend)(void *ctx);
int32_t (*resume_restore)(void *ctx);
} lisa_pm_system_ops_t;
回调 |
执行时机 |
返回值语义 |
|---|---|---|
|
HAL |
返回 |
|
HAL enter handler 中,真正睡眠前 |
返回 |
|
HAL exit handler 中,唤醒后 |
返回 |
实现要求:
不能阻塞:PM 关键路径中不要等待 mutex/event,不要访问文件系统、网络或大块动态内存分配。
只做快速硬件动作:
prepare_suspend()/resume_restore()可能在关中断或调度受限阶段执行,应只处理寄存器、HAL 状态和 pinmux 等必要动作。忙态显式阻止睡眠:设备正在传输或处于不可断电阶段时,
check_idle()必须返回0。区分驱动恢复和应用恢复:
resume_restore()只负责驱动基础状态;业务通道、IRQ、callback、USB 枚举、音频流等应用态配置需要由应用在唤醒后重新配置。需要显式释放的设备:如果设备驱动的
deinit_fn/init_fn会释放或创建 FreeRTOS 对象、堆内存、USB/Audio 等复杂资源,应用应在进入AUTO_LIGHT_SLEEP前的正常任务上下文调用lisa_device_destroy()或对应 stop/deinit 接口;唤醒后在after_wake或普通任务上下文调用lisa_device_reinit()或对应 start/init 接口,再重新完成业务配置。禁止在 PM 临界区重建资源:不要在
prepare_suspend()/resume_restore()中调用lisa_device_destroy()、lisa_device_reinit()或会创建/删除 OS 对象的 API;这些接口应放在 shell 命令、业务任务或 appafter_wake任务上下文中执行。
wakeup_ops 语义
wakeup_ops 只描述设备作为唤醒源时的配置缓存和硬件启停,不参与 check_idle() 判断,也不替代 prepare_suspend() / resume_restore()。lisa_device 提供与源类型无关的 wakeup-source 总闸:
bool lisa_device_wakeup_is_capable(lisa_device_t *dev);
int32_t lisa_device_wakeup_enable(lisa_device_t *dev, bool enable);
bool lisa_device_wakeup_is_enabled(lisa_device_t *dev);
驱动侧 vtable:
typedef struct {
int32_t (*configure)(struct lisa_device *dev, uint32_t sub_idx, uint32_t trigger);
int32_t (*clear)(struct lisa_device *dev, uint32_t sub_idx);
int32_t (*set_enabled)(struct lisa_device *dev, bool enable);
} lisa_pm_wakeup_ops_t;
当前约定是强一致缓存模型:
driver 的
configure()/clear()只更新内部 wakeup 缓存,不下发硬件。lisa_device_wakeup_enable(dev, true)调用 driverset_enabled(true),一次性把缓存下发到硬件。lisa_device_wakeup_enable(dev, false)撤销该 device 已下发的所有 wakeup 配置。在线修改触发条件必须按
enable(false) -> configure/clear -> enable(true)顺序执行。缓存为空时
enable(true)约定返回 0,但不会实际打开任何硬件唤醒源。
以 GPIO 为例:
lisa_device_t *gpiob = lisa_device_get("gpiob");
lisa_gpio_configure(gpiob, 7, LISA_GPIO_INPUT | LISA_GPIO_PULL_UP);
lisa_gpio_configure_wakeup(gpiob, 7, LISA_GPIO_WAKEUP_LEVEL_LOW);
lisa_device_wakeup_enable(gpiob, true);
ARCS PMU GPIO 唤醒仅支持 GPIOB_00…GPIOB_09。
HAL PM 睡眠和唤醒流程
lisa_pm 不直接执行硬件睡眠,而是把策略、锁、设备回调和应用回调接入 ARCS HAL PM。HAL PM 在 FreeRTOS idle 的 tickless 路径中决定本轮是否进入低功耗:
vPortSuppressTicksAndSleep()
-> pm_can_sleep()
-> 允许睡眠: pm_light_sleep(xExpectedIdleTime)
-> 不允许睡眠: __WFI()
pm_can_sleep() 的核心准入条件:
PM 环境已经初始化完成。
pm_env.config->mode == PM_MODE_LIGHT_SLEEP。pm_env.lock_bits == 0;lisa_pm_lock_acquire()会设置PM_LOCK_APP。双核模式下,本核心
cross_core_lock == 0。primary 核需要
vrtc_is_allow_sleep()返回允许。所有 HAL device handler 的
check_idle(PM_MODE_LIGHT_SLEEP)都不能返回 0。
如果任一条件不满足,本轮 idle 只执行普通 __WFI(),不会进入深睡恢复路径,也不会触发 lisa_pm 的 prepare_suspend() / resume_restore()。
睡眠进入流程
满足准入条件后,HAL 进入 pm_light_sleep():
pm_light_sleep()
-> 停止 SysTimer
-> 关中断并 flush log
-> eTaskConfirmSleepModeStatus() 二次确认
-> pm_execute_enter_handler()
-> pm_light_sleep_prepare()
-> pm_hw_execute_sleep()
关键步骤如下:
执行 enter handler:HAL 按 handler 类型从后向前执行 enter handler。对
lisa_pm来说,顺序表现为stats enter、framework enter、app before_sleep、lisa_device prepare_suspend。保存上下文:
pm_light_sleep_prepare()保存寄存器上下文;primary 核清除 AON wake cause、保存 BootClock、配置 AON 唤醒源和 RAM retention;非 primary 核调整 mailbox IRQ 优先级并清除 VRTC alert 状态。设置唤醒入口:
pm_hw_execute_sleep()调用pm_set_wakeup_entry((uint32_t)__light_sleep_entry),把__light_sleep_entry登记为本次低功耗的 wakeup entry。AON 唤醒后,硬件/启动恢复路径会读取该入口地址并跳转执行,从而进入 HAL 的恢复流程。配置硬件深睡:primary 核调用
HAL_PMU_ConfigDeepSleepMode(PMU_SLEEPMODE_MODE2, PMU_HOLDENTRY_WFI),使用 PMU deep sleep mode2 承载本次PM_MODE_LIGHT_SLEEP。保存 snapshot:启用
CONFIG_PM_PSRAM时,HAL 把已注册 snapshot 区域复制到 PSRAM,并记录 checksum;primary 核随后让 PSRAM 进入 sleep。进入低功耗:执行
__light_sleep_save(),系统进入由 AON 唤醒源控制的低功耗状态。
唤醒恢复流程
AON 唤醒源触发后,系统从 __light_sleep_entry 进入 pm_sleep_startup(),再回到 pm_light_sleep() 后半段:
AON wake source
-> __light_sleep_entry
-> pm_sleep_startup()
-> 回到 pm_light_sleep()
-> pm_light_sleep_restore()
-> vTaskStepTick()
-> pm_execute_exit_handler()
恢复路径的主要工作:
恢复基础硬件:primary 核恢复 RAM power、BootClock、cache、PSRAM、Flash 和中断控制相关状态;非 primary 核先进入
PM_CORE_STATE_STARTUP,等待 primary 核通过 IPC 唤醒后继续恢复。恢复 snapshot:启用
CONFIG_PM_PSRAM时,pm_snapshot_restore()把 PSRAM 中的 snapshot 内容复制回原地址,并用 checksum 校验恢复结果。获取唤醒原因:HAL 读取 AON wake cause,写入
pm_wakeup_cause;双核模式下 primary 核同时更新共享pm_data.last_wakeup_cause。恢复寄存器和浅 WFI 模式:回到
pm_light_sleep()后执行pm_light_sleep_restore(),恢复寄存器上下文,必要时唤醒对端核心,并把 WFI 模式切回WFI_SHALLOW_SLEEP。修正系统 tick:HAL 用 VRTC 统计的睡眠时长更新 SysTimer 和 FreeRTOS tick。
执行 exit handler:HAL 执行 exit handler。对
lisa_pm来说,先进入 device.on_exit,执行lisa_device resume_restore并投递 appafter_wake;随后 common hook 更新统计和最近一次唤醒原因;最后lisa_pm_wake任务释放临时 HAL 锁并执行 appafter_wake。
当前 lisa_pm 在 HAL managed device 中不使用 .on_wake,设备恢复统一走 .on_exit。
深睡模拟浅睡
LISA_PM_SYSTEM_POLICY_AUTO_LIGHT_SLEEP 对应用暴露的是“自动轻睡眠”语义:应用只需要声明系统允许在空闲时自动睡眠,唤醒后任务继续运行,FreeRTOS tick 会补偿睡眠时间,lisa_pm 会调度设备和应用恢复回调。
ARCS HAL 当前用 PMU deep sleep mode2 实现这层语义,而不是传统意义上只停时钟、不掉电的浅睡眠。也就是说:
接口层是 light sleep:应用设置的是
LISA_PM_SYSTEM_POLICY_AUTO_LIGHT_SLEEP,porting 下发的是PM_MODE_LIGHT_SLEEP。硬件层走 deep sleep:HAL 在
pm_hw_execute_sleep()中配置PMU_SLEEPMODE_MODE2,并通过__light_sleep_save()进入深睡保存/恢复入口。连续性由软件重建:HAL 通过 BootClock/cache/Flash/PSRAM 恢复、snapshot 还原、寄存器上下文恢复、FreeRTOS tick 补偿和
lisa_pm设备回调,让应用看到接近 light sleep 的运行连续性。掉电域需要应用配合重建:除 AON/保留域和 snapshot 覆盖区域外,普通外设寄存器、HAL 状态和业务配置不能假设跨睡眠保持。
resume_restore()只覆盖 PM 关键路径允许的快速基础恢复;对会释放/创建 OS 对象、堆内存或复杂外设状态的设备,应用需要在睡前正常任务上下文显式调用lisa_device_destroy()或对应 stop/deinit 接口,唤醒后在after_wake或普通任务上下文调用lisa_device_reinit()或对应 start/init 接口,并重新完成业务配置。
常见保留和恢复来源:
来源 |
用途 |
|---|---|
AON 域 |
保存 AON wake cause、GPIOB 唤醒状态、VRTC/RTC 等低功耗资源 |
RAM retention |
保持配置的 RAM bank 供电 |
PSRAM snapshot |
保存 ILM/DLM/非 AON SRAM 等注册区域,唤醒后复制回原地址 |
HAL register context |
保存并恢复部分外设寄存器、IPC IRQ、GPIO retention 等上下文 |
|
让具体 driver 在睡眠前关闭硬件、唤醒后恢复 HAL/pinmux 基础状态 |
app |
让应用恢复业务级状态,例如显示、电源控制、网络或外设通道重配置 |
因此,接入 AUTO_LIGHT_SLEEP 时不要把它理解成“所有 SRAM 和外设寄存器天然保持”的硬件浅睡;应按深睡恢复模型设计数据保留、设备恢复和业务重配置。
AP/CP 双核运行模式
双核运行模式要求 AP remote 固件和 CP 主固件同时存在。AP 不是睡眠前被关闭、唤醒后再拉起的 boot-shim,而是作为 HAL PM 对端核心参与 shared state 协同。
典型职责:
核 |
典型职责 |
|---|---|
AP remote 固件 |
引导 CP,初始化 IPC 和 |
CP 主固件 |
运行 WiFi/LWIP/业务逻辑,IP ready 后切到 |
双核共享状态来自 amp_shared_info.pm_data:
pm_data.config 当前 HAL PM 配置
pm_data.sleep_cfg 唤醒源、GPIO mask、timer 等睡眠配置
pm_data.core_ctx[] 每个核心的 state / cross_core_lock
pm_data.last_wakeup_cause 最近一次 AON 唤醒原因
当前示例约定:
AP:
CONFIG_LISA_PM_CORE_PRIMARY=n,对应 HALPM_CORE_PRIMARY=0。CP:
CONFIG_LISA_PM_CORE_PRIMARY=y,对应 HALPM_CORE_PRIMARY=1。CP:必须启用
CONFIG_LISA_PM_DUAL_CORE=y,避免选择CONFIG_ARCS_HAL_PM_CLOSE_AP。
简化时序:
AP(non-primary) idle -> 设置自身 IDLE -> 清 CP cross_core_lock -> IPC_SIG_ENTER_IDLE -> WFI_DEEP_SLEEP
CP(primary) idle -> 检查 cross_core_lock=0 -> 配置 AON/PMU/VRTC/snapshot -> __light_sleep_save()
AON wake source -> CP 先恢复 -> 必要时 IPC_SIG_WAKEUP 唤醒 AP
AP 恢复 -> 重新置位 CP cross_core_lock -> AP/CP 回到 ACTIVE
参考示例:
samples/subsys/lisa_pm/dual_core/basic/samples/subsys/lisa_pm/dual_core/gpio_wakeup/
使用示例
基础系统睡眠
#include "lisa_pm.h"
int app_pm_start(void)
{
int32_t ret = lisa_pm_init();
if (ret != 0) {
return ret;
}
return lisa_pm_set_system_policy(LISA_PM_SYSTEM_POLICY_AUTO_LIGHT_SLEEP);
}
睡眠锁保护关键事务
void flash_update_begin(void)
{
(void)lisa_pm_lock_acquire();
}
void flash_update_end(void)
{
(void)lisa_pm_lock_release();
}
应用 after-wake 恢复
static void board_after_wake(void *user_data, lisa_pm_wakeup_cause_t cause)
{
(void)user_data;
(void)cause;
board_display_power_on();
}
static const lisa_pm_sleep_callback_t sleep_cb = {
.before_sleep = NULL,
.after_wake = board_after_wake,
.user_data = NULL,
};
void board_pm_callback_init(void)
{
(void)lisa_pm_sleep_callback_register(&sleep_cb);
}
WiFi LISTEN 省电
int app_wifi_pm_prepare(void)
{
lisa_pm_wifi_ps_config_t ps_cfg = {
.listen_interval = 10,
};
int32_t ret = lisa_pm_init();
if (ret != 0) {
return ret;
}
ret = lisa_pm_wifi_set_ps_mode(LISA_PM_WIFI_PS_LISTEN, &ps_cfg);
if (ret != 0) {
return ret;
}
wifi_sta_connect(ssid, pwd);
wait_until_ip_ready();
net_enable_keep_alive();
return lisa_pm_set_system_policy(LISA_PM_SYSTEM_POLICY_AUTO_LIGHT_SLEEP);
}
注意事项
先初始化:使用系统策略、统计、设备 system PM 或应用睡眠回调前,应先调用
lisa_pm_init()。区分锁类型:
lisa_pm_lock_*()阻止系统 deep sleep;lisa_pm_wifi_lock_*()只阻止 WiFi 进入省电。回调上下文受限:
before_sleep和 devicesystem_ops属于 PM 关键路径,不能执行阻塞操作;复杂业务恢复应放到after_wake或普通任务。LISTEN 参数时机:WiFi LISTEN interval 必须在 WiFi 发起连接前设置。
双核不要关闭 AP:AP/CP runtime 双核模式下 CP 必须启用
CONFIG_LISA_PM_DUAL_CORE,确保不会走CONFIG_ARCS_HAL_PM_CLOSE_AP单核 boot-shim 路径。GPIO 唤醒范围:ARCS PMU GPIO 唤醒只支持 GPIOB_00…GPIOB_09,进入睡眠前引脚不能已经处于触发电平。
snapshot 按需配置:启用 ILM/DLM/SRAM snapshot 时需同时确认
CONFIG_PM_PSRAM、CONFIG_PM_SNAPSHOT_PSRAM_SIZE和各固件 PSRAM 布局足够。