Files
DCU_APP/GD32E508_DCU_APP/comm/ethercat_diff_stats.h
T
cbb 1742d9a759 feat(comm): 1.6.21 段2改电机整轮密排, 删段4历史覆盖窗
- 段2(32..543): count=实际电机数(0..9), 空节点不占位, 槽序按 node_id 升序
- 同号多通道取 seq 最新; magic@35=0xA5 区分密排与旧滑窗
- 差分填充: 节点集合+seq/online 未变时整段复用影子
- 删段4 fillRxWindow; 非STATUS仍走段1/3最近一帧
- 输入PDO总长仍600B, SII无需重刷; 主站需按count密排解码
- 动机: 接3电机却看到5状态帧(空槽占位); win_base滑窗对已识别电机无意义
2026-09-11 01:08:37 +08:00

61 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file ethercat_diff_stats.h
* @brief [DIFF-STATS] 临时仪表:量化"若把输入 PDO 改成差分写,每拍真正需要写多少字节、
* 变化点碎成几个连续段(run)"。只测量,不改变任何现有写行为。
*
* 存在的理由:差分写(方案 A)的收益完全取决于"每拍有多少字节真的变了",而 run 碎片
* 数量决定它会不会把一次 600B 整块写退化成几百次带 AVAIL 轮询的小写。这两个数今天
* 都没有实测依据,所以先只上仪表,拿分布再决定 A1(语义分区条件写) 值不值得做、
* A2(块粒度差分) 的碎片上限 N 该取几。
*
* 顺带把"比较本身要多久"也测出来(sub23 累计 DWT 周期)——这是差分方案最容易被
* 质疑的成本项,用实测代替拍脑袋。
*
* @note 结果按 1s 窗口滚动(与 sys/cpu_load.cpp 同法,用 DWT 周期判窗口边界),
* getter 返回**上一个已完成的完整窗口**,因此主站任何时刻 SDO 读到的都是
* 稳定值,不会拿到半累积的窗口。窗口未满时 windowSeq()==0,读侧应显示
* "等待首个完整窗口"而不是当 0 解读。
*
* @note 删除方法:删本文件与 ethercat_diff_stats.cpp + 删全工程 [DIFF-STATS] 标记行
* + 把 sys/config.h 的 CONFIG_ECAT_DIFF_STATS 置 0。对象字典 0x2000 的
* sub13..23 字段建议保留(恒 0,不影响任何既有子索引)。
*/
#ifndef COMM_ETHERCAT_DIFF_STATS_H
#define COMM_ETHERCAT_DIFF_STATS_H
#include <cstdint>
/**
* @brief 输入镜像差分统计。
* @note 全静态;observe() 在 PDI_Isr 上下文每拍调用一次,故内部状态无需临界区
* (唯一写者),getter 由 APPL_InputMapping 同上下文读取。
*/
class EthercatDiffStats {
public:
/**
* @brief 与上一份已发布的输入镜像比对并累计统计。
* @param[in] cur 刚发布完成的完整输入 PDO 镜像(kEcatPdoInBytes 字节)。
* @note 内部自持上一份副本,调用方无需额外维护缓冲、也不必自己 memcpy。
* 首次调用只建立基准,不产生样本(否则会把"全 600B 都变了"记成第一拍)。
*/
static void observe(const uint8_t *cur) noexcept;
/** @brief 丢弃基准,下一次调用重新起算(AL 状态跳变、布局变更时用)。 */
static void reset() noexcept;
/* ── 对象字典 0x2000 sub13..23 的取值接口,均为"上一个完整 1s 窗口" ── */
static uint32_t windowSeq() noexcept; /**< sub13 已完成窗口数,0=还没有完整窗口 */
static uint32_t cycles() noexcept; /**< sub14 窗口内参与比对的拍数 */
static uint32_t changedMax() noexcept; /**< sub15 单拍变化字节峰值 */
static uint32_t runsTotal() noexcept; /**< sub16 窗口内 run 总数(配 cycles 求均值) */
static uint32_t runsMax() noexcept; /**< sub17 单拍 run 数峰值,A2 的 N 由它定 */
static uint32_t seg1Bytes() noexcept; /**< sub18 段1(0..31) 桥状态+短快照 */
static uint32_t seg2Bytes() noexcept; /**< sub19 段2(32..543) 电机整轮密排 */
static uint32_t seg3Bytes() noexcept; /**< sub20 段3(544..583) 长帧快照 */
static uint32_t seg4Bytes() noexcept; /**< sub21 已删(1.6.21 恒 0) */
static uint32_t seg5Bytes() noexcept; /**< sub22 段5(584..599) 诊断区+保留 */
static uint32_t compareCyc() noexcept; /**< sub23 比对自身累计 DWT 周期(本征开销) */
};
#endif /* COMM_ETHERCAT_DIFF_STATS_H */