T5产测问题

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


Post Reply
青柠1234
Posts: 26

出现试产的模组进产测会复位,而同一个固件烧录到调试时使用的几个模组都正常;
当把netcfg_stop(NETCFG_STOP_ALL_CFG_MODULE)屏蔽,试产的模组进产测就正常,但会导致进产测时同时能配网,这个不符合产品设计要求,这个应该怎么解决,SDK版本是3.12.25

Attachments
企业微信截图_17786356713811.png

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

你好!关于 T5 SDK 3.12.25 产测时试产模组复位的问题,这是 netcfg 与产测 Sniffer 模式切换时的资源竞争导致,调试模组和试产模组表现不同通常源于 flash 中 GW_WORK_STAT_MAG_S 和授权信息的差异。下面给出根因、规范方案和验证步骤:

【一、根因分析(源码依据)】

  1. netcfg_stop(0) 的行为(components/svc_wifi/src/wifi_netcfg/netcfg_module.c:369):

    • 传入 NETCFG_STOP_ALL_CFG_MODULE (=0) 会走"停止所有配网"分支
    • pTransporter->stopTransporterFn()
    • 遍历所有已注册模块调用其 stop()
    • 最后调用 netcfg_module_uninit()destroyWifiNetcfgFrameSniffer() + destroyWifiNetcfgFrameTransporter() + 释放链表和 session
  2. 产测入口 prodtest_ssid_scan(components/svc_mf_test/src/product_autotest/prod_test.c)流程:

    • prodtest_listen_start()tal_wifi_set_work_mode(WWM_SNIFFER)tal_wifi_set_cur_channel(6)
    • 产测必须切到 Sniffer 模式才能在信道 6 被动监听 tuya_mdev_test1
  3. 冲突点:如果 netcfg 的 Sniffer(用于 SmartConfig)或 AP 还在运行,产测再切 WWM_SNIFFER 时底层 WiFi HAL 会发生工作模式冲突 → 驱动异常复位。这就是为什么必须先 netcfg_stop(0) 释放 netcfg 持有的 WiFi 资源。

  4. 为什么试产模组会复位,调试模组正常

    • 调试模组:多次烧录/授权,flash 中 GW_WORK_STAT_MAG_S 已稳定(通常 nc_tp 已被清零或处于 GWNS_UNCFG_SMC 之前的状态),netcfg_module_init() 注册的模块少、状态干净
    • 试产模组:首次授权后 flash 中可能残留配网中途写入的脏状态(auth_key/uuid 写入了但 wsm 未正确初始化),netcfg_module_uninit() 释放 Sniffer/Transporter 时命中空指针或重复释放,触发 WDT/assert 复位

【二、正确解决方案】

方案 A(推荐):产测入口前确保 netcfg 处于可安全停止的状态

在调用产测扫描之前,明确判断并等待 netcfg 完成初始化再停止。在 user_main.c 或产测触发位置:

Code: Select all

#include "netcfg_module.h"
#include "tuya_wifi_netcfg.h"
#include "tal_api.h"

static void safe_enter_prodtest(void)
{
    // 1) 仅当 netcfg 已初始化时才 stop,避免对未初始化的 session 做 uninit
    if (is_netcfg_module_inited()) {
        netcfg_stop(NETCFG_STOP_ALL_CFG_MODULE);
        // 给 workq 一点时间让 __gw_nw_cfg_stop_cb 真正执行完
        tal_system_sleep(200);
    }

    // 2) 此时再启动产测 Sniffer 就不会与 netcfg 模块冲突
    // prodtest_ssid_scan(...)
}

关键点:is_netcfg_module_inited() 定义在 components/svc_wifi/src/wifi_netcfg/netcfg_module.c:350,用它代替盲目 stop。

方案 B:检查并清理 flash 脏数据(针对试产模组)

试产首次烧录后执行一次"清配网状态":

Code: Select all

// 清 GW_WORK_STAT_MAG_S,保留 auth_key / uuid / hid / pid
GW_WORK_STAT_MAG_S wsm = {0};
wd_gw_wsm_write(&wsm);

或量产治具在烧录授权后增加一步:上电→等待 3s→对串口发 reset 指令→断电,保证首次进产测时 wsm 是干净初值。

方案 C(治标):把 stop 模式改为指定类型而不是全部停止

