#include "firmware.h" static uint8_t _fw_start_write_flag; /* 固件开始写入的标志位 */ static uint16_t _update_progress; /* 固件更新的进度, 10000 制 */ static uint16_t _update_progress_step_num; /* 固件更新进度的步进单位 */ static uint16_t _storage_data_size; /* 固件包写入时记录暂存的固件分包大小,单位 byte */ static uint32_t _write_part_addr; /* 固件包写入时记录写入 flash 的相对地址 */ static uint16_t _write_last_pkg_size; /* 固件包写入时最后一个分包的大小,单位 byte */ static uint8_t _fw_first_bytes[CONFIG_WRITE_BYTES_LEASET]; /* 固件包的前几个字节 */ static uint8_t _upk_min_handle_buff[UPK_LEAST_HANDLE_BYTE]; /* upk 固件最小处理单位的缓存区,多次使用以降低系统资源开销 */ static struct upk_head_t upkHdr; /* 用于存放 upk 固件包头 */ #if (CONFIG_DECRYPT) static struct AES_ctx aesCtx; /* AES 对象 */ #endif static struct BSP_FLASH _flash_app_part; /* APP 分区 */ #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) static struct BSP_FLASH _flash_download_part; /* download 分区 */ #if (CONFIG_CHIP_PARTS == USE_TRIPLE_PARTITION) static struct BSP_FLASH _flash_factory_part; /* factory 分区 */ #endif #endif /* Extern function prototypes ------------------------------------------------*/ extern void Firmware_OperateCallback(uint16_t progress); /* Private function prototypes -----------------------------------------------*/ static eErrCode _Write_FirmwareSubPackage( const struct BSP_FLASH *part, uint8_t *data, uint16_t pkg_size, uint8_t decrypt, FM_FIRMWARE_WRITE_DIR write_dir); static void _Reset_Write(void); /* Exported functions ---------------------------------------------------------*/ /** * @brief 初始化接口 * @note * @retval None */ void FM_Init (void) { BSP_Flash_Init(&_flash_app_part, NAME_PART_APPLICATION, BASE_APPLICATION, SIZE_PART_APPLICATION); #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) BSP_Flash_Init(&_flash_download_part, NAME_PART_DOWNLOAD, BASE_DOWNLOAD, SIZE_PART_DOWNLOAD); #if (CONFIG_CHIP_PARTS > USE_DOUBLE_PARTITION) BSP_Flash_Init(&_flash_factory_part, NAME_PART_FACTORY, BASE_FACTORY, SIZE_PART_FACTORY); #endif #endif #if 0 printf("onchip size : 0x%lX\r\n", SIZE_ONCHIP_FLASH); printf("0x%08lX+0x%lX 'parameters'.\r\n", BASE_PARAMETERS, SIZE_PART_PARAMETERS); printf("0x%08X+0x%X 'app'.\r\n", _flash_app_part.addr, _flash_app_part.len); #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) printf("0x%08X+0x%X 'download'.\r\n", _flash_download_part.addr, _flash_app_part.len); #if (CONFIG_CHIP_PARTS > USE_DOUBLE_PARTITION) printf("0x%08X+0x%X 'factory'.\r\n", _flash_factory_part.addr, _flash_app_part.len); #endif #endif #endif #if (CONFIG_DECRYPT) AES_init_ctx_iv(&aesCtx, (uint8_t *)AES256_KEY, (uint8_t *)AES256_IV); #endif } /** * @brief 固件包是否有加密 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 0: 未加密。1: 有加密 */ inline uint8_t FM_IsEncrypt(void) { /* 读取加密选项 */ if (upkHdr.config[1] == 0x01) return 1; return 0; } /** * @brief 检测某个分区是否为空 * @note ERR_OK: 分区数据空 * @param[in] part_name: 分区名 * @retval eErrCode */ eErrCode FM_IsEmpty(const char *part_name) { int read_len = 0; uint16_t i = 0; uint16_t need_read_size = UPK_LEAST_HANDLE_BYTE; uint32_t *p_data = (uint32_t *)_upk_min_handle_buff; uint32_t read_posit = 0; ASSERT(part_name != NULL); const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: '%s' not found.\r\n", __func__, part_name); return ERR_NO_THIS_PART; } for (read_posit = 0; read_posit < part->len; ) { if ((part->len - read_posit) < UPK_LEAST_HANDLE_BYTE) { need_read_size = part->len - read_posit; } read_len = BSP_Flash_Read(part, read_posit, _upk_min_handle_buff, need_read_size); if (read_len < 0) { printf("%s: read error (%d).\r\n", __func__, __LINE__); return ERR_READ_IS_EMPTY_ERR; } for (i = 0; i < (UPK_LEAST_HANDLE_BYTE / sizeof(p_data)); i++) { if (p_data[i] != 0xFFFFFFFF) { printf("part '%s' not empty.\r\n", part_name); return ERR_FLASH_NO_EMPTY; } } read_posit += read_len; } //printf("%s: '%s' part empty.\r\n", __func__, part_name); return ERR_OK; } /** * @brief 获取固件包的固件版本 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 固件新版本 */ inline char * FM_GetNewFirmwareVersion(void) { return upkHdr.fw_new_ver; } /** * @brief 获取源固件的 CRC32 值 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 源固件的 CRC32 值 */ inline uint32_t FM_GetRawCRC32(void) { return upkHdr.raw_crc; } /** * @brief 暂存固件包头 * @note 会同时校验固件包头 * @param[in] part_name: 分区名 * @param[in] data: 数据 * @retval eErrCode */ eErrCode FM_StorageFirmwareHead(const char *part_name, uint8_t *data) { uint32_t head_crc = 0xFFFFFFFF; uint8_t *pHdr = (uint8_t *)&upkHdr; ASSERT(part_name != NULL); ASSERT(data != NULL); _Reset_Write(); memcpy(pHdr, data, UPK_HEAD_SIZE); #if (!CONFIG_DECRYPT) /* 若固件包加密,检查是否有解密组件 */ if (FM_IsEncrypt()) { printf("%s: no decrypt component\r\n", __func__); return ERR_NO_DECRYPT_COMPONENT; } #endif const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found.\r\n", __func__); return ERR_NO_THIS_PART; } //printf("%s: '%s' part.\r\n", __func__, part_name); if (strncmp(upkHdr.name, "upk", sizeof("upk")) != 0) { return ERR_FAULT_FIRMWARE; } if ((upkHdr.pkg_size > part->len) || (upkHdr.raw_size > part->len)) { return ERR_FIRMWARE_OVERSIZE; } head_crc = crc32_step(head_crc, pHdr, UPK_HEAD_SIZE - 4); if (head_crc != upkHdr.head_crc) { printf("%s: head crc verify failed. (%.8X - %.8X)\r\n", __func__, upkHdr.head_crc, head_crc); return ERR_FIRMWARE_HEAD_VERIFY_ERR; } printf("\n\r--------------------\n\r"); printf("head: \t\t%s\n\r", upkHdr.name); printf("config: \t%d %d %d %d\n\r", upkHdr.config[0], upkHdr.config[1], upkHdr.config[2], upkHdr.config[3]); printf("old_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]); printf("new_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]); printf("string: \t%s\n\r",upkHdr.user_string); printf("partition: \t%s\n\r", upkHdr.part_name); printf("raw_size: \t%d\n\r", upkHdr.raw_size); printf("pkg_size: \t%d\n\r", upkHdr.pkg_size); printf("timestamp: \t%d\n\r", upkHdr.timestamp); printf("raw_crc: \t%.8X\n\r", upkHdr.raw_crc); printf("pkg_crc: \t%.8X\n\r", upkHdr.pkg_crc); printf("head_crc: \t%.8X\n\r", upkHdr.head_crc); printf("--------------------\n\r"); /* 计算固件更新进度的最小单位,降低过程计算量,无更新进度需求可删除 */ _update_progress_step_num = upkHdr.pkg_size / UPK_LEAST_HANDLE_BYTE; _update_progress_step_num += upkHdr.pkg_size % UPK_LEAST_HANDLE_BYTE; _update_progress_step_num = 10000 / _update_progress_step_num; //printf("%s: progress unit: %d\r\n", __func__, _update_progress_step_num); return ERR_OK; } /** * @brief 校验已放置在分区的固件包的包体数据的正确性 * @note 一般要先校验包头,注意各分区包体的偏移地址有区别 * @param[in] part_name: 分区名称 * @param[in] crc32: 需进行比对的 CRC32 校验值 * @param[in] is_auto_fill: 是否自动填充固件的首地址数据 * @retval eErrCode */ eErrCode FM_VerifyFirmware (const char *part_name, uint32_t crc32, uint8_t is_auto_fill) { int read_len = 0; uint8_t app_part_flag = 0; uint32_t pkg_size = 0; uint32_t body_crc = 0xFFFFFFFF; uint32_t read_posit = 0; uint32_t read_posit_temp = 0; uint16_t need_read_size = UPK_LEAST_HANDLE_BYTE; #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) uint8_t first_flag = 0; #endif ASSERT(part_name != NULL); #if (!CONFIG_DECRYPT) /* 若固件包加密,检查是否有解密组件 */ if (FM_IsEncrypt()) { printf("%s: no decrypt component\r\n", __func__); return ERR_NO_DECRYPT_COMPONENT; } #endif if (strncmp(part_name, NAME_PART_APPLICATION, MAX_NAME_LEN) == 0) { app_part_flag = 1; } const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found.\r\n", part_name); return ERR_NO_THIS_PART; } hex_printf((uint8_t *)&upkHdr, UPK_HEAD_SIZE); printf("--------------------\n\r"); printf("head: \t\t%s\n\r", upkHdr.name); printf("config: \t%d %d %d %d\n\r", upkHdr.config[0], upkHdr.config[1], upkHdr.config[2], upkHdr.config[3]); printf("old_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]); printf("new_ver: \t%d.%d.%d.%d\n\r", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]); printf("string: \t%s\n\r",upkHdr.user_string); printf("partition: \t%s\n\r", upkHdr.part_name); printf("raw_size: \t%d\n\r", upkHdr.raw_size); printf("pkg_size: \t%d\n\r", upkHdr.pkg_size); printf("timestamp: \t%d\n\r", upkHdr.timestamp); printf("raw_crc: \t%.8X\n\r", upkHdr.raw_crc); printf("pkg_crc: \t%.8X\n\r", upkHdr.pkg_crc); printf("head_crc: \t%.8X\n\r", upkHdr.head_crc); printf("--------------------\n\r"); if (app_part_flag) { pkg_size = upkHdr.raw_size; } else { pkg_size = upkHdr.pkg_size; } /* 校验固件包体的数据正确性 */ for (; read_posit < pkg_size; ) { /* 剩余的数据数小于最小处理单位时,按剩余字节数处理 */ if ((pkg_size - read_posit) < UPK_LEAST_HANDLE_BYTE) { need_read_size = pkg_size - read_posit; } /* 非 APP 分区,需要偏移包头的地址才是包体 */ if (app_part_flag) { read_posit_temp = read_posit; } else { read_posit_temp = read_posit + UPK_HEAD_SIZE; } read_len = BSP_Flash_Read(part, read_posit_temp, _upk_min_handle_buff, need_read_size); if (read_len < 0) { printf("%s: read error (%d).\r\n", __func__, __LINE__); return ERR_VERIFY_READ_ERR; } #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) if (is_auto_fill) { if (first_flag == 0) { first_flag = 1; for (uint8_t i = 0; i < CONFIG_WRITE_BYTES_LEASET; i++) { _upk_min_handle_buff[i] = _fw_first_bytes[i]; } } } #endif body_crc = crc32_step(body_crc, _upk_min_handle_buff, read_len); read_posit += read_len; } if (body_crc != crc32) { printf("%s: '%s' body crc verify failed. (%08X vs %08X)\r\n", __func__, part_name, crc32, body_crc); if (app_part_flag) { return ERR_RAW_BODY_VERIFY_ERR; } else { return ERR_PKG_BODY_VERIFY_ERR; } } return ERR_OK; } /** * @brief 擦除某个分区的固件 * @note * @param[in] part_name: 分区名称 * @retval eErrCode */ eErrCode FM_EraseFirmware(const char *part_name) { ASSERT(part_name != NULL); const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found %s part.\r\n", __func__, part_name); return ERR_NO_THIS_PART; } if (BSP_Flash_Erase(part, 0, part->len) < 0) { printf("%s: %s part erase failed.\r\n", __func__, part_name); return ERR_ERASE_PART_ERR; } return ERR_OK; } /** * @brief 固件写入分区的最终阶段,将分区首地址的几个字节数据写入 flash * @note 程序调用 _Write_FirmwareSubPackage 函数时已暂存进 _fw_first_bytes * @param[in] part_name: 分区名称 * @retval eErrCode */ eErrCode FM_WriteFirmwareDone (const char *part_name) { ASSERT(part_name != NULL); const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found part.\r\n", __func__); return ERR_NO_THIS_PART; } if (BSP_Flash_Write(part, 0, _fw_first_bytes, CONFIG_WRITE_BYTES_LEASET) < 0) { printf("%s: write error (%d).\r\n", __func__, __LINE__); return ERR_WRITE_FIRST_ADDR_ERR; } _Reset_Write(); Firmware_OperateCallback(10000); return ERR_OK; } /** * @brief 将固件分包按顺序写入分区 * @note 由于固件包头已经写入,这里写入的是固件包体,需要注意在 flash 的偏移位置 * @param[in] part_name: 分区名称 * @param[in] data: 数据包 * @param[in] pkg_size: 数据包大小,单位 byte * @retval eErrCode */ eErrCode FM_WriteFirmwareSubPackage(const char *part_name, uint8_t *data, uint16_t pkg_size) { ASSERT(part_name != NULL); ASSERT(data != NULL); ASSERT(pkg_size != 0); const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found %s part.\r\n", __func__, part_name); return ERR_NO_THIS_PART; } printf(","); #if (CONFIG_CHIP_PARTS == USE_SINGLE_PARTITION) uint8_t decrypt = 0; /* 读取加密选项 */ decrypt = FM_IsEncrypt(); return _Write_FirmwareSubPackage(part, data, pkg_size, decrypt, FM_DIR_HOST_TO_APP); /* 写入前解密 */ #else return _Write_FirmwareSubPackage(part, data, pkg_size, 0, FM_DIR_HOST_TO_DOWNLOAD); /* 写入前不解密 */ #endif } /** * @brief 检查固件的完整性 * @note 通过首地址数据最后写入的机制,判断首地址 4 个字节是否有正确的数据 * @param[in] addr: 分区首地址 * @retval eErrCode */ eErrCode FM_CheckFirmwareIntegrity(uint32_t addr) { uint32_t value = *(volatile uint32_t *)addr; eErrCode fw_integrity = ERR_JUMP_TO_APP_ERR; printf("\r\nvalue = 0x%08X @ offset 0x%.8X", value, addr); if (BASE_APPLICATION == addr) { fw_integrity = ((value & 0x2FF00000) == 0x20000000) ? ERR_OK : ERR_JUMP_TO_APP_ERR; } #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) else if ((BASE_DOWNLOAD == addr)||(BASE_FACTORY == addr)) { if (UPK_IDENTIFIER == value) { fw_integrity = ERR_OK; } } #endif return fw_integrity; } #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) /** * @brief 判断是否要进行固件自动更新 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 0: 无须更新。1: 需自动更新 */ uint8_t FM_IsNeedAutoUpdate(void) { #if (CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP) const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(NAME_PART_APPLICATION); if (part == NULL) { printf("%s: not found app part.\r\n", __func__); return ERR_NO_THIS_PART; } if (BSP_Flash_Read(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_old_ver[0], UPK_VERSION_SIZE) < 0) { printf("%s: read error.\r\n", __func__); return ERR_READ_VER_ERR; } #endif printf("fw old ver: V%d.%d.%d.%d\r\n", upkHdr.fw_old_ver[0], upkHdr.fw_old_ver[1], upkHdr.fw_old_ver[2], upkHdr.fw_old_ver[3]); printf("fw new ver: V%d.%d.%d.%d\r\n", upkHdr.fw_new_ver[0], upkHdr.fw_new_ver[1], upkHdr.fw_new_ver[2], upkHdr.fw_new_ver[3]); if (upkHdr.fw_old_ver[0] != upkHdr.fw_new_ver[0] || upkHdr.fw_old_ver[1] != upkHdr.fw_new_ver[1] || upkHdr.fw_old_ver[2] != upkHdr.fw_new_ver[2] || upkHdr.fw_old_ver[3] != upkHdr.fw_new_ver[3]) { printf("Need to update.\r\n"); return 1; } return 0; } /** * @brief 获取当前操作的固件包的分区名称 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 分区名称 */ inline char * FM_GetPartName(void) { return upkHdr.part_name; } /** * @brief 获取旧的固件版本,即 APP 分区正在运行的固件版本 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 固件旧版本 */ inline char * FM_GetOldFirmwareVersion(void) { return upkHdr.fw_old_ver; } /** * @brief 获取打包后固件的 CRC32 值 * @note 调用前需确保 upkHdr 已经读入了数据 * @retval 打包后固件的CRC32值 */ inline uint32_t FM_GetPackageCRC32(void) { return upkHdr.pkg_crc; } /** * @brief 将分区内的固件包头读出 * @note 读出后的数据将放在 upkHdr 中 * @param[in] part_name: 分区名称 * @retval eErrCode */ eErrCode FM_ReadFirmwareHead(const char *part_name) { ASSERT(part_name != NULL); _Reset_Write(); const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found.\r\n", __func__); return ERR_NO_THIS_PART; } if (BSP_Flash_Read(part, 0, (uint8_t *)&upkHdr, UPK_HEAD_SIZE) < 0) { printf("%s: read error.\r\n", __func__); return ERR_READ_FIRMWARE_HEAD_ERR; } return ERR_OK; } /** * @brief 从某个分区将固件包更新至 APP 分区 * @note 读取 -> 解密 -> 写入 * @param[in] from_part_name: 放置需要更新至 APP 分区的固件包的分区 * @retval eErrCode */ eErrCode FM_UpdateToAPP(const char *from_part_name) { int read_len = 0; uint8_t decrypt = 0; uint32_t read_posit = 0; uint32_t write_posit = 0; uint32_t need_read_size = UPK_LEAST_HANDLE_BYTE; eErrCode result = ERR_OK; ASSERT(from_part_name != NULL); const struct BSP_FLASH *app_part = NULL; const struct BSP_FLASH *firmware_part = NULL; app_part = BSP_Flash_GetHandle(NAME_PART_APPLICATION); if (app_part == NULL) { printf("%s: not found.\r\n", __func__); return ERR_NO_THIS_PART; } firmware_part = BSP_Flash_GetHandle(from_part_name); if (firmware_part == NULL) { printf("%s: not found %s part.\r\n", __func__, from_part_name); return ERR_NO_THIS_PART; } _Reset_Write(); printf("part '%s' write to 'app'.\r\n", from_part_name); /* 读取加密选项 */ decrypt = FM_IsEncrypt(); for (write_posit = 0; write_posit < upkHdr.pkg_size; ) { if ((upkHdr.pkg_size - read_posit) < UPK_LEAST_HANDLE_BYTE) { need_read_size = upkHdr.pkg_size - read_posit; } read_len = BSP_Flash_Read(firmware_part, (read_posit + UPK_HEAD_SIZE), _upk_min_handle_buff, need_read_size); if (read_len < 0) { printf("%s: read error (%d).\r\n", __func__, __LINE__); return ERR_UPDATE_READ_ERR; } result = _Write_FirmwareSubPackage(app_part, _upk_min_handle_buff, read_len, decrypt, FM_DIR_DOWNLOAD_TO_APP); if (result) { printf("%s: write error (%d).\r\n", __func__, __LINE__); return result; } read_posit += read_len; write_posit += read_len; } return ERR_OK; } #if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD) /** * @brief 更新固件包中的版本信息 * @note * @param[in] part_name: 分区名称 * @retval eErrCode */ eErrCode FM_UpdateFirmwareVersion(const char *part_name) { ASSERT(part_name != NULL); #if (ONCHIP_FLASH_ERASE_GRANULARITY > UPK_LEAST_HANDLE_BYTE) #error "erase granularity oversize than _upk_min_handle_buff array" #endif /* 将 download 分区首地址的数据读出,长度为片内 flash 最小擦除粒度 */ const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(part_name); if (part == NULL) { printf("%s: not found.\r\n", __func__); return ERR_NO_THIS_PART; } printf("%s: part name: %s\r\n", __func__, part_name); if (BSP_Flash_Read(part, 0, &_upk_min_handle_buff[0], ONCHIP_FLASH_ERASE_GRANULARITY) < 0) { printf("%s: read error.\r\n", __func__); return ERR_UPDATE_VER_READ_ERR; } /* 修改固件包头中旧版本字段的版本信息为新的固件版本 */ struct upk_head_t *p_pkg_head = (struct upk_head_t *)&_upk_min_handle_buff[0]; p_pkg_head->fw_old_ver[0] = p_pkg_head->fw_new_ver[0]; p_pkg_head->fw_old_ver[1] = p_pkg_head->fw_new_ver[1]; p_pkg_head->fw_old_ver[2] = p_pkg_head->fw_new_ver[2]; p_pkg_head->fw_old_ver[3] = p_pkg_head->fw_new_ver[3]; /* 将读出数据的区域擦除 */ if (BSP_Flash_Erase(part, 0, ONCHIP_FLASH_ERASE_GRANULARITY) < 0) { printf("%s: %s part erase failed.\r\n", __func__, part_name); return ERR_UPDATE_VER_ERASE_ERR; } /* 将新的数据写入擦除的区域 */ if (BSP_Flash_Write(part, 0, &_upk_min_handle_buff[0], ONCHIP_FLASH_ERASE_GRANULARITY) < 0) { printf("%s: write error (%d).\r\n", __func__, __LINE__); return ERR_UPDATE_VER_WRITE_ERR; } memcpy((uint8_t *)&upkHdr, &_upk_min_handle_buff[0], UPK_HEAD_SIZE); printf("fw old ver: V%d.%d.%d.%d\r\n", p_pkg_head->fw_old_ver[0], p_pkg_head->fw_old_ver[1], p_pkg_head->fw_old_ver[2], p_pkg_head->fw_old_ver[3]); printf("fw new ver: V%d.%d.%d.%d\r\n", p_pkg_head->fw_new_ver[0], p_pkg_head->fw_new_ver[1], p_pkg_head->fw_new_ver[2], p_pkg_head->fw_new_ver[3]); return ERR_OK; } #elif (CONFIG_AUTO_UPDATE_MODE == MODE_APPEND_TO_APP) /** * @brief 更新固件包中的版本信息 * @note * @param[in] part_name: 分区名称 * @retval eErrCode */ eErrCode FM_UpdateFirmwareVersion(const char *part_name) { const struct BSP_FLASH *part = NULL; part = BSP_Flash_GetHandle(NAME_PART_APPLICATION); if (part == NULL) { printf("%s: not found APP part.\r\n", __func__); return ERR_NO_THIS_PART; } if (BSP_Flash_Read(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_old_ver[0], UPK_VERSION_SIZE) < 0) { printf("%s: read error.\r\n", __func__); return ERR_READ_VER_ERR; } if (upkHdr.fw_old_ver[0] != 0xFF || upkHdr.fw_old_ver[1] != 0xFF || upkHdr.fw_old_ver[2] != 0xFF || upkHdr.fw_old_ver[3] != 0xFF) { printf("%s: version area no erase.\r\n", __func__); return ERR_VER_AREA_NO_ERASE; } if (BSP_Flash_Write(part, (SIZE_PART_APPLICATION - UPK_VERSION_SIZE), (uint8_t *)&upkHdr.fw_new_ver[0], UPK_VERSION_SIZE) < 0) { printf("%s: write error.\r\n", __func__); return ERR_WRITE_VER_ERR; } return ERR_OK; } #endif /* #if (CONFIG_AUTO_UPDATE_MODE == MODE_UPDATE_DOWNLOAD_HEAD) */ #endif /* #if (CONFIG_CHIP_PARTS > USE_SINGLE_PARTITION) */ /* Private functions ---------------------------------------------------------*/ /** * @brief 复位写固件的一些记录信息 * @note * @retval None */ static void _Reset_Write(void) { _fw_start_write_flag = 0; /* 固件开始写入的标志位 */ _update_progress = 0; /* 固件更新的进度, 10000 制 */ _storage_data_size = 0; /* 固件包写入时记录暂存的固件分包大小,单位 byte */ _write_part_addr = 0; /* 固件包写入时记录写入 flash 的相对地址 */ _write_last_pkg_size = 0; /* 固件包写入时最后一个分包的大小,单位 byte */ } uint32_t wcrc32 = 0xFFFFFFFF; uint32_t wlen = 0; /** * @brief 将固件分包按顺序写入某个分区 * @note 循环调用本函数,无须指定写入地址,函数内部自行记录已写入的大小 * @param[in] part: 分区对象 * @param[in] data: 数据 * @param[in] pkg_size: 数据大小,单位 byte * @param[in] decrypt: 0: 固件包无加密。1: 固件包有加密 * @retval eErrCode */ static eErrCode _Write_FirmwareSubPackage( const struct BSP_FLASH *part, uint8_t *data, uint16_t pkg_size, uint8_t decrypt, FM_FIRMWARE_WRITE_DIR write_dir) { uint8_t *fw_4096byte_buff = data; /* 主机直接下发的固件分包不满 UPK_LEAST_HANDLE_BYTE 个字节,需要先暂存至满足后再写入 */ if (write_dir == FM_DIR_HOST_TO_APP) { fw_4096byte_buff = &_upk_min_handle_buff[0]; /* 判断是否是最后一个包 */ if (_storage_data_size == 0) { if (upkHdr.pkg_size - _write_part_addr < UPK_LEAST_HANDLE_BYTE) { /* 最后一个固件分包的标志 */ _write_last_pkg_size = upkHdr.pkg_size - _write_part_addr; printf("_write_last_pkg_size : %d\r\n", _write_last_pkg_size); } } /* 小于最小处理单位时,暂存 */ if (_storage_data_size < UPK_LEAST_HANDLE_BYTE) { memcpy(&fw_4096byte_buff[_storage_data_size], data, pkg_size); _storage_data_size += pkg_size; if (_write_last_pkg_size) { if (_storage_data_size < _write_last_pkg_size) { return ERR_OK; } } else if (_storage_data_size < UPK_LEAST_HANDLE_BYTE) { return ERR_OK; } } } /* 从 download 或 factory 更新至 APP ,因可以直接读取 UPK_LEAST_HANDLE_BYTE 个字节,所以无须暂存 */ else { if (_fw_start_write_flag == 0) { wlen = upkHdr.pkg_size; _storage_data_size = pkg_size; } else { if (wlen >= pkg_size) { wlen -= pkg_size; _storage_data_size = pkg_size; } else { _storage_data_size = wlen; } } } #if (CONFIG_DECRYPT) if (decrypt) { AES_CBC_decrypt_buffer(&aesCtx, fw_4096byte_buff, _storage_data_size); } #endif /* 保存首地址的几个字节数据,等待最后写入 */ if (_fw_start_write_flag == 0) { for (uint8_t i = 0; i < CONFIG_WRITE_BYTES_LEASET; i++) { _fw_first_bytes[i] = fw_4096byte_buff[i]; } fw_4096byte_buff += CONFIG_WRITE_BYTES_LEASET; _storage_data_size -= CONFIG_WRITE_BYTES_LEASET; _write_part_addr = CONFIG_WRITE_BYTES_LEASET; } if (BSP_Flash_Write(part, _write_part_addr, fw_4096byte_buff, _storage_data_size) < 0) { printf("%s: write error (%d) 0x%08X + 0x%08X, len %d.\r\n", __func__, __LINE__, part->addr,_write_part_addr, _storage_data_size); _Reset_Write(); return ERR_WRITE_PART_ERR; } if (_storage_data_size!=92) { wcrc32 = crc32_step(wcrc32, fw_4096byte_buff, _storage_data_size); } _write_part_addr += _storage_data_size; _storage_data_size = 0; _fw_start_write_flag = 1; _update_progress += _update_progress_step_num; Firmware_OperateCallback(_update_progress); return ERR_OK; }