Files
Motor_v2/Robot_V2/sys/flash.h
T
cbb 40fea328b0 feat(can): 反馈报文刷新率逐帧可配置并持久化
STATUS/CONFIG 反馈帧各自独立按 period_ms(1ms 节拍分频,0=停发)发送,
默认 STATUS 1kHz、CONFIG 250Hz,可运行时修改:

- 0x0400 扩展格式(DLC=4):[选择器 u16][值 u16],选择器 0x0000=节点 ID
  (仅单播),0x0100/0x0101=对应帧刷新周期;回 5B ACK,广播只应用不应答
- 0x0401 扩展格式(DLC=2):查询选择器对应值,回 [sel][val](4B);
  DLC<=1 及 SET DLC 1~2 保持旧格式行为完全不变
- 刷新率经 FlashEEPROM 独立 u16 记录(虚拟地址 0x08/0x09)持久化,
  不并入 6 参数 CRC 组,避免老设备升级后整组参数回退默认值
- save_system_config 追加从 RAM 副本回写两条记录,页满 format()
  重建后配置不丢失;read() 增加保留字节校验防 CRC 头部字误匹配
- CANFD_all_Send 拆分为 send_status_frame/send_config_frame,
  初始化失败上报路径直调 STATUS 帧不受分频影响

GATE_DRIVER_DRV8323 0/1 两种板型均编译通过
2026-09-12 19:00:06 +08:00

