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 两种板型均编译通过
This commit is contained in:
@@ -331,6 +331,15 @@ constexpr u8 CONFIG_SAVED_NUM = 6;
|
||||
constexpr u16 CANFD_STATUS_ID = 0x0100; // 状态反馈基础 ID
|
||||
constexpr u16 CANFD_CONFIG_ID = 0x0101; // 配置信息基础 ID
|
||||
constexpr u16 CANFD_VERSION_ID = 0x00FF; // 版本信息基础 ID
|
||||
// 周期反馈帧刷新周期(单位 ms,基于 1ms CAN 任务节拍分频;0=停发),
|
||||
// 可通过 SET_NODE_ID(0x0400) 扩展格式运行时修改并持久化,
|
||||
// 未配置时使用以下默认值(CONFIG 帧内容为控制模式/目标设定回显,
|
||||
// 不实时依赖,默认 250Hz 降低总线占用)
|
||||
constexpr u16 CANFD_TX_PERIOD_STATUS_DEFAULT_MS = 1; // STATUS 帧默认 1kHz
|
||||
constexpr u16 CANFD_TX_PERIOD_CONFIG_DEFAULT_MS = 4; // CONFIG 帧默认 250Hz
|
||||
// 0x0400/0x0401 扩展格式(DLC>=2/4)的参数选择器:0x0000=节点 ID,
|
||||
// 其余选择器直接使用目标反馈帧的基础 ID(如 0x0100/0x0101)
|
||||
constexpr u16 CANFD_PARAM_NODE_ID = 0x0000;
|
||||
// 命令基础 ID
|
||||
constexpr u16 CANFD_CMD_ID = 0x0200; // 控制命令基础 ID
|
||||
constexpr u16 CANFD_RESET_ID = 0x0301; // 重置命令基础 ID
|
||||
|
||||
+50
-2
@@ -83,6 +83,18 @@ u8 FlashEEPROM::init() {
|
||||
}
|
||||
KTH7823.set_calibration(calib);
|
||||
|
||||
// 加载周期反馈帧刷新率(独立 u16 记录,无记录/读取失败回退默认值,
|
||||
// 不影响 EEPROMStatus 的 CRC 参数组判定)
|
||||
u16 tx_period = 0;
|
||||
tx_period_status_ms =
|
||||
(read(ADDR_TX_PERIOD_STATUS, &tx_period) == FLASH_EEPROM_OK)
|
||||
? tx_period
|
||||
: CANFD_TX_PERIOD_STATUS_DEFAULT_MS;
|
||||
tx_period_config_ms =
|
||||
(read(ADDR_TX_PERIOD_CONFIG, &tx_period) == FLASH_EEPROM_OK)
|
||||
? tx_period
|
||||
: CANFD_TX_PERIOD_CONFIG_DEFAULT_MS;
|
||||
|
||||
if (EEPROMStatus == FLASH_EEPROM_OK) {
|
||||
return FLASH_EEPROM_OK;
|
||||
} else {
|
||||
@@ -189,8 +201,9 @@ FlashEepromStatus FlashEEPROM::read(u8 virtualAddr, u16 *data) const {
|
||||
// 检查是否是有效数据(非擦除状态)
|
||||
if (data_word != 0xFFFFFFFF) {
|
||||
u8 addr = (u8)(data_word & DATA_ADDR_MASK);
|
||||
// 找到匹配的虚拟地址
|
||||
if (addr == virtualAddr) {
|
||||
// u16 记录保留字节恒为 0(write() 写入格式 [data:16][rsvd:8][addr:8]),
|
||||
// 借此排除 EEPROM 头部区 CRC 字(低 8 位恰为虚拟地址)的误匹配
|
||||
if (addr == virtualAddr && (data_word & 0x0000FF00) == 0) {
|
||||
// 右移 16 位以提取高 16 位的 u16 数据
|
||||
*data = (u16)((data_word & DATA_U16_MASK) >> 16);
|
||||
EEP_DEBUG_PRINT("read u16: addr=0x%x, val=%d\r\n", address, *data);
|
||||
@@ -487,10 +500,45 @@ FlashEepromStatus FlashEEPROM::save_system_config(bool saved) {
|
||||
CRC_NUM = crc_block_data_calculate(crc_data_words, CONFIG_SAVED_NUM);
|
||||
writeCRC(CRC_NUM, saved);
|
||||
|
||||
// 周期反馈帧刷新率(独立记录,非 CRC 组):从 RAM 副本追加写入。
|
||||
// 放在 CRC 组保存之后,写入失败不影响参数组状态(下次上电回退默认值);
|
||||
// 页满 format() 重建时也经此路径从 RAM 副本恢复,刷新率配置不丢失
|
||||
status = write(ADDR_TX_PERIOD_STATUS, tx_period_status_ms);
|
||||
if (status != FLASH_EEPROM_OK) {
|
||||
EEP_DEBUG_PRINT("save tx period STATUS failed (%d)\r\n", status);
|
||||
}
|
||||
status = write(ADDR_TX_PERIOD_CONFIG, tx_period_config_ms);
|
||||
if (status != FLASH_EEPROM_OK) {
|
||||
EEP_DEBUG_PRINT("save tx period CONFIG failed (%d)\r\n", status);
|
||||
}
|
||||
|
||||
EEPROMStatus = FLASH_EEPROM_OK;
|
||||
return FLASH_EEPROM_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将 RAM 副本中的两帧刷新周期写入 Flash
|
||||
* @note 独立 u16 记录(非 CRC 参数组),值不变时 write() 自动跳过以减少
|
||||
* 磨损。运行时 SET 命令修改 RAM 副本后调用本函数持久化;若触发
|
||||
* 页满 format() 重建,save_system_config() 会从 RAM 副本重写这两
|
||||
* 条记录,本次修改不会丢失。
|
||||
* @return FlashEepromStatus 操作状态
|
||||
*/
|
||||
FlashEepromStatus FlashEEPROM::write_tx_periods() {
|
||||
FlashEepromStatus status = write(ADDR_TX_PERIOD_STATUS, tx_period_status_ms);
|
||||
if (status != FLASH_EEPROM_OK) {
|
||||
EEP_DEBUG_PRINT("write_tx_periods: STATUS period write failed (%d)\r\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
status = write(ADDR_TX_PERIOD_CONFIG, tx_period_config_ms);
|
||||
if (status != FLASH_EEPROM_OK) {
|
||||
EEP_DEBUG_PRINT("write_tx_periods: CONFIG period write failed (%d)\r\n",
|
||||
status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 保存电角度零位校准角到 Flash
|
||||
|
||||
@@ -57,9 +57,16 @@ class FlashEEPROM {
|
||||
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();
|
||||
|
||||
@@ -128,6 +135,14 @@ class FlashEEPROM {
|
||||
*/
|
||||
FlashEepromStatus save_calibration_angle(float angle);
|
||||
|
||||
// 周期反馈帧刷新率持久化(独立 u16 记录,不属于 CRC 参数组,
|
||||
// 读取失败/无记录由调用方回退默认值,避免老设备升级后 CRC 全组失效)
|
||||
/**
|
||||
* @brief 将 RAM 副本中的两帧刷新周期写入 Flash(值不变自动跳过)
|
||||
* @return FlashEepromStatus 操作状态
|
||||
*/
|
||||
FlashEepromStatus write_tx_periods();
|
||||
|
||||
// 节点 ID 独立读写函数(主/备双备份分属独立 Flash 页 + 魔数 + 计数器 + CRC)
|
||||
// 从 Flash 读取节点 ID(双备份均有效取计数器最新,单份有效则回退)
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user