/*****************************************************************************
|
* @file BootMark.c
|
* @brief Boot标记管理模块实现
|
* @author AI Assistant
|
* @date 2025-12-21
|
*****************************************************************************/
|
|
#include "BootMark.h"
|
#include "MCUFlash.h"
|
#include "SoftCRC.h"
|
#include <string.h>
|
|
/*****************************************************************************
|
* 函数实现
|
*****************************************************************************/
|
|
/**
|
* @brief 初始化Boot标记模块
|
*/
|
int32_t BootMark_Init(void)
|
{
|
// 确保MCUFlash模块已初始化
|
return MCUFlash_Init();
|
}
|
|
/**
|
* @brief 计算Boot标记的CRC32
|
*/
|
uint32_t BootMark_CalculateCRC(const BootMark_t *pMark)
|
{
|
if (pMark == NULL) {
|
return 0;
|
}
|
|
// 计算前28字节的CRC(除u32BootMarkCRC字段)
|
// sizeof(BootMark_t) = 32, CRC field is last 4 bytes
|
return SoftCRC_Calculate((uint32_t *)pMark, (sizeof(BootMark_t) - 4) / 4);
|
}
|
|
/**
|
* @brief 读取Boot标记
|
*/
|
int32_t BootMark_Read(BootMark_t *pMark)
|
{
|
if (pMark == NULL) {
|
return BOOT_ERR_PARAM;
|
}
|
|
// 从Flash读取标记
|
memcpy(pMark, (const void *)BOOT_MARK_BASE_ADDR, sizeof(BootMark_t));
|
|
// 校验魔术字
|
if (pMark->u32Magic != BOOT_MARK_MAGIC) {
|
return BOOT_ERR_MAGIC;
|
}
|
|
// 校验CRC
|
uint32_t calcCRC = BootMark_CalculateCRC(pMark);
|
if (calcCRC != pMark->u32BootMarkCRC) {
|
return BOOT_ERR_CRC;
|
}
|
|
return BOOT_OK;
|
}
|
|
/**
|
* @brief 写入Boot标记(请求更新)
|
*/
|
int32_t BootMark_Write(const BootMark_t *pMark)
|
{
|
int32_t ret;
|
BootMark_t markCopy;
|
|
if (pMark == NULL) {
|
return BOOT_ERR_PARAM;
|
}
|
|
// 复制标记并计算CRC
|
memcpy(&markCopy, pMark, sizeof(BootMark_t));
|
markCopy.u32Magic = BOOT_MARK_MAGIC;
|
markCopy.u32BootMarkCRC = BootMark_CalculateCRC(&markCopy);
|
|
// 擦除对应的Flash扇区(128KB)
|
ret = MCUFlash_Erase(BOOT_MARK_BASE_ADDR, 128 * 1024);
|
if (ret != 0) {
|
return BOOT_ERR_FLASH;
|
}
|
|
// 写入标记(32字节对齐)
|
ret = MCUFlash_Write(BOOT_MARK_BASE_ADDR, (const uint8_t *)&markCopy, sizeof(BootMark_t));
|
if (ret != 0) {
|
return BOOT_ERR_FLASH;
|
}
|
|
return BOOT_OK;
|
}
|
|
/**
|
* @brief 清除Boot标记(更新完成或取消)
|
*/
|
int32_t BootMark_Clear(void)
|
{
|
// 擦除整个128KB参数区
|
int32_t ret = MCUFlash_Erase(BOOT_MARK_BASE_ADDR, 128 * 1024);
|
if (ret != 0) {
|
return BOOT_ERR_FLASH;
|
}
|
return BOOT_OK;
|
}
|
|
/**
|
* @brief 验证暂存区固件完整性
|
*/
|
int32_t BootMark_VerifyStaging(const BootMark_t *pMark)
|
{
|
uint32_t calcCRC;
|
uint32_t wordCount;
|
|
if (pMark == NULL) {
|
return BOOT_ERR_PARAM;
|
}
|
|
// 检查地址和大小
|
if (pMark->u32SrcAddress != BOOT_OTA_STAGING_ADDR) {
|
return BOOT_ERR_PARAM;
|
}
|
|
if (pMark->u32FirmwareSize == 0 || pMark->u32FirmwareSize > BOOT_APP_MAX_SIZE) {
|
return BOOT_ERR_PARAM;
|
}
|
|
// 计算固件的CRC32(需要按32位字计算)
|
wordCount = (pMark->u32FirmwareSize + 3) / 4; // 向上取整
|
calcCRC = SoftCRC_Calculate((uint32_t *)pMark->u32SrcAddress, wordCount);
|
|
// 比较CRC
|
if (calcCRC != pMark->u32FirmwareCRC) {
|
return BOOT_ERR_CRC;
|
}
|
|
return BOOT_OK;
|
}
|