big-bang 迁移(硬约束: Npcap 网卡独占, 无法双主站并存), 四阶段真机验收的 完整契约与对拍记录见 MIGRATION.md —— Python 已删, 该文件是唯一行为基准。 - 新增 ecat_native.c: 与 Python 同构的全路由 native 守护 —— 总线生命周期 open/close/status/op.start/op.stop, 电机 motor.start/stop/spin/state/ send/rx/period/dbg, can/send|state, 配置维护 sdo/eeprom.read|write| verify/flash/sync_diag, 静态托管 src/web, shutdown/focus/--parent-pid 看门狗/独立启动清场/端口漂移; 独占 8090 即生产链路。PDO 热循环天花板 ~5kHz → ~7kHz。 - 删除 src/ecat_server.py(2826 行)、src/test_motor_backend.py(684 行)、 ecat_app.vbs(桌面窗口随 pywebview 依赖一并移除): Python 后端不留副本。 - 编码回归改金标准: native_enc_diff.py 对照 native_enc_golden.json (阶段 2 与 Python _fill_can_out 逐字节对拍通过后固化, 不碰网卡), 当场抓掉 json_tok 不跳闭合引号会静默丢 motor/send 参数的真 bug。 - build_native.bat: 编译前跑 gen_eeprom.py 生成 eeprom_image.h 供 native #include —— 同一生成器同一套断言, 断言失败构建中止; 改 SII 重跑即可。 - 修 flash 探针字历史隐患(本文件与 ecat_native.c 同步改): SCRATCH_WORD 0x0200 实际落在 TxPDO 类别区内部(类别区已长到 0x0281), 单独跑 eeprom 探针不烧录会把真数据擦成空洞; 移到 SII END 之后的 0x0400。 - 启动器 ecat_web.vbs/bat 改拉 build_native\ecat_native.exe (--substr I226 --web src\web)。 - 收录 soem-src wpcap 链接库(vendored, 构建必需)。 两轮回归修复(细节见 MIGRATION.md): 1) op/start 卡 AL 0x001B(SM 看门狗): 固件"自己写 1s 看门狗"的假设破产, do_op_start 第 5 步改为 ~5ms 节奏喂帧 ≥1s 再请求 OP, 24s 两次失败 变 1.2s 进 OP。 2) OP 态数据冻结(从站 PDI_Isr SM2 分支被旗标挡住, 固件侧根因): 主站加 楔死看门狗(输出窗口轮转 + 回显冻结 128 周期判死)与 /api/motor/state 自动恢复(10s 冷却, 快照新增 wr 字段)。 已知差异: SDO 失败文本无 pysoem abort code 粒度; 250µs 亚毫秒周期从站 吃不下, 修复前勿用。build_native/ 构建产物入 .gitignore, 由脚本重建。
91 lines
5.8 KiB
Markdown
91 lines
5.8 KiB
Markdown
# dcu-ecat-master
|
||
|
||
**DCU LAN9252 EtherCAT 主站工具集**(工作目录 `DCU/tools/ecat`)
|
||
|
||
**生产后端是原生 C/SOEM 守护进程** `build_native/ecat_native.exe`(`ecat_native.c` +
|
||
`build_native.bat` 编译,见 `MIGRATION.md` 的迁移记录):同一套 REST 契约、同一批
|
||
前端页面,PDO 热循环天花板从 Python 的 ~5kHz 提到 ~7kHz。Python 版后端已彻底删除
|
||
(2026-09-04,含备份);编码面回归改打金标准
|
||
`native_enc_golden.json`(`native_enc_diff.py`)。命令行工具 `ecat_tool.py`
|
||
仍是 Python + pysoem(低频诊断用,不与时序敏感的热循环抢网卡)。
|
||
|
||
在 Windows 上直接从网卡驱动 DCU 的 LAN9252 EtherCAT 从站:
|
||
扫描总线、读写 SII EEPROM、CoE SDO 读写、PDO 循环收发,以及一个本地网页/桌面控制台。
|
||
|
||
## 环境准备
|
||
|
||
- Python 3.12(venv 不入库;命令行工具与 legacy 后端用)
|
||
- [Npcap](https://npcap.com/):收发裸 EtherCAT 帧的前提(native 与 pysoem 共用)
|
||
- VS2022(Community 即可):编译 `build_native.bat` 产出原生守护进程
|
||
- 一块直连从站的物理网卡(示例中为 Intel I226)
|
||
|
||
```bat
|
||
py -3.12 -m venv venv
|
||
venv\Scripts\python.exe -m pip install -r requirements.txt
|
||
```
|
||
|
||
## 目录结构
|
||
|
||
入口在最外层,双击即用;代码全部收进 `src/`。
|
||
|
||
```
|
||
ecat/
|
||
├─ ecat_web.vbs ← 浏览器标签(启动 native 守护进程, 隐藏控制台)
|
||
├─ ecat_web.bat ← 控制台模式(看日志)
|
||
├─ ecat.bat ← 命令行工具
|
||
├─ run_scan.bat ← bring-up 扫描
|
||
├─ ecat_native.c ← 原生守护进程(生产后端, 全路由)
|
||
├─ build_native.bat ← 编译 native(先跑 gen_eeprom.py 生成 SII 默认镜像头)
|
||
├─ soem-src/ ← vendored SOEM(从 pysoem sdist 解出, 有一处补丁)
|
||
├─ MIGRATION.md ← Python→native 迁移记录(契约/验收/已知差异)
|
||
├─ native_enc_diff.py ← 编码回归: native enctest vs 金标准(不碰网卡)
|
||
├─ native_enc_golden.json ← 金标准(阶段 2 与 Python 逐字节对拍通过后固化)
|
||
├─ README.md / requirements.txt
|
||
├─ build_native/ ← ecat_native.exe + eeprom_image.h 等构建产物
|
||
├─ src/
|
||
│ ├─ ecat_tool.py 一体化命令行主站
|
||
│ ├─ ecat_flash_eeprom.py 经网线烧写 SII 镜像(被 ecat_tool flash 复用)
|
||
│ ├─ web/ 前端资源(URL 路径不变, 仍是 / 与 /motor.html; native 也托管这里)
|
||
│ └─ diag/ 独立诊断脚本(互不依赖, 直接单跑)
|
||
└─ venv/ 本地虚拟环境(不入库; CLI 与构建期 gen_eeprom 用)
|
||
```
|
||
|
||
| 文件 | 说明 |
|
||
|------|------|
|
||
| `src/ecat_tool.py` | 一体化命令行主站:`adapters` / `status` / `flash` / `eeprom` / `sdo` / `send` 等子命令 |
|
||
| `ecat_native.c` + `build_native.bat` | **生产后端**:原生 C/SOEM 守护进程(全路由 + 生命周期契约),默认端口 **8090**(8080 已被 ESP32 tools 占用)。迁移记录见 `MIGRATION.md` |
|
||
| `src/ecat_flash_eeprom.py` | 通过网线烧写 `gen_eeprom.py` 生成的 SII 镜像,逐字回读校验(烧完需断电重启让 ESC 重新加载)。被 `ecat_tool.py flash` 复用 |
|
||
| `native_enc_diff.py` + `native_enc_golden.json` | 编码回归:native `enctest` 路由输出 vs 金标准(阶段 2 与 Python `_fill_can_out` 逐字节对拍通过后固化)。改 `fill_can_out`/`pack_tx_batch` 后必跑 |
|
||
| ~~`legacy_py/`~~ | Python 后端已彻底删除(2026-09-04 切换收官,含备份 zip)。行为基准只存在于 `MIGRATION.md` 的逐字段对拍记录里;`ecat_app.vbs` 桌面窗口模式随之退役 |
|
||
| `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_web.vbs` | 后台起 native 守护进程并打开浏览器标签,无控制台窗口 |
|
||
| `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 才会重新加载配置。
|