feat(can): 添加节点ID设置命令的安全防护和改进闪存写入逻辑

- 添加目标节点验证机制,防止SET_NODE_ID命令被错误处理
- 修改节点ID范围验证逻辑,限制为1到0xFF
- 调整闪存写入顺序,在确认写入成功后再发送响应
- 修复SET_NODE_ID消息处理中的边界条件检查

fix(can): 启用自动总线离线恢复功能

- 将CAN参数auto_bus_off_recovery从DISABLE改为ENABLE
- 提高CAN通信的稳定性和自动恢复能力

chore(config): 更新软件版本号并添加编译时间信息

- 将软件补丁版本从24更新到25
- 添加APP_BUILD_DATE和APP_BUILD_TIME宏定义
- 新增getAppBuildTime函数获取编译时间信息
- 添加Flash页大小相关注释说明

perf(debug): 调整ST-Link调试器时钟频率

- 将调试器时钟从10MHz降低到4MHz
- 提高调试连接的稳定性

refactor(static_test): 移除静态测试文件列表

- 删除static_test_automotive_business_20260523/files.csv文件内容
This commit is contained in:
cbb
2026-08-13 01:14:07 +08:00
parent b71fba2016
commit 42c9f2f669
15 changed files with 37 additions and 8050 deletions
+14 -9
View File
@@ -418,7 +418,7 @@ void canfd_config(void) {
/* initialize CAN */
can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = DISABLE;
can_parameter.auto_bus_off_recovery = ENABLE;
can_parameter.auto_wake_up = DISABLE;
can_parameter.auto_retrans = ENABLE;
can_parameter.rec_fifo_overwrite = ENABLE;
@@ -1155,6 +1155,12 @@ void CAN_transmiter::handle_boot_message(u16 sender_node_id) {
}
void CAN_transmiter::handle_set_node_id_message(can_receive_message_struct &current_message) {
// ── 防护:只处理发给本节点(或广播)的 SET_NODE_ID ──
u16 target_node = (u16)((current_message.rx_efid >> 16) & 0xFFFF);
if (target_node != node_id && target_node != BROADCAST_NODE_ID) {
return;
}
// 支持 1 字节和 2 字节节点 ID 命令,兼容旧上位机。
CAN_DEBUG_PRINT(
"SET_NODE_ID: rx_dlen=%d, data[0]=%02X data[1]=%02X\r\n",
@@ -1173,23 +1179,22 @@ void CAN_transmiter::handle_set_node_id_message(can_receive_message_struct &curr
// 响应帧使用旧节点 ID 构造,确保上位机能收到确认。
node_id = old_node_id;
if (new_node_id > MAX_NODE_ID || new_node_id == BROADCAST_NODE_ID) {
CAN_DEBUG_PRINT("SET_NODE_ID: invalid new_id=%d (max=%d)\r\n",
new_node_id, MAX_NODE_ID);
if (new_node_id < 1 || new_node_id > SETTABLE_NODE_ID_MAX) {
CAN_DEBUG_PRINT("SET_NODE_ID: invalid new_id=%d (range 1~%d)\r\n",
new_node_id, SETTABLE_NODE_ID_MAX);
transmit_data[0] = 0x00;
CANFD_AsyncSend(build_can_id(CANFD_SET_NODE_ID), 3, transmit_data);
return;
}
transmit_data[0] = 0x01;
u8 send_result = CANFD_AsyncSend(build_can_id(CANFD_SET_NODE_ID), 3,
transmit_data);
// 先写 Flash,成功后再回确认,避免 Flash 失败时上位机已收到 OK。
u8 save_status = save_node_id_to_flash(new_node_id);
CAN_DEBUG_PRINT("SET_NODE_ID: save_status=%d, send_result=%d\r\n",
save_status, send_result);
CAN_DEBUG_PRINT("SET_NODE_ID: save_status=%d\r\n", save_status);
if (save_status == FLASH_EEPROM_OK) {
transmit_data[0] = 0x01;
CANFD_AsyncSend(build_can_id(CANFD_SET_NODE_ID), 3, transmit_data);
CAN_DEBUG_PRINT("SET_NODE_ID: SUCCESS, node_id updated from %d to %d\r\n",
old_node_id, new_node_id);
return;
+11 -2
View File
@@ -1,4 +1,4 @@
/**
/**
* @file sys/config.h
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
@@ -23,7 +23,7 @@
// 版本号定义 - 可根据实际项目进行调整
constexpr u16 SOFTWARE_VERSION_MAJOR = 26;
constexpr u16 SOFTWARE_VERSION_MINOR = 5;
constexpr u16 SOFTWARE_VERSION_PATCH = 24;
constexpr u16 SOFTWARE_VERSION_PATCH = 25;
constexpr u16 SOFTWARE_VERSION_BUILD = 2;
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
@@ -35,6 +35,9 @@ constexpr u16 BOOT_VERSION_MAJOR = 26;
constexpr u16 BOOT_VERSION_MINOR = 1;
constexpr u16 BOOT_VERSION_PATCH = 12;
constexpr u16 BOOT_VERSION_BUILD = 0;
// 编译时间(AC6 编译器自动生成)
#define APP_BUILD_DATE __DATE__
#define APP_BUILD_TIME __TIME__
// Flash 分区配置
constexpr u32 BOOTLOADER_SIZE = 0x6000; // 24KB
@@ -65,6 +68,7 @@ constexpr u32 NODE_ID_MAGIC = 0x4E4F4445; // 魔数 'NODE' 用于验证数据
constexpr u16 DEFAULT_NODE_ID = 1; // 默认节点 ID
constexpr u16 BROADCAST_NODE_ID = 0x1FFF; // 广播 ID (所有节点响应)
constexpr u16 MAX_NODE_ID = 0x1FFE; // 最大有效节点 ID (0~0x1FFE)
constexpr u16 SETTABLE_NODE_ID_MAX = 0x00FF; // SET_NODE_ID 命令允许设置的上限 (1~0xFF)
// 节点 ID 存储结构 (存储在Flash中的格式)
// 地址偏移 0x00: 魔数 (0x4E4F4445 = 'NODE')
@@ -79,6 +83,10 @@ constexpr u8 NODE_ID_COUNTER_OFFSET = 0x08; // 写入计数器偏移
constexpr u8 NODE_ID_CRC_OFFSET = 0x0C; // CRC偏移
// BOOT 相关
// 版图/页大小核验:以下 6 个 OTA 标志位共处 0x0801E000 所在的 1KB Flash 页。
// OTA_SET 会整页擦除该页,故必须保证 FMC 页大小为 1KB(0x400),否则会连带擦除
// 相邻的 SLEEP_CONFIG(0x0801E400)/NODE_ID(0x0801E800)。GD32C103CB 实测页大小为
// 1KB(睡眠/节点 ID/EEPROM 分居相邻 1KB 页且互不影响即为佐证),与 FMC_PAGE_SIZE 一致。
constexpr u32 OTA_CONFIG_NUM = 6;
constexpr u32 n_APP_LATEST_AVAL_ADDR = 0x0801E000; // 最新 APP 可用地址
constexpr u32 n_APP_BACKUP_AVAL_ADDR = 0x0801E004; // 备份 APP 可用地址
@@ -290,3 +298,4 @@ constexpr float VBUS_RECOVERY_RATIO = 0.9f; // 恢复比例(基准电压
#endif
+6 -2
View File
@@ -1,4 +1,4 @@
/**
/**
* @file sys/initial.cpp
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
@@ -231,6 +231,10 @@ void VersionManager::printVersions() const {
versionToString(getBootVersion(), versionStr, sizeof(versionStr)));
}
const char* VersionManager::getAppBuildTime() const {
return APP_BUILD_DATE " " APP_BUILD_TIME;
}
/* retarget the C library printf function to the USART */
/**
* @brief 初始化 USART0 调试串口
@@ -383,4 +387,4 @@ void OTA_initial(void) {
} else {
EEP_DEBUG_PRINT("check\r\n");
}
}
}
+5 -2
View File
@@ -1,4 +1,4 @@
/**
/**
* @file sys/initial.h
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
@@ -155,6 +155,9 @@ class VersionManager {
char *versionToString(const VersionInfo &version, char *buffer,
size_t bufSize) const;
// 获取编译时间
const char* getAppBuildTime() const;
// 打印所有版本信息
/**
* @brief printVersions 函数
@@ -179,4 +182,4 @@ class VersionManager {
}
#endif
#endif
#endif