cbb 79633a2b0f feat(motor): 自适应 PDO 窗口与通道活动指示,新增原生 SOEM 时序诊断
后端 PDO 循环改为按在线槽收缩状态窗口,稀疏总线下单槽每周期都能刷新,
并补上尾部槽的发现扫描游标;新增自旋节拍源(阈值/显式覆盖)、P 核识别
与线程级钉核,自旋期间释放 GIL 以免 HTTP 线程被饿死;启动时先关停旧实例,
避免两个进程争用 Npcap 适配器。

记录每拍完整时间线、GC stop-the-world 事件与网格跳拍数,经 /api/motor/dbg
导出用于归因固定频率的超时;配
2026-09-05 01:20:14 +08:00

dcu-ecat-master

DCU LAN9252 EtherCAT 主站工具集(工作目录 DCU/tools/ecat)

在 Windows 上用 Python + pysoem(SOEM)直接从网卡驱动 DCU 的 LAN9252 EtherCAT 从站: 扫描总线、读写 SII EEPROM、CoE SDO 读写、PDO 循环收发,以及一个本地网页/桌面控制台。

环境准备

  • Python 3.12(venv 不入库)
  • Npcap:pysoem 收发裸 EtherCAT 帧的前提
  • 一块直连从站的物理网卡(示例中为 Intel I226)
py -3.12 -m venv venv
venv\Scripts\python.exe -m pip install -r requirements.txt

目录结构

入口在最外层,双击即用;代码全部收进 src/。

ecat/
├─ ecat_app.vbs            ← 桌面窗口(推荐)
├─ ecat_web.vbs            ← 浏览器标签
├─ ecat_web.bat            ← 控制台模式(看日志)
├─ ecat.bat                ← 命令行工具
├─ run_scan.bat            ← bring-up 扫描
├─ README.md / requirements.txt
├─ src/
│  ├─ ecat_server.py       网页控制台后端(REST API + 静态文件), 默认端口 8090
│  ├─ ecat_tool.py         一体化命令行主站
│  ├─ ecat_flash_eeprom.py 经网线烧写 SII 镜像(被 ecat_tool flash 复用)
│  ├─ test_motor_backend.py 电机后端自测(不接硬件)
│  ├─ web/                 前端资源(URL 路径不变, 仍是 / 与 /motor.html)
│  └─ diag/                独立诊断脚本(互不依赖, 直接单跑)
└─ venv/                   本地虚拟环境(不入库)

src/ 根下那四个 .py 平放是有原因的:ecat_tool.py import ecat_flash_eeprom、 test_motor_backend.py import ecat_server,互相 import 的必须同层,再往下分 就得改 import 或做成包,不值得。

文件 说明
src/ecat_tool.py 一体化命令行主站:adapters / status / flash / eeprom / sdo / send 等子命令
src/ecat_server.py 网页控制台后端(REST API + 静态文件),默认端口 8090(8080 已被 ESP32 tools 占用)
src/ecat_flash_eeprom.py 通过网线烧写 gen_eeprom.py 生成的 SII 镜像,逐字回读校验(烧完需断电重启让 ESC 重新加载)
src/test_motor_backend.py 电机后端自测,不接硬件(假从站模拟 GD32 buildInput/processOutput)。跑法:在 src/ 下 ..\venv\Scripts\python.exe test_motor_backend.py
src/web/ecat.html + ecat.css 网页控制台前端
src/web/motor.html + motor.js 电机控制台:N1–N9 九节点,走 EtherCAT 过程数据(不经 WiFi/HTTP)。节点总览、8 种 Control_Mode、STATUS 实时解码、示波器曲线
src/diag/ecat_scan.py 最小化 bring-up 扫描:从站身份 + SII dump,--op 追加 PDO 测试
src/diag/ecat_esc_regs.py 从网络侧直读 LAN9252 ESC 寄存器,绕开 GD32/PDI,用于判断 EEPROM 加载是否真的失败;支持 --reload
src/diag/ecat_sniff.py 旁路抓包,hexdump SOEM 自己发出的帧,用于对照裸帧格式

启动方式

双击根目录下的入口即可(脚本自己定位路径,不必在特定目录下运行):

入口 效果
ecat_app.vbs pywebview 桌面窗口,无控制台无浏览器标签(已针对部分 GPU 驱动白屏加 --disable-gpu-compositing)
ecat_web.vbs 后台起服务并打开浏览器标签,无控制台窗口
ecat_web.bat 控制台模式,可见日志,调试用
ecat.bat 命令行工具入口,如 ecat.bat status、ecat.bat flash
run_scan.bat 直接跑 bring-up 扫描,无参数则列出 Npcap 适配器

电机控制台在服务起来后从主页右上「电机控制台」进入,或直接访问 /motor.html。 它只读写 EtherCAT 过程数据,需先在主页点「连接」并让从站进入 OP。

注意

  • ESC 的 SyncManager 寄存器是 0x0800 + 8n:邮箱是 SM0=0x0800、SM1=0x0808, 0x0810/0x0818 是 SM2/SM3(过程数据)。写诊断代码时别混用,否则抓到的现场会误导判断。
  • 邮箱楔死判据:SM0/SM1 寄存器正常(start=0x1000/0x1200、act=01)但 SDO 持续失败, 就是 SSC 的 u16EscAddrSendMbx 错位——响应帧写到 SM1 start+4/+8 且逐会话累积, 断电才清零。固件 <1.5.52 无自愈需断电重启,1.5.52+ 有守护自动写回。 config_map 失败时后端会自动转储 4 个 SM 现场,可直接对照。
  • 前端 CSS/JS 改动后记得 bump ?v= 缓存版本,否则浏览器会加载旧代码。 src/web/ecat.css 被 ecat.html 与 motor.html 共用,两处版本号要一起改。
  • EEPROM 烧写后必须断电冷启动,ESC 才会重新加载配置。
S
Description
No description provided
Readme
651 KiB
Languages
C 83.2%
Python 5.1%
HTML 4.2%
JavaScript 3.9%
CSS 3.4%
Other 0.2%