#include #include "sys.h" #include "iap.h" #include "sysport.h" #include "user_flash.h" #include "usercmd.h" #include "user_tcp.h" #include "user_oled.h" #include "watchdog.h" /******************************************************************************** * @file iap.c * @author 晏诚科技 Mr.Wang * @version V1.0.0 * @date 11-Dec-2018 * @brief 实现固件的跳转 ****************************************************************************** * @attention *******************************************************************************/ /********************************************************************************** *定义常变量 ***********************************************************************************/ iapfun jump2app ; /********************************************************************************************* 校验固件合法性、获取跳转的FLASH存放区域首地址 *********************************************************************************************/ uint32_t QueryNewAppArea(uint32_t appNum ) { uint32_t appAddr = 0 ; Watchdog_Feed() ; switch( appNum ) { case 0x00000031: case APP1_AREA_ADDR: { uint32_t addr = ((*(vu32*)(APP1_AREA_ADDR+4))&0xFFFF0000); RUNAPP1: if((addr == (APP1_AREA_ADDR & 0xFFFF0000)) ||(addr == 0x8020000))//判断是否为0X08XXXXXX. { TcpUpdata( BOOTTOTCPFRAME, "开始执行APP1用户代码!") ; appAddr = APP1_AREA_ADDR ; } else { TcpUpdata( BOOTTOTCPFRAME, "APP1用户代码已受损!") ; } break ; } case 0x00000032: case APP2_AREA_ADDR: { if( ((*(vu32*)(APP2_AREA_ADDR+4))&0xFFFF0000) == (APP2_AREA_ADDR & 0xFFFF0000)) //校验存储在FLASH中的固件合法 { TcpUpdata( BOOTTOTCPFRAME, "开始执行APP2用户代码!") ; appAddr = APP2_AREA_ADDR ; } else { TcpUpdata( BOOTTOTCPFRAME, "APP2用户代码已受损!") ; goto RUNAPP1 ; //执行应急程序 } break ; } case 0x00000033: case APP3_AREA_ADDR: { if( ((*(vu32*)(APP3_AREA_ADDR+4))&0xFFFF0000) == (APP3_AREA_ADDR & 0xFFFF0000)) //校验存储在FLASH中的固件合法 { TcpUpdata( BOOTTOTCPFRAME, "开始执行APP3用户代码!") ; appAddr = APP3_AREA_ADDR ; } else { TcpUpdata( BOOTTOTCPFRAME, "APP3用户代码已受损!") ; goto RUNAPP1 ; } break ; } default: { TcpUpdata( BOOTTOTCPFRAME, "APPNUM不合法!即将执行应急程序!") ; goto RUNAPP1 ; } } return (appAddr) ; } /************************************************************************************************** * 名 称: void Iap_Load_App(u32 appxAddr) * 说 明: 跳转执行APP程序 * 入口参数: * @param1 appxAddr: 用户代码起始地址. * @arg 0x0801C000: 从Flash地址0x08010000开始执行APP * 说 明: * 调用方法: Iap_Load_App(FLASH_APP1_ADDR) ;//执行FLASH APP代码 * Iap_Load_App(0X20001000) ;//SRAM地址 *************************************************************************************************/ void Iap_Load_App(u32 appxAddr) { if( ((*(vu32*)appxAddr)&0x2FFE0000) == 0x20000000 ) //检查栈顶地址是否合法. { jump2app = (iapfun)*(vu32*)(appxAddr+4) ; //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxAddr) ; //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app() ; //跳转到APP. } }