T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍
T5_3.13.6版本,我在进入深度休眠状态之前播放了一段提示音,播放结束后再执行进入休眠。进入休眠时间设置为1分钟,但是目前的状况是第1分钟会播报提示音但无法进入休眠,且按键唤醒后无法正常对话,等到第2分钟才会进入休眠,奇怪的是第2分钟居然不会播报提示音,直接就休眠了。求解答!
T5_3.13.6版本,我在进入深度休眠状态之前播放了一段提示音,播放结束后再执行进入休眠。进入休眠时间设置为1分钟,但是目前的状况是第1分钟会播报提示音但无法进入休眠,且按键唤醒后无法正常对话,等到第2分钟才会进入休眠,奇怪的是第2分钟居然不会播报提示音,直接就休眠了。求解答!
你好!
进入深度休眠前播放提示音,设置1分钟超时变成2分钟才进入休眠。
经代码排查,定位到tuya_ai_toy.c中__on_ai_toy_lowpower_timer回调的逻辑问题:
时序分析:
总等待时间=60s+60s=120s,翻倍。第2分钟不播提示音是因为音频播放已完成、状态已变迁。
关键代码(tuya_ai_toy.c:618):
if(wukong_audio_player_is_playing()) {
tal_sw_timer_start(s_ai_toy->lowpower_timer, TOY_LOWPOWER_TIMEOUT, TAL_TIMER_ONCE);
}
// 问题:重置为完整60s而非短间隔重试
方案1(推荐):修改重置逻辑为短间隔重试
将重置间隔从TOY_LOWPOWER_TIMEOUT(60s)改为1s:
Code: Select all
// 修改前
tal_sw_timer_start(s_ai_toy->lowpower_timer, TOY_LOWPOWER_TIMEOUT, TAL_TIMER_ONCE);
// 修改后
tal_sw_timer_start(s_ai_toy->lowpower_timer, 1000, TAL_TIMER_ONCE);播放提示音场景下总等待时间从120s变为约61s。
方案2:播放提示音前停止lowpower_timer
在播放本地提示音前调用tuya_ai_toy_lowpower_timer_ctrl(FALSE),播放结束回调中调用tuya_ai_toy_lowpower_timer_ctrl(TRUE),休眠从提示音播完后重新计时60s。
修改后播放提示音,总等待时间应为原超时+提示音剩余播放时间(约61s),不再翻倍。
T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍
本地资料够了:svc_ai_agent 的输出会话/提示音机制和 T5 深睡唤醒机制都能对上这个「第一分钟播不睡、第二分钟不播直接睡」的现象,可以回答。
结论:大概率不是“时间翻倍”,而是第一次休眠尝试被自己的提示音否决了——提示音走音频输出通道播放时,系统处于“音频会话活跃”状态,休眠条件检查不通过,这一轮就放弃了;但休眠准备动作(停会话/关麦克风)已经做了一半且没有回滚,所以按键唤醒后无法对话;第二分钟提示音的 one-shot 标志已被消费、也没有音频再阻塞,就直接睡进去了。
逐分钟拆解(出处:components/svc_ai_agent/README_CN.md、vendor/T5/README_CN.md):
PLAYING,要等 AI_EVENT_END 才算空闲;休眠入口检查时音频未结束(或刚结束、I2S/DMA 还没排空),本轮休眠被跳过,等下一个周期tkl_wakeup_source_set 注册过的源唤醒,普通 GPIO IRQ 在 Deep Sleep 下不触发,这部分你们已验证能唤醒,说明平台配置本身没问题建议改法:
| 问题点 | 修改 |
|---|---|
| 提示音阻塞休眠 | 先播提示音,在播放完成回调(AI_EVENT_END 或本地播放器完成事件)里再发起休眠,不要在休眠入口同步等 |
| 失败后状态不回滚 | 休眠失败分支要把麦克风/会话重新拉起,保证按键对话可用 |
| 提示音只播一次 | 挂到“每次真正进休眠前”的路径上,而不是一次性标志 |
Code: Select all
// 定时器到点:先播,播完再睡
STATIC VOID prompt_done_cb(VOID_T *arg)
{
// 用一次性软件_timer 延时 500ms,等 I2S/DMA 排空,别在回调里阻塞
tal_sw_timer_start(s_sleep_timer, 500, TAL_TIMER_ONCE);
}
STATIC VOID on_sleep_timer_expire(TAL_TIMER_CB cb, VOID_T *arg)
{
tkl_cpu_sleep_mode_set(TRUE, TUYA_CPU_SLEEP); // 唤醒源开机时已注册
}
void on_idle_timeout(void)
{
play_prompt_async(PROMPT_GOING_SLEEP, prompt_done_cb);
}细节行为(比如 3.13.6 里休眠前检查的具体条件)需要看你们 实现代码.txt 的实际流程才能确认,可以点「查代码」进一步对照。
以上内容由 AI 自动分析生成,如有疑问请回复补充。