Files
ESP32_COMM/main/monitor/motor_ota_relay.h
T
小龙虾 2138a572ee feat(esp32): 添加多电机OTA中继功能并优化调试日志系统
- 新增多电机状态、版本和OTA中继监控模块(monitor/motor_state.cpp,
  monitor/motor_version.cpp, monitor/motor_ota_relay.cpp)
- 在CAN反馈任务中添加0xC5/0xC6/0xD2类型消息处理,支持多电机状态推送
- 重构调试日志系统,将一次性JSON分配改为512B栈缓冲流式发送,降低内存峰值
- 调试UART波特率从115200提升至30000
- 修改版本管理方式,从自动生version.h改为手动维护
- 更新VSCode设置以支持ESP-IDF开发环境配置
- 在OTA协调器中添加电机OTA互斥机制,防止并发冲突
- 完善中继状态机异常处理,添加远程取消通知机制
2026-07-26 20:40:16 +08:00

98 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.
/*
* motor_ota_relay.h - 电机 OTA relay ESP32 侧(固件缓冲 + SPI 喂数据 + 进度缓存)
*
* 两段式流程(与 BLE 刷 GD32 对齐,避免收固件期间与 GD32 按铃争抢单缓冲 MISO):
* 1. 前端 POST /motor/ota 上传固件 + channel → 流式写 gd32_ota flash 分区,写 meta
* 2. 前端 POST /motor/ota/relay?ch=X → motorOtaStart 发 SPI 0xD0(start) + 启动 feedTask
* 3. feedTask 从 flash 分块读,经 SPI 0xD1(data) 喂 GD32
* 4. GD32 通过 0xD2 ring push 报进度,ESP32 缓存
* 5. 前端 GET /motor/ota/status 轮询进度
*/
#ifndef MOTOR_OTA_RELAY_H
#define MOTOR_OTA_RELAY_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MOTOR_OTA_MAX_FW_SIZE 0xC000U /* 48 KB */
/* SPI payload 上限 236 = 256 - V2_OVERHEAD(20)。前 4B 为绝对 offset LE,数据最多 232B。
* 无 offset 时 SPI 超时重传会被 GD32 重复追加(BLF:前 236B 循环 → 刷坏)。 */
#define MOTOR_OTA_CHUNK_HDR 4U
#define MOTOR_OTA_CHUNK_DATA 232U
#define MOTOR_OTA_CHUNK_SIZE (MOTOR_OTA_CHUNK_HDR + MOTOR_OTA_CHUNK_DATA)
typedef enum {
MOTOR_OTA_IDLE = 0,
MOTOR_OTA_HANDSHAKE_REQ,
MOTOR_OTA_HANDSHAKE_NONCE,
MOTOR_OTA_HANDSHAKE_CONFIRM,
MOTOR_OTA_ERASE,
MOTOR_OTA_TRANSFER,
MOTOR_OTA_FINISH_OTA, /* 收到 0xF0F0F0F0,已发 FINISH_OTA,等跳转 ACK */
MOTOR_OTA_FINISHED,
MOTOR_OTA_ERROR,
MOTOR_OTA_PRE_CANCEL = 9 /* 握手前预取消:发 CANCEL 清理电机残留会话(GD32 侧过渡态) */
} motor_ota_state_t;
typedef struct {
motor_ota_state_t state;
uint8_t error_code;
uint16_t packets_acked;
uint16_t total_packets;
uint32_t fw_size;
uint16_t buf_used; /* GD32 侧缓冲占用 */
int64_t last_update_ms; /* ESP32 收到状态的时间 */
} motor_ota_status_t;
/**
* @brief 处理 GD32 0xD2 ring push(由 can_feedback_task 分发)。
*/
void onMotorOtaStatusPush(const uint8_t *payload, size_t len);
/**
* @brief 启动电机 OTA:发 SPI start + 启动喂数据 task。
*
* 固件须已由调用方(HTTP handler)流式写入 gd32_ota flash 分区
* (Gd32FlashStore::flashWriteChunk,offset 0 起)。喂数据 task 从
* flash 分块读取并经 SPI 0xD1 喂给 GD32,不在堆上缓冲整个固件
* (48KB 整块 malloc 会超出 ESP32-C3 的 largest_free_block,导致 OOM)。
*
* @param fw_size 固件大小 (≤48KB),须与已写入 flash 的大小一致
* @param channel CAN 通道 (0-2)
* @return 0 成功, -1 参数错误, -2 已在进行中, -3 SPI 失败
*/
int motorOtaStart(uint32_t fw_size, uint8_t channel);
/**
* @brief 电机 OTA 是否正在进行(喂数据 task 存活)。
* 供 OtaCoordinator 在 beginGd32Storage/beginEsp32Ota 中检查:
* 电机喂数期间禁止新的 GD32/ESP32 OTA,避免 gd32_ota 分区被并发覆写。
*/
bool motorOtaIsActive(void);
/**
* @brief 取消电机 OTA。
*/
void motorOtaCancel(void);
/**
* @brief 获取最新状态(线程安全)。
*/
motor_ota_status_t motorOtaGetStatus(void);
/**
* @brief 模块初始化(创建 mutex 等)。
*/
void motorOtaRelayInit(void);
#ifdef __cplusplus
}
#endif
#endif /* MOTOR_OTA_RELAY_H */