feat(sys): 添加AES加密和电机OTA中继功能模块

添加了AES128加密算法实现和电机OTA中继相关文件,包括:
- ./sys/aes128.h 和 ./sys/aes128.cpp - AES128加密算法头文件和实现
- ./sys/motor_ota_relay.h 和 ./sys/motor_ota_relay.cpp - 电机OTA中继功能
- 更新了项目配置文件包含这些新模块
This commit is contained in:
cbb
2026-07-26 20:39:59 +08:00
parent 934836618a
commit 079c6442d4
25 changed files with 2503 additions and 103 deletions
+55 -35
View File
@@ -267,7 +267,7 @@ bool CanFd::initNominalTiming(uint32_t canPeriph)
can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = ENABLE;
can_parameter.auto_wake_up = DISABLE;
can_parameter.auto_retrans = ENABLE;
can_parameter.auto_retrans = ENABLE; /* 默认自动重发兜底偶发 ACK 丢失;OTA 停等协议期间由 setChannelAutoRetrans(ch,false) 临时关闭,避免重发打穿电机单缓冲 RX */
can_parameter.rec_fifo_overwrite = ENABLE;
can_parameter.trans_fifo_order = ENABLE;
can_parameter.working_mode = CAN_NORMAL_MODE;
@@ -936,40 +936,19 @@ CanFd::CanTxResult CanFd::transmitFrame(uint8_t channelIndex, uint32_t ext_id,
return CanTxResult::kErrInvalid;
}
/* 总线健康检查:BUS_OFF 或 TEC 过高时跳过发送,防止测试帧把通道推向 BUS_OFF */
/* 诊断:捕获任何通过 transmitFrame 发 0x100 DLC=16 的帧(排查幽灵帧来源) */
if (ext_id == 0x00000100U && dlc == 16U) {
printf("[CAN-DIAG] TX 0x100 DLC=16 via transmitFrame ch=%u\r\n",
(unsigned)channelIndex);
}
/* BUS_OFF 不再软件拦截——CAN_ERR_BOERR 是粘性标志,控制器恢复后仍置位,
* 导致总线正常时仍拒绝发送(用户确认其他设备能收到 GD32 帧)。
* CAN 硬件自带恢复机制(128×11隐性位后自动回 Normal);
* 若确实发不出,can_message_transmit 会返回 NOMAILBOX → kErrMailbox。 */
const uint32_t canPeriph = kChannels[channelIndex].canPeriph;
const uint32_t errReg = CAN_ERR(canPeriph);
if (errReg & CAN_ERR_BOERR) {
static uint32_t s_lastBusOffLogSeq[kChannelCount] = {0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU};
if (s_lastBusOffLogSeq[channelIndex] != s_feedbackSeq) {
printf("[CAN-TX-REJECT] CH%u BUS_OFF ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
static_cast<unsigned>(channelIndex),
static_cast<unsigned long>(errReg),
static_cast<unsigned long>((errReg >> 4U) & 0x07U),
canLastErrorName(errReg),
static_cast<unsigned long>((errReg >> 16U) & 0xFFU),
static_cast<unsigned long>((errReg >> 24U) & 0xFFU),
static_cast<unsigned long>(CAN_TSTAT(canPeriph)));
s_lastBusOffLogSeq[channelIndex] = s_feedbackSeq;
}
return CanTxResult::kErrBusOff; /* 通道处于 BUS_OFF,不发送 */
}
const uint32_t tec = (errReg >> 16) & 0xFFU;
if (tec > 96U && !periodic) {
static uint32_t s_lastTecLogSeq[kChannelCount] = {0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU};
if (s_lastTecLogSeq[channelIndex] != s_feedbackSeq) {
printf("[CAN-TX-REJECT] CH%u TEC_HIGH ERR=0x%08lX ERRN=%lu(%s) TEC=%lu REC=%lu TSTAT=0x%08lX\r\n",
static_cast<unsigned>(channelIndex),
static_cast<unsigned long>(errReg),
static_cast<unsigned long>((errReg >> 4U) & 0x07U),
canLastErrorName(errReg),
static_cast<unsigned long>(tec),
static_cast<unsigned long>((errReg >> 24U) & 0xFFU),
static_cast<unsigned long>(CAN_TSTAT(canPeriph)));
s_lastTecLogSeq[channelIndex] = s_feedbackSeq;
}
return CanTxResult::kErrTecHigh; /* TEC 过高(>75% 错误被动阈值),暂停发送保护通道 */
}
/* CAN 硬件自有 error-passive(TEC>127 自动加间隔)
* 和 bus-off(TEC=256 → 自动恢复) 保护。软件不再做任何发送拦截。 */
/* 周期发送只允许一个邮箱保持自动重发。无 ACK 时同一帧会持续产生
* 总线波形;不要每 1ms 再填满其余邮箱,更不能主动 abort 旧帧,否则
@@ -1045,6 +1024,44 @@ CanFd::CanTxResult CanFd::transmitFrame(uint8_t channelIndex, uint32_t ext_id,
return CanTxResult::kErrMailbox;
}
void CanFd::abortPendingTx(uint8_t channelIndex)
{
if (channelIndex >= kChannelCount || !kChannelEnabled[channelIndex]) {
return;
}
const uint32_t canPeriph = kChannels[channelIndex].canPeriph;
for (uint8_t mb = CAN_MAILBOX0; mb <= CAN_MAILBOX2; ++mb) {
if (can_transmit_states(canPeriph, mb) == CAN_TRANSMIT_PENDING) {
(void)can_transmission_stop(canPeriph, mb);
}
}
}
void CanFd::setChannelAutoRetrans(uint8_t channelIndex, bool enable)
{
if (channelIndex >= kChannelCount || !kChannelEnabled[channelIndex]) {
return;
}
const uint32_t canPeriph = kChannels[channelIndex].canPeriph;
/* ARD 位仅在 init mode 可写:进 init mode → 改 ARD → 退 init mode。 */
CAN_CTL(canPeriph) |= CAN_CTL_IWMOD;
for (volatile uint32_t t = 0U; t < 200000U; ++t) {
if (CAN_STAT(canPeriph) & CAN_STAT_IWS) break;
}
if (enable) {
CAN_CTL(canPeriph) &= ~CAN_CTL_ARD; /* 自动重发 ON(业务默认) */
} else {
CAN_CTL(canPeriph) |= CAN_CTL_ARD; /* 自动重发 OFF(单发,停等式 OTA 用) */
}
CAN_CTL(canPeriph) &= ~CAN_CTL_IWMOD;
for (volatile uint32_t t = 0U; t < 200000U; ++t) {
if ((CAN_STAT(canPeriph) & CAN_STAT_IWS) == 0U) break;
}
printf("[CAN] CH%u set auto_retrans=%u -> ARD=%u\r\n",
(unsigned)channelIndex, (unsigned)enable,
(CAN_CTL(canPeriph) & CAN_CTL_ARD) ? 1U : 0U);
}
/**
* @brief 获取 CANFD 诊断统计信息只读指针。
* @param[in] 无。
@@ -1319,13 +1336,16 @@ void CanFd::refreshFeedbackSnapshot()
}
s_feedbackSeq++;
/* 每 5 秒打印一次 seq 心跳;诊断期间同时输出实际错误通道的最后错误类型。 */
/* 每 5 秒采样硬件错误态;正常心跳不打印(统计走 SPI 0xC1)。
* 仅当 TEC/REC 或告警位非零时输出 [CAN-HW-ERR];全量 seq 心跳见 CONFIG_UART_DIAG_LEVEL。 */
if (s_feedbackSeq % 5U == 0U) {
#if (CONFIG_UART_DIAG_LEVEL != 0)
printf("[CAN-FB] refresh seq=%lu rx0=%lu rx1=%lu rx2=%lu\r\n",
(unsigned long)s_feedbackSeq,
(unsigned long)s_channelStats[0].rx_count,
(unsigned long)s_channelStats[1].rx_count,
(unsigned long)s_channelStats[2].rx_count);
#endif
for (size_t i = 0; i < kChannelCount; ++i) {
if (hw_tec[i] == 0U && hw_rec[i] == 0U
&& (hw_err[i] & (CAN_ERR_WERR | CAN_ERR_PERR | CAN_ERR_BOERR)) == 0U) {