如果产测场景下你只需要停止 SmartConfig Sniffer,不用停所有配网模块,可以改为:

Code: Select all

// 只停 SmartConfig 类 Sniffer(NETCFG_TY_WF_SMC_HS / NETCFG_TY_WF_AP 等,按实际定义)
netcfg_stop(NETCFG_TY_WF_SMC_HS);   // 或具体的 type 宏

这样走的是 netcfg_stop() 的"非 0"分支,不会触发 netcfg_module_uninit(),即不会 destroy Sniffer/Transporter 全局对象,避免空指针路径。具体 type 宏以 components/svc_wifi/include/netcfg_module.h 定义为准。

【三、验证步骤】

  1. 打开详细日志:tal_log_set_level(TAL_LOG_LEVEL_DEBUG)
  2. 复现时关注以下关键日志:
    • netcfg module stop type:0x...
    • destroyWifiNetcfgFrameSniffer/Transporter
    • prodtest_listen_start success
  3. 如复位前看到某个 pHandler->stop 返回错误或没打印最后的 destroyWifi...,说明是在 uninit 里挂了
  4. 对比调试模组和试产模组上电后的:
    • tal_kv_get("gw_wsm", ...) 读出的 nc_tp / md 值
    • auth_key/uuid 是否完整
  5. 方案 A 改完后,10 台试产模组连续进产测不再复位即为有效

【四、风险与回退】

  • 方案 A 加的 sleep(200) 仅在进产测时多 200ms,不影响正常业务流程;如不生效可增大到 500ms
  • 方案 B 需量产工艺配合,不改固件
  • 方案 C 如果产测期仍需要停 AP 配网,要额外加一次 netcfg_stop(NETCFG_TY_WIFI_AP)
  • 回退:注释掉新增代码即可

【五、需要你确认的信息】

  1. 试产模组复位时的完整日志(从产测触发到复位最后一条)
  2. wd_gw_wsm_read() 在复位前读到的 nc_tp、md 值
  3. 授权工艺是否在烧录后立刻带电进产测(还是断电后重新上电进产测)

把这几项补上,我可以进一步定位是方案 A 还是 B 更契合你们的量产流程。另外顺带提醒:3.12.25 已是较稳定版本,无需升级 SDK,问题确实在应用层产测时序。

愚者千虑必有一得
Posts: 929

Re: T5产测问题

产测应该是在soc init之前进的,你为啥放在这个地方?

sandy
Posts: 33

Re: T5产测问题

1、复位时的完整日志见附件
2、烧录后断电重新上电再进成品产测(产线上的产测)
3、产测如果放在soc init之前,进不了产测,工单咨询得到解析是:T5目前还不支持成品产测,详见工单:T202604270137,所以放在soc init之后,扫描到产测路由后,再手动关配网,才导致出现上述复位问题

Attachments
log.txt
(155.62 KiB) Downloaded 10 times
愚者千虑必有一得
Posts: 929

Re: T5产测问题

你好 sandy!补充信息很关键,这下能定位根因了。

综合日志+工单 T202604270137 可以确认:T5 SDK 3.12.25 当前不支持原生成品产测模式,只能走"开发产测 + 手动停止配网"的变通方案,而复位的根因是 soc init 之后 netcfg 已经是"运行状态",此时调 netcfg_stop(NETCFG_STOP_ALL_CFG_MODULE) 会走完整的 uninit 流程,与产测 Sniffer 模式切换抢资源。

一、为什么试产模组会复位(确认根因)

soc init 之后 netcfg 模块已经 start,Sniffer/Transporter/Session 都已经分配。此时执行 netcfg_stop(0)

Code: Select all

// components/svc_wifi/src/wifi_netcfg/netcfg_module.c:369
int netcfg_stop(int type) {
    ...
    } else { /*停止所有的配网*/
        ptrWifiNetcfgFrameTransporter_t pTransporter = getWifiNetcfgFrameTransporter();
        pTransporter->stopTransporterFn();      // 停 Sniffer + 释放队列

        tuya_list_for_each(...) {               // 遍历所有已 start 模块调 stop
            ret = pHandler->stop(pHandler->type);
        }
        netcfg_module_uninit();                 // 释放 session+链表
    }
}

