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:
@@ -370,17 +370,15 @@ void AppSpiCommand::configureExti()
|
||||
{
|
||||
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_15);
|
||||
exti_init(EXTI_15, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
|
||||
/* 1.6.35:先清 STAT 再开 IMR。原 enable→clear 顺序在 warm jump 下有害——
|
||||
* BOOT 关中断跳转(v1.1.0.15)前 ESP32 持续拉 CS,EXTI15 STAT 大概率残留;
|
||||
* 本函数在 AppSpiCommandBus.init() 里跑,此刻 PRIMASK 已被 init 开头清零,
|
||||
* 若先 enable IMR,那个残留位会立即回放成一次假 CS 沿进 NVIC。 */
|
||||
/* 先清 STAT 再开 IMR。warm jump 下 BOOT 关中断跳转前 ESP32 持续拉 CS,
|
||||
* EXTI15 STAT 大概率残留;若先 enable IMR,残留位会立即回放成一次假 CS
|
||||
* 沿进 NVIC。 */
|
||||
exti_interrupt_flag_clear(EXTI_15);
|
||||
exti_interrupt_enable(EXTI_15);
|
||||
/* 1.6.32:SPI CS EXTI 抢占级 1→0。原 1 与 PDI/SYNC1/SCHED 同级不抢占
|
||||
* (1.6.13 实测 PDI 窗口 ~357µs),且被 RT_CRITICAL(BASEPRI≥1) 完全屏蔽;
|
||||
* release ISR 一旦拖过 ESP32 的 CS 间隔(0.4.4 起 1ms),re-arm 落空,
|
||||
* 下一笔查询帧头部丢失→GD32 解析失败回 0x82 0xE8→迟到被 serviceRing
|
||||
* 偷读("偷读迟到 RESPONSE 0xEE/E8"风暴根因)。提到 0 后仅与 SYNC0/CAN-RX
|
||||
/* SPI CS EXTI 抢占级 0。抢占级 1 与 PDI/SYNC1/SCHED 同级不抢占
|
||||
* (PDI 窗口可达数百 µs),且被 RT_CRITICAL(BASEPRI≥1) 完全屏蔽;
|
||||
* release ISR 一旦拖过 ESP32 的 CS 间隔(1ms),re-arm 落空,
|
||||
* 下一笔查询帧头部丢失。提到 0 后仅与 SYNC0/CAN-RX
|
||||
* (µs 级)同级排队,release 处理确定性 µs 级完成。代价:0xA2 pmDrive 的
|
||||
* 忙等(≤10ms,手动 PM 诊断才用)会阻塞 SYNC0——诊断窗口,可接受。 */
|
||||
nvic_irq_enable(EXTI10_15_IRQn, 0U, 1U);
|
||||
@@ -534,7 +532,7 @@ void AppSpiCommand::processCommand()
|
||||
|
||||
if (!spi_try_parse_frame(m_rxBuf, m_rxLen, &frame_type, &payload, &payload_len, &hdr)) {
|
||||
postLogFmt("[SPI-APP] 非v2帧 0x%02X -> ERROR", m_rxBuf[0]);
|
||||
/* 1.6.30: 0xE8 payload 携带接收诊断——[0]=0xE8, [1]=rxLen, [2..5]=rxBuf 前 4 字节。
|
||||
/* 0xE8 payload 携带接收诊断——[0]=0xE8, [1]=rxLen, [2..5]=rxBuf 前 4 字节。
|
||||
* ESP32 /system/status rsp_err_last_p0..p3 直读,无需串口即可判定损坏形态
|
||||
* (全FF=DMA 未装/CS 丢失;SOF 错位=相位漂移;SOF 对但 CRC 败=帧内位错)。 */
|
||||
uint16_t tx_len = 0U;
|
||||
@@ -554,8 +552,8 @@ void AppSpiCommand::processCommand()
|
||||
return;
|
||||
}
|
||||
|
||||
/* 1.6.29:逐帧"收到非刷写"行已移除(UART 刷屏);CONFIG_SPI_APP_LOG_ENABLE
|
||||
* 现在只覆盖下方异常路径(非v2帧/未知type/SEQ跳变/session不匹配),正常态静默。 */
|
||||
/* 正常帧不打日志(避免 UART 刷屏);CONFIG_SPI_APP_LOG_ENABLE
|
||||
* 只覆盖异常路径(非v2帧/未知type/SEQ跳变/session不匹配),正常态静默。 */
|
||||
|
||||
g_pendingAckSeq = hdr.tx_seq;
|
||||
|
||||
@@ -650,15 +648,14 @@ void AppSpiCommand::processCommand()
|
||||
|
||||
if (!handled) {
|
||||
postLogFmt("[SPI-APP] 未知 type=0x%02X -> ERROR", frame_type);
|
||||
uint8_t err = 0xE9U; /* 1.6.29: E9=无 handler 认领 */
|
||||
uint8_t err = 0xE9U; /* E9=无 handler 认领 */
|
||||
spi_build_frame(kRspError, &err, 1U, m_txBuf, &tx_len);
|
||||
}
|
||||
|
||||
if (tx_len == 0U) {
|
||||
uint8_t err = 0xEAU; /* 1.6.29: EA=handler 命中但未产出响应 */
|
||||
uint8_t err = 0xEAU; /* EA=handler 命中但未产出响应 */
|
||||
spi_build_frame(kRspError, &err, 1U, m_txBuf, &tx_len);
|
||||
/* 1.6.29:这条兜底原本完全静默——0x82 0xEE 的三大来源里唯一不可见的。
|
||||
* handler 命中但没产出响应(典型=buildResponse 构帧失败/业务拒绝)。 */
|
||||
/* handler 命中但没产出响应(典型=buildResponse 构帧失败/业务拒绝)走此兜底错误路径。 */
|
||||
postLogFmt("[SPI-APP] handler t=0x%02X tx_len=0 -> ERROR", frame_type);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user