61 lines
3.6 KiB
C++
61 lines
3.6 KiB
C++
/**
|
|||
|
|
* @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..319) 电机状态窗口 */
|
||
|
|
static uint32_t seg3Bytes() noexcept; /**< sub20 段3(320..359) 长帧快照 */
|
||
|
|
static uint32_t seg4Bytes() noexcept; /**< sub21 段4(360..583) 批量覆盖窗 */
|
||
|
|
static uint32_t seg5Bytes() noexcept; /**< sub22 段5(584..599) 诊断区+保留 */
|
||
|
|
static uint32_t compareCyc() noexcept; /**< sub23 比对自身累计 DWT 周期(本征开销) */
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif /* COMM_ETHERCAT_DIFF_STATS_H */
|