feat!: 1.6.0 DWT 剖分探针 + 1.6.1 输入 PDO 瘦身 640→496(待重烧验收)
1.6.0 剖分探针(上一轮真机已验证, 随本轮一并入库): - ecatappl.c: 0x2000 sub5..12 DWT 周期累加器(PDI_Isr/输入映射/640B 写细分) - ethercat_pdo.cpp: 输出按需全量读(12B 探针判 seq 沿, 省每周期 ~190µs 全量读) - 段5 诊断区(负载率+seq)随 PDO 上报, 主站 /api/app/load 轮询 1.6.1 输入 PDO 瘦身 640→496(62×64bit; 0..359 与 1.5.61 逐字节兼容): - 依据: DWT 实测 640B 写恒 296µs/拍且与 SYNC0 相位无关(主站 dc_bench 五形态 对拍极差 0.04%), PRAM ≈0.463µs/B 线性; 真机 6086 帧 DLC 仅 24/32 - 批量接收条目 8B 头+64B 数据 → 8B+32B(DLC 真值保留, 截断打 flags bit1, 环形队列仍存全量 64B); 段5 诊断区 632→484 - 预期写侧 −67µs/拍(→~230µs, 占空 29.7%→23%); LRW 帧 1024→880B - 五处一致: ethercat_pdo_size.h(真源) / dc_app.c(62 条目+映射初始化器) / gen_eeprom.py(PD_IN_SIZE, nEntry 自动推导) / DCU_ESI.xml(SM3 496+62 条目) / bridge.h(kEcatRxBatchDataMax=32, 断言更新) - 主站 tools/ecat decode_input 按 Ibytes 双布局自适应, 固件/EEPROM 与主站可 任意先后升级; 混烧(只烧一侧)会被 SM 长度校验拦下(AL 0x001A) - AC6 编译 0 警告; 真机验收待: 烧 axf + ecat.bat flash + 断电冷启动 (流程与复验判据见 tools/ecat/MIGRATION.md 1.6.1 节)
This commit is contained in:
@@ -37,7 +37,8 @@
|
||||
*
|
||||
* 新增两个批量区,每条帧带 8B 头(ch/dlc/flags/rsvd + id)+ 数据:
|
||||
* 输出 48..383(336B):批量发送,一个 seq 沿一次性发 N 帧
|
||||
* 输入 360..639(280B):批量接收,一周期回收多帧而不是只带最近一帧
|
||||
* 输入 360..483(124B):批量接收,一周期回收多帧而不是只带最近一帧
|
||||
* (1.6.1 数据条目 64→32B,段 5 诊断区 484..491,原 360..639/280B)
|
||||
*
|
||||
* 三条兼容性铁律(改动只做追加,不动既有偏移):
|
||||
* 1. 输出 0..47 与 1.5.55 单帧布局完全一致(seq/ch/dlc/flags/id/win/data32);
|
||||
@@ -128,7 +129,9 @@ enum : uint16_t {
|
||||
ECAT_XRX_OFF_DATA = 328U, /**< 数据区,32 字节完整 payload */
|
||||
};
|
||||
|
||||
/** 输入 PDO 段 4(360..639):CANFD 批量接收区(1.5.56 新增)。 */
|
||||
/** 输入 PDO 段 4(360..483):CANFD 批量接收区(1.5.56 新增,1.6.1 数据条目 64→32B)。
|
||||
* 每项 8B 头 + 最多 32B 数据(kEcatRxBatchDataMax);DLC 字节仍填**原始值**,
|
||||
* 超长帧被截断时 flags bit1=1 —— 主站按 "8 + min(dlc,32)" 推进游标。 */
|
||||
enum : uint16_t {
|
||||
ECAT_RXB_OFF_COUNT = 360U, /**< 本周期回收的帧数 0..kEcatRxBatchMax */
|
||||
ECAT_RXB_OFF_LOST = 361U, /**< 本周期因批量区放不下而丢弃的帧数 */
|
||||
@@ -137,15 +140,15 @@ enum : uint16_t {
|
||||
ECAT_RXB_OFF_ITEMS = 364U, /**< 帧数组起点,项布局同 ECAT_FRM_OFF_* */
|
||||
};
|
||||
|
||||
/** 输入 PDO 段 5(632..639):设备诊断区(1.5.61 新增,尾部追加)。
|
||||
* 批量接收区最坏情况(全 DLC64 满帧)只用到 364+3×72=580,580..639 永久空闲,
|
||||
* 诊断区锚在 632 起的 8 字节,写侧是 EthercatPdo::process()。 */
|
||||
/** 输入 PDO 段 5(484..491):设备诊断区(1.5.61 尾部追加,1.6.1 随批量区
|
||||
* 数据条目 64→32B 前移:364+3×40=484,诊断区锚在紧随其后的 8 字节,
|
||||
* 写侧是 EthercatPdo::fillDiagTail())。 */
|
||||
enum : uint16_t {
|
||||
ECAT_DIAG_OFF_LOAD = 632U, /**< 负载率,小端 uint16,单位 0.1%(1000=100%)。
|
||||
ECAT_DIAG_OFF_LOAD = 484U, /**< 负载率,小端 uint16,单位 0.1%(1000=100%)。
|
||||
中断 + 非延迟处理段(任务派发/OTA relay)占墙钟比,
|
||||
不含常开轮询与空转;1s 滚动窗口(见 sys/cpu_load.h) */
|
||||
ECAT_DIAG_OFF_RSVD = 634U, /**< 保留 2B */
|
||||
ECAT_DIAG_OFF_SEQ = 636U, /**< 诊断区序号,小端 uint32,每完成一个统计窗口 +1,
|
||||
ECAT_DIAG_OFF_RSVD = 486U, /**< 保留 2B */
|
||||
ECAT_DIAG_OFF_SEQ = 488U, /**< 诊断区序号,小端 uint32,每完成一个统计窗口 +1,
|
||||
主站据此判断负载值是否仍在滚动刷新 */
|
||||
};
|
||||
|
||||
@@ -163,20 +166,25 @@ constexpr uint8_t kEcatMotSlotsPerPdo = 7U;
|
||||
|
||||
/** 过程数据长度,唯一真源见 comm/ethercat_pdo_size.h(C/C++ 共用)。 */
|
||||
constexpr uint16_t kEcatPdoOutBytes = ECAT_PDO_OUT_BYTES; /* 48×64bit = 384B */
|
||||
constexpr uint16_t kEcatPdoInBytes = ECAT_PDO_IN_BYTES; /* 80×64bit = 640B */
|
||||
constexpr uint16_t kEcatPdoInBytes = ECAT_PDO_IN_BYTES; /* 62×64bit = 496B */
|
||||
|
||||
/** CANFD 单帧数据上限(DLC 64)—— 批量区按此上限做容量推导。 */
|
||||
/** CANFD 单帧数据上限(DLC 64)—— 环形队列/发送批量区按此上限做容量推导。 */
|
||||
constexpr uint8_t kEcatCanFdDataMax = 64U;
|
||||
|
||||
/** 批量**接收**条目在 PDO 内的数据字节数上限(1.6.1 从 64 压到 32)。
|
||||
* 真机采样 6086 帧 DLC 只有 24/32 两档;超长帧在装填时截断(flags bit1),
|
||||
* 环形队列 RxRingItem 仍存全量 64B,截断只发生在 PDO 快照这一步。 */
|
||||
constexpr uint8_t kEcatRxBatchDataMax = 32U;
|
||||
|
||||
/** 批量发送区可用字节数与最坏情况(全 DLC64)帧数上限。 */
|
||||
constexpr uint16_t kEcatTxBatchBytes = (uint16_t)(kEcatPdoOutBytes - ECAT_TXB_OFF_ITEMS);
|
||||
constexpr uint8_t kEcatTxBatchMax =
|
||||
(uint8_t)(kEcatTxBatchBytes / (ECAT_FRM_HDR_SIZE + kEcatCanFdDataMax));
|
||||
|
||||
/** 批量接收区可用字节数与最坏情况帧数上限。 */
|
||||
/** 批量接收区可用字节数与最坏情况(全 DLC32 截断满帧)帧数上限。 */
|
||||
constexpr uint16_t kEcatRxBatchBytes = (uint16_t)(kEcatPdoInBytes - ECAT_RXB_OFF_ITEMS);
|
||||
constexpr uint8_t kEcatRxBatchMax =
|
||||
(uint8_t)(kEcatRxBatchBytes / (ECAT_FRM_HDR_SIZE + kEcatCanFdDataMax));
|
||||
(uint8_t)(kEcatRxBatchBytes / (ECAT_FRM_HDR_SIZE + kEcatRxBatchDataMax));
|
||||
|
||||
/** 批量接收环形队列槽数。取 kEcatRxBatchMax 的 4 倍,让主站慢一两拍也不丢帧。
|
||||
* 注意这是 RAM 成本(槽数 × 72B),不是 PDO 成本。 */
|
||||
@@ -194,9 +202,9 @@ static_assert(ECAT_RXB_OFF_ITEMS < kEcatPdoInBytes, "批量接收区起点越界
|
||||
static_assert(ECAT_TXB_OFF_ITEMS < kEcatPdoOutBytes, "批量发送区起点越界");
|
||||
/* 批量区至少要装得下一帧满长 CANFD,否则"批量"没有意义 */
|
||||
static_assert(kEcatTxBatchMax >= 1U, "批量发送区装不下一帧 DLC64");
|
||||
static_assert(kEcatRxBatchMax >= 1U, "批量接收区装不下一帧 DLC64");
|
||||
static_assert(kEcatRxBatchMax >= 1U, "批量接收区装不下一帧 DLC32");
|
||||
/* 段 5 诊断区必须在批量接收区的最坏占用之外(改批量区布局时一起核对) */
|
||||
static_assert(ECAT_RXB_OFF_ITEMS + (uint16_t)kEcatRxBatchMax * (ECAT_FRM_HDR_SIZE + kEcatCanFdDataMax)
|
||||
static_assert(ECAT_RXB_OFF_ITEMS + (uint16_t)kEcatRxBatchMax * (ECAT_FRM_HDR_SIZE + kEcatRxBatchDataMax)
|
||||
<= ECAT_DIAG_OFF_LOAD, "批量接收区最坏占用与段5诊断区重叠");
|
||||
|
||||
/**
|
||||
@@ -215,6 +223,17 @@ public:
|
||||
* @param[in] out kEcatPdoOutBytes 字节输出过程数据。
|
||||
* @note 由 APPL_Application() 每周期调用。
|
||||
*/
|
||||
/** @brief 输出探针(1.6.0 输出按需全量读)。
|
||||
*
|
||||
* PDI_Isr 每周期先读输出 PDO 头 12B(覆盖 SEQ@0 与 WIN@8),由本函数判定
|
||||
* 是否需要全量读 384B:
|
||||
* - 始终从探针刷新 s_winBase(主站每周期移动窗口扫描,与 seq 沿无关);
|
||||
* - 首帧只记 seq 基准(与 processOutput 的 priming 一致),返回 false;
|
||||
* - seq 变化沿或 FLAGS bit0(清统计请求)→ 返回 true,调用方全量读。
|
||||
* s_lastSeq 仍由 processOutput 在全量路径上推进,本函数不写,保证沿语义
|
||||
* 只处理一次。 */
|
||||
static bool peekOutput(const uint8_t *head);
|
||||
|
||||
static void processOutput(const uint8_t *out);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user