为提升EtherCAT通信性能,实现以下两项优化:
1. 对EscLan9252::csrRead方法增加verify参数,支持分级验证:
- verify=true(默认):保持原有的双读比对+重试机制,用于SM/AL/邮箱等
关键路径防止EXMC毛刺
- verify=false:单读模式,用于诊断回读/MII busy轮询/init轮询等低风
险场景,节省一半CSR间接访问时间
2. 实现PDO输入差分写ESC功能:
- 将输入PDO分为三区:段1桥状态(0-31)、段2电机密排(32-543)、段3+5
快照诊断(544-599)
- 采用3-buffer冲刷协议:变化后连续写3拍确保3个缓冲区全部更新
- 对内容稳定的段跳过写操作,显著减少PRAM字节搬运时间
- 全段跳过时强制写末2字节完成SM事件应答
同时更新配置版本至1.6.25,添加相关配置选项和文档说明。
151 lines
8.5 KiB
Markdown
151 lines
8.5 KiB
Markdown
---
|
||
feature: lan9252-perf-audit
|
||
status: delivered
|
||
updated: 2026-02-14
|
||
branch: master
|
||
commits: <no-commit — analysis-only on dirty master WIP>
|
||
---
|
||
|
||
# LAN9252 使用效率审计
|
||
|
||
## Report
|
||
|
||
**What was built** — LAN9252 使用效率审计 + 后续 P1/P2 实现。结论:**DPRAM 用得满但是设计上的满,不算差;真正的速度瓶颈是 PRAM 字节搬运(约 0.44µs/B)**。1.6.25 落地:(1) 输入 PDO 三区差分写 ESC(段1 桥状态 / 段2 电机密排 / 段3+5 快照诊断,变化后 3-buffer 冲刷 3 拍才允许跳过);(2) csrRead 增加 verify 参数,SM/AL/邮箱保持双读,诊断/MII busy/init 轮询单读。
|
||
|
||
**Verification** — 本报告为静态代码审计,对照仓库内 DWT 实测注释与布局常量交叉验证;未在本回合重跑上机测量(DIFF-STATS 当前 `CONFIG_ECAT_DIFF_STATS=0`,写侧基线须置 0 重测才可对拍)。
|
||
|
||
**Journey log**
|
||
1. 先验怀疑「内存差」不成立:3-buffer 硬上限把 out+in 钉在 ≤1024B,当前 984B 已是极限附近。
|
||
2. 1.6.0 PRAM 批量弹 DWORD 因短读损坏回退——任何再加速不能走回未弄清语义的批量模式。
|
||
3. 工作区 master 上有未提交的 1.6.22–1.6.24(稀疏写 + pmDrive),审计不改动这些 WIP。
|
||
4. 1.6.25 已实现 P1 差分写(三区 + 3-buffer 冲刷)与 P2 csrRead verify 分级;上机对拍 sub10 待做。
|
||
|
||
---
|
||
|
||
## [S1] Problem
|
||
|
||
用户问题:
|
||
1. LAN9252 使用是否有提升效率/速度的优化空间?
|
||
2. 现在是不是内存空间使用比较差?
|
||
|
||
需要基于当前代码(含未提交 1.6.22 稀疏写)给出可执行的结论与优先级,而不是泛泛「还能优化」。
|
||
|
||
## [S2] Design / 分析结论
|
||
|
||
### S2.1 内存:不是“差”,是 3-buffer 硬上限下的近满设计
|
||
|
||
**ESC 片内 DPRAM 4KB 布局(LAN9252)**
|
||
|
||
| 区域 | 范围 | 占用 |
|
||
|------|------|------|
|
||
| 邮箱 SM0/SM1 | 0x1000–0x13FF | 2×256B 固定 |
|
||
| 过程数据 SM2(out)+SM3(in) | 0x1400–0x1FFF | 3072B 可用 |
|
||
| 3-buffer 实占 | (384+600)×3 = **2952B** | 余 **120B** |
|
||
|
||
推导见 `comm/ethercat_pdo_size.h`:`(out+in)×3 ≤ 3072` ⇒ **out+in ≤ 1024B 是硬上限**。当前 384+600=984B,已用到 96%。
|
||
|
||
若将来还要更大,只有两条路,都有代价:
|
||
- 邮箱压到 `MIN_MBX_SIZE(0x22)` → 上限约 1280B,拖慢 SDO/FoE
|
||
- 改 1-buffer → 上限 3072B,失去三缓冲并发保护
|
||
|
||
**结论:DPRAM 满是约束结果,不是浪费。段 2 密排(1.6.21)已经把空节点从有效载荷里挤掉。**
|
||
|
||
**MCU 侧 RAM**
|
||
|
||
- `aPdInputData` + `aPdOutputData` = 1024B(SSC 对象存储)
|
||
- `EthercatPdo::s_out/s_in/s_build` = 3×384~600B 级
|
||
- 段 2 影子 `s_motShadow` ≈ 512B 量级
|
||
- DIFF-STATS 自持 600B 快照(仅开启时)
|
||
|
||
相对 GD32E508 的 128KB SRAM 可忽略。**MCU 内存不是瓶颈。**
|
||
|
||
### S2.2 速度:热成本在 PRAM 搬运,不在“存不下”
|
||
|
||
**已实测的通道速率(仓库内 DWT 注释,0x2000 sub9/sub10)**
|
||
|
||
| 场景 | 耗时 | 占 1ms 周期 |
|
||
|------|------|-------------|
|
||
| 输入 640B 整包写(历史) | 296µs | 29.7% |
|
||
| 输入 496B 整包写(1.6.1) | 218.7µs | 21.9% |
|
||
| 输入 600B 整包写(1.6.15) | ≈265µs(600×0.441) | 26.5% |
|
||
| 满载 1024B PRAM(历史估算) | ≈218µs(更早时序) | — |
|
||
| 输出 384B 全量读(被探针跳过) | ≈190µs | 已优化 |
|
||
|
||
通道近似线性:**≈0.44–0.463 µs/B**。写多少、读多少,时间就按字节缩放。
|
||
|
||
**已落地的减法(正确方向)**
|
||
|
||
1. **输出按需读**(1.6.0,`ecatappl.c`):每拍先读 12B 头探针;seq 无变化则跳过 384B 全量读,只补读末字应答。
|
||
2. **段 2 差分填充**(1.6.21,`ethercat_can_bridge.cpp::fillMotorRound`):节点集合与各 seq 未变时整段复用影子,跳过 MotorState 重读与逐槽拷贝——省的是 MCU 侧填充,不直接省 PRAM 字节。
|
||
3. **稀疏写 ESC**(1.6.22,工作区未提交):`CONFIG_ECAT_SPARSE_ESC_WRITE=1` 时,密排 count 有效则只写「段1+段2有效区」与「段3+段5」,跳过空槽区。count=3 时约省 (9−3)×56 ≈ 336B PRAM 写 ≈ 150µs/拍。magic 不对/count 撑满自动回退整包。
|
||
4. **输入 PDO 瘦身**(1.6.1,历史):640→496 已证明“减字节=减时间”;1.6.15 为批量窗扩回 600 是容量权衡,不是速度回退。
|
||
|
||
**未做 / 被否决的加速**
|
||
|
||
| 尝试 | 结果 | 依据 |
|
||
|------|------|------|
|
||
| PRAM 批量弹 DWORD(用 AVAIL_CNT) | **已回退**(1.6.2) | 短读首 DWORD 新鲜、后续取陈旧项;窗口冻结 |
|
||
| EXMC 慢档时序试速 | 无效 | 当年失败根因是访问模型错误,与时序无关 |
|
||
| 压缩总线时序 | **不建议** | BUSLAT 1→4 是为温漂可靠(+3HCLK≈16.7ns/访问) |
|
||
|
||
### S2.3 仍有空间的优化点(按 ROI 排序)
|
||
|
||
#### P1 — 输入 PDO 真正的差分写 ESC
|
||
|
||
- **现状**:填充侧有段 2 影子;**写侧**仍是整包 600B 或稀疏两段,段 1/3/5 每拍全写。
|
||
- **前提**:开 `CONFIG_ECAT_DIFF_STATS=1` 采 0x2000 sub13..23(changedMax / runsMax / 各段变化字节),拿分布再定 A1(语义分区条件写)或 A2(块粒度差分,N 由 runsMax 定)。
|
||
- **预期**:若稳定工况下每拍变化字节数远小于 600,写侧可再省数十至上百 µs。
|
||
- **风险**:run 碎片会把一次大写退化成多次带 AVAIL 轮询的小写;必须设碎片上限,超限回退整段/整包。
|
||
- **验收**:`CONFIG_ECAT_DIFF_STATS=0` 对拍 sub10 与 load_perm;布局/SII/主站解码不变。
|
||
|
||
#### P2 — csrRead 双读校验分级
|
||
|
||
- **现状**:`EscLan9252::csrRead` 对每次事务读两遍 CSR_DATA 并比较(1.5.59),不一致整事务重跑一次。对 EXMC 毛刺防护有效,但 **CSR 路径访问次数近似翻倍**。
|
||
- **热路径调用方**:AL Event(每拍 1–2 次)、邮箱长度/SM 状态、看门狗状态、LED、诊断。
|
||
- **可行做法**:提供 `csrReadOnce`(或按寄存器关键级别开关);**几何/状态关键寄存器(SM、AL、邮箱)保持双读**;LED/诊断/低频路径可单读。
|
||
- **风险**:去掉防护的路径可能偶发读错;须限定白名单,不可一刀切。
|
||
- **预期**:CSR 间接访问(多步 HBI)减少约一半;相对 600B PRAM 写占比更小,属次优先。
|
||
|
||
#### P3 — 稀疏写收益标定(已实现,待验收)
|
||
|
||
- 工作区已实现 `sparseEscWritePlan` + `CONFIG_ECAT_SPARSE_ESC_WRITE=1`。
|
||
- **验收动作**:同工况开关 0/1 各测一轮 sub10;count 越小收益越大。
|
||
- 空洞区为 SM 缓冲上次残留,主站必须只按 count 迭代(1.6.21 已如此)。
|
||
|
||
#### 不建议再碰
|
||
|
||
- **EXMC 时序收紧**:BUSLAT=4 / DSET=20 为全温区可靠性的已知代价;已有“慢档无效、访问模型才是当年根因”的记录。除非板级时序重测给出明确裕量,否则不动。
|
||
- **恢复 PRAM 批量弹 DWORD**:短读语义未弄清前禁止。
|
||
- **改 1-buffer 扩 DPRAM**:失去三缓冲,并发读写会拿到半新半旧过程数据。
|
||
|
||
### S2.4 访问模型备忘(审计时反复踩过的坑)
|
||
|
||
```
|
||
主站帧
|
||
→ LAN9252 DPRAM (4KB)
|
||
邮箱 0x1000+ / PDO 0x1400+
|
||
← PDI (HBI Indexed)
|
||
HBI_IDX_0 / HBI_DATA_0 ← 仅系统 CSR + 访问端口
|
||
ECAT_CSR_CMD/DATA 0x304/0x300 ← 核心 CSR 0x0000–0x0FFF
|
||
PRAM FIFO 0x000–0x03C + 0x308–0x314 ← 过程 RAM 0x1000–0x1FFF
|
||
→ EXMC NE0 @ 0x60000000, 16-bit
|
||
```
|
||
|
||
核心 CSR **不能**直读 HBI 索引(1.5.37 之前全 0 的根因)。过程数据 **必须**走 PRAM FIFO。
|
||
|
||
## [S3] Out of Scope
|
||
|
||
- 不重生成 SII、不烧录、不改主站解码。
|
||
- 不审计主站侧解码或 CAN 桥竞态(另见 1.6.9–1.6.21 修复记录)。
|
||
- 不重新设计 PDO 布局或 EEPROM。
|
||
- 上机 A/B 对拍(T3/T6)待现场执行。
|
||
|
||
## Tasks
|
||
|
||
- [x] T1: 审计 DPRAM/MCU 内存占用与 PRAM 热路径 — acceptance: 本报告 S2.1/S2.2 有依据与数字 (covers: S2)
|
||
- [x] T2: 给出优化优先级与不做清单 — acceptance: S2.3 含 ROI/风险/验收 (covers: S2)
|
||
- [x] T4: (1.6.25)实现输入 PDO 差分写 — acceptance: 三区影子+3-buffer 冲刷;全跳过写末 2 字节;SII 不变;CONFIG_ECAT_DIFF_ESC_WRITE 门控 (covers: S2.3)
|
||
- [x] T5: (1.6.25)csrRead 分级单读 — acceptance: verify 参数;SM/AL 默认双读;MII busy/init/诊断回读单读 (covers: S2.3)
|
||
- [ ] T3: (后续)开 DIFF-STATS + 上机对拍 sub10 — acceptance: 记录写侧耗时 A/B(差分开/关)(covers: S2.3)
|
||
- [ ] T6: (遗留)验收工作区稀疏写 A/B — acceptance: CONFIG_ECAT_SPARSE_ESC_WRITE 0/1 同工况 sub10 对比入档 (covers: S2.3)
|