• 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后清除显示	  
    		}
    	}   	   
    }
    
  • 相关阅读:
    继承关系中子类使用@Data注解问题
    Professional, Entreprise, Architect版本的区别
    Delphi中ARC内存管理的方向
    技术的止境(客户价值第一,快速实现第二,边做边学,迅速成为牛人。紧贴客户的需求去做技术,立于不败之地。追求的目标:把一项产品去做好,用产品去养活自己和家人)good
    C++ 函数模板与类模板(使用 Qt 开发编译环境)
    C++进阶之虚函数表
    Net反编译软件
    python虚拟环境--virtualenv和virtualenvwrapper
    Windows同时安装python3和python2
    python的pip源在windows和linux修改
  • 原文地址:https://www.cnblogs.com/hhsxy/p/14018399.html
Copyright © 2020-2023  润新知