feat(canfd): 添加TX错误事件驱动的快速重发机制

添加TX错误事件标志和相关API以支持ARD模式下单发帧丢失的快速检测和重发,
实现停等式OTA在丢帧后的立即重发,避免等待ACK超时的延迟。

- 新增s_txErrorEvent数组跟踪各通道TX错误事件
- 添加readChannelErrorReg()读取CAN_ERR寄存器原始值
- 添加consumeTxError()消费TX错误事件并返回状态
- 在TX中断中检测MTE位设置错误事件标志

fix(motor-ota): 优化OTA重发策略和错误处理

调整OTA重发参数和逻辑,提升传输可靠性和响应速度。

- 将ACK超时重发间隔从500ms调整为100ms,提高响应速度
- 增加每包补发上限从2次到4次,保持总容错时间窗
- 实现TX错误驱动的快速重发,丢帧后立即按间隔补发
- 增加错误统计信息输出,包含重发和快速重发计数
- 提高仲裁段再同步跳跃宽度从1TQ到2TQ,增强总线容错能力
This commit is contained in:
cbb
2026-07-27 00:02:14 +08:00
parent 079c6442d4
commit edebde4a02
4 changed files with 91 additions and 11 deletions
+29
View File
@@ -165,6 +165,10 @@ uint32_t CanFd::s_feedbackSeq = 0U;
CanFd::IdSnapshotTable CanFd::s_idSnapshot[3]{};
bool CanFd::s_channelHwOk[3]{};
/* TX 错误事件标志(ARD=1 单发丢帧通知):TX 完成 ISR 置位,主循环
* consumeTxError() 读清;单写单读,无锁。 */
static volatile bool s_txErrorEvent[3]{};
/**
* @brief 查询指定通道是否已使能。
*/
@@ -1062,6 +1066,28 @@ void CanFd::setChannelAutoRetrans(uint8_t channelIndex, bool enable)
(CAN_CTL(canPeriph) & CAN_CTL_ARD) ? 1U : 0U);
}
uint32_t CanFd::readChannelErrorReg(uint8_t channelIndex)
{
if (channelIndex >= kChannelCount || !kChannelEnabled[channelIndex]) {
return 0U;
}
/* 单次寄存器读,供事件时刻(如 OTA ACK 超时)抓取总线错误状态;
* 不走 1Hz refreshFeedbackSnapshot,避免采样混叠。 */
return CAN_ERR(kChannels[channelIndex].canPeriph);
}
bool CanFd::consumeTxError(uint8_t channelIndex)
{
if (channelIndex >= kChannelCount || !kChannelEnabled[channelIndex]) {
return false;
}
if (!s_txErrorEvent[channelIndex]) {
return false;
}
s_txErrorEvent[channelIndex] = false;
return true;
}
/**
* @brief 获取 CANFD 诊断统计信息只读指针。
* @param[in] 无。
@@ -1301,6 +1327,9 @@ void CanFd::handleTxInterrupt(uint8_t channelIndex)
} else if ((tstat & errorBits[mailbox]) != 0U) {
s_diag.error_count++;
s_channelStats[channelIndex].error_count++;
/* ARD=1 单发模式下 MTE 置位 = 该帧已确认丢失;置事件标志供停等式
* OTA 快速重发(免等 ACK 超时)。单写(ISR)单读清(主循环),无锁。 */
s_txErrorEvent[channelIndex] = true;
}
}