feat(comm): 1.6.51 CAN 空通道自动静默 + PDO 诊断 + OTA 布局共用头

变更点:
1. CAN-FD(device/CANFD.cpp、sys/config.h)
   - 发送统一 FD+BRS(DLC≤8 不再回退经典 CAN);OTA 期仍按通道压制 BRS
   - 空通道自动识别:连续 5 个 1Hz 窗口无有效帧且有错误 → 静默上报;有帧即恢复
   - 三路 CAN 默认全开;RX parse budget 48→64
2. EtherCAT 桥 / PDO
   - 段1 增 txtxid/rx00ff;版本应答 0x00FF 粘滞发布,避免被 CONFIG 冲掉
   - STATUS 禁止写入 xrx 快照;processSeq 新鲜度救援
3. OTA / 配置
   - sys/config.h include 仓库内 shared/ota_layout.h(与 BOOT 共用,不再依赖仓外路径)
   - ota_boot_request 对齐配置页 word 布局
4. docs/audit_ecat_spi_wifi_ota_compatibility.md:ECAT/SPI/WiFi/OTA 兼容性审计
5. .gitignore:忽略 .trae/、docs/traework-import、评审过程稿
This commit is contained in:
cbb
2026-09-20 22:58:09 +08:00
parent 63af85e7be
commit 5fd986299c
32 changed files with 2592 additions and 781 deletions
+16 -16
View File
@@ -2,7 +2,7 @@
* @file esc_lan9252.h
* @brief LAN9252 EtherCAT 从站控制器(ESC)驱动接口。
* @note 通过 EscExmcBus 16-bit 并行总线,以 HBI Indexed Address Mode 访问 LAN9252。
* 访问模型(1.5.39 按 DS 12.11 修正,此前误以为整个 16 位索引空间统一可寻址):
* 访问模型(DS 12.11):
* - HBI 直接地址空间:仅 LAN9252 系统 CSR(BYTE_TEST 0x064 等)+ 访问端口
* (PRAM FIFO 0x000-0x03C、ECAT_CSR_DATA/CMD 0x300/0x304、PRAM_ADDR_LEN/CMD
* 0x308-0x314)——经 HBI_IDX_0/HBI_DATA_0 直接读写;
@@ -29,7 +29,7 @@
class EscLan9252 {
public:
/** @brief 初始化 EXMC 总线与 ESC 基本寄存器。
* @note 1.5.25 起内部先执行一次 hardwareReset() 受控复位(s_resetDone 门控,
* @note 内部先执行一次 hardwareReset() 受控复位(s_resetDone 门控,
* 重复调用不会二次复位 SSC 已配置好的芯片),再探活 EXMC/HBI。
* @return bool true 表示 EXMC 总线探活通过(可继续读取芯片 ID)。 */
static bool init();
@@ -65,20 +65,20 @@ public:
static uint32_t readChipId();
/** @brief INIT-ONLY:仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用;运行期禁止调用,需 ESC 寄存器访问须通过 SSC 移植层(HW_*)。
* @note 1.5.39 起经 CSR_CMD/CSR_DATA 间接端口读 ESC 核心 CSR(此前直读 HBI 索引,
* 而 EtherCAT 核心寄存器根本不在 HBI 直接地址空间,恒读 0)。 */
* @note 经 CSR_CMD/CSR_DATA 间接端口读 ESC 核心 CSR
* (EtherCAT 核心寄存器不在 HBI 直接地址空间,直读恒 0)。 */
static uint16_t initOnlyReadReg(uint16_t addr);
/** @brief INIT-ONLY:仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用;运行期禁止调用。 */
static void initOnlyWriteReg(uint16_t addr, uint16_t v);
/** @brief ESC 核心 CSR 间接读(ECAT_CSR_CMD/DATA 端口,0x0000-0x0FFF 地址空间)。
* @note 1.5.39:LAN9252 的 HBI/SPI 直接地址空间只有 LAN9252 系统 CSR 与访问端口
* @note LAN9252 的 HBI/SPI 直接地址空间只有 LAN9252 系统 CSR 与访问端口
* (DS 12.11/表 12-13),EtherCAT 核心寄存器(0x0000-0x0FFF)必须经
* CSR_CMD(0x304)/CSR_DATA(0x300) 间接访问;过程 RAM(0x1000-0x1FFF)
* 必须经 PRAM FIFO。size=1/2/4(size2 需偶地址,size4 需 4 字节对齐)。
* 调用方负责 HBI 互斥(主循环 EscExmcBus::maskEnter / 已在 ISR 上下文)。
* @param verify true(默认)=双读比对+不一致重试(1.5.59,防 EXMC 毛刺,SM/AL/邮箱
* @param verify true(默认)=双读比对+不一致重试(防 EXMC 毛刺,SM/AL/邮箱
* 等关键路径必须开);false=单读(诊断回读/MII busy 轮询/init 等低风险路径,
* 省约一半 CSR 间接访问)。 */
static uint32_t csrRead(uint16_t addr, uint8_t size, bool verify = true);
@@ -93,40 +93,40 @@ public:
static void pramWrite(uint16_t addr, const uint8_t *buf, uint16_t len);
/** @brief EXMC 总线 + BYTE_TEST 往返探针通过(init 成功)后为 true。
* @note 1.6.40 起 HBI_IDX_0 复位默认值降级为诊断读数,不再参与放行
* @note HBI_IDX_0 复位默认值仅作诊断读数,不参与放行
* (它只证明"芯片刚出过复位",证明不了 HBI 通路)。
* 与 init() 返回值一致,可作运行期查询。 */
static bool isBusReady() { return s_busReady; }
/** @brief EEPROM(SII) 加载完成、EtherCAT 核心使能(1.5.39)。
/** @brief EEPROM(SII) 加载完成、EtherCAT 核心使能。
* @note false 时核心寄存器对 PDI 读全 0、写静默丢弃,SSC MainInit 会全部
* 落空(AL Event Mask/邮箱 SM 配置写不进),调用方必须跳过 SSC 初始化。 */
static bool isCoreReady() { return s_coreReady; }
/** @brief ESC 已被 pmDrive 置入 D1-D3 睡眠、所有 HBI 消费者必须静默(1.6.27)。
* @note 1.6.24 实测睡眠中任何 HBI 访问(含读)都会把芯片打回 D0。置位期间
/** @brief ESC 已被 pmDrive 置入 D1-D3 睡眠、所有 HBI 消费者必须静默。
* @note 睡眠中任何 HBI 访问(含读)都会把芯片打回 D0。置位期间
* task_runner 停调 MainLoop()/AL 守护/AL 心跳,ethercat_sync 三个 EXTI
* ISR 清 pending 后直接返回——否则芯片进入睡眠后毫秒级就被主循环的
* ECAT_Main(读 0x220)叫醒,根本睡不住(2026-09-12 休眠 ~20s 即"复活")。
* ECAT_Main(读 0x220)叫醒,根本睡不住。
* 解除:pmDrive 唤醒/读到 D0、nrstDrive 释放复位、hardwareReset。
* ISR 上下文安全:读一个 bool 静态成员,无锁。 */
static bool pmSuspended() { return s_pmSuspended; }
private:
/** @brief 使能 LAN9252 的 IRQ 引脚输出(IRQ_CFG 0x054 / INT_EN 0x05C)。
* @note 1.5.43 新增,由 init() 在 PDI/核心就绪后调用。两寄存器复位默认全 0,
* @note 由 init() 在 PDI/核心就绪后调用。两寄存器复位默认全 0,
* 不配则 EtherCAT 事件永不到达 PB1、SSC 的 PDI_Isr 从不执行,
* bEcatFirstOutputsReceived 恒 FALSE 使 SAFEOP->OP 被无限挂起。 */
* SAFEOP->OP 被无限挂起。 */
static void enableEcatIrqOutput();
/** @brief 过程数据看门狗 100ms(复位默认)→1s(1.5.45)。
/** @brief 过程数据看门狗 100ms(复位默认)→1s。
* @note 由 init() 在 PDI/核心就绪后调用。写 ESC_REG_WD_TIME_PD(0x0420)=10000
* (100µs 分频保持默认)。不写则主站 100ms 手动调试周期触发 SM2 看门狗,
* SSC 以 0x001B 拖回 SAFEOP。 */
static void configPdWatchdog();
static bool s_busReady; /**< init 成功(EXMC+BYTE_TEST 往返,1.6.40;IDX 残值不挡)后置位。 */
static bool s_coreReady; /**< EEPROM 加载完成、EtherCAT 核心使能后置位(1.5.39)。 */
static bool s_busReady; /**< init 成功(EXMC+BYTE_TEST 往返;IDX 残值不挡)后置位。 */
static bool s_coreReady; /**< EEPROM 加载完成、EtherCAT 核心使能后置位。 */
static bool s_resetDone; /**< hardwareReset 已执行门控(防二次复位清掉 SSC 配置)。 */
static bool s_pmPhyDown; /**< pmDrive 进 D3 时两 PHY 已被置 PowerDown,唤醒后需恢复。 */
static bool s_pmSuspended; /**< ESC 睡眠挂起:置位期间全固件 HBI 消费者静默(见 pmSuspended)。 */