DFU固件拷贝升级
GR551x的应用固件进行OTA时采用双区后台升级方式。将DFU固件存放至Bank1区域,并更新DFU Image Info区域信息,然后复位GR551x设备后运行Second Boot固件,将Bank1区域中的DFU固件拷贝至Bank0区域运行。
DFU固件拷贝升级主要代码介绍如下。
路径:工程目录下的user_app\user_boot.c
名称:is_fw_need_copy();
is_fw_need_copy()函数用于读取DFU Image Info,判断是否存在DFU固件拷贝任务。
static bool is_fw_need_copy(void)
{
copy_load_addr = 0;
hal_flash_read_judge_security(IMG_INFO_DFU_ADDR, (uint8_t*)©_load_addr, 4);
memset((uint8_t*)&dfu_img_info, 0, sizeof(img_info_t));
hal_flash_read_judge_security(IMG_INFO_DFU_ADDR+4, (uint8_t*)&dfu_img_info,
sizeof(img_info_t));
if (dfu_img_info.pattern != 0x4744 ||\
(memcmp(dfu_img_info.comments, USER_FW_COMMENTS, strlen(USER_FW_COMMENTS)) != 0))
{
APP_LOG_DEBUG("There is no incomplete DFU copy task.");
return false;
}
APP_LOG_DEBUG("---------------------------------------------------------------");
APP_LOG_DEBUG("copy addr = 0x%08x", copy_load_addr);
APP_LOG_DEBUG("DFU fw boot info:");
log_boot_info(&dfu_img_info.boot_info);
APP_LOG_DEBUG("---------------------------------------------------------------");
APP_LOG_DEBUG("There is incomplete DFU copy task.");
return true;
}
路径:工程目录下的user_app\user_boot.c
名称:incplt_dfu_task_continue();
incplt_dfu_task_continue()函数用于检查DFU固件有效性,有效性通过之后将DFU固件从Bank1区域拷贝至Bank0区域,并更新APP Image Info,擦除DFU Image Info,然后复位设备,程序将跳转到新的应用固件并运行,示例代码如下。
static void incplt_dfu_task_continue(void)
{
if (!boot_fw_valid_check(copy_load_addr, &dfu_img_info.boot_info))
{
APP_LOG_DEBUG("DFU FW image valid check fail.");
return;
}
if(copy_load_addr != dfu_img_info.boot_info.load_addr)
{
uint32_t copy_size = dfu_img_info.boot_info.bin_size + 48;
APP_LOG_DEBUG("DFU FW image start copy.");
if(sys_security_enable_status_check())
{
copy_size += 856;
}
else
{
#if BOOTLOADER_SIGN_ENABLE
copy_size += 856;
#endif
}
dfu_fw_copy(dfu_img_info.boot_info.load_addr, copy_load_addr, copy_size);
}
user_img_info_update(&dfu_img_info);
hal_flash_erase(IMG_INFO_DFU_ADDR, CODE_PAGE_SIZE);//clear copy info
hal_nvic_system_reset();
}