yincheng.zhong
2 天以前 2aae41035e511f47b7c434ee97f327baf6e1baf3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*****************************************************************************
* @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;
}