From 297c020a202695ece416bb9109359e52116f61d8 Mon Sep 17 00:00:00 2001 From: cbb <2625274797@qq.com> Date: Tue, 20 Oct 2026 21:27:39 +0800 Subject: [PATCH] =?UTF-8?q?docs(review):=20=E4=B8=93=E5=AE=B6=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=202026-10-19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../revisions/device-link_REV_2026-10-19.html | 25 ++++++++++++ .../ecat-rx-stuck_REV_2026-10-19.html | 25 ++++++++++++ .../host-code-quality_REV_2026-10-19.html | 25 ++++++++++++ .../pdo-fast-send_REV_2026-10-19.html | 25 ++++++++++++ .../tab-keepalive_REV_2026-10-19.html | 25 ++++++++++++ .../ECAT_BEAT_TAIL_REPORT_REV_2026-10-19.html | 25 ++++++++++++ .../ECAT_RATE_TRADEOFF_REV_2026-10-19.html | 25 ++++++++++++ .../GD32_OTA_FLOW_COMPARE_REV_2026-10-19.html | 25 ++++++++++++ ...ecat_skip_opt_20260917_REV_2026-10-19.html | 25 ++++++++++++ .../ecat_integral_report_REV_2026-10-19.html | 25 ++++++++++++ ...DesktopController_专家评审_2026-10-19.html | 40 +++++++++++++++++++ 11 files changed, 290 insertions(+) create mode 100644 docs/compose/spec/revisions/device-link_REV_2026-10-19.html create mode 100644 docs/compose/spec/revisions/ecat-rx-stuck_REV_2026-10-19.html create mode 100644 docs/compose/spec/revisions/host-code-quality_REV_2026-10-19.html create mode 100644 docs/compose/spec/revisions/pdo-fast-send_REV_2026-10-19.html create mode 100644 docs/compose/spec/revisions/tab-keepalive_REV_2026-10-19.html create mode 100644 docs/reports/revisions/ECAT_BEAT_TAIL_REPORT_REV_2026-10-19.html create mode 100644 docs/reports/revisions/ECAT_RATE_TRADEOFF_REV_2026-10-19.html create mode 100644 docs/reports/revisions/GD32_OTA_FLOW_COMPARE_REV_2026-10-19.html create mode 100644 docs/reports/revisions/REPORT_ecat_skip_opt_20260917_REV_2026-10-19.html create mode 100644 docs/reports/revisions/ecat_integral_report_REV_2026-10-19.html create mode 100644 docs/review/DCU_DesktopController_专家评审_2026-10-19.html diff --git a/docs/compose/spec/revisions/device-link_REV_2026-10-19.html b/docs/compose/spec/revisions/device-link_REV_2026-10-19.html new file mode 100644 index 0000000..3d0d711 --- /dev/null +++ b/docs/compose/spec/revisions/device-link_REV_2026-10-19.html @@ -0,0 +1,25 @@ + +
原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| DL-1 | 外壳 Owner + BroadcastChannel 快照 | 已修复(已交付) | tabs.html:205; js/common/device-link.js:117, 389 | |
| DL-2 | 端点配置只在 ConnectionHub | 部分修复 | pages/can_monitor.html:55; js/can_monitor.js:60-68; js/app.js:63-71 | CAN 监控页硬编码 IP 优先于 Hub(C-11);OTA 页 IP 输入可绕过 |
| DL-3 | 功能页不再各自判定在线 | 部分修复 | js/common/polling.js; js/can.js:424; js/can_monitor.js:487 | 多处仍独立轮询 /system/status(C-13) |
| DL-4 | 外壳启动强制开总线,失败 10s 退避 | 仍存在风险 | js/common/device-link.js:32, 250-287 | 无 reason、unknown 视为需启动、OTA 闸读不到 iframe 标志(M-6、M-7) |
| DL-5 | BLE 经 reportBle 上报 | 已修复(已交付) | js/ble/gatt.js:119, 123, 128 |
pages/can_monitor.html:55; js/can_monitor.js:60-68; js/can/dbc.js:40-47js/motor/transport-ecat.js:394-459, 668; js/common/device-link.js:250-287, 322-327js/motor/transport-ecat.js:80-82; js/common/device-link.js:255js/common/device-link.js:30; js/can.js:131, 424; js/can_monitor.js:487, 490; tabs.html:76-81; js/common/polling.js:350-352原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| RX-1 | 主站 OP 后 seq 沿踢帧 + 活性判据加宽 | 无法在本仓库核实 | — | ecat_native.c 不在本仓 |
| RX-2 | 从站新鲜度救援先 Process 再 InputMapping | 无法在本仓库核实 | — | 固件仓 |
| RX-3 | 规格状态仍为 in-progress,但 T1~T3 已勾选 | 仍存在 | docs/compose/spec/ecat-rx-stuck.md:3 | 建议改为 delivered 或注明剩余事项 |
原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| HQ-R1 | 非幂等不自动重发 | 部分修复 | ecat_client.py:58-62, 290-299, 418-436 | HTTP 代理已遵守;ESF1 快发重试违反同一原则(P-2) |
| HQ-R2 | 网卡默认 I210 | 已修复 | ecat_proc.py:28 | |
| HQ-R3 | 跨进程互斥/复用 | 部分修复 | ecat_proc.py:67-94, 125-140 | 锁超时/CreateMutexW 失败仍继续执行(P-4) |
| HQ-R4 | 拆 main.js | 部分修复 | js/motor/main.js(3254 行) | 仍为上帝文件(M-18) |
| HQ-R5 | 版本/参数下沉 | 仍未实施 | — | |
| HQ-R6 | ECAT bootstrap 单点 | 部分修复 | js/motor/transport-ecat.js:418-441; js/common/ecat-bus.js:65-75 | 电机侧仍自算周期并绕过预算(M-6) |
| HQ-R7 | toast/quiet 去重 | 仍未实施 | js/can/send.js:17 | CAN 侧还出现 toast 双实例(C-9) |
| HQ-R8~R14 | 服务端拆分与卫生 | 已修复(大部分) | ecat_client.py; ecat_proc.py; docs/reports/ | 但 .qoder/.zcode 入库(H-1) |
| HQ-R15 | README | 部分修复 | README.md:3, 190, 449 | 个人路径与默认周期描述过时(H-2、H-4) |
ecat_client.py:247-279.qoder/repowiki/(约 75 个文件); .zcode/plans/plan-sess_*.md; .gitignorejs/motor/transport-ecat.js:394-459, 668; js/common/device-link.js:250-287, 322-327ecat_proc.py:67-94(尤其 72-81)js/can/send.js:17; js/can.js:19-20, 47scripts/build_mem.bat:21; README.md:3, 449; docs/compose/spec/host-code-quality.md:67js/motor/transport-ecat.js:37, 166, 416-417, 607; README.md:190js/motor/main.js:807-948原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| FS-1 | Python 桥 ESF1 仅走 TCP,无 HTTP 回落 | 已修复(已交付) | ecat_client.py:231-287 | |
| FS-2 | 前端 sendViaFastOrJson 有桥时只调快发 | 已修复(已交付) | js/motor/transport-ecat.js:282-300 | |
| FS-3 | 失败重探端口后再试 TCP 一次 | 仍存在风险 | ecat_client.py:247-279 | sendall 成功后 recv 失败也会重发,同一帧可能入队两次(P-2,致命) |
| FS-4 | 堵死慢发原则 | 部分修复 | js/motor/transport-ecat.js:259-271 | 低频路径(motor/send、motor/start)桥失败仍回落 HTTP(M-8) |
ecat_client.py:247-279js/motor/transport-ecat.js:259-271; js/common/desktop-bridge.js:59-74原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| TK-1 | 多 iframe 宿主 + visibility 切换 | 已修复(已交付) | tabs.html:70-81, 100, 113 | |
| TK-2 | F5/⟳ 只 reload .page-frame.active | 已修复(已交付) | esp32_server.py:126, 150, 166 | |
| TK-3 | 不做后台页降频(Out of Scope) | 仍存在风险 | tabs.html:76-81; js/common/polling.js:350-352 | 隐藏帧持续轮询挤占设备 6 个 socket(C-13);电机页发送节拍在后台被节流(M-10)——建议重新评估此决策 |
js/motor/main.js:2488; js/motor/seq.js:503js/common/device-link.js:30; js/can.js:131, 424; js/can_monitor.js:487, 490; tabs.html:76-81; js/common/polling.js:350-352原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| BT-1 | 前端每 PDO 电机槽数与扫描拍数按 dense 布局改(MOT_SLOTS_PER_PDO=9、MOTOR_SCAN_CYCLES=1) | 已修复 | js/motor/transport-ecat.js:57, 88 | |
| BT-2 | 测速页跳拍卡改读 cyc_us.late/lost | 已修复 | lab/spi_test.html:506, 1522-1534, 2154-2167 | |
| BT-3 | 刷写≠生效:flash_gd32.py 增加生效守卫 | 已过时 | —(beeae8a 随 scripts 收敛删除) | 网页 WiFi 中继路径无替代版本比对,见新问题 H-6;ECAT 直灌有 0x100A 比对(boot_ecat.js:629-632, 792-794) |
| BT-4 | 345µs 归因:win 布局固有成本 vs 主站 97fab23 回归,需一次刷板钉死实验 | 无法在本仓库核实 | — | 涉及固件布局与 ecat_native.c,不在本仓 |
| BT-5 | 0.25ms 档实测列为待办 | 仍存在 | js/common/ecat-bus.js:28 | 默认已是 0.25ms 却无复测记录,见 H-5 |
| BT-6 | 报告引用 lab/ecat_rate_sweep.csv 等证据数据 | 已过时 | — | 数据随归档删除,报告不可复现,见 H-7 |
js/ota/upload-gd32.js; js/ota/stages.js:497-499docs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/REPORT_ecat_skip_opt_20260917.md原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| RT-1 | 建议周期停在 0.5ms,0.25ms 为功能损坏 | 仍存在 | js/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431 | 代码默认 0.25ms,建议未采纳且无复测依据(H-5) |
| RT-2 | 周期可被 localStorage 覆盖(原 :227-228) | 仍存在 | js/motor/transport-ecat.js:167, 428-430 | 设计如此,但应在 UI 明示并限定合法档位 |
| RT-3 | drop 口径、fillRxWindow 计时待办 | 无法在本仓库核实 | — | 属固件/native 侧 |
| RT-4 | sweep_ecat_rate.py / calibrate_ecat_metrics.py / plot_* / build_ecat_report_html.py 与图表数据 | 已过时 | — | beeae8a 删除,.md 中图片链接失效(H-7) |
| RT-5 | 注释/README 称默认 4ms 由后端决定 | 仍存在 | js/motor/transport-ecat.js:166, 416-417; README.md:190 | 文档与代码不符(H-4) |
js/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431js/motor/transport-ecat.js:37, 166, 416-417, 607; README.md:190docs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/REPORT_ecat_skip_opt_20260917.md原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| OF-1 | 新流程 0 次上板实测 | 已过时 | js/ota/boot_ecat.js:55-58, 307-322 | EtherCAT 直灌已移植入本仓(d73e2fb 起),注释含 2026-10-12/13 实测记录 |
| OF-2 | 正在跑 APP 的机器还不能直接刷 | 部分修复 | js/ota/boot_ecat.js:663-676 | 主机侧已写 CoE 0x2502:00=1 交接;固件侧无法核实 |
| OF-3 | 刷前刷后 0x100A 版本比对 | 已修复 | js/ota/boot_ecat.js:629-632, 792-794 | |
| OF-4 | 4 字节对齐补 0xFF | 无法在本仓库核实 | — | 发生在 native 侧 |
| OF-5 | 固件 OTA.cpp 尾巴丢弃缺陷 | 无法在本仓库核实 | — | 固件仓 |
| OF-6 | 老流程无断点续传,每次从偏移 0 重写 | 仍存在 | js/ota/upload-esp32.js:213-247 | 整文件 POST 且内存双份(O-15) |
| OF-7 | 报告引用行号 upload-gd32.js:58,194 | 已过时(行号漂移) | js/ota/upload-gd32.js:67-68; js/ota/file-handle.js:458, 563 | file-handle 引用仍有效 |
| OF-8 | 两条路互为备份、复用同一 flash 写入者 | 无法在本仓库核实 | — | 前端侧两条路缺统一互斥,见新问题 O-1(致命) |
js/ota/session.js:128; js/ota/boot_ecat.js:176-189, 576-577; js/ota/console-mode.js:67, 120; js/ota/ecat_load.js:114-117; js/ota/upload-esp32.js:62-91; js/ble/transfer.js:457-472js/ota/console-mode.js:170-199; js/ota/upload-esp32.js:213-247; js/ota/progress.js:177; js/ota/upload-gd32.js:85-104原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| SK-1 | ecat_native 提权为 RealTime | 部分修复 | ecat_proc.py:97-120, 273-276 | 仅新拉起进程提权;复用实例分支 :212-215 不提权;且 REALTIME 有饿死系统线程风险(P-7) |
| SK-2 | 生产建议 2ms | 仍存在 | js/common/ecat-bus.js:28 | 默认 0.25ms,与建议冲突(H-5) |
| SK-3 | 第四节回滚命令依赖 scripts/skip_*.py | 已过时 | — | 脚本已删除,回滚步骤不可直接执行 |
| SK-4 | I210 协议绑定/高级属性调整 | 无法在本仓库核实 | — | 属主机网卡配置 |
| SK-5 | 标定/实验脚本(第五节) | 已过时 | — | 已出库(H-7) |
js/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431ecat_proc.py:96-121, 212-215, 273-276docs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/REPORT_ecat_skip_opt_20260917.md原文件保持不变;本附录逐条记录其结论在当前代码中的状态。
| 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|
| IN-1 | 数据源 lab/ecat_passive_latest.csv | 已过时 | — | CSV 不在仓库,报告不可复现(H-7) |
| IN-2 | 结论:积分差大头在停车段 | 存疑 | docs/reports/ecat_integral_report.html(附带脚本输出) | 附带 JSON 的 main_source_of_integral_error=起动段、who_lags_at_stop=N2,与正文『N3 停车更拖』相矛盾(H-8) |
| IN-3 | 建议④ 序列 hold 不短于两台都停稳时间 | 仍存在 | js/motor/seq.js:95 | holdMs 范围 0~600000,无『停稳确认』机制;且序列重启存在并发循环(M-4) |
| IN-4 | 建议①~③ 统一减速段、对称负载、v2+v3 纠偏 | 无法在本仓库核实 | — | 属固件控制器 |
js/motor/seq.js:431-447, 449-455, 461-504docs/reports/ecat_integral_report.htmldocs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/REPORT_ecat_skip_opt_20260917.md本仓库是 DCU(GD32E508 主控 + LAN9252 EtherCAT 从站 + ESP32-C3 通信中继)的 上位机调试控制台:HTML/CSS/JS(ES module)纯前端 + 本地 Python 页面服务与桌面窗口外壳(pywebview/WebView2)。仓库内不含固件;业务 API 由 ESP32 固件 80 端口跨域提供,EtherCAT 主站 ecat_native.exe 位于外部 tools/ecat,由本仓 Python 代码拉起/代理。代码约 1.9 MB、184 个文件。
┌──────────────────── 桌面窗口 esp32_app.vbs (pywebview, GUI 进程) ────────────────────┐ +│ tabs.html 标签外壳 · DeviceLink Owner(BroadcastChannel) · app-lease WebSocket │ +│ ├─ pages/index.html OTA:ESP32 WiFi OTA / GD32 中继 / BLE OTA / EtherCAT 直灌 │ +│ ├─ pages/can.html CAN:DBC 解析、信号编码、批量发送 (+ can_monitor 内嵌) │ +│ ├─ pages/motor.html 电机:CAN FD 指令、周期发送、命令序列、示波器 (WiFi | ECAT) │ +│ └─ lab/*.html SPI/ECAT 测速、LAN9252 电源管理、PDO 布局 │ +│ js_api 桥: ecat_api / ecat_send_raw ──(ESF1 TCP 快发)──┐ │ +└──────────────────────────────────────────────────────────┼───────────────────────────┘ + HTTP 127.0.0.1:2625 (esp32_server.py 子进程) │ + ├─ 静态文件 + _reload 注入 ▼ + ├─ /ecat/api/* 反向代理 ──► ecat_client.py ──► ecat_native.exe (8090+, Npcap/I210) + │ ecat_proc.py (拉起/互斥/RealTime/强杀) │ EtherCAT + ├─ /api/lan/probe ─► lan_probe.py (局域网发现) ▼ + └─ WS 租约:全部窗口关闭 → op/stop GD32 + LAN9252 从站 ──CAN FD──► 电机 + 浏览器 ──HTTP(跨域)──► ESP32:80 (/system/status, /can/*, /ota/*) ──SPI──► GD32 + 浏览器 ──Web Bluetooth GATT──► ESP32 (BLE OTA)
| 模块 | 主要文件 | 职责 | 评分 |
|---|---|---|---|
| 主机服务/安全 | esp32_server.py, ecat_client.py, ecat_proc.py, lan_probe.py, *.vbs/bat | 本地静态服务、ECAT 代理、桌面桥、native 进程治理、局域网发现 | 6/10 |
| 电机控制/故障保护 | js/motor/*, js/common/ecat-bus.js, device-link.js, app-lease.js, desktop-bridge.js, pages/motor.html | 双链路电机指令、周期发送、序列、示波器、总线所有权 | 4.5/10 |
| OTA/刷写 | js/app.js, js/ota/*, js/ble/*, js/ble_ota.js, pages/index.html | ESP32/GD32 多通道刷写会话与进度 | 5/10 |
| CAN/公共层 | js/can.js, js/can/*, js/can_monitor.js, js/common/* | DBC 解析编码、发送、监控;连接、轮询、日志 | 6/10 |
| 仓库卫生/文档 | README.md, docs/, .gitignore, .qoder/, .zcode/, scripts/ | 文档、报告、测试脚本与版本控制卫生 | 5.5/10 |
eac3717 下全部源码与配置——Python 服务 4 个、JS 模块 50+、页面 5 个、lab 页 3 个、CSS 6 个、scripts/ 测试与探针 31 个,以及 docs/ 下全部既有报告和规格、.zcode 计划。.qoder/repowiki 为工具生成物,仅做卫生评估。tools/ecat/ecat_native.c 不在本仓,相关结论标注为“无法在本仓库核实”。行号以基线 commit 为准。scripts/ 中 .mjs 与多数 .py 以 process.exit/sys.exit 返回码判定,test_app_lease.py、test_esf_pack.py 有较多断言;probe_*.py 为采样器无断言(合理)。覆盖集中在传输契约、刷新速率、租约与快发打包,不覆盖停机路径、序列竞态、指令数值边界、链路丢失判定、HEX 解析(见 M-19)。| 编号 | 严重度 | 模块 | 标题 | 位置 |
|---|---|---|---|---|
| M-1 | 致命 | 电机控制/故障保护 | 无急停/全部失能,停止类操作均不下发失能帧 | js/motor/main.js:809-811, 2391, 2403, 2494; js/motor/seq.js:449; js/motor/main.js:1103, 11… |
| M-2 | 致命 | 电机控制/故障保护 | CMD 数值无范围校验,整数编码会回绕 | js/motor/main.js:744-756; pages/motor.html:141-149; js/motor/main.js:2462-2470 |
| M-3 | 致命 | 电机控制/故障保护 | 真实链路丢失永远判不出离线 | js/motor/main.js:969-987, 1175 |
| M-4 | 致命 | 电机控制/故障保护 | 序列停止后立即重启会出现两个并发执行循环 | js/motor/seq.js:431-447, 449-455, 461-504 |
| O-1 | 致命 | OTA/刷写 | 同一块 GD32 可被两条通道同时刷写 | js/ota/session.js:128; js/ota/boot_ecat.js:176-189, 576-577; js/ota/console-mode.js:67, 12… |
| O-2 | 致命 | OTA/刷写 | HEX 解析可放过损坏或截断文件 | js/ota/file-handle.js:458-516(校验 472-477,分配 506-509) |
| P-1 | 致命 | 主机服务/安全 | 本地服务无 Origin/Host/Content-Type 校验,任意网页可跨站驱动电机 | esp32_server.py:480-541(do_POST),504-532(ECAT 代理分支) |
| P-2 | 致命 | 主机服务/安全 | ESF1 快发在 sendall 成功后出错仍整包重发 | ecat_client.py:247-279 |
| C-1 | 严重 | CAN/公共层 | DBC 中 [0|0] 被当成真实范围 | js/can/dbc.js:164-165; js/can/signals.js:299-304 |
| C-11 | 严重 | CAN/公共层 | 独立 CAN 监控页无视所选设备 | pages/can_monitor.html:55; js/can_monitor.js:60-68; js/can/dbc.js:40-47 |
| C-12 | 严重 | CAN/公共层 | 监控页超时永不显示离线 | js/can_monitor.js:199 |
| C-2 | 严重 | CAN/公共层 | 扩展多路复用信号被静默丢弃 | js/can/dbc.js:153 |
| C-4 | 严重 | CAN/公共层 | 扩展/标准帧靠 ID 数值猜测,发送载荷无帧类型标志 | js/can/dbc.js:146; js/can/send.js:304, 373, 453, 461 |
| C-5 | 严重 | CAN/公共层 | DLC 未按 CAN FD 合法长度校验 | js/can/send.js:406; js/can/signals.js:233-235 |
| H-1 | 严重 | 仓库卫生/文档 | AI 工具目录被提交 | .qoder/repowiki/(约 75 个文件); .zcode/plans/plan-sess_*.md; .gitignore |
| H-5 | 严重 | 仓库卫生/文档 | 默认 ECAT 周期 0.25 ms 与既有报告建议冲突且缺复测依据 | js/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431 |
| M-10 | 严重 | 电机控制/故障保护 | 周期发送与序列计时在后台标签被节流,且无可见性处理 | js/motor/main.js:2488; js/motor/seq.js:503 |
| M-11 | 严重 | 电机控制/故障保护 | ECAT 发送不核对 queued,失败也报成功 | js/motor/transport-ecat.js:803-810 |
| M-5 | 严重 | 电机控制/故障保护 | ECAT 活性保持把陈旧数据显示为在线 | js/motor/transport-ecat.js:526, 552, 572-590; js/motor/refresh-rate.js:138 |
| M-6 | 严重 | 电机控制/故障保护 | 「谁可以动总线」红线被多处绕过 | js/motor/transport-ecat.js:394-459, 668; js/common/device-link.js:250-287, 322-327 |
| M-7 | 严重 | 电机控制/故障保护 | OTA 忙标志写在 iframe 窗口,外壳 Owner 读不到 | js/motor/transport-ecat.js:80-82; js/common/device-link.js:255 |
| M-8 | 严重 | 电机控制/故障保护 | ECAT 桥失败回落 HTTP,非幂等命令可能执行两次 | js/motor/transport-ecat.js:259-271; js/common/desktop-bridge.js:59-74 |
| M-9 | 严重 | 电机控制/故障保护 | 修改网卡输入框即关闭运行中总线,无任何保护 | js/motor/transport-ecat.js:899-908; js/motor/main.js:3215-3227 |
| O-3 | 严重 | OTA/刷写 | ESP32 重启按钮无 OTA 守卫 | js/ota/upload-esp32.js:594-613; pages/index.html:368 |
| O-4 | 严重 | OTA/刷写 | GD32 完成判定可被陈旧 alive 标志误判 | js/ota/stages.js:497-499 |
| O-5 | 严重 | OTA/刷写 | ESP32 重启后成功判定不核对新版本 | js/common/polling.js:~236; js/ota/upload-esp32.js:435-449, 468-474 |
| O-6 | 严重 | OTA/刷写 | WiFi/BLE OTA 不通知其它标签,端点可中途切换 | js/ota/boot_ecat.js:598; js/app.js:63-71, 403-421 |
| O-7 | 严重 | OTA/刷写 | BLE abort 总发会话 0;中继阶段可随意中止 | js/ble/session.js:89; js/ble/state.js |
| O-8 | 严重 | OTA/刷写 | BLE GD32 身份检查未 await | js/ble/file.js:174, 182-205 |
| O-9 | 严重 | OTA/刷写 | 前端不校验 ESP32 镜像 | js/ota/file-handle.js:725-751 |
| P-3 | 严重 | 主机服务/安全 | 健康探测 1 s 超时即无差别强杀所有 ecat_native | ecat_proc.py:124-140, 143-194, 250-253 |
| P-4 | 严重 | 主机服务/安全 | 跨进程锁超时或 CreateMutexW 失败仍继续执行 | ecat_proc.py:67-94(尤其 72-81) |
| P-5 | 严重 | 主机服务/安全 | 桌面桥路径不记录循环状态,『关 app 必停从站』可能失效 | ecat_client.py:470-497; esp32_server.py:331-340, 403-420, 533 |
| P-6 | 严重 | 主机服务/安全 | 外链在窗口内导航,外部页面可调用桌面桥 js_api | esp32_server.py:142-146, 998-1000 |
| P-7 | 严重 | 主机服务/安全 | ecat_native 提到 REALTIME 优先级,配合自旋线程可能拖死系统;复用实例不提权 | ecat_proc.py:96-121, 212-215, 273-276 |
| C-10 | 一般 | CAN/公共层 | 单条发送无防重入 | js/can/send.js:282, 358, 435 |
| C-13 | 一般 | CAN/公共层 | 对设备的并发轮询过多 | js/common/device-link.js:30; js/can.js:131, 424; js/can_monitor.js:487, 490; tabs.html:76-… |
| C-14 | 一般 | CAN/公共层 | 轮询超时计时器可能丢失 | js/common/polling.js:194 |
| C-16 | 一般 | CAN/公共层 | 读取已存 IP 不校验;网关猜测探测 | js/common/base-url.js:44-50; js/common/connection.js:761-789 |
| C-3 | 一般 | CAN/公共层 | 多行 CM_ 注释丢失 | js/can/dbc.js:178, 184 |
| C-6 | 一般 | CAN/公共层 | 手动 ID 解析过宽 | js/can/dbc.js:58 |
| C-7 | 一般 | CAN/公共层 | 枚举/多路复用/浮点信号编码细节错误 | js/can/signals.js:45-51, 76, 294-296, 406 |
| C-8 | 一般 | CAN/公共层 | 持久化静默失败且状态只增不减 | js/can/persist.js:93-124; js/can.js:229 |
| C-9 | 一般 | CAN/公共层 | toast 模块被加载成两个实例 | js/can/send.js:17; js/can.js:19-20, 47 |
| H-2 | 一般 | 仓库卫生/文档 | 受版本控制文件含个人绝对路径 | scripts/build_mem.bat:21; README.md:3, 449; docs/compose/spec/host-code-quality.md:67 |
| H-3 | 一般 | 仓库卫生/文档 | README 脚本清单与 scripts/ 不一致;.gitignore 规则重叠 | README.md; scripts/check_fe_guard_mutation.py; scripts/ui_diag_motor.mjs; .gitignore; .git… |
| H-4 | 一般 | 仓库卫生/文档 | 注释/文档与代码不符(默认周期等) | js/motor/transport-ecat.js:37, 166, 416-417, 607; README.md:190 |
| H-6 | 一般 | 仓库卫生/文档 | GD32 WiFi 中继刷写缺『刷写≠生效』版本比对,守卫脚本已删除 | js/ota/upload-gd32.js; js/ota/stages.js:497-499 |
| H-8 | 一般 | 仓库卫生/文档 | ecat_integral_report 结论与其附带脚本输出自相矛盾 | docs/reports/ecat_integral_report.html |
| M-12 | 一般 | 电机控制/故障保护 | 运行中导入/水合配置会替换正在使用的参数 | js/motor/main.js:242-289; js/motor/seq.js:223 |
| M-13 | 一般 | 电机控制/故障保护 | 危险默认值 | js/motor/seq.js:76-89; pages/motor.html:105, 123, 127 |
| M-14 | 一般 | 电机控制/故障保护 | NaN/Inf 浮点被显示为 0 | js/motor/main.js:624-627, 666-669 |
| M-15 | 一般 | 电机控制/故障保护 | 磁盘水合后链路状态不一致 | js/motor/main.js:268, 3172 |
| M-16 | 一般 | 电机控制/故障保护 | 节点 ID 修改不核对 ACK;去重表键不含通道 | js/motor/main.js:3044-3046 |
| M-19 | 一般 | 电机控制/故障保护 | 自动化测试未覆盖停机/序列竞态/数值范围 | scripts/test_motor_transport.mjs; scripts/test_motor_refresh.mjs; scripts/test_ecat_autost… |
| O-10 | 一般 | OTA/刷写 | BLE ACK/重传机制薄弱 | js/ble/gatt.js:249-255; js/ble/transfer.js:45-57, 75-78, 282 |
| O-11 | 一般 | OTA/刷写 | BLE 载荷固定 480 B,无 MTU 回退 | js/ble/constants.js:38, 50; js/ble/state.js:76 |
| O-12 | 一般 | OTA/刷写 | BLE 断开不拒绝结果等待 | js/ble/gatt.js:139-150; js/ble/transfer.js:394 |
| O-13 | 一般 | OTA/刷写 | GD32 中继触发超时后可能误判失败 | js/ota/upload-gd32.js:191-216 |
| O-14 | 一般 | OTA/刷写 | ECAT 直灌无完整性校验,api() 不查 HTTP 状态 | js/ota/boot_ecat.js:89-99, 635-661 |
| P-10 | 一般 | 主机服务/安全 | 代理读取 Content-Length 与 native 响应均无上限 | esp32_server.py:509-512; ecat_client.py:350-355 |
| P-11 | 一般 | 主机服务/安全 | ESF 打包静默修改数据 | ecat_client.py:140-141, 157-166 |
| P-12 | 一般 | 主机服务/安全 | 静态服务暴露整个 BASE_DIR,无扩展名文件被当 HTML 注入脚本 | esp32_server.py:434, 454-466, 474 |
| P-13 | 一般 | 主机服务/安全 | WebSocket 实现不完整且不校验 Origin | esp32_server.py:551-564, 604-606 |
| P-14 | 一般 | 主机服务/安全 | 端口复用与单实例检测存在竞态 | esp32_server.py:756-779, 897-898, 954 |
| P-15 | 一般 | 主机服务/安全 | 退出路径可能跳过停机 | ecat_proc.py:301-311; esp32_server.py:348, 873-878 |
| P-8 | 一般 | 主机服务/安全 | 非幂等请求首次可能误报 503 | ecat_client.py:405, 415, 426-439 |
| P-9 | 一般 | 主机服务/安全 | 桥接路径可写入任意 HTTP 请求行 | ecat_client.py:93-107, 337-344, 470 |
| C-15 | 建议 | CAN/公共层 | 大量隐式全局与重复代码 | js/common/polling.js:10-29; js/common/connection.js:6-13; js/can/send.js:36; js/can_monito… |
| H-7 | 建议 | 仓库卫生/文档 | 报告中的资源与脚本链接随归档失效 | docs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/R… |
| M-17 | 建议 | 电机控制/故障保护 | 示波器数据经滤波与重采样,定时器从不停止 | js/motor/scope.js:31, 228-256, 269 |
| M-18 | 建议 | 电机控制/故障保护 | main.js 约 3250 行,流控逻辑重复 | js/motor/main.js:807-948 |
| O-15 | 建议 | OTA/刷写 | 大量 window.* 全局、猴补 showOpenFilePicker、内存复制 | js/ota/console-mode.js:170-199; js/ota/upload-esp32.js:213-247; js/ota/progress.js:177; js… |
| P-16 | 建议 | 主机服务/安全 | native_stdout.log 只追加不轮转 | ecat_proc.py:259-262 |
| P-17 | 建议 | 主机服务/安全 | LAN 探测接口可被当端口扫描器 | lan_probe.py:320-333; esp32_server.py:673-684 |
js/motor/main.js:809-811, 2391, 2403, 2494; js/motor/seq.js:449; js/motor/main.js:1103, 1193; pages/motor.htmljs/motor/main.js:744-756; pages/motor.html:141-149; js/motor/main.js:2462-2470js/motor/main.js:969-987, 1175js/motor/seq.js:431-447, 449-455, 461-504js/motor/main.js:2488; js/motor/seq.js:503js/motor/transport-ecat.js:803-810js/motor/transport-ecat.js:526, 552, 572-590; js/motor/refresh-rate.js:138js/motor/transport-ecat.js:394-459, 668; js/common/device-link.js:250-287, 322-327js/motor/transport-ecat.js:80-82; js/common/device-link.js:255js/motor/transport-ecat.js:259-271; js/common/desktop-bridge.js:59-74js/motor/transport-ecat.js:899-908; js/motor/main.js:3215-3227js/motor/main.js:242-289; js/motor/seq.js:223js/motor/seq.js:76-89; pages/motor.html:105, 123, 127js/motor/main.js:624-627, 666-669js/motor/main.js:268, 3172js/motor/main.js:3044-3046scripts/test_motor_transport.mjs; scripts/test_motor_refresh.mjs; scripts/test_ecat_autostart.mjsjs/motor/scope.js:31, 228-256, 269js/motor/main.js:807-948esp32_server.py:480-541(do_POST),504-532(ECAT 代理分支)ecat_client.py:247-279ecat_proc.py:124-140, 143-194, 250-253ecat_proc.py:67-94(尤其 72-81)ecat_client.py:470-497; esp32_server.py:331-340, 403-420, 533esp32_server.py:142-146, 998-1000ecat_proc.py:96-121, 212-215, 273-276esp32_server.py:509-512; ecat_client.py:350-355ecat_client.py:140-141, 157-166esp32_server.py:434, 454-466, 474esp32_server.py:551-564, 604-606esp32_server.py:756-779, 897-898, 954ecat_proc.py:301-311; esp32_server.py:348, 873-878ecat_client.py:405, 415, 426-439ecat_client.py:93-107, 337-344, 470ecat_proc.py:259-262lan_probe.py:320-333; esp32_server.py:673-684js/ota/session.js:128; js/ota/boot_ecat.js:176-189, 576-577; js/ota/console-mode.js:67, 120; js/ota/ecat_load.js:114-117; js/ota/upload-esp32.js:62-91; js/ble/transfer.js:457-472js/ota/file-handle.js:458-516(校验 472-477,分配 506-509)js/ota/upload-esp32.js:594-613; pages/index.html:368js/ota/stages.js:497-499js/common/polling.js:~236; js/ota/upload-esp32.js:435-449, 468-474js/ota/boot_ecat.js:598; js/app.js:63-71, 403-421js/ble/session.js:89; js/ble/state.jsjs/ble/file.js:174, 182-205js/ota/file-handle.js:725-751js/ble/gatt.js:249-255; js/ble/transfer.js:45-57, 75-78, 282js/ble/constants.js:38, 50; js/ble/state.js:76js/ble/gatt.js:139-150; js/ble/transfer.js:394js/ota/upload-gd32.js:191-216js/ota/boot_ecat.js:89-99, 635-661js/ota/console-mode.js:170-199; js/ota/upload-esp32.js:213-247; js/ota/progress.js:177; js/ota/upload-gd32.js:85-104js/can/dbc.js:164-165; js/can/signals.js:299-304pages/can_monitor.html:55; js/can_monitor.js:60-68; js/can/dbc.js:40-47js/can_monitor.js:199js/can/dbc.js:153js/can/dbc.js:146; js/can/send.js:304, 373, 453, 461js/can/send.js:406; js/can/signals.js:233-235js/can/send.js:282, 358, 435js/common/device-link.js:30; js/can.js:131, 424; js/can_monitor.js:487, 490; tabs.html:76-81; js/common/polling.js:350-352js/common/polling.js:194js/common/base-url.js:44-50; js/common/connection.js:761-789js/can/dbc.js:178, 184js/can/dbc.js:58js/can/signals.js:45-51, 76, 294-296, 406js/can/persist.js:93-124; js/can.js:229js/can/send.js:17; js/can.js:19-20, 47js/common/polling.js:10-29; js/common/connection.js:6-13; js/can/send.js:36; js/can_monitor.js:14, 100; js/can.js:86.qoder/repowiki/(约 75 个文件); .zcode/plans/plan-sess_*.md; .gitignorejs/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431scripts/build_mem.bat:21; README.md:3, 449; docs/compose/spec/host-code-quality.md:67README.md; scripts/check_fe_guard_mutation.py; scripts/ui_diag_motor.mjs; .gitignore; .gitattributesjs/motor/transport-ecat.js:37, 166, 416-417, 607; README.md:190js/ota/upload-gd32.js; js/ota/stages.js:497-499docs/reports/ecat_integral_report.htmldocs/reports/ECAT_RATE_TRADEOFF.md; docs/reports/ecat_integral_report.html; docs/reports/REPORT_ecat_skip_opt_20260917.md对仓库内全部既有报告与规格逐条核对(原文件保留不动),每份另出修订附录:
| 原文件 | 修订附录 | 已修复 | 部分 | 仍存在/存疑 | 已过时 | 无法核实 |
|---|---|---|---|---|---|---|
docs/reports/ECAT_BEAT_TAIL_REPORT.html | ECAT_BEAT_TAIL_REPORT_REV_2026-10-19.html | 2 | 0 | 1 | 2 | 1 |
docs/reports/ECAT_RATE_TRADEOFF.html + .md | ECAT_RATE_TRADEOFF_REV_2026-10-19.html | 0 | 0 | 3 | 1 | 1 |
docs/reports/REPORT_ecat_skip_opt_20260917.md | REPORT_ecat_skip_opt_20260917_REV_2026-10-19.html | 0 | 1 | 1 | 2 | 1 |
docs/reports/GD32_OTA_FLOW_COMPARE.html | GD32_OTA_FLOW_COMPARE_REV_2026-10-19.html | 1 | 1 | 1 | 2 | 3 |
docs/reports/ecat_integral_report.html | ecat_integral_report_REV_2026-10-19.html | 0 | 0 | 2 | 1 | 1 |
docs/compose/spec/device-link.md | device-link_REV_2026-10-19.html | 2 | 2 | 1 | 0 | 0 |
docs/compose/spec/tab-keepalive.md | tab-keepalive_REV_2026-10-19.html | 2 | 0 | 1 | 0 | 0 |
docs/compose/spec/ecat-rx-stuck.md | ecat-rx-stuck_REV_2026-10-19.html | 0 | 0 | 1 | 0 | 2 |
docs/compose/spec/pdo-fast-send.md | pdo-fast-send_REV_2026-10-19.html | 2 | 1 | 1 | 0 | 0 |
docs/compose/spec/host-code-quality.md | host-code-quality_REV_2026-10-19.html | 2 | 5 | 2 | 0 | 0 |
.zcode/plans/plan-sess_*.md | (无附录,仅本表跟踪) | 2 | 0 | 0 | 0 | 2 |
| 来源 | 编号 | 原结论 / 建议 | 当前状态 | 证据(文件:行号) | 备注 |
|---|---|---|---|---|---|
| ECAT_BEAT_TAIL_REPORT | BT-1 | 前端每 PDO 电机槽数与扫描拍数按 dense 布局改(MOT_SLOTS_PER_PDO=9、MOTOR_SCAN_CYCLES=1) | 已修复 | js/motor/transport-ecat.js:57, 88 | |
| ECAT_BEAT_TAIL_REPORT | BT-2 | 测速页跳拍卡改读 cyc_us.late/lost | 已修复 | lab/spi_test.html:506, 1522-1534, 2154-2167 | |
| ECAT_BEAT_TAIL_REPORT | BT-3 | 刷写≠生效:flash_gd32.py 增加生效守卫 | 已过时 | —(beeae8a 随 scripts 收敛删除) | 网页 WiFi 中继路径无替代版本比对,见新问题 H-6;ECAT 直灌有 0x100A 比对(boot_ecat.js:629-632, 792-794) |
| ECAT_BEAT_TAIL_REPORT | BT-4 | 345µs 归因:win 布局固有成本 vs 主站 97fab23 回归,需一次刷板钉死实验 | 无法在本仓库核实 | — | 涉及固件布局与 ecat_native.c,不在本仓 |
| ECAT_BEAT_TAIL_REPORT | BT-5 | 0.25ms 档实测列为待办 | 仍存在 | js/common/ecat-bus.js:28 | 默认已是 0.25ms 却无复测记录,见 H-5 |
| ECAT_BEAT_TAIL_REPORT | BT-6 | 报告引用 lab/ecat_rate_sweep.csv 等证据数据 | 已过时 | — | 数据随归档删除,报告不可复现,见 H-7 |
| ECAT_RATE_TRADEOFF | RT-1 | 建议周期停在 0.5ms,0.25ms 为功能损坏 | 仍存在 | js/common/ecat-bus.js:28; js/motor/transport-ecat.js:428-431 | 代码默认 0.25ms,建议未采纳且无复测依据(H-5) |
| ECAT_RATE_TRADEOFF | RT-2 | 周期可被 localStorage 覆盖(原 :227-228) | 仍存在 | js/motor/transport-ecat.js:167, 428-430 | 设计如此,但应在 UI 明示并限定合法档位 |
| ECAT_RATE_TRADEOFF | RT-3 | drop 口径、fillRxWindow 计时待办 | 无法在本仓库核实 | — | 属固件/native 侧 |
| ECAT_RATE_TRADEOFF | RT-4 | sweep_ecat_rate.py / calibrate_ecat_metrics.py / plot_* / build_ecat_report_html.py 与图表数据 | 已过时 | — | beeae8a 删除,.md 中图片链接失效(H-7) |
| ECAT_RATE_TRADEOFF | RT-5 | 注释/README 称默认 4ms 由后端决定 | 仍存在 | js/motor/transport-ecat.js:166, 416-417; README.md:190 | 文档与代码不符(H-4) |
| REPORT_ecat_skip_opt_20260917 | SK-1 | ecat_native 提权为 RealTime | 部分修复 | ecat_proc.py:97-120, 273-276 | 仅新拉起进程提权;复用实例分支 :212-215 不提权;且 REALTIME 有饿死系统线程风险(P-7) |
| REPORT_ecat_skip_opt_20260917 | SK-2 | 生产建议 2ms | 仍存在 | js/common/ecat-bus.js:28 | 默认 0.25ms,与建议冲突(H-5) |
| REPORT_ecat_skip_opt_20260917 | SK-3 | 第四节回滚命令依赖 scripts/skip_*.py | 已过时 | — | 脚本已删除,回滚步骤不可直接执行 |
| REPORT_ecat_skip_opt_20260917 | SK-4 | I210 协议绑定/高级属性调整 | 无法在本仓库核实 | — | 属主机网卡配置 |
| REPORT_ecat_skip_opt_20260917 | SK-5 | 标定/实验脚本(第五节) | 已过时 | — | 已出库(H-7) |
| GD32_OTA_FLOW_COMPARE | OF-1 | 新流程 0 次上板实测 | 已过时 | js/ota/boot_ecat.js:55-58, 307-322 | EtherCAT 直灌已移植入本仓(d73e2fb 起),注释含 2026-10-12/13 实测记录 |
| GD32_OTA_FLOW_COMPARE | OF-2 | 正在跑 APP 的机器还不能直接刷 | 部分修复 | js/ota/boot_ecat.js:663-676 | 主机侧已写 CoE 0x2502:00=1 交接;固件侧无法核实 |
| GD32_OTA_FLOW_COMPARE | OF-3 | 刷前刷后 0x100A 版本比对 | 已修复 | js/ota/boot_ecat.js:629-632, 792-794 | |
| GD32_OTA_FLOW_COMPARE | OF-4 | 4 字节对齐补 0xFF | 无法在本仓库核实 | — | 发生在 native 侧 |
| GD32_OTA_FLOW_COMPARE | OF-5 | 固件 OTA.cpp 尾巴丢弃缺陷 | 无法在本仓库核实 | — | 固件仓 |
| GD32_OTA_FLOW_COMPARE | OF-6 | 老流程无断点续传,每次从偏移 0 重写 | 仍存在 | js/ota/upload-esp32.js:213-247 | 整文件 POST 且内存双份(O-15) |
| GD32_OTA_FLOW_COMPARE | OF-7 | 报告引用行号 upload-gd32.js:58,194 | 已过时(行号漂移) | js/ota/upload-gd32.js:67-68; js/ota/file-handle.js:458, 563 | file-handle 引用仍有效 |
| GD32_OTA_FLOW_COMPARE | OF-8 | 两条路互为备份、复用同一 flash 写入者 | 无法在本仓库核实 | — | 前端侧两条路缺统一互斥,见新问题 O-1(致命) |
| ecat_integral_report | IN-1 | 数据源 lab/ecat_passive_latest.csv | 已过时 | — | CSV 不在仓库,报告不可复现(H-7) |
| ecat_integral_report | IN-2 | 结论:积分差大头在停车段 | 存疑 | docs/reports/ecat_integral_report.html(附带脚本输出) | 附带 JSON 的 main_source_of_integral_error=起动段、who_lags_at_stop=N2,与正文『N3 停车更拖』相矛盾(H-8) |
| ecat_integral_report | IN-3 | 建议④ 序列 hold 不短于两台都停稳时间 | 仍存在 | js/motor/seq.js:95 | holdMs 范围 0~600000,无『停稳确认』机制;且序列重启存在并发循环(M-4) |
| ecat_integral_report | IN-4 | 建议①~③ 统一减速段、对称负载、v2+v3 纠偏 | 无法在本仓库核实 | — | 属固件控制器 |
| device-link | DL-1 | 外壳 Owner + BroadcastChannel 快照 | 已修复(已交付) | tabs.html:205; js/common/device-link.js:117, 389 | |
| device-link | DL-2 | 端点配置只在 ConnectionHub | 部分修复 | pages/can_monitor.html:55; js/can_monitor.js:60-68; js/app.js:63-71 | CAN 监控页硬编码 IP 优先于 Hub(C-11);OTA 页 IP 输入可绕过 |
| device-link | DL-3 | 功能页不再各自判定在线 | 部分修复 | js/common/polling.js; js/can.js:424; js/can_monitor.js:487 | 多处仍独立轮询 /system/status(C-13) |
| device-link | DL-4 | 外壳启动强制开总线,失败 10s 退避 | 仍存在风险 | js/common/device-link.js:32, 250-287 | 无 reason、unknown 视为需启动、OTA 闸读不到 iframe 标志(M-6、M-7) |
| device-link | DL-5 | BLE 经 reportBle 上报 | 已修复(已交付) | js/ble/gatt.js:119, 123, 128 | |
| tab-keepalive | TK-1 | 多 iframe 宿主 + visibility 切换 | 已修复(已交付) | tabs.html:70-81, 100, 113 | |
| tab-keepalive | TK-2 | F5/⟳ 只 reload .page-frame.active | 已修复(已交付) | esp32_server.py:126, 150, 166 | |
| tab-keepalive | TK-3 | 不做后台页降频(Out of Scope) | 仍存在风险 | tabs.html:76-81; js/common/polling.js:350-352 | 隐藏帧持续轮询挤占设备 6 个 socket(C-13);电机页发送节拍在后台被节流(M-10)——建议重新评估此决策 |
| ecat-rx-stuck | RX-1 | 主站 OP 后 seq 沿踢帧 + 活性判据加宽 | 无法在本仓库核实 | — | ecat_native.c 不在本仓 |
| ecat-rx-stuck | RX-2 | 从站新鲜度救援先 Process 再 InputMapping | 无法在本仓库核实 | — | 固件仓 |
| ecat-rx-stuck | RX-3 | 规格状态仍为 in-progress,但 T1~T3 已勾选 | 仍存在 | docs/compose/spec/ecat-rx-stuck.md:3 | 建议改为 delivered 或注明剩余事项 |
| pdo-fast-send | FS-1 | Python 桥 ESF1 仅走 TCP,无 HTTP 回落 | 已修复(已交付) | ecat_client.py:231-287 | |
| pdo-fast-send | FS-2 | 前端 sendViaFastOrJson 有桥时只调快发 | 已修复(已交付) | js/motor/transport-ecat.js:282-300 | |
| pdo-fast-send | FS-3 | 失败重探端口后再试 TCP 一次 | 仍存在风险 | ecat_client.py:247-279 | sendall 成功后 recv 失败也会重发,同一帧可能入队两次(P-2,致命) |
| pdo-fast-send | FS-4 | 堵死慢发原则 | 部分修复 | js/motor/transport-ecat.js:259-271 | 低频路径(motor/send、motor/start)桥失败仍回落 HTTP(M-8) |
| host-code-quality | HQ-R1 | 非幂等不自动重发 | 部分修复 | ecat_client.py:58-62, 290-299, 418-436 | HTTP 代理已遵守;ESF1 快发重试违反同一原则(P-2) |
| host-code-quality | HQ-R2 | 网卡默认 I210 | 已修复 | ecat_proc.py:28 | |
| host-code-quality | HQ-R3 | 跨进程互斥/复用 | 部分修复 | ecat_proc.py:67-94, 125-140 | 锁超时/CreateMutexW 失败仍继续执行(P-4) |
| host-code-quality | HQ-R4 | 拆 main.js | 部分修复 | js/motor/main.js(3254 行) | 仍为上帝文件(M-18) |
| host-code-quality | HQ-R5 | 版本/参数下沉 | 仍未实施 | — | |
| host-code-quality | HQ-R6 | ECAT bootstrap 单点 | 部分修复 | js/motor/transport-ecat.js:418-441; js/common/ecat-bus.js:65-75 | 电机侧仍自算周期并绕过预算(M-6) |
| host-code-quality | HQ-R7 | toast/quiet 去重 | 仍未实施 | js/can/send.js:17 | CAN 侧还出现 toast 双实例(C-9) |
| host-code-quality | HQ-R8~R14 | 服务端拆分与卫生 | 已修复(大部分) | ecat_client.py; ecat_proc.py; docs/reports/ | 但 .qoder/.zcode 入库(H-1) |
| host-code-quality | HQ-R15 | README | 部分修复 | README.md:3, 190, 449 | 个人路径与默认周期描述过时(H-2、H-4) |
| .zcode-plan | ZC-A1 | ecat_native 新增 /api/pm/hold | 无法在本仓库核实 | — | native 不在本仓 |
| .zcode-plan | ZC-A2 | lan9252_pm.html enterMode 后发 pm/hold | 已修复 | lab/lan9252_pm.html:447 | |
| .zcode-plan | ZC-A3 | 睡眠标记另写带时间戳 localStorage | 已修复 | lab/lan9252_pm.html:289-309 | |
| .zcode-plan | ZC-B | GD32 固件 HBI 门控 | 无法在本仓库核实 | — | 固件仓 |
| 维度 | 评分 | 说明 |
|---|---|---|
| 架构与模块划分 | 6.5 | 外壳/功能页/链路层分层清晰,DeviceLink、多 iframe 保活、双链路 transport 抽象设计合理;但跨帧状态依赖 window.* 全局,main.js 过大。 |
| 实时性与通信协议 | 6 | ESF1 快发、幂等白名单、Worker 状态轮询等用心;后台节流、重复轮询、默认 0.25ms 周期缺依据。 |
| 安全与故障保护 | 3.5 | 无急停、无数值限幅、离线判不出、序列并发、本地服务无来源校验——是本次评审最主要的扣分项。 |
| OTA/刷写可靠性 | 5 | 设备侧 SHA/身份检查、ECAT 0x100A 比对等较好;跨通道互斥缺失与 HEX 解析漏洞可致变砖。 |
| 代码质量与可维护性 | 5.5 | 注释详尽、经验教训有记录;上帝文件、重复逻辑、注释与代码不符。 |
| 测试 | 5 | 有真机与浏览器验收链、返回码规范;安全关键路径无用例。 |
| 构建与仓库卫生 | 5.5 | scripts 已收敛、报告归档;AI 工具目录与个人路径入库,报告证据随归档丢失。 |
| 综合 | 5.4 | 功能完整度高、工程经验积累扎实,但作为可直接驱动电机的工具,安全兜底明显不足。完成 P0 项后预计可达 7 分。 |
本评审只新增 docs/ 下文件,未修改任何源码、未删除任何文件。