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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user