Files
GD32_BOOT/Robot_V2/sys/flash.cpp
T
cbb 9c7145ef99 feat(ota): 实现安全OTA更新协议支持AES加密和CRC校验
- 添加AES128加密解密功能支持安全固件传输
- 实现基于随机数握手的安全会话密钥协商机制
- 集成CRC32带密钥校验确保数据完整性
- 重构OTA状态机支持握手、数据传输和验证流程
- 添加CANFD数据长度规范处理和安全跳转逻辑
- 移除调试打印语句优化性能

refactor(can): 优化CANFD发送和OTA确认处理逻辑

- 重构CANFD_AsyncSend函数支持规范数据长度
- 重命名sendACK为sendDATA_ACK并添加重载函数
- 修复数据长度处理和缓冲区填充逻辑
- 优化CAN消息发送的数据复制和验证流程
- 移除未使用的联合体类型定义

chore(project): 添加AES加密模块和系统初始化配置

- 在项目配置中添加AES128加密解密文件
- 在main.cpp中初始化CRC外设模块
- 添加安全十六进制打印调试函数
- 集成AES加密库到OTA处理流程中
- 优化系统时钟初始化配置
2026-01-01 01:39:19 +08:00

106 lines
2.7 KiB
C++

#include "flash.h"
#include "gd32c10x.h"
#include "gd32c10x_crc.h"
#include "gd32c10x_fmc.h"
#include "math.h"
#include <Can.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdint.h>
FlashEEPROM flashEEP = FlashEEPROM();
// FlashEEPROM类实现
FlashEEPROM::FlashEEPROM() {
// 构造函数可以为空,或者做一些初始化工作
}
/**
* @brief 初始化Flash EEPROM模拟
* @param None
* @retval None
*/
u8 FlashEEPROM::init() {
rcu_periph_clock_enable(RCU_CRC);
crc_deinit(); // 初始化CRC模块
return 0; // 正常不会返回这个,未预料的异常情况返回
}
/**
* @brief 格式化Flash EEPROM页面
* @param None
* @retval FlashEepromStatus: 操作状态
*/
FlashEepromStatus FlashEEPROM::format() {
fmc_state_enum fmc_status;
#if EEPDEBUG
printf("擦除页面\r\n");
#endif
fmc_unlock();
fmc_status = fmc_page_erase(EEPROM_START_ADDRESS); // 擦除第一页
if (fmc_status != FMC_READY) {
fmc_lock();
return FLASH_EEPROM_ERASE_ERROR;
}
fmc_status = fmc_page_erase(EEPROM_DATA_PAGE2_ADDRESS); // 擦除第二页
if (fmc_status != FMC_READY) {
fmc_lock();
return FLASH_EEPROM_ERASE_ERROR;
}
fmc_lock();
return FLASH_EEPROM_OK;
}
/**
* @brief 保存CRC数据到Flash
* @return FlashEepromStatus: 状态
*/
FlashEepromStatus FlashEEPROM::writeCRC(u32 CRC_NUM) {
static u32 next_address;
// 遍历Flash页面寻找下一个可写入crc的位置
for (u32 address = EEPROM_DATA_START_ADDRESS - SIZE_U32;
address > EEPROM_START_ADDRESS; address -= SIZE_U32) {
// 安全读取Flash数据
volatile u32 *flash_ptr = (volatile u32 *)address;
u32 data_word = *flash_ptr;
// 找到空位置
if (data_word == 0xFFFFFFFF) {
next_address = address;
break;
}
// 更新下一个可能的写入位置(如果需要格式化)
next_address = address - SIZE_U32;
}
// 如果当前CRC与现在的crc值不同,则写入
if (*((u32 *)next_address) != CRC_NUM) {
// 如果有足够空间,直接写入crc值
if (next_address > EEPROM_START_ADDRESS) {
fmc_unlock();
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
fmc_state_enum fmc_status = fmc_word_program(next_address, CRC_NUM);
fmc_lock();
#if EEPDEBUG
printf("CRC cmp1,0x%X_0x%x \r\n", CRC_NUM, *((u32 *)next_address));
#endif
// 检查写入是否成功
if (fmc_status != FMC_READY) {
EEPROMStatus = fmc_status;
return FLASH_EEPROM_WRITE_ERROR;
}
}
}
// 重新读取CRC校验
if (CRC_NUM == *((u32 *)next_address)) {
EEPROMStatus = FLASH_EEPROM_OK; // 设置EEPROM状态
return FLASH_EEPROM_OK;
} else {
EEPROMStatus = FLASH_EEPROM_CRC_ERROR; // 设置EEPROM错误状态
return FLASH_EEPROM_CRC_ERROR;
}
}