STM32
直播中

最强海贼王

8年用户 1344经验值
擅长:MEMS/传感技术
私信 关注
[问答]

如何去实现STM32f103c8t6的IAP在线升级呢

如何去实现STM32f103c8t6的IAP在线升级呢?其流程是怎样的?

回帖(1)

张珊珊

2021-12-14 15:15:38
STM32f103c8t6 IAP在线升级
设计思路:(自己理解的哈,如果有问题,欢迎大家提出来,一起学习哈)
首先程序每次执行都会从基地址0x0800 0000开始执行。IAP程序升级最重要的就是写BOOTLOADER程序,进行引导升级,加载,跳转app程序。每次上电后进入bootloader判断是否升级如果需要升级,就就收bin文件进行升级,如果不升级直接跳入原app程序执行。

bootloader和app程序的FLASH大小根据实际情况自己确定分配就可以了
下面是我自己画得一个流程图:主要介绍整个大的流程





bin文件的生成方法可以百度一下,网上很多的

代码:(我是根据正点原子的例程改的,代码只贴了重要部分,如果有需要的可以留言。因为注释会乱码,所以我把注释删了)
bootloader.c:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"


iapfun jump2app;
u16 iapbuf[1024];   


void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
        u16 t;
        u16 i=0;
        u16 temp;
        u32 fwaddr=appxaddr;
        u8 *dfu=appbuf;
        for(t=0;t         {                                                    
                temp=(u16)dfu[1]<<8;
                temp+=(u16)dfu[0];          
                dfu+=2;
                iapbuf[i++]=temp;            
                if(i==1024)
                {
                        i=0;
                        STMFLASH_Write(fwaddr,iapbuf,1024);       
                        fwaddr+=2048;
                }
        }
        if(i)STMFLASH_Write(fwaddr,iapbuf,i);
}




void iap_load_app(u32 appxaddr)
{
        if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)       
        {
                __set_MSP(*(vu32*)appxaddr);                                       
                jump2app=(iapfun)*(vu32*)(appxaddr+4);               
                jump2app();                                                                       
        }
}




bootloader.h:


#ifndef __IAP_H__
#define __IAP_H__
#include "sys.h"  


typedef  void (*iapfun)(void);                       


#define FLASH_APP1_ADDR                0x08005000         
                                                                               


void iap_load_app(u32 appxaddr);                       
void iap_load_appsram(u32 appxaddr);       
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 applen);       
#endif
main函数:


#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
int main(void)
{               
        u8 key;
        u16 oldcount=0;                               
        u16 applenth=0;                               
        SystemInit();
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(115200);       
        delay_init();                    
       
        LED_Init();                                         
        KEY_Init();                               


        printf("readyn");
       
        while(1)
        {
                GPIO_SetBits(GPIOC,GPIO_Pin_13);                                                
                delay_ms(500);
                GPIO_ResetBits(GPIOC,GPIO_Pin_13);                                                  
                delay_ms(500);
       
                 if(USART_RX_CNT)
                {
                        if(oldcount==USART_RX_CNT)
                        {
                                applenth=USART_RX_CNT;
                                oldcount=0;
                                USART_RX_CNT=0;
                                printf("用户程序接收完成!rn");
                                printf("代码长度:%dBytesrn",applenth);
                        }
                        else
                                oldcount=USART_RX_CNT;                       
                }
                key=KEY_Scan(0);
                if(key==WKUP_PRES)
                {
                        if(applenth)
                        {
                                printf("开始更新固件库...rn");       
                                if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)
                                {         
                                        iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);


                                        printf("固件更新完成!rn");       
                                }
                                else
                                {
                                        printf("非FLASH应用程序!rn");
                                }
                        }
                        else
                        {
                                printf("没有可以更新的固件!rn");
                        }
                }
                if(key==KEY2_PRES)
                {
                        if(applenth)
                        {                                                                                                                                         
                                printf("固件清除完成!rn");   
                                applenth=0;
                        }
                        else
                        {
                                printf("没有可以清除的固件!rn");
                        }
                }
                if(key==KEY1_PRES)
                {
                                printf("开始执行FLASH!!rn");
                        if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
                        {         
                                __set_PRIMASK(1);
                                iap_load_app(FLASH_APP1_ADDR);
                        }
                        else
                        {
                                printf("非FLASH应用程序,无法执行!rn");
                        }                                                                         
                }
        }             
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分