Files
DCU_APP/GD32E508_DCU_APP/sys/motor_ota_relay.h
T
cbb 079c6442d4 feat(sys): 添加AES加密和电机OTA中继功能模块
添加了AES128加密算法实现和电机OTA中继相关文件,包括:
- ./sys/aes128.h 和 ./sys/aes128.cpp - AES128加密算法头文件和实现
- ./sys/motor_ota_relay.h 和 ./sys/motor_ota_relay.cpp - 电机OTA中继功能
- 更新了项目配置文件包含这些新模块
2026-07-26 20:39:59 +08:00

85 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file motor_ota_relay.h
* @brief 电机 OTA relay 状态机 — GD32 本地完成与电机 Bootloader 的全部交互。
*
* 职责:
* - AES-128 密钥协商(K_master 存本地 flash)
* - 固件数据 AES-ECB 加密 + keyed-CRC32
* - CAN 上逐包 stop-and-wait(发 0x101 → 等 0x102 ACK → 按包号继续)
* - 进度/完成/错误通过 SPI ring push 报 ESP32
*
* ESP32 通过 SPI 0xD0(start) / 0xD1(data) / 0xD3(cancel) 喂数据,
* GD32 通过 0xD2 ring push 报进度。
*/
#ifndef SYS_MOTOR_OTA_RELAY_H
#define SYS_MOTOR_OTA_RELAY_H
#include <cstdint>
namespace MotorOtaRelay {
/* 电机 Bootloader CAN ID(固定,非节点相关) */
static constexpr uint32_t kOtaReqId = 0x00000100U; /* Host→Motor 握手 */
static constexpr uint32_t kOtaDataId = 0x00000101U; /* Host→Motor 数据 */
static constexpr uint32_t kOtaAckId = 0x00000102U; /* Motor→Host ACK */
static constexpr uint32_t kOtaWaitId = 0x00000103U; /* Motor→Host IDLE心跳 */
static constexpr uint32_t kOtaCancelId = 0x00000000U; /* Host→Motor 取消 */
static constexpr uint32_t kPacketPayload = 48U; /* 每包有效载荷 */
static constexpr uint32_t kFrameDlc = 64U; /* CAN FD DLC */
static constexpr uint32_t kMaxFwSize = 0xC000U; /* 48 KB */
static constexpr uint32_t kAckTimeoutMs = 5000U; /* 单包 ACK 超时 */
static constexpr uint32_t kHandshakeTimeoutMs = 3000U;
enum class State : uint8_t {
kIdle = 0,
kHandshakeReq, /* 已发 [00 AC],等 ACK */
kHandshakeNonce, /* 已发 nonce,等 36B ACK */
kHandshakeConfirm, /* 已发 confirm,等 [BA C0] */
kErase, /* 已发 size,等擦除完成 ACK */
kTransfer, /* 逐包传输中 */
kFinishOta, /* 收到 0xF0F0F0F0,已发 [0A AC],等 FINISH ACK */
kFinished, /* 完成 */
kError, /* 错误 */
kPreCancel = 9 /* 等待电机 BOOT 心跳(0x103)确认已进入 Bootloader,然后进 kHandshakeReq */
};
struct Status {
State state;
uint8_t error_code;
uint16_t packets_acked;
uint16_t total_packets;
uint32_t fw_size;
};
/* 初始化(注册 CAN RX 回调等) */
void init();
/* 主循环推进(从 task_runner 周期调用,建议 1~5ms 一次) */
void process();
/* 数据发送推进:由主循环 TaskRunner 每圈调用,按 SysTick 钟表控制每包间隔
* (不再走 ISR 计时 + TASK 标志,消除跨上下文计数器竞争)。 */
void onTxTick();
/* CAN RX 分发入口:匹配 0x102 ACK 帧时消费,返回 true 表示已处理 */
bool onCanFrame(uint8_t channel, uint32_t id, const uint8_t *data, uint8_t len);
/* SPI 命令接口 */
bool start(uint8_t can_channel, uint32_t fw_size);
/**
* @brief 喂入固件明文。payload 布局:[offset:u32 LE][data...]
* offset 为固件绝对字节偏移;重复/重叠区间幂等 ACK,缺口拒绝(→SPI WAIT)。
* 无 offset 的旧纯流会在 SPI 超时重传时把同一 chunk 追加进环缓(BLF 见前 236B 循环)。
*/
bool feedData(const uint8_t *data, uint16_t len);
void cancel();
/* 状态查询 */
Status getStatus();
bool isActive();
} /* namespace MotorOtaRelay */
#endif /* SYS_MOTOR_OTA_RELAY_H */