CN / EN
文档反馈
感谢关注汇顶文档,期待您的宝贵建议!
感谢您的反馈,祝您愉快!

应用固件校验跳转运行

当不存在应用固件OTA拷贝升级任务时,Second Boot会对该应用固件进行有效性检查并跳转至该应用固件中运行。

路径:工程目录下的user_app\user_boot.c

名称:is_jump_user_fw();

is_jump_user_fw()函数用于跳转到应用固件运行前的检查。

在is_jump_user_fw()函数中,通过读取APP Image Info的comments和实际应用固件的comments(USER_FW_COMMENTS)进行对比,判断两者comments是否相同,相同说明Bank0中存在应用固件,进一步校验APP Image Info有效性,有效性通过则可跳转到该应用固件运行。

如comments不相同,说明Bank0中不存在应用固件,此时可通过读取SCA区域索引到的应用固件Image Info的comments,和USER_FW_COMMENTS对比,如两者comments相同,再校验该SCA中应用固件Image Info有效性,有效性通过,会将SCA中的应用固件Image Info更新至APP Image Info;如两者comments不同,或者有效性不通过,则不能跳转。

static bool is_jump_user_fw(void)
{
    memset((uint8_t*)&app_img_info, 0, sizeof(img_info_t));
    hal_flash_read_judge_security(IMG_INFO_APP_ADDR, (uint8_t*)&app_img_info, 
                                  sizeof(img_info_t));
    
    if ((app_img_info.pattern == 0x4744) &&\
        (0 == memcmp(app_img_info.comments, USER_FW_COMMENTS, strlen(USER_FW_COMMENTS))))
    {
        APP_LOG_DEBUG("found APP img info.");
        log_boot_info(&app_img_info.boot_info);
        if (boot_fw_valid_check(app_img_info.boot_info.load_addr, &app_img_info.boot_info))
        {
            APP_LOG_DEBUG("check APP img valid.");
            return true;
        }
    }
    APP_LOG_DEBUG("Not found APP img info on the third page,continue to search on the first 
                  page");    
    
    img_info_t img_info_main;
    for (uint8_t i = 0; i < IMG_INFO_SAVE_NUM_MAX; i++)
    {
        fw_img_info_get(BOOT_INFO_ADDR + 0x40, i, &img_info_main);

        if (0 == memcmp(img_info_main.comments, USER_FW_COMMENTS, strlen(USER_FW_COMMENTS)))
        {
            if (boot_fw_valid_check(img_info_main.boot_info.load_addr, 
                &img_info_main.boot_info))
            {
                user_img_info_update(&img_info_main);
                memcpy(&app_img_info, &img_info_main, sizeof(img_info_t));
                APP_LOG_DEBUG("Found the APP firmware on the first page");
                return true;
            }
        }
    }

    APP_LOG_DEBUG("Not found APP FW image info.");
    return false;
}

路径:工程目录下的user_app\user_boot.c

名称1:jump_user_fw();

名称2:sec_boot_jump();

跳转前需更新热启动Boot Info、设置MSP、重定位向量表。

static void jump_user_fw(void)
{
    APP_LOG_DEBUG("Jump to APP FW.");
    APP_LOG_DEBUG("---------------------------------------------------------------");
    sec_boot_jump(&app_img_info.boot_info);
}
 static void sec_boot_jump(boot_info_t *p_boot_info)
{
    extern void rom_init(void);
    extern void jump_app(uint32_t addr);
    extern boot_info_t bl1_boot_info;
    extern void bl_xip_dis(void);
    uint16_t enc_mode = *(uint16_t*)0x30000020;
    bool mirror_mode = false;
    
    if(p_boot_info->run_addr != p_boot_info->load_addr)//mirror mode
    {
        mirror_mode = true;
        if(!enc_mode)
            SET_CODE_LOAD_FLAG();
        memcpy((uint8_t*)p_boot_info->run_addr, (uint8_t*)p_boot_info->load_addr, 
               p_boot_info->bin_size);
    }
    if(enc_mode)
    {
        REG(0xA000C578UL) &= ~0xFFFFFC00;
        REG(0xA000C578UL) |= (p_boot_info->run_addr & 0xFFFFFC00);
    }

    rom_init();
    __disable_irq();
    SysTick->CTRL = 0;
    __enable_irq();
    memcpy(&bl1_boot_info, p_boot_info, sizeof(boot_info_t));
    if(mirror_mode)
    {
        if(enc_mode)
        {
            REG(0xa000d470) = ENCRY_CTRL_DISABLE;
        }
    }
    jump_app(p_boot_info->run_addr);
}
说明:

为了在睡眠唤醒后热启动时,可直接跳转至应用固件,需先将应用固件boot info赋值给全局变量bl1_boot_info,即memcpy(&bl1_boot_info, p_boot_info, sizeof(boot_info_t));,此处切勿改动 。

扫描关注

打开微信,使用“扫一扫”即可关注。