SLE 模块导致 PM 系统无法进入深睡,存在 PM_VETO_ID_BTC 投票一直无法清除
实际现象:
系统可以正常启动,传感器数据通过 SLE 发送,SLE 连接正常。
PM 状态机按设定时间切换:30 秒后进入待机(work_to_standby_handler 被调用),随后进入深睡(standby_to_sleep_handler 被调用)。
但在深睡阶段,PM 系统始终被 睡眠否决票 阻止,无法真正进入深睡。
通过 uapi_pm_veto_get_info() 打印发现始终存在 PM_VETO_ID_BTC(ID0)的投票,票数为 1,last_id 为 5(PM_VETO_ID_SYS),系统无法睡眠,最终导致反复复位(复位原因 0x200F)。
即使我们在 standby_to_sleep_handler 中强制清除所有投票(直接修改结构体),并尝试调用 disable_sle() 关闭 SLE 协议栈,该投票依然无法清除,系统无法进入深睡。
期望:能够正常进入深睡,功耗降至微安级,由传感器中断唤醒后恢复工作。
已尝试的措施:
PM 回调实现:
注册了 work_to_standby、standby_to_sleep、sleep_to_work、standby_to_work 四个回调。
在 work_to_standby 中关闭 UART/I2C 外设,配置 GPIO 为低电平,切换到 ULP 中断。
在 standby_to_sleep 中调用 sle_disconnect_all_remote_device()、sle_stop_seek(),并尝试 disable_sle()。
在 sleep_to_work 中恢复外设,并调用 enable_sle()。
投票清除尝试:
使用 uapi_pm_remove_sleep_veto 循环移除所有 ID(0~MAX)。
直接修改 pm_veto_t 结构体清零 total_counts 和所有 sub_counts。
在 pm_veto_porting.c 中强制 pm_port_get_customized_sleep_veto 返回 false。
修改 pm_sleep.c 中的 uapi_pm_enter_sleep 直接调用 pm_enter_deep_sleep,绕过所有检查。
配置修改:
在 menuconfig 中将 SLE 模式设为 sle peripheral,关闭低延迟、HADM、性能特性,关闭 AT SLE 命令。
关闭 Enable sle ble release 等选项。
关闭其他未使用外设的驱动。
结果:
所有尝试均未能消除 PM_VETO_ID_BTC 投票,系统在 standby_to_sleep_handler 执行后复位,无法进入深睡。
串口日志显示 veto total=1, last_id=5, sub_counts[0]=1 持续存在。
调用 disable_sle() 有时导致系统崩溃(可能是函数未实现或时序问题)。
**
串口信息:**
veto total=1, last_id=5
sub_counts[0]=1
Work -> Standby, sensor enter low power.
System entering deep sleep.
[pm_sys]mail.state switch: 0
... (后续出现复位)