Files
DCU_APP/GD32E508_DCU_APP/comm/ethercat_diff_stats.h
T

61 lines
3.5 KiB
C++
Raw Normal View History

/**
* @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 */