feat(comm): 1.6.14~1.6.20 —— CAN-FD 数据段 5M、批量区改定长覆盖窗口(输入 PDO 496→600)、drop 口径修复、差分写仪表
1.6.14 CAN-FD 数据段 2Mbps→5Mbps:CONFIG_CAN_DATA_PRESCALER 9→3、BS1 3→4TQ (90MHz/(3×6TQ),采样点 80%→83.3%),仲裁段仍 1M。TDC filter/offset 维持 4 不做 等比缩放(TDCMOD=CALC_AND_OFFSET 下硬件已自动测回路延时;放到 12 会让本节点回采 错开约 6 个数据位,自发热帧被判错误帧)。配套电机 APP/BOOT data_prescaler=2。 1.6.15 段4 批量接收由"环形队列 + 变长紧排排空"改为 5×44B 定长覆盖窗口,输入 PDO 496→600(75×64bit),段5 诊断区 484→584。动机两条:现场 4000 帧/s 超旧容量 3 帧/拍 恒丢 1 帧;更关键是排空赤字把队列长期压在饱和态,而 1.6.9~1.6.13 追的错标/拼接竞态 正是饱和态喂出来的(判满用的 tail 滞后→生产者写进消费者刚读过的槽)。定长消灭 tail/判满/pending,边界越界写在结构上不可能再犯。每槽带 u32 seqlock:buildInput 在 PDI_Isr(preempt=0) 抢占主循环写侧,无它则主站会拿到"新 ID + 旧数据"拼出的假帧。 out+in=984 ≤ 1024 硬上限,DPRAM 留 120B。语义变更:批量区从"不丢的事件流"变"最近 N 帧窗口",去重与丢帧判据移交主站按 seq 归一。三端同步 size.h/bridge/dc_app/ gen_eeprom/DCU_ESI.xml,必须重烧固件 + 烧 EEPROM + 断电冷启动,只烧一边 SAFEOP 报 AL 0x001A/0x0011。 1.6.16 段1/段3 快照 drop 计数口径修复(纯判据,PDO 布局逐字节不动):旧判据 s_rxValid 置位后永不清零 ⇒ 开机首帧后每帧都算丢弃,drop ≡ rx−1,是零灵敏度假仪表 且把网页状态栏刷成 ERR。新增 s_rxPublished,判据改 s_rxValid && !s_rxPublished。 1.6.17~19 [DIFF-STATS] 差分写取证仪表,零行为变更,只加 0x2000 sub13..23(11 个只读 UINT32) ⇒ 不动 PDO 长度/映射,无需重生成 SII。实测:每拍 27.4% 字节真变化(164B)、 run 峰值 12~13、段2 占变化量 ~53%、段4 ~25%。 1.6.19 推翻 1.6.18 的自我诊断:比对开销虚报不是 -Oz 把 memcpy 编成调用(手拼移位 反而 21.3µs→41µs),真根因是 alignas(4) 到 const uint8_t* 形参处丢失,优化器无法 证明 4 字节对齐。__builtin_assume_aligned + memcpy 后循环体缩成 ldr/ldr/cmp/bne、 bl 归零。教训:测量工具自身的开销会直接变成结论。 1.6.20 基线对照版(当前提交状态 CONFIG_ECAT_DIFF_STATS=0):同工况(电机在线无指令) 实测 load 49.1% vs 仪表开的 51.6% ⇒ 仪表自身成本 2.4 个点,差分改造收益 = 0。 按实测变化量推算 A1(段粒度条件写) 只值约 1 点(段2/段4 每拍都变,必然整块重写), 仅 A2(8B 块粒度 + run 上限退化为整写) 有空间 —— 推算值,未做 A/B 实测不作为结论。
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
<!-- SM2: Process Data Output (RxPDO, Master -> Slave) -->
|
||||
<Sm DefaultSize="384" StartAddress="#x1400" ControlByte="#x64" Enable="1">Outputs</Sm>
|
||||
<!-- SM3: Process Data Input (TxPDO, Slave -> Master) -->
|
||||
<Sm DefaultSize="496" StartAddress="#x1880" ControlByte="#x20" Enable="1">Inputs</Sm>
|
||||
<Sm DefaultSize="600" StartAddress="#x1880" ControlByte="#x20" Enable="1">Inputs</Sm>
|
||||
<!-- RxPDO (Output, Master -> Slave): 索引 0x1600-0x17FF,映射 0x7000:01..48
|
||||
1.5.56 扩到 48 条目(384B):兼容单帧区 48B + CANFD 批量发送区 336B。
|
||||
与 dc_app.c 的 PDO_OUT_ENTRIES / gen_eeprom.py 的 PD_OUT_SIZE 必须一致,
|
||||
@@ -370,12 +370,13 @@
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<!-- TxPDO (Input, Slave -> Master): 索引 0x1A00-0x1BFF,映射 0x6000:01..80
|
||||
<!-- TxPDO (Input, Slave -> Master): 索引 0x1A00-0x1BFF,映射 0x6000:01..75
|
||||
1.5.56 扩到 80 条目(640B):电机状态窗口 + CANFD 批量接收区 280B。
|
||||
SM3 起址随之挪到 #x1880 —— SM2 是 3-buffer 模式,384B×3 占到 #x187F。
|
||||
(384+640)×3 = 3072 = 过程数据区 0x1400-0x1FFF 全长,恰好用满。
|
||||
1.6.1 输入瘦身 640→496: 批量接收条目数据 64→32B(截断见 bridge.h),
|
||||
条目 80→62, SM3 实占 3×496=1488B (0x1880-0x1E4F), DPRAM 留 432B。
|
||||
1.6.1 输入瘦身 640→496: 批量接收条目数据 64→32B, 条目 80→62。
|
||||
1.6.15 496→600: 批量接收改定长覆盖窗口 5 槽(每槽 12B 头含 u32 seqlock
|
||||
+ 32B 数据), 条目 62→75, SM3 实占 3×600=1800B (0x1880-0x1F67),
|
||||
out+in=984 <= 1024 硬上限。推导见 comm/ethercat_pdo_size.h。
|
||||
撞址会被 SSC ecatslv.c 重叠检查拦下,报 INVALIDSMOUTCFG。 -->
|
||||
<TxPdo Fixed="1" Mandatory="1" Sm="3">
|
||||
<Index>#x1A00</Index>
|
||||
@@ -814,24 +815,97 @@
|
||||
<Name>Status Data 62</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>63</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 63</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>64</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 64</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>65</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 65</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>66</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 66</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>67</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 67</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>68</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 68</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>69</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 69</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>70</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 70</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>71</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 71</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>72</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 72</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>73</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 73</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>74</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 74</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>75</SubIndex>
|
||||
<BitLen>64</BitLen>
|
||||
<Name>Status Data 75</Name>
|
||||
<DataType>ULINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE SdoInfo="true" CompleteAccess="true" SegmentedSdo="true"/>
|
||||
|
||||
@@ -42,13 +42,15 @@
|
||||
* 1.5.56 扩到 DPRAM 硬上限:输出 48×64bit=384B,输入 80×64bit=640B(非对称)。
|
||||
* 1.6.1 输入瘦身 640→496(62×64bit):批量接收条目数据 64→32B + 诊断区前移,
|
||||
* 依据与推导见 comm/ethercat_pdo_size.h 的 1.6.1 注。
|
||||
* 1.6.15 输入 496→600(75×64bit):批量接收改定长覆盖窗口 5 槽(每槽带 u32
|
||||
* seqlock,槽长 44B),诊断区随之后移到 584。推导见该头文件的 1.6.15 注。
|
||||
* 长度的唯一真源是 comm/ethercat_pdo_size.h;本文件用 _Static_assert 与之绑定,
|
||||
* 改一处漏一处会编译失败。为何硬上限是 out+in≤1024B 见该头文件的推导。
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
/** 输出/输入 PDO 的 64bit 条目数。 */
|
||||
#define PDO_OUT_ENTRIES 48u /* 48×8 = 384 B */
|
||||
#define PDO_IN_ENTRIES 62u /* 62×8 = 496 B (1.6.1 瘦身,原 80×8=640) */
|
||||
#define PDO_IN_ENTRIES 75u /* 75×8 = 600 B (1.6.15 覆盖窗口,原 62×8=496) */
|
||||
|
||||
/** 输出数据对象 0x7000 (主站→从站, RxPDO) */
|
||||
typedef struct OBJ_STRUCT_PACKED_START {
|
||||
@@ -73,7 +75,7 @@ static TOBJ6000 s_inputObj = {PDO_IN_ENTRIES, {0}};
|
||||
_Static_assert(offsetof(TOBJ7000, u64Data) == 2, "TOBJ7000 未紧排:检查 OBJ_STRUCT_PACKED_START");
|
||||
_Static_assert(offsetof(TOBJ6000, u64Data) == 2, "TOBJ6000 未紧排:检查 OBJ_STRUCT_PACKED_START");
|
||||
_Static_assert(sizeof(TOBJ7000) == 2 + 8 * PDO_OUT_ENTRIES, "TOBJ7000 尺寸应为 2+384");
|
||||
_Static_assert(sizeof(TOBJ6000) == 2 + 8 * PDO_IN_ENTRIES, "TOBJ6000 尺寸应为 2+496");
|
||||
_Static_assert(sizeof(TOBJ6000) == 2 + 8 * PDO_IN_ENTRIES, "TOBJ6000 尺寸应为 2+600");
|
||||
|
||||
/* 与 C++ 侧桥接层的长度约定绑定:任一处改了尺寸而忘了另一处,这里直接编译失败,
|
||||
* 而不是等到运行期 SAFEOP 报 AL 0x001A/0x0011 再回头查。 */
|
||||
@@ -105,10 +107,25 @@ typedef struct OBJ_STRUCT_PACKED_START {
|
||||
UINT32 u32InWriteCyc; /* sub10: 其中 HW_EscWriteIsr 输入PDO 过程数据写 */
|
||||
UINT32 u32AlCyc; /* sub11: PDI_Isr 内 AL 事件读×2+超限应答 */
|
||||
UINT32 u32AppCyc; /* sub12: ECAT_Application(桥 processOutput) */
|
||||
/* [DIFF-STATS] 差分写取证仪表(sub13..23):上一个完整 1s 窗口的值,
|
||||
* 取自 comm/ethercat_diff_stats.cpp。CONFIG_ECAT_DIFF_STATS 置 0 时恒 0,
|
||||
* 字段保留(不影响任何既有子索引,也不动 PDO/映射,故无需重刷 SII)。 */
|
||||
UINT32 u32DsWinSeq; /* sub13: 已完成窗口数,0=还没有完整窗口(勿把 0 当"无变化") */
|
||||
UINT32 u32DsCycles; /* sub14: 窗口内参与比对的拍数 */
|
||||
UINT32 u32DsChangedMax; /* sub15: 单拍变化字节峰值(差分写的理论上限=600×拍数) */
|
||||
UINT32 u32DsRunsTotal; /* sub16: 窗口内 run(连续变化段)总数,配 sub14 求均值 */
|
||||
UINT32 u32DsRunsMax; /* sub17: 单拍 run 数峰值 —— 块粒度差分的碎片上限由它定 */
|
||||
UINT32 u32DsSeg1; /* sub18: 段1(0..31) 桥状态+短快照 变化字节合计 */
|
||||
UINT32 u32DsSeg2; /* sub19: 段2(32..319) 电机状态窗口 */
|
||||
UINT32 u32DsSeg3; /* sub20: 段3(320..359) 长帧快照 */
|
||||
UINT32 u32DsSeg4; /* sub21: 段4(360..583) 批量覆盖窗 */
|
||||
UINT32 u32DsSeg5; /* sub22: 段5(584..599) 诊断区+保留 */
|
||||
UINT32 u32DsCompareCyc; /* sub23: 比对自身累计 DWT 周期(u32 粒度,不含快照拷贝) */
|
||||
} OBJ_STRUCT_PACKED_END
|
||||
TOBJ2000;
|
||||
|
||||
static TOBJ2000 s_syncDiag = {12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static TOBJ2000 s_syncDiag = {23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* 同上:UINT32 首条目必须落在字节 2(未紧排时为 4)。 */
|
||||
_Static_assert(offsetof(TOBJ2000, u32Sync0) == 2, "TOBJ2000 未紧排:检查 OBJ_STRUCT_PACKED_START");
|
||||
@@ -129,6 +146,9 @@ extern volatile UINT32 g_dbg_inWriteCyc;
|
||||
extern volatile UINT32 g_dbg_alCyc;
|
||||
extern volatile UINT32 g_dbg_appCyc;
|
||||
|
||||
/* [DIFF-STATS] 差分写统计窗口值(comm/ethercat_diff_stats.cpp),out[0..10] 对应 sub13..23 */
|
||||
void EcatDiffStats_GetWindow(UINT32 *out);
|
||||
|
||||
/* 过程数据收发模块 (comm/ethercat_pdo.cpp 的 extern "C" shim, 1.5.54)。
|
||||
* 1.5.53 时这里直接调 EcatCan_* 转发桥;1.5.54 把"一个 EtherCAT 周期怎么收发"
|
||||
* 收拢进 EthercatPdo 类,本文件退回纯 SSC 移植层:只留对象字典 + 三行转发。 */
|
||||
@@ -182,13 +202,12 @@ static TOBJ_RXPDO_MAPPING sRxPDOMap = {PDO_OUT_ENTRIES, {
|
||||
PDO_MAP_8(0x7000, 24), PDO_MAP_8(0x7000, 32), PDO_MAP_8(0x7000, 40)
|
||||
}};
|
||||
|
||||
/* 0x1A00: 映射 0x6000:01..62, 每个 64 bits(1.6.1 瘦身 80→62:7×8 + 6) */
|
||||
/* 0x1A00: 映射 0x6000:01..75, 每个 64 bits(1.6.15 覆盖窗口 62→75:9×8 + 3) */
|
||||
static TOBJ_TXPDO_MAPPING sTxPDOMap = {PDO_IN_ENTRIES, {
|
||||
PDO_MAP_8(0x6000, 0), PDO_MAP_8(0x6000, 8), PDO_MAP_8(0x6000, 16),
|
||||
PDO_MAP_8(0x6000, 24), PDO_MAP_8(0x6000, 32), PDO_MAP_8(0x6000, 40),
|
||||
PDO_MAP_8(0x6000, 48),
|
||||
PDO_MAP_ENTRY(0x6000, 57), PDO_MAP_ENTRY(0x6000, 58), PDO_MAP_ENTRY(0x6000, 59),
|
||||
PDO_MAP_ENTRY(0x6000, 60), PDO_MAP_ENTRY(0x6000, 61), PDO_MAP_ENTRY(0x6000, 62)
|
||||
PDO_MAP_8(0x6000, 48), PDO_MAP_8(0x6000, 56), PDO_MAP_8(0x6000, 64),
|
||||
PDO_MAP_ENTRY(0x6000, 73), PDO_MAP_ENTRY(0x6000, 74), PDO_MAP_ENTRY(0x6000, 75)
|
||||
}};
|
||||
|
||||
_Static_assert(sizeof(sRxPDOMap.aEntries) / 4 == PDO_OUT_ENTRIES, "0x1600 条目数不符");
|
||||
@@ -237,22 +256,36 @@ OBJCONST TSDOINFOENTRYDESC OBJMEM asInputEntryDesc[] = {
|
||||
{DEFTYPE_UNSIGNED64, 0x40, ACCESS_READ | OBJACCESS_TXPDOMAPPING}
|
||||
};
|
||||
|
||||
/* SYNC 诊断 0x2000: REC, Sub0..Sub12 共 13 项, 纯只读不参与 PDO 映射。
|
||||
* sub5..12 为 1.6.0 剖分埋点(DWT 周期/计数累加), 定位负载构成后移除。 */
|
||||
/* SYNC 诊断 0x2000: REC, sub0..sub23 共 24 项, 纯只读不参与 PDO 映射,
|
||||
* 改子索引数无需重刷 SII/EEPROM。sub5..12 为 1.6.0 剖分埋点(DWT 周期/计数
|
||||
* 累加,定位负载构成后移除);sub13..23 为 [DIFF-STATS] 差分写取证仪表。
|
||||
* 行数必须与 TOBJ2000 字段一一对应:少一行不会编译报错,只会让 SDO 从错误的
|
||||
* 偏移取值 —— 故逐行标号便于核对。 */
|
||||
OBJCONST TSDOINFOENTRYDESC OBJMEM asSyncDiagEntryDesc[] = {
|
||||
{DEFTYPE_UNSIGNED8, 0x08, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}
|
||||
{DEFTYPE_UNSIGNED8, 0x08, ACCESS_READ}, /* sub0 : 子索引个数 = 23 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub1 : SYNC0 计数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub2 : SYNC1 计数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub3 : ESC IRQ 计数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub4 : uptime 秒 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub5 : PDI_Isr 累计周期 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub6 : PDO_OutputMapping */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub7 : MainLoop free-run 块 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub8 : PDI_Isr 次数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub9 : PDO_InputMapping 全程 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub10 : 其中输入 PDO 过程数据写 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub11 : AL 事件读×2+超限应答 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub12 : ECAT_Application */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub13 : [DIFF-STATS] 已完成窗口数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub14 : [DIFF-STATS] 窗口内拍数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub15 : [DIFF-STATS] 单拍变化字节峰值 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub16 : [DIFF-STATS] run 总数 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub17 : [DIFF-STATS] 单拍 run 峰值 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub18 : [DIFF-STATS] 段1 变化字节 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub19 : [DIFF-STATS] 段2 变化字节 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub20 : [DIFF-STATS] 段3 变化字节 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub21 : [DIFF-STATS] 段4 变化字节 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub22 : [DIFF-STATS] 段5 变化字节 */
|
||||
{DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}, /* sub23 : [DIFF-STATS] 比对自身 DWT 周期 */
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
@@ -297,7 +330,7 @@ TOBJECT OBJMEM ApplicationObjDicList[] = {
|
||||
asInputEntryDesc, aName0x6000, &s_inputObj, NULL, NULL, 0x0000},
|
||||
|
||||
/* 0x2000: SYNC 诊断 (只读, 主站 SDO 轮询验证 DC 通路; sub5..8 为 1.6.0 剖分埋点) */
|
||||
{NULL, NULL, 0x2000, {DEFTYPE_RECORD, 12 | (OBJCODE_REC << 8)},
|
||||
{NULL, NULL, 0x2000, {DEFTYPE_RECORD, 23 | (OBJCODE_REC << 8)},
|
||||
asSyncDiagEntryDesc, aName0x2000, &s_syncDiag, NULL, NULL, 0x0000},
|
||||
|
||||
/* 终止条目 */
|
||||
@@ -311,7 +344,7 @@ TOBJECT OBJMEM * VARMEM ApplicationObjDic = ApplicationObjDicList;
|
||||
*---------------------------------------------------------------------------*/
|
||||
UINT16 APPL_GenerateMapping(UINT16 *pInputSize, UINT16 *pOutputSize)
|
||||
{
|
||||
*pInputSize = ECAT_PDO_IN_BYTES; /* 62×UINT64 = 496 bytes (1.6.1) */
|
||||
*pInputSize = ECAT_PDO_IN_BYTES; /* 75×UINT64 = 600 bytes (1.6.15) */
|
||||
*pOutputSize = ECAT_PDO_OUT_BYTES; /* 48×UINT64 = 384 bytes */
|
||||
return 0;
|
||||
}
|
||||
@@ -381,6 +414,24 @@ void APPL_InputMapping(UINT16 *pInputData)
|
||||
s_syncDiag.u32AlCyc = g_dbg_alCyc;
|
||||
s_syncDiag.u32AppCyc = g_dbg_appCyc;
|
||||
|
||||
/* [DIFF-STATS] 差分写统计快照(sub13..23):一次取全 11 个窗口值,
|
||||
* 取的都是"上一个已完成的 1s 窗口",故 SDO 读不会拿到半累积值。 */
|
||||
{
|
||||
UINT32 ds[11];
|
||||
EcatDiffStats_GetWindow(ds);
|
||||
s_syncDiag.u32DsWinSeq = ds[0];
|
||||
s_syncDiag.u32DsCycles = ds[1];
|
||||
s_syncDiag.u32DsChangedMax = ds[2];
|
||||
s_syncDiag.u32DsRunsTotal = ds[3];
|
||||
s_syncDiag.u32DsRunsMax = ds[4];
|
||||
s_syncDiag.u32DsSeg1 = ds[5];
|
||||
s_syncDiag.u32DsSeg2 = ds[6];
|
||||
s_syncDiag.u32DsSeg3 = ds[7];
|
||||
s_syncDiag.u32DsSeg4 = ds[8];
|
||||
s_syncDiag.u32DsSeg5 = ds[9];
|
||||
s_syncDiag.u32DsCompareCyc = ds[10];
|
||||
}
|
||||
|
||||
/* 1.5.54:先让 EthercatPdo 把本周期的输入数据写进 0x6000 的对象存储,
|
||||
* 再交给 ESC。经由对象存储中转(而非直接写 pInputData)是为了让主站
|
||||
* SDO 读 0x6000 时看到与过程数据一致的内容。 */
|
||||
|
||||
@@ -70,8 +70,10 @@ MBX_TX_SIZE = 256
|
||||
# 邮箱 SM0/SM1 各 256B 固定占 0x1000-0x13FF,过程数据区只剩 0x1400-0x1FFF=3072B。
|
||||
# SM2/SM3 都是 3-buffer 模式(control 0x64 / 0x20,bit1=0),实际占用 3×size:
|
||||
# SM2 384B -> 0x1400-0x187F (384×3 = 1152B)
|
||||
# SM3 640B -> 0x1880-0x1FFF (640×3 = 1920B) ← 恰好用满最后一字节
|
||||
# (384+640)×3 = 3072 = 过程数据区全长,一字节不剩也一字节不越界。
|
||||
# SM3 600B -> 0x1880-0x1F67 (600×3 = 1800B) ← 1.6.15,DPRAM 留 120B 余量
|
||||
# (384+600)×3 = 2952 ≤ 3072 = 过程数据区全长。历史上 1.5.56 曾取 640B
|
||||
# ((384+640)×3 = 3072 恰好用满),1.6.1 瘦身到 496B 换 CPU,1.6.15 回到 600B
|
||||
# 换批量区容量——推导与取舍见 comm/ethercat_pdo_size.h。
|
||||
# SSC 在 ecatslv.c:708-721 按 (start + size*buffer) 做重叠检查,撞了会在
|
||||
# PREOP->SAFEOP 返回 ALSTATUSCODE_INVALIDSMOUTCFG,不是静默出错。
|
||||
# 要再更大只能压邮箱(拖慢 SDO/FoE)或改 1-buffer(失去读写并发保护),见
|
||||
@@ -79,10 +81,15 @@ MBX_TX_SIZE = 256
|
||||
PD_OUT_OFFSET = 0x1400 # SM2: RxPDO (Master -> Slave outputs)
|
||||
PD_OUT_SIZE = 384 # 48×64bit
|
||||
PD_IN_OFFSET = 0x1880 # SM3: TxPDO (Slave -> Master inputs)
|
||||
PD_IN_SIZE = 496 # 62×64bit (1.6.1 瘦身,原 80×64bit=640)
|
||||
PD_IN_SIZE = 600 # 75×64bit (1.6.15 覆盖窗口;1.6.1 曾瘦身到 496=62×64bit,更早 640=80×64bit)
|
||||
# 1.6.1 瘦身 640→496:批量接收条目数据 64→32B + 段5诊断区前移到 484。
|
||||
# SM3 实占 3×496=1488B (0x1880-0x1E4F),DPRAM 留 432B 余量;
|
||||
# 依据见 comm/ethercat_pdo_size.h 的 1.6.1 注。改后必须重烧 EEPROM 并断电冷启动。
|
||||
# 1.6.15 496→600:批量接收改**定长覆盖窗口** 5 槽(每槽 12B 头含 u32 seqlock
|
||||
# + 32B 数据 = 44B,共 220B,落在 364..583),段5诊断区 484→584。
|
||||
# 动机:旧"环形队列+变长紧排"容量 3 帧/拍,现场 4000 帧/s 下每拍恒丢 1 帧,
|
||||
# 且饱和态喂出了 1.6.9~1.6.13 追的错标/拼接竞态。5 槽 = 5000 帧/s@1ms。
|
||||
# SM3 实占 3×600=1800B (0x1880-0x1F67),out+in=984 ≤ 1024 硬上限,留 120B 余量;
|
||||
# 依据见 comm/ethercat_pdo_size.h 的 1.6.1 / 1.6.15 注。
|
||||
# 改后必须重烧 EEPROM 并断电冷启动。
|
||||
|
||||
# 3-buffer 占用与 DPRAM 上限自检:改尺寸/偏移时立刻在生成阶段拦住,
|
||||
# 而不是等烧进 EEPROM、冷启动后再看 AL 错误码。
|
||||
|
||||
Reference in New Issue
Block a user