fix(ssc): 根治邮箱楔死(1.5.59): 几何常量化消灭建立路径, 守护字节序修复

- ecat_def.h: 新增 MBX_SM0/1_START/SIZE 构建期常量(=SII 真值 0x1000/0x1200 各 256B,
  与 gen_eeprom.py/DCU_ESI.xml 三方一致, 改 SII 邮箱尺寸必须同步)
- mailbox.c: MBX_StartMailboxHandler 常量直达缓存, CSR 单次间接读降为交叉校验
  (失配打 [ECAT][MBX] WARN)。根因: INIT→PREOP 单次 CSR 读错值(0x1204/0x1208,
  BUSLAT 余量外的 EXMC 毛刺)被缓存成 u16EscAddrSendMbx → 响应写错址 → 断电才清;
  常量化后错值无进入缓存的路径, 运行期内存踩踏也会在每次 INIT→PREOP 被覆写
- esc_lan9252.cpp: csrRead 双读 CSR_DATA 一致校验+整事务重试(CSR_DATA 为锁存
  寄存器非 FIFO, 连读必一致; 不一致即本拍总线毛刺)。瞬态错读曾致 CheckSmSettings
  以 0x0016/0x001F 打断转换
- dc_app.c: 修复守护/心跳 SWAPWORD 字节序 bug——ESC 寄存器 PDI/CSR 读即主机序
  (与 GetSyncMan/mailbox 裸读一致), 交换使 sm0Len=0x0001<8 恒短路, 1.5.52~1.5.58
  地址失配守护从未生效过; 现降级为运行期内存踩踏兜底并真正可用; ReadAlDiag 同修,
  期间串口日志的 al/evt 均为字节交换错值, 历史日志需交换重读
- task_runner.cpp: 守护注释同步
- 新增 _syntax_check.bat + _syntaxcheck_stubs: 无 AC6 环境用 VS2022 cl /Zs 验 C 文件

真机验收: 140 次 op/start 全成功(40 轮 DC 4ms + 100 轮 DC/free-run 交替),
每轮进 OP、SDO 0x2000:3/4 全成功, 无 0x0016/0x001D/0x001B。
This commit is contained in:
cbb
2026-09-05 17:38:35 +08:00
parent f9ef1b8da2
commit 2ebd4ff1d2
7 changed files with 112 additions and 31 deletions
+30 -5
View File
@@ -133,6 +133,8 @@ V4.07 ECAT 1: The sources for SPI and MCI were merged (in ecat_def.h<br>
#include "ecatcoe.h"
#include <stdio.h> /* printf: SM 几何交叉校验 WARN(1.5.59,见 MBX_StartMailboxHandler) */
/*--------------------------------------------------------------------------------------
------
------ internal Types and Defines
@@ -282,24 +284,47 @@ void MBX_Init(void)
UINT16 MBX_StartMailboxHandler(void)
{
UINT16 result = 0;
/* get address of the receive mailbox sync manager (SM0) */
/* 1.5.59 根治"邮箱楔死"(响应帧头落在 SM1 start+4/+8、逐会话漂移,断电才清):
* 根因链 = INIT→PREOP 时经 GetSyncMan/CSR 单次间接读(EXMC HBI)把 SM0/SM1
* 几何缓存进 u16EscAddr* 与 u16*MbxSize 等变量;总线毛刺给出的"合法"错值
* (0x1204/0x1208 均为偶地址且在检查范围内)即被缓存,此后所有 SDO 响应写错址,
* 主站按协议从 0x1200 读永远错位,重枚举重读仍错 → 只有断电能解。本板邮箱
* 几何是 SII 固定值(gen_eeprom.py 的 MBX_RX/TX_OFFSET/SIZE,ESC 上电自行
* 加载,主站 config_init 也只是照抄),改为构建期常量(ecat_def.h:
* MBX_SM0/1_START/SIZE)直达缓存,CSR 读降级为交叉校验:失配打 WARN(说明
* ESC 寄存器被非常规改写,需查)但缓存仍取常量——CSR 错值从此没有进入
* 缓存的路径,楔死无建立点;运行期内存踩踏也会在每次 INIT→PREOP 被常量覆写。
* 注意:ESC 寄存器经 PDI/CSR 读出即主机序(与 GetSyncMan 既有路径一致,勿加
* SWAPWORD;PRAM 帧数据才是线上大端,那边交换是对的)。 */
/*ECATCHANGE_START(V5.11) HW1*/
TSYNCMAN ESCMEM * pSyncMan = (TSYNCMAN ESCMEM *)GetSyncMan(MAILBOX_WRITE);
/*ECATCHANGE_END(V5.11) HW1*/
if (pSyncMan->PhysicalStartAddress != MBX_SM0_START || pSyncMan->Length != MBX_SM0_SIZE)
{
printf("[ECAT][MBX] WARN: SM0 reg 0x%04X/%u != build-time 0x%04X/%u -> keep build-time\r\n",
(unsigned)pSyncMan->PhysicalStartAddress, (unsigned)pSyncMan->Length,
(unsigned)MBX_SM0_START, (unsigned)MBX_SM0_SIZE);
}
/* store size of the receive mailbox */
u16ReceiveMbxSize = pSyncMan->Length;
u16ReceiveMbxSize = MBX_SM0_SIZE;
/* store the address of the receive mailbox */
u16EscAddrReceiveMbx = pSyncMan->PhysicalStartAddress;
u16EscAddrReceiveMbx = MBX_SM0_START;
/* get address of the send mailbox sync manager (SM1) */
/*ECATCHANGE_START(V5.11) HW1*/
pSyncMan =(TSYNCMAN ESCMEM *) GetSyncMan(MAILBOX_READ);
/*ECATCHANGE_END(V5.11) HW1*/
if (pSyncMan->PhysicalStartAddress != MBX_SM1_START || pSyncMan->Length != MBX_SM1_SIZE)
{
printf("[ECAT][MBX] WARN: SM1 reg 0x%04X/%u != build-time 0x%04X/%u -> keep build-time\r\n",
(unsigned)pSyncMan->PhysicalStartAddress, (unsigned)pSyncMan->Length,
(unsigned)MBX_SM1_START, (unsigned)MBX_SM1_SIZE);
}
/* store the size of the send mailbox */
u16SendMbxSize = pSyncMan->Length;
u16SendMbxSize = MBX_SM1_SIZE;
/* store the address of the send mailbox */
u16EscAddrSendMbx = pSyncMan->PhysicalStartAddress;
u16EscAddrSendMbx = MBX_SM1_START;
// HBu 02.05.06: it should be checked if there are overlaps in the sync manager areas
if ((u16EscAddrReceiveMbx + u16ReceiveMbxSize) > u16EscAddrSendMbx && (u16EscAddrReceiveMbx < (u16EscAddrSendMbx + u16SendMbxSize)))