feat(ethercat): 添加LAN9252睡眠挂起机制防止HBI访问冲突

添加了s_pmSuspended状态标志来管理LAN9252的电源管理模式,在芯片进入D1-D3
睡眠状态时阻止HBI访问以避免唤醒问题。同步修改了ethercat_sync中断处理程序,
在睡眠挂起期间跳过HBI相关操作确保芯片能够正常维持睡眠状态。

fix(spi): 提升SPI CS EXTI抢占优先级避免帧丢失

将SPI CS EXTI中断优先级从1提升至0,使其能够抢占PDI/SYNC1等关键中断,确
保SPI帧释放处理能够在微秒级完成,避免因延时导致的ESP32 CS间隔超时和帧
丢失问题。

feat(ssc): 实现OP输入新鲜度不变量监控机制

添加了输入映射序列号监控机制,当PDI路径中断时能够检测到输入数据冻结并
自动触发强制刷新,解决结构洞问题导致的输入数据停止更新现象。

chore(pdo): 更新PDO输入字节注释说明布局变更历史
This commit is contained in:
cbb
2026-09-13 18:59:57 +08:00
parent 6afaacd03a
commit 6136c2363f
12 changed files with 524 additions and 56 deletions
@@ -372,7 +372,14 @@ void AppSpiCommand::configureExti()
exti_init(EXTI_15, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
exti_interrupt_enable(EXTI_15);
exti_interrupt_flag_clear(EXTI_15);
nvic_irq_enable(EXTI10_15_IRQn, 1U, 1U);
/* 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
* (µs 级)同级排队,release 处理确定性 µs 级完成。代价:0xA2 pmDrive 的
* 忙等(≤10ms,手动 PM 诊断才用)会阻塞 SYNC0——诊断窗口,可接受。 */
nvic_irq_enable(EXTI10_15_IRQn, 0U, 1U);
}
@@ -523,17 +530,28 @@ 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 字节。
* ESP32 /system/status rsp_err_last_p0..p3 直读,无需串口即可判定损坏形态
* (全FF=DMA 未装/CS 丢失;SOF 错位=相位漂移;SOF 对但 CRC 败=帧内位错)。 */
uint16_t tx_len = 0U;
uint8_t err = 0xEEU;
spi_build_frame(kRspError, &err, 1U, m_txBuf, &tx_len);
uint8_t diag[8];
diag[0] = 0xE8U;
diag[1] = (m_rxLen > 255U) ? 255U : (uint8_t)m_rxLen;
diag[2] = (m_rxLen > 0U) ? m_rxBuf[0] : 0xFFU;
diag[3] = (m_rxLen > 1U) ? m_rxBuf[1] : 0xFFU;
diag[4] = (m_rxLen > 2U) ? m_rxBuf[2] : 0xFFU;
diag[5] = (m_rxLen > 3U) ? m_rxBuf[3] : 0xFFU;
diag[6] = 0x5AU;
diag[7] = 0xA5U;
/* 非v2帧时 hdr 未初始化:禁止缓存/推进序号(垃圾缓存会被 dup 重放) */
spi_build_frame(kRspError, diag, sizeof(diag), m_txBuf, &tx_len);
m_txLen = tx_len;
finishResponseAndReady();
return;
}
if (CONFIG_SPI_APP_LOG_ENABLE != 0 && !isFlashRelatedFrame(frame_type)) {
postLogFmt("[SPI-APP] 收到非刷写 SPI type=0x%02X", frame_type);
}
/* 1.6.29:逐帧"收到非刷写"行已移除(UART 刷屏);CONFIG_SPI_APP_LOG_ENABLE
* 现在只覆盖下方异常路径(非v2帧/未知type/SEQ跳变/session不匹配),正常态静默。 */
g_pendingAckSeq = hdr.tx_seq;
@@ -628,13 +646,16 @@ void AppSpiCommand::processCommand()
if (!handled) {
postLogFmt("[SPI-APP] 未知 type=0x%02X -> ERROR", frame_type);
uint8_t err = 0xEEU;
uint8_t err = 0xE9U; /* 1.6.29: E9=无 handler 认领 */
spi_build_frame(kRspError, &err, 1U, m_txBuf, &tx_len);
}
if (tx_len == 0U) {
uint8_t err = 0xEEU;
uint8_t err = 0xEAU; /* 1.6.29: EA=handler 命中但未产出响应 */
spi_build_frame(kRspError, &err, 1U, m_txBuf, &tx_len);
/* 1.6.29:这条兜底原本完全静默——0x82 0xEE 的三大来源里唯一不可见的。
* handler 命中但没产出响应(典型=buildResponse 构帧失败/业务拒绝)。 */
postLogFmt("[SPI-APP] handler t=0x%02X tx_len=0 -> ERROR", frame_type);
}
m_txLen = tx_len;