DCU EtherCAT PDO 布局

布局 1.6.21 固件 1.6.24 · 字段级 · 稀疏写
384 B输出 SM2
600 B输入 SM3
96–600 B稀疏写实占
40 BDPRAM 余量
真源 ethercat_can_bridge.h 尺寸 ethercat_pdo_size.h PRAM 写 从站侧(≠ 主站 rx) 魔数 @35=0xA5 电机槽 ≤9 × 56 B 稀疏写 CONFIG=1

布局 1.6.21 · 固件 1.6.24 · 写侧 1.6.22 起稀疏

桥状态 / 快照 段头 / 元数据 电机密排槽 批量发送区 诊断 保留 / 填充
1

输入 PDO · 600 B · 从站 → 主站

稀疏写 96–600 B · 整包 ≈265 µs · 3 电机 ≈116 µs

段总览

SM3 · 0x1880–0x1F67 · 3-buffer · 写侧稀疏

段内字段

每段独占全宽 · 宽度 ∝ 字节数

字段明细

段 / 字段偏移宽 类型内容属性
合计 600 逻辑总长;写侧按 count 稀疏(见下) 96–600 B
2

输出 PDO · 384 B · 主站 → 从站

pramRead(384) · 96 DWORD · ≈169 µs 折算

段总览

SM2 · 0x1400–0x187F · WIN@8 忽略

段内字段

每段独占全宽 · 宽度 ∝ 字节数

字段明细

段 / 字段偏移宽 类型内容属性
合计 384 每拍一次 pramRead(384)(未实测) ≈169 µs
3

电机槽内部 · 56 B × ≤9

PDO 地址 = 40 + i×56 · node_id 升序

密排槽区 @40..543

空节点不占位 · count 决定有效槽数
单槽 56 B 字段

主站解码

count = in[32];                    // 0..9
magic = in[35];                    // 必须 0xA5
for (i = 0; i < count; i++) {
    p      = in + 40 + i*56;
    node   = p[0];  ch = p[1];  online = p[2];
    seq    = le32(p+4);
    status = p+8;                  // 48 B
}

同号多通道取 seq 最新的一条;写侧 seqlock 奇数(写入中)的槽本拍省略、下拍自愈。 节点集合与各 seq/online 未变时整段复用影子区(CPU 差分),PRAM 写侧仍按 count 决定字节数。 1.6.22+ 稀疏写:ESC 中 40+count×56 .. 543 为上次残留, 主站只许按 count 迭代,不得读空洞区。

单槽字段明细

字段槽内偏移宽类型内容
单槽合计56 8 B 头 + 48 B STATUS
4

每拍成本与 SM 预算

从站写 ESC 成本 · 稀疏写 1.6.22+(不是主站 rx)
输入写侧 · 3 电机稀疏
—
从站写 ESC · 按实占字节估(≠ 主站 rx)
输入写侧 · 整包基线
—
从站写 ESC · 600B 整包(≠ 主站 rx)
输出读侧 · 探针命中
12
B 探针 · 无沿时跳过 384B 全量读

1.6.22 稀疏写 ESC · 写侧字节随 count 缩

CONFIG_ECAT_SPARSE_ESC_WRITE=1(默认开)。HW_EscWriteIsr 只写两段:

段A = [0 .. 40+count×56)     // 段1 桥状态 + 段2 头 + 有效密排槽
段B = [544 .. 600)           // 段3 长帧 + 段5 诊断 + 保留
跳过 = [40+count×56 .. 544)  // 空槽区(ESC 中为 SM 缓冲上次残留)

count=0 →  96 B  ≈  42 µs
count=3 → 264 B  ≈ 116 µs
count=8 → 544 B  ≈ 240 µs
count=9 → 整包 600 B(两段相接,回退)

APPL 仍整填 aPdInputData(对齐 SDO 0x6000);省的是 PRAM 搬运时间,不是 RAM 拷贝。 主站必须继续只按 count 迭代——空洞区内容是上次残留,不可读。

实测锚点:从站自报负载

1 ms 档 49.2% → 0.5 ms 档 81.4% → 0.25 ms 档 98.7%,同时 λ 从 6000 帧/s 塌到 317 帧/s —— 饱和发生在从站,不在主站的 Npcap 或钉核上。

上表为 1.6.21 整包基线。1.6.22 稀疏写开启后写侧字节随 count 缩,同工况 load_perm 应显著下降; 验收看 0x2000 sub10(EscWrite 周期)与 load_perm,同工况开关各测一轮。

DPRAM 预算 · out + in ≤ 1024 B

LAN9252 · 过程区 0x1400–0x1FFF · 3-buffer

邮箱 SM0/SM1 各 256 B 固定占 0x1000–0x13FF;SM2/SM3 均为 3-buffer(control 0x64/0x20,bit1=0),实占 (out+in)×3。 要再大只有两条路:邮箱压小(上限约 1280 B,代价 SDO/FoE 变慢)或改 1-buffer(上限 3072 B,代价失去三缓冲并发保护)。

5

段 4 历史覆盖窗口 · 已删除

1.6.15 引入 → 1.6.21 删除

为什么删

1.6.15 曾把批量接收区做成「定长覆盖窗口」:5 个固定格子(每格 44 B = 12 B 头 + 32 B 数据)+ 写游标绕圈。它是「最近 5 帧」而不是队列 —— 第 6 帧盖掉第 1 帧,未取走的计入 OVF。

  • 覆盖窗口反复重发最近几条非 STATUS 帧,属于「历史帧 / 重复帧」,对电机状态视图是噪声;
  • 用户实测病理:接 3 个电机,网页却看到 5 个状态帧 —— 旧段 2 固定 5 槽里空槽 node_id=0 也占位,主站不滤空槽就多报。

本版语义:每一拍只携带「总线上已识别电机的完整一轮状态」。版本/CONFIG 仍走段 1/段 3「最近一帧」快照。对象字典 sub21 恒 0;596..599 保留空洞。