197 lines
6.3 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 sys/flash.h
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
*/
#ifndef __FLASH_H
#define __FLASH_H
#include "config.h"
#include "gd32c10x.h" // 添加GD32主头文件以确保外设函数声明可用
#include <cstdint>
// 修改后 - 强制4字节对齐
/** @brief ALIGN_4BYTE 宏定义 */
#define ALIGN_4BYTE(addr) ((addr) & 0xFFFFFFFC) // 4字节对齐
// EEPROM操作状态
/**
* @brief 匿名枚举 枚举定义
*/
typedef enum {
FLASH_EEPROM_OK = 0, // 操作成功
FLASH_EEPROM_WRITE_ERROR, // 写入错误
FLASH_EEPROM_READ_ERROR, // 读取错误
FLASH_EEPROM_ERASE_ERROR, // 擦除错误
FLASH_EEPROM_INVALID_ADDR, // 无效地址
FLASH_EEPROM_DATA_NOT_FOUND, // 找不到数据
FLASH_EEPROM_CRC_ERROR, // CRC错误
FLASH_EEPROM_ALIGNMENT_ERROR, // 对齐错误
} FlashEepromStatus;
// Flash EEPROM类
/**
* @brief FlashEEPROM 类或结构体
*/
class FlashEEPROM {
public:
// EEPROM emulation constants
static constexpr u32 EEPROM_START_ADDRESS = 0x0801F800; // 第一页(1KB)
static constexpr u32 EEPROM_DATA_PAGE2_ADDRESS = 0x0801FC00; // 第二页(1KB)
static constexpr u32 EEPROM_END_ADDRESS = 0x08020000; // Flash结束地址
static constexpr u32 EEPROM_MAX_SIZE = 0x800; // EEPROM最大容量
static constexpr u32 EEPROM_DATA_START_ADDRESS =
0x0801F900; // DATA段开始地址
static constexpr u32 DATA_FLOAT_MASK = 0xFFFFFF00; // float存储地址掩码
static constexpr u32 DATA_U16_MASK = 0xFFFF0000; // u16存储地址掩码
static constexpr u32 DATA_ADDR_MASK = 0x000000FF; // 虚拟地址掩码
// 定义用户自定义的虚拟地址
static constexpr u8 ADDR_CONTROL_MODE = 0x0; // 控制模式
static constexpr u8 ADDR_ANGLE = 0x01; // 角度数据存储地址
static constexpr u8 ADDR_TARGET_ANGLE = 0x02; // 角度命令数据存储地址
static constexpr u8 ADDR_TARGET_VEL = 0x03; // 速度命令数据存储地址
static constexpr u8 ADDR_VOLTAGE_LIMIT = 0x4; // 电压限制
static constexpr u8 ADDR_VEL_LIMIT = 0x05; // 角度数据存储地址
static constexpr u8 ADDR_NODE_ID = 0x06; // 节点 ID 存储地址
static constexpr u8 ADDR_CALIBRATION_ANGLE = 0x07; // 电角度零位校准角存储地址
static constexpr u8 ADDR_TX_PERIOD_STATUS = 0x08; // STATUS 帧刷新周期(ms)存储地址
static constexpr u8 ADDR_TX_PERIOD_CONFIG = 0x09; // CONFIG 帧刷新周期(ms)存储地址
bool system_config_saved = false;
u8 EEPROMStatus;
// 周期反馈帧刷新周期 RAM 副本(ms,0=停发)。init() 从 Flash 加载,
// 无记录时回退 config.h 默认值;CAN_transmiter::init() 读取应用,
// SET 命令修改后经 write_tx_periods() 持久化
u16 tx_period_status_ms = CANFD_TX_PERIOD_STATUS_DEFAULT_MS;
u16 tx_period_config_ms = CANFD_TX_PERIOD_CONFIG_DEFAULT_MS;
// 构造函数
FlashEEPROM();
// 初始化Flash EEPROM模拟
/**
* @brief 初始化对象或模块
* @return u8 返回值
*/
u8 init();
// 从Flash EEPROM中读取数据
/**
* @brief 读取数据
* @param[in] virtualAddr 参数
* @param[in] data 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus read(u8 virtualAddr, u16 *data) const;
// 向Flash EEPROM写入数据
/**
* @brief 写入数据
* @param[in] virtualAddr 参数
* @param[in] data 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus write(u8 virtualAddr, u16 data);
// Float数据读相关函数
/**
* @brief 从 Flash EEPROM 读取浮点数据
* @param[in] virtualAddr 参数
* @param[in] data 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus readFloat(u8 virtualAddr, float *data) const;
// Float数据存储相关函数
/**
* @brief 向 Flash EEPROM 写入浮点数据
* @param[in] virtualAddr 参数
* @param[in] data 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus writeFloat(u8 virtualAddr, float data);
// 格式化Flash EEPROM页面
/**
* @brief 格式化存储区域
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus format();
/**
* @brief 保存系统配置参数
* @param[in] saved 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus save_system_config(bool saved);
/**
* @brief 读取已保存的系统配置参数
* @return u8 返回值
*/
u8 read_saved_system_config(void);
/**
* @brief 保存电角度零位校准角到 Flash
* @param[in] angle 校准角(度)
* @return FlashEepromStatus 操作状态
*/
FlashEepromStatus save_calibration_angle(float angle);
// 周期反馈帧刷新率持久化(独立 u16 记录,不属于 CRC 参数组,
// 读取失败/无记录由调用方回退默认值,避免老设备升级后 CRC 全组失效)
/**
* @brief 将 RAM 副本中的两帧刷新周期写入 Flash(值不变自动跳过)
* @return FlashEepromStatus 操作状态
*/
FlashEepromStatus write_tx_periods();
// 节点 ID 独立读写函数(主/备双备份分属独立 Flash 页 + 魔数 + 计数器 + CRC)
// 从 Flash 读取节点 ID(双备份均有效取计数器最新,单份有效则回退)
/**
* @brief 读取节点 ID 配置
* @param[in] node_id 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus readNodeId(u16 *node_id) const;
// 保存节点 ID 到 Flash(乒乓写入非最新页,另一页保有旧值,掉电安全)
/**
* @brief 写入节点 ID 配置
* @param[in] node_id 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus writeNodeId(u16 node_id);
// 擦除节点 ID 双备份存储页(恢复默认值)
/**
* @brief 擦除节点 ID 配置
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus eraseNodeId();
private:
/**
* @brief 写入 writeCRC 相关数据
* @param[in] CRC_NUM 参数
* @param[in] saved 参数
* @return FlashEepromStatus 返回值
*/
FlashEepromStatus writeCRC(u32 CRC_NUM, bool saved);
};
/**
* @brief flash_eeprom_example_main 函数
* @return void
*/
void flash_eeprom_example_main(void);
u8 OTA_SET(u32 addr, u32 data);
/**
* @brief move_app_data 函数
* @return fmc_state_enum 返回值
*/
fmc_state_enum move_app_data(void);
/**
* @brief 写入 write_ADDRESS 相关数据
* @param[in] address 参数
* @param[in] data 参数
* @return fmc_state_enum 返回值
*/
fmc_state_enum write_ADDRESS(u32 address, u32 data);
#endif /* __FLASH_H */