#include "includes.h" #include "update.h" #include "Flash.h" typedef void (*otafun)(void); //定义一个函数类型的参数. otafun jump2app; //擦除app int erase_app(u8 app_num) { u32 FlashAddress = 0; int Size = OTA_UPDATE_APP_FLASH_SIZE; switch(app_num) { case UPDATE_ENUM_APP1: FlashAddress = OTA_UPDATE_APP1_FLASH_START_ADDR; break; case UPDATE_ENUM_APP2: FlashAddress = OTA_UPDATE_APP2_FLASH_START_ADDR; break; case UPDATE_ENUM_APP3: FlashAddress = OTA_UPDATE_APP3_FLASH_START_ADDR; break; default: return -1; } Flash_RangeErase(FlashAddress, Size); return 0; } //复制, int copy_app(u8 from, u8 to) { u32 FromFlashAddress = 0; int Size = OTA_UPDATE_APP_FLASH_SIZE; u32 ToFlashAddress = 0; u8 buffer[1024]; switch(from) { case UPDATE_ENUM_APP1: FromFlashAddress = OTA_UPDATE_APP1_FLASH_START_ADDR; break; case UPDATE_ENUM_APP2: FromFlashAddress = OTA_UPDATE_APP2_FLASH_START_ADDR; break; case UPDATE_ENUM_APP3: FromFlashAddress = OTA_UPDATE_APP3_FLASH_START_ADDR; break; default: return -1; } switch(to) { case UPDATE_ENUM_APP1: ToFlashAddress = OTA_UPDATE_APP1_FLASH_START_ADDR; break; case UPDATE_ENUM_APP2: ToFlashAddress = OTA_UPDATE_APP2_FLASH_START_ADDR; break; case UPDATE_ENUM_APP3: ToFlashAddress = OTA_UPDATE_APP3_FLASH_START_ADDR; break; default: return -1; } Size = Flash_DatalenRead(FromFlashAddress,OTA_UPDATE_APP_FLASH_SIZE); while(Size > 0) { Flash_BufferRead(FromFlashAddress, buffer, 1024); Flash_BufferWrite(ToFlashAddress, (u32 *)buffer, 1024); FromFlashAddress += 1024; ToFlashAddress += 1024; Size -= 1024; } return -1; } int read_app(u8 app_num) { u32 FlashAddress = 0; int Size = OTA_UPDATE_APP_FLASH_SIZE; u8 buffer[1024]; switch(app_num) { case UPDATE_ENUM_APP1: FlashAddress = OTA_UPDATE_APP1_FLASH_START_ADDR; break; case UPDATE_ENUM_APP2: FlashAddress = OTA_UPDATE_APP2_FLASH_START_ADDR; break; case UPDATE_ENUM_APP3: FlashAddress = OTA_UPDATE_APP3_FLASH_START_ADDR; break; default: return -1; } while(Size > 0) { Flash_BufferRead(FlashAddress, buffer, 1024); Size -= 1024; // data_dump("Flash Data READ", buffer, 1024); } return 0; } //复制, int reset_app(u8 app_num, u8 value) { u32 FlashAddress = 0; int Size = OTA_UPDATE_APP_FLASH_SIZE; u8 buffer[1024]; memset(buffer, value, 1024); switch(app_num) { case UPDATE_ENUM_APP1: FlashAddress = OTA_UPDATE_APP1_FLASH_START_ADDR; break; case UPDATE_ENUM_APP2: FlashAddress = OTA_UPDATE_APP2_FLASH_START_ADDR; break; case UPDATE_ENUM_APP3: FlashAddress = OTA_UPDATE_APP3_FLASH_START_ADDR; break; default: return -1; } while(Size > 0) { Flash_BufferWrite(FlashAddress, (u32 *)buffer, 1024); FlashAddress += 1024; Size -= 1024; } return 0; } //设置栈顶地址 __asm void MSR_MSP(u32 addr) { MSR MSP, r0 //set Main Stack value MSR PSP, r0 //set Main Stack value BX r14 } //THUMB指令不支持汇编内联 //采用如下方法实现执行汇编指令WFI void WFI_SET(void) { __ASM volatile("wfi"); } //关闭所有中断 void INTX_DISABLE(void) { __ASM volatile("cpsid i"); } //开启所有中断 void INTX_ENABLE(void) { __ASM volatile("cpsie i"); } typedef void (*usercode)(void); usercode EnterApp; //运行app1 uint32_t run_app1(void) { uint32_t appxaddr=OTA_UPDATE_APP1_FLASH_START_ADDR; printf("jump to 0x%08X.\r\n",appxaddr); if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法. { INTX_DISABLE(); jump2app=(otafun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) gpio_deinit(GPIOB); gpio_deinit(GPIOC); jump2app(); //跳转到APP. while(1); } else { printf("栈顶地址不合法\r\n"); } return 0; }