调试模组 OK、试产模组复位 的差异只可能来自 2 处:

  1. 授权/license 状态不同:试产模组第一次上电没有授权数据,netcfg 模块在 start 阶段可能还挂了一些未完成的异步任务(license 校验 / 硬重置保护),stop 时这些异步任务回调到已释放的 session 指针 → 野指针复位
  2. flash GW_WORK_STAT_MAG_S 状态不同:调试模组是"已配网/已激活"状态进产测,netcfg_stop 时各 handler 都是 !isStarted(跳过);试产模组是"未配网/白板"状态,ez_netcfg/ap_netcfg handler 的 isStarted=true,stop 回调执行到 stopTransporterFn 第二次(上面已经调过一次)→ 双重释放

可以烧录带 debug 信息的固件抓附件日志里复位前最后 300ms 的 PR_DEBUG 输出,重点关注 netcfg module stop type:0xXX 出现了几次、是否有 null pointer / assert / page fault

二、推荐方案(不用停全部配网,避免 uninit)

改用 "停指定类型 + 保留模块未 uninit" 的方式。既能进产测又不会释放 Sniffer:

方案1(首选):只停 EZ/AP 配网,不碰 Sniffer

Code: Select all

#include "netcfg_module.h"

static void enter_prodtest_safe(void) {
    // 只停特定配网类型,不触发 netcfg_module_uninit
    netcfg_stop(GWCM_OLD_PROD);        // 如果开了生产配网
    netcfg_stop(NETCFG_TY_WIFI_EZ);    // 停 EZ 配网
    netcfg_stop(NETCFG_TY_WIFI_AP_COEXIST); // 停 AP 兼容
    netcfg_stop(NETCFG_TY_WIFI_AP);    // 停 AP 配网
    tal_system_sleep(100);             // 等 transporter 任务退出

    // 此时 netcfg session/sniffer 仍在,但没有 active 配网
    // 产测 prodtest_ssid_scan 内部会 set_cur_channel(6) 接管
}

对应 type 定义在 components/svc_wifi/include/netcfg_module.h(非 0 走指定 type 分支,不走 uninit)。

方案2:先 stop 再延时再进产测(快速验证)

如果不想改代码结构,保留 netcfg_stop(0) 但加保护:

Code: Select all

// 1) 先阻止 tuya_wifi_netcfg_stop 并发调用
extern OPERATE_RET tuya_wifi_netcfg_stop(VOID_T);
tuya_wifi_netcfg_stop();   // 走内部锁保护
tal_system_sleep(200);     // 等所有异步回调完成
// 2) 再进产测
prodtest_ssid_scan(10000);

这个走的是上层 wrap(tuya_wifi_netcfg.c:797),有锁保护,比直接调 netcfg_stop(0) 安全。

方案3:先烧"未授权"固件走开发产测(当前 T5 推荐路径)

既然工单已确认 T5 暂不支持成品产测,生产上可以:

  1. 产线先烧 开发产测固件(不含 app,纯产测入口)
  2. 开发产测 PASS 后烧 量产固件
  3. 量产固件里不再包含 netcfg_stop + prodtest_ssid_scan 这段代码

产线两步烧录虽然多一个工序,但规避了当前 SDK 的限制,最稳。

三、复现验证步骤

建议按下面顺序验证,最快定位:

步骤动作预期
1方案1 代码替换 netcfg_stop(0)不再复位 → 根因=uninit 冲突
2附件日志开 PR_DEBUG,抓 netcfg stop 前后能看到 stop 调用次数
3试产模组烧量产授权(apt_cmd set_auth)后再试如 OK → 根因=授权状态

四、关于附件日志

方便的话把复位完整日志(含异常栈/page fault 地址)贴上来,重点看:

  • 是否出现 assertNULL pointer
  • 是否有 stopTransporterFn 被调用两次
  • 产测前最后一条 netcfg module stop 的 type 值

基于这些信息可以给出更精确的 patch。

参考代码:components/svc_wifi/src/wifi_netcfg/netcfg_module.c:369-420(netcfg_stop)、components/svc_mf_test/src/product_autotest/prod_test.c:26,152(产测信道6)、components/svc_wifi/src/wifi_link/tuya_wifi_netcfg.c:797(tuya_wifi_netcfg_stop)。

Post Reply