3.4 KiB
3.4 KiB
诊断结论(本次核心交付)
你的怀疑正确,确实冲突,且共两层:
-
主站楔死看门狗无豁免(自动拉起的推手)
G:\Robot_v2\DCU\tools\ecat\ecat_native.c的 wedge_worker 后台线程:WKC 异常持续 5s 即判死,之后每 ~8s 无限重拉 INIT→OP,直到成功,全程无「用户手动休眠」豁免。日志实锤(build_native\native_stdout.log):t=176002.9s 判死(从站掉 OP) → 重拉失败(枚举不到从站) → t=176011.0s 重拉成功已进 OP,与你任务管理器图上 ~20s 流量缺口完全吻合。 -
GD32 固件进睡眠时没冻结 HBI 访问者(芯片睡不住的根因)
EscLan9252::pmDrive()写完 PMT_CTRL 进入 D1-D3 后,GD32 侧 SSC 主循环MainLoop()→ECAT_Main()每圈仍无条件 HBI 读 0x220(AL 事件寄存器),另有 250ms AL mask 守护、5s AL 心跳,全部无睡眠门控。按 1.6.24 实测「任何 HBI 访问(含读)都会唤醒芯片」,芯片进入睡眠后毫秒级就被 GD32 自己打回 D0。你看到的低谷不是「睡了多久」,而是被唤醒后 SM/FMMU 失效、主站重建连接所需的时间。 -
次要发现:电源页
enterMode已正确暂停轮询并写 sessionStorage(同标签页安全),但换新标签页打开会丢标记 → 自动状态读(HBI 读)直接把芯片唤醒,属潜在坑。
修复计划
Phase A:PC 侧(立即生效,不动固件)
- A1
ecat_native.c:新增g_pm_hold标志 +POST /api/pm/hold {on:0|1};在三处跳过——pdo_worker 的楔死判定(~859-908 行)、wedge_worker 巡检(~2940-2990 行)、/api/motor/state路由快路径(~2262-2300 行);hold 时重置检测计时避免恢复后误触发。build_new.bat重编,verify_wedge_fix.py回归。 - A2
lab\lan9252_pm.html:enterMode 成功后发pm/hold on=1;手动唤醒/NRST 流程开头先发on=0(恢复主站自愈)再走 recoverEcatMaster;banner 文案同步。 - A3(小改)睡眠标记另写一份带时间戳的 localStorage,新标签页打开时据此跳过自动状态读。
- 效果:休眠期间主站不再自动拉回 OP;但芯片仍会被 GD32 自己唤醒,EtherCAT 保持断开直到你手动唤醒(行为=「我睡了就是睡了」,但低功耗目的未真正达成)。
Phase B:GD32 固件根因修复(需 cbuild 构建 + 刷板)
- B1
G:\Robot_v2\DCU\DCU_APP\GD32E508_DCU_APP\comm\esc_lan9252.cpp/.h:新增全局挂起标志;pmDrive op=1/2/3 成功进睡眠时置位,op=4 唤醒成功/nrstDrive/hardwareReset 时清除。 - B2 门控点:
sys\task_runner.cpp的MainLoop()、ethercatAleMaskGuard()、ethercatAlHeartbeat();PDI/Sync0 EXTI ISR 顶部查标志直接返回(ISR 内 HBI 读同样会唤醒芯片)。0xC5/0xC4 轮询不碰 ESC,无需改。 - B3 核对唤醒后 SSC 阴影状态一致性(现有页面唤醒路径一律 NRST+motor/start,NRST 会全复位芯片)。
- B4 按 cbuild+vcpkg AC6+ninja 链构建刷板,刷完
/api/motor/start恢复 OP。 - 加上 B 后芯片才能真正保持 D1-D3 低功耗态。
验证
- 进睡眠后任务管理器流量掉 0 并保持,native 日志无 WEDGE 重拉;GD32 串口
[ECAT][HB]心跳停止(B 后);间隔 2s/10s/30s 查询状态仍为睡眠态;手动唤醒后流量恢复进 OP。 - hold=0 时正常楔死自愈回归不受影响。