a1ec486c742d0c6d809be5c649b117fd35109917
1) g_op_active = Falseg_httpd = None 这行把 None 赋给了 g_op_active 和 笔误变量 Falseg_httpd, 导致 g_httpd 在模块级从未定义, 第 744 行 if g_httpd is not None 在服务启动前命中即 NameError。拆成两行。 语法合法故初次提交未拦住。 2) _require_op_ready 入口无条件预清理(回 INIT + config_init 重枚举): 同一连接反复停止/启动而不重枚举时从站邮箱通路逐轮退化, 第 4 轮 config_map() 内 SOEM CoE 分段读的无边界 memcpy 吃到楔死邮箱异常帧 触发 0xC0000005 闪退。置于入口使所有调用方全覆盖, 单从站成本 ~100ms。 op_start 的重试分支因此简化为直接重跑序列。 3) config_map 失败时附带邮箱 SM 寄存器现场, 便于对照 GD32 串口日志。 地址按 SM = 0x0800 + 8n 修正为 SM0=0x0800 / SM1=0x0808; 原写的 0x0810/0x0818 实为 SM2/SM3(过程数据), 抓的现场会误导判断。
ecat — DCU LAN9252 EtherCAT 主站工具集
在 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
目录内容
| 文件 | 说明 |
|---|---|
ecat_tool.py |
一体化命令行主站:adapters / status / flash / eeprom / sdo / send 等子命令 |
ecat_server.py |
网页控制台后端(REST API + 静态文件),默认端口 8090(8080 已被 ESP32 tools 占用) |
ecat.html / ecat.css |
网页控制台前端 |
ecat_scan.py |
最小化 bring-up 扫描:从站身份 + SII dump,--op 追加 PDO 测试 |
ecat_esc_regs.py |
从网络侧直读 LAN9252 ESC 寄存器,绕开 GD32/PDI,用于判断 EEPROM 加载是否真的失败;支持 --reload |
ecat_flash_eeprom.py |
通过网线烧写 gen_eeprom.py 生成的 SII 镜像,逐字回读校验(烧完需断电重启让 ESC 重新加载) |
ecat_sniff.py |
旁路抓包,hexdump SOEM 自己发出的帧,用于对照裸帧格式 |
_repro_hang.py |
复现 op/start 卡住→闪退的最小脚本,带 faulthandler 看门狗 |
启动方式
| 入口 | 效果 |
|---|---|
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 适配器 |
注意
- 前端 CSS/JS 改动后记得 bump
?v=缓存版本,否则浏览器会加载旧代码。 - EEPROM 烧写后必须断电冷启动,ESC 才会重新加载配置。
Languages
C
83.2%
Python
5.1%
HTML
4.2%
JavaScript
3.9%
CSS
3.4%
Other
0.2%