Files
cbb 5fd986299c feat(comm): 1.6.51 CAN 空通道自动静默 + PDO 诊断 + OTA 布局共用头
变更点:
1. CAN-FD(device/CANFD.cpp、sys/config.h)
   - 发送统一 FD+BRS(DLC≤8 不再回退经典 CAN);OTA 期仍按通道压制 BRS
   - 空通道自动识别:连续 5 个 1Hz 窗口无有效帧且有错误 → 静默上报;有帧即恢复
   - 三路 CAN 默认全开;RX parse budget 48→64
2. EtherCAT 桥 / PDO
   - 段1 增 txtxid/rx00ff;版本应答 0x00FF 粘滞发布,避免被 CONFIG 冲掉
   - STATUS 禁止写入 xrx 快照;processSeq 新鲜度救援
3. OTA / 配置
   - sys/config.h include 仓库内 shared/ota_layout.h(与 BOOT 共用,不再依赖仓外路径)
   - ota_boot_request 对齐配置页 word 布局
4. docs/audit_ecat_spi_wifi_ota_compatibility.md:ECAT/SPI/WiFi/OTA 兼容性审计
5. .gitignore:忽略 .trae/、docs/traework-import、评审过程稿
2026-09-20 22:58:09 +08:00

100 lines
3.8 KiB
C++
Raw Permalink 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.
#ifndef SYS_OTA_BOOT_REQUEST_H
#define SYS_OTA_BOOT_REQUEST_H
#include <stdint.h>
/**
* @brief BOOT 版本号结构体(从 Flash OTA 配置页读取)。
*
* Flash 字布局(与 BOOT 工程 sys/config.h 对称):
* word6 (ADDR0): [15:0]=major [31:16]=minor
* word7 (ADDR1): [15:0]=patch [31:16]=build
*/
struct BootVersion {
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t build;
};
/**
* @brief DCU_APP 进入 Bootloader OTA 窗口控制模块。
* @note ESP32 通过 CAN-FD 发送受保护命令,APP 写 OTA 标志后软复位,
* Bootloader 下次启动会停留在 OTA 等待窗口。
*/
class OtaBootRequest {
public:
/** @brief 初始化内部状态。 */
static void init();
/**
* @brief 从 OTA 配置页 Flash 读取 BOOT 版本号。
*
* BOOT 启动时将自身版本写入 0x0807E018/0x0807E01C,
* APP 运行期通过本函数读出,用于 SPI PING 响应、日志等场景。
*
* @return BootVersion 结构体,字段已按 Flash 字布局拆包。
*
* @note 若 Flash 未写入(擦除态 0xFFFFFFFF),返回值各字段为 0xFF,
* 调用方可据此判断 BOOT 版本是否有效。
*/
static BootVersion readBootVersion();
/**
* @brief 清零 BOOT 侧连续 FWDGT 崩溃计数(配置页 word9)。
* @note 不要在 init 里立刻调用;见 maybeClearCrashCount()。
*/
static bool clearCrashCount();
/**
* @brief APP 持续喂狗满 CONFIG_CRASH_CLEAR_AFTER_SEC 后清一次崩溃计数。
* @param[in] uptime_sec 当前 APP 运行秒数(g_app_uptime_sec)。
* @note 挂在主循环;init 未走完或 30s 内崩溃时计数保留,BOOT 才能攒到阈值。
*/
static void maybeClearCrashCount(uint32_t uptime_sec);
/**
* @brief 尝试处理一帧 CAN 接收报文。
* @param[in] channel 报文来源 CAN 通道。
* @param[in] id 报文 ID。
* @param[in] data 报文负载。
* @param[in] length 报文负载长度。
* @retval true 该报文已被 OTA/BOOT 控制模块消费。
* @retval false 该报文不是 OTA/BOOT 控制报文。
*/
static bool handleCanFrame(uint8_t channel, uint32_t id, const uint8_t *data, uint8_t length);
/**
* @brief 设置 Bootloader OTA 等待标志并安排软复位。
* @retval true 标志写入成功,稍后会复位进入 Bootloader。
* @retval false Flash 标志写入失败。
* @note 此函数会执行 Flash 操作(可能擦页 20-30ms),不可在 ISR 内调用。
*/
static bool requestEnterBoot();
/**
* @brief 异步请求进入 Bootloader(ISR 安全)。
* @note 仅设置 pending 标志,Flash 操作和复位由 process() 在主循环执行。
* 用于 SPI EXTI ISR 内的 0xB0 命令处理,避免 Flash 擦除阻塞 SPI 中断。
*/
static void requestEnterBootAsync();
/** @brief 若已确认进入 BOOT 请求,则延迟片刻后复位。 */
static void process();
/** @brief 查询是否已进入“即将进 BOOT”路径(异步 pending 或已写标志待复位)。
* 供 CAN 按铃等模块在复位前停止干扰 SPI 的操作。 */
static bool isRebootPending() { return s_rebootPending || s_bootRequestPending; }
/** @brief SPI 命令路径查询:true 时忽略业务帧,仅释放 ready。 */
static bool isSpiFrozenForBoot() { return s_spiFrozenForBoot; }
private:
static volatile bool s_rebootPending;
static volatile bool s_bootRequestPending; ///< 0xB0 异步请求标志,process() 中执行 Flash 操作
/** 写 OTA 配置页期间冻结 SPI 业务,避免 Flash 擦写与 SPI ISR 互踩。 */
static volatile bool s_spiFrozenForBoot;
};
#endif /* SYS_OTA_BOOT_REQUEST_H */