STM32 IAP程序升级

硬件平台:STM32F103ZET6的最小系统,512K Flash 64KRAM

Bootloader区:0x08000000 ----- 0x08010000 64K

APP区:     0x080010000 ----- 0x08080000 448K


1.Bootloader部分

#define ApplicationAddress 0x08010000 //app存放的起始地址
#define ApplicationPages 224
#define App1Address 0x20001000 //app程序中接收的更新程序存放在RAM中,起始地址为0x20001000,试验的程序代码比较小

#ifdef iap

if(((*(__IO uint32_t*)(App1Address+4))& 0x2FFE0000 ) == 0x20000000 && (*(__IO uint32_t*)App1Address)!=0) 
{
printf("There is a new app program,now preapring to update the fermware.");
printf("Erasing flash¡­¡­");

FLASH_Unlock();
for(i=0;i{
status=FLASH_ErasePage(ApplicationAddress+i*0x400);
}
FLASH_Lock();

printf("Erase flash ok!!!");

printf("Programing flash¡­¡­");
FlashProgram(ApplicationAddress,(*(__IO uint32_t*)App1Address),(uint8_t *)(App1Address+4));

printf("Programe flash ok!!!");
printf("Jump to app_main!!!");

*(__IO uint32_t*)App1Address = 0;

JumpAddress = (iapfun)*(__IO uint32_t*) (ApplicationAddress+4);  
__set_MSP(*(__IO uint32_t*) ApplicationAddress);  
JumpAddress(); 
}
  else if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)  
  {
printf("Jump to app_main!!!");



JumpAddress = (iapfun)*(__IO uint32_t*) (ApplicationAddress+4);  
__set_MSP(*(__IO uint32_t*) ApplicationAddress);  
JumpAddress();  
}
else   
{
printf("Jump to app_main failed!\n\r");
}
#endif

(1)上电时检测有无更新文件,有更新文件时,根据指定的App长度将新程序拷贝到App的Flash区

(2)跳转到APP的FLASH区执行app程序


2.APP程序的串口接收程序

struct
{
uint32_t length;
uint8_t ReceiveDatebuff1[RecvLength];
}app_program __attribute__ ((at(0X20001000)));


void USART1_IRQHandler()
{
uint8_t ReceiveData;
if(!(USART_GetITStatus(USART1,USART_IT_RXNE)));
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);

if(recievestatus==0)
{
ReceiveData=USART_ReceiveData(USART1);
if(ReceiveData==0x55)recievestatus=1;
printf("prepared for recieve a new app program!");
}
else if(recievestatus==1)
{
ReceiveData=USART_ReceiveData(USART1);
if(recievelength < RecvLength)
{
app_program.ReceiveDatebuff1[recievelength++]=ReceiveData;
}
if(app_program.ReceiveDatebuff1[recievelength-1]==0x55
&&app_program.ReceiveDatebuff1[recievelength-2]==0x55)
{
recievelength-=2;
app_program.length=recievelength;
recievestatus=2;
printf("Recieved a new app program!");
printf("please press enter to update the new program");
}
}
else if(recievestatus==2)
{
ReceiveData=USART_ReceiveData(USART1);
if(ReceiveData==0x13)
{
NVIC_SystemReset();
}
}
}  
}

(1)接收0x55,指示准备接收更新程序

(2)发送app.bin文件,APP程序接收后存放在RAM中指定的地址0X20001000处,并记录app长度

(3)接收0x5555,指示接收APP更新程序结束,准备好更新操作

(4)接收0x13,启动更新操作,软复位,跳转至Bootloader处重启


实现的功能很简单,在APP中接收更新程序,再跳转到Bootloader中去更新;这里没有做任何的出错检验,只是简单的演示下IAP的过程。


(1)BIN文件在通过串口接收时,速率过快可能会出错,可以将波特率调低些做实验

(2)接收APP更新程序可以在APP中也可以在Bootloader中,获取更新文件的途径可以为串口、USB、SD卡、can等

(3)更新文件的存放可以是任何的存储设备,只要足够大的空间即可;

(4)为了更新的准确性和可操作性,无线方式应考虑BIN的分包断点续传;更新前旧APP程序的备份;数据的校验;

你可能感兴趣的:(STM32)