T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍

Wi-Fi 设备、蜂窝设备、WuKongAI、开发板、TuyaOS 移植等


Post Reply
Ann
Posts: 5

T5_3.13.6版本,我在进入深度休眠状态之前播放了一段提示音,播放结束后再执行进入休眠。进入休眠时间设置为1分钟,但是目前的状况是第1分钟会播报提示音但无法进入休眠,且按键唤醒后无法正常对话,等到第2分钟才会进入休眠,奇怪的是第2分钟居然不会播报提示音,直接就休眠了。求解答!

Attachments
实现代码.txt
(2.02 KiB) Downloaded 231 times

Tags:
愚者千虑必有一得
Posts: 955

Re: T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍

你好!

问题概述

进入深度休眠前播放提示音,设置1分钟超时变成2分钟才进入休眠。

根因分析

经代码排查,定位到tuya_ai_toy.c中__on_ai_toy_lowpower_timer回调的逻辑问题:

时序分析:

  1. idle状态启动lowpower_timer(60s)
  2. 用户播放本地提示音
  3. 第1分钟timer到期,但wukong_audio_player_is_playing()==TRUE
  4. 回调将timer重置为完整的TOY_LOWPOWER_TIMEOUT(60s),而非短间隔重试
  5. 按键唤醒后AI agent处于idle不可交互状态
  6. 第2分钟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),不再翻倍。

fangweng
Posts: 24

Re: T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍

T5_3.13.6版本在进入低功耗之前播放本地提示音,进入低功耗时间翻倍


本地资料够了:svc_ai_agent 的输出会话/提示音机制和 T5 深睡唤醒机制都能对上这个「第一分钟播不睡、第二分钟不播直接睡」的现象,可以回答。

结论:大概率不是“时间翻倍”,而是第一次休眠尝试被自己的提示音否决了——提示音走音频输出通道播放时,系统处于“音频会话活跃”状态,休眠条件检查不通过,这一轮就放弃了;但休眠准备动作(停会话/关麦克风)已经做了一半且没有回滚,所以按键唤醒后无法对话;第二分钟提示音的 one-shot 标志已被消费、也没有音频再阻塞,就直接睡进去了。

逐分钟拆解(出处:components/svc_ai_agent/README_CN.mdvendor/T5/README_CN.md):

  • 第 1 分钟:定时到点 → 业务先播提示音。音频输出会话进入 PLAYING,要等 AI_EVENT_END 才算空闲;休眠入口检查时音频未结束(或刚结束、I2S/DMA 还没排空),本轮休眠被跳过,等下一个周期
  • 唤醒后不能对话:休眠流程里先执行的“退出 AI 会话/关麦克风”在休眠被否决后没有恢复,agent 状态机停在半关闭状态,按键说话送不进会话
  • 第 2 分钟:播提示音的逻辑挂在“休眠流程入口”且只执行一次,标志已消费 → 不再播报;这次没有音频阻塞,休眠成功
  • T5 平台侧:深睡只能靠 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 自动分析生成,如有疑问请回复补充。

Post Reply