STM32——IAP

        解决要如何从IAP的APP程序中返回BootLoader重新更新固件:

  1. 在APP执行的循环中加入一个外部中断,当触发中断使触发系统软件复位
while(1)
{					
	key=KEY_Scan(0);
	if(key==KEY1_PRES)
	{
		//软件复位
		NVIC_SystemReset();
	}
	//APP功能程序
	//user  conde
}
  1. 以正点原子战舰IAP例程为例,当串口接受完成数据,autoflag=1,更新.bin文件到FLASH,然后startflashflag=1,执行APP程序,在执行APP的功能程序中,当检测到KEY1按下,系统复位,从新加载BootLoader,这时要么重新从串口接收一个APP程序,要么再次按下KEY1运行APP程序。
int main(void)
{		
	u8 t;
	u8 key;
	u16 oldcount=0;				//老的串口接收数据值
	u16 applenth=0;				//接收到的app代码长度
	u8 clearflag=0;  
	u8 autoflag=0;				//用于自动更新固件
	u8 startflashflag=0;	//用于自动执行APP
	
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	//串口初始化为115200
	delay_init();	   	 	//延时初始化 
 	LED_Init();		  			//初始化与LED连接的硬件接口
	KEY_Init();					//初始化按键
	LCD_Init();			   		//初始化LCD  
	POINT_COLOR=RED;//设置字体为红色 
	LCD_ShowString(30,50,200,16,16,"Warship STM32");	
	LCD_ShowString(30,70,200,16,16,"IAP TEST");	  
	LCD_ShowString(30,150,200,16,16,"KEY2:Erase SRAM APP");
	LCD_ShowString(30,170,200,16,16,"KEY1:Run FLASH APP");
	POINT_COLOR=BLUE;
	//显示提示信息
	POINT_COLOR=BLUE;//设置字体为蓝色	  
	while(1)
	{
	 	if(USART_RX_CNT)
		{
			if(oldcount==USART_RX_CNT)//新周期内,没有收到任何数据,认为本次数据接收完成.
			{
				applenth=USART_RX_CNT;
				oldcount=0;
				USART_RX_CNT=0;
				printf("用户程序接收完成!
");
				printf("代码长度:%dBytes
",applenth);
				autoflag=1;
			}else oldcount=USART_RX_CNT;			
		}
		t++;
		delay_ms(10);
		if(t==30)
		{
			LED0=!LED0;
			t=0;
			if(clearflag)
			{
				clearflag--;
				if(clearflag==0)LCD_Fill(30,210,240,210+16,WHITE);//清除显示
			}
		}	  	 
		key=KEY_Scan(0);
		if(autoflag)
		{
			if(applenth)
			{
				printf("开始更新固件...
");	
				LCD_ShowString(30,210,200,16,16,"Copying APP2FLASH...");
 				if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
				{	 
					iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码   
					LCD_ShowString(30,210,200,16,16,"Copy APP Successed!!");
					printf("固件更新完成!
");
					startflashflag=1;
				}else 
				{
					LCD_ShowString(30,210,200,16,16,"Illegal FLASH APP!  ");	   
					printf("非FLASH应用程序!
");
					startflashflag=0;
				}
 			}else 
			{
				printf("没有可以更新的固件!
");
				LCD_ShowString(30,210,200,16,16,"No APP!");
				startflashflag=0;
			}
			autoflag=0;
			clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示									 
		}
		if(key==KEY2_PRES)
		{
			if(applenth)
			{																	 
				printf("固件清除完成!
");    
				LCD_ShowString(30,210,200,16,16,"APP Erase Successed!");
				applenth=0;
			}else 
			{
				printf("没有可以清除的固件!
");
				LCD_ShowString(30,210,200,16,16,"No APP!");
			}
			clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示									 
		}
		if(startflashflag||key==KEY1_PRES)
		{
			printf("开始执行FLASH用户代码!!
");
			if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
			{	 
				iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
			}else 
			{
				printf("非FLASH应用程序,无法执行!
");
				LCD_ShowString(30,210,200,16,16,"Illegal FLASH APP!");	   
			}									 
			clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示	  
		}
	}   	   
}
原文地址:https://www.cnblogs.com/hhsxy/p/14018399.html