fix(comm): 回退LAN9252批量读写优化并修复多个CAN-EtherCAT桥竞态问题

回退1.6.0引入的LAN9252 PRAM批量读写优化,因其AVAIL_CNT计数器对短读存在语义问题,
导致邮箱短读和探针传输时出现FIFO陈旧数据损坏问题。

同时修复EtherCAT-CAN桥中的多个竞态条件:
- 修复消费者在fillRxBatch中直接访问共享ring buffer导致的数据混淆问题
- 修复生产者-消费者间tail指针发布时机不当造成的槽位覆盖竞态
- 修复WIN窗口基址更新位置错误导致电机状态窗口被锁定的问题
- 修复buildInput中断上下文与主循环间的数据竞争和内存撕裂问题
- 添加STATUS帧过滤机制减少批量区压力并解决队列饱和问题

此外还增加了多个诊断计数器用于监控撕裂、溢出和拼接错误,并调整了
输入PDO段布局和大小参数以支持新的48字节STATUS格式。

这些修改解决了上位机观察到的帧标签错误、电机状态丢失和数据拼接问题。
This commit is contained in:
cbb
2026-09-08 00:52:35 +08:00
parent ace5a1671b
commit 0cd3d9bed2
13 changed files with 518 additions and 111 deletions
+11 -1
View File
@@ -75,6 +75,10 @@ public:
/** @brief 累计交回输入的周期数。 */
static uint32_t inputCycles() { return s_inputCycles; }
/** @brief process() 被重入拦下的次数。持续增长 = 跨上下文抢占确实在发生
* (PDI_Isr / Sync0_Isr / Sync1_Isr / MainLoop 互相打断),也就证明了
* 批量区跨轮次拼接的成因;恒为 0 则说明该机制推断有误。 */
static uint32_t reentryCount() { return s_reentryCount; }
/** @brief 是否已开始过程数据交换(收到过至少一个输出周期)。 */
static bool isExchanging() { return s_outputCycles != 0U; }
@@ -96,8 +100,14 @@ private:
/** @brief 最近一份主站下发的输出数据。 */
static uint8_t s_out[kPdoOutBytes];
/** @brief 待交回主站的输入数据。 */
/** @brief 待交回主站的输入数据(已发布的完整镜像,writeInputs 只读它)。 */
static uint8_t s_in[kPdoInBytes];
/** @brief 输入 PDO 工作缓冲:buildInput 填这里,填完整块发布到 s_in。
* ECAT_Application() 会在 PDI_Isr / Sync0_Isr / Sync1_Isr / MainLoop 四个
* 上下文被调用并互相抢占,直接写 s_in 会让读侧取到跨轮次的半成品。 */
static uint8_t s_build[kPdoInBytes];
/** @brief process() 被重入拦下的次数(诊断用,见 reentryCount())。 */
static volatile uint32_t s_reentryCount;
static volatile uint32_t s_outputCycles;
static volatile uint32_t s_inputCycles;