×
单片机 > 单片机程序设计 > 详情

STM32F103C8T6在线升级 IAP

发布时间:2020-08-27 发布时间:
|

stm32程序每次执行都会从基地址0x800 0000开始执行。IAP程序升级的执行是在bootloader引导文件执行后,进行加载、跳转APP程序。所以每次上电后进入BootLoader判断是否需要升级,如果升级则接受bin文件,如果不升级则直接跳转app程序。


BootLoader和app程序的FLASH大小需要根据自己的程序情况自由的分配大小就可以了。


代码:根据正点原子的例程进行修改的


1、由于BootLoader引导程序比较小,我设置的flash大小为0x1800


2、iap函数:由于STM32F103C8T6程序存储容量是64KB,每页的大小为1K字节即1024,所以iapbuf数组设置为512。


代码如下:


#include "stmflash.h"

#include "iap.h"

iapfun jump2app; 

u16 iapbuf[512];   

//appxaddr:应用程序的起始地址

//appbuf:应用程序CODE.

//appsize:应用程序大小(字节).

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;//偏移2个字节

iapbuf[i++]=temp;     

if(i==512)

{

i=0;

STMFLASH_Write(fwaddr,iapbuf,512);

fwaddr+=1024;//偏移1024  

}

}

if(i)

STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去. 

}

//跳转到应用程序段

//appxaddr:用户代码起始地址.

void iap_load_app(u32 appxaddr)

{

if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.

jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)

MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)

jump2app(); //跳转到APP.

}


}


3、BootLoader函数 :


    首先判断app代码的首地址是否为0x0800 000,是则进入app,否的话进行引导区。


    判断app代码栈顶是否为0x2000 000,不是则进入升级模式,代码如下,其中FLASH_APP1_ADDR=0x8001800


while(1)

{

if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

{

iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码

}

if((((*(vu32*)FLASH_APP1_ADDR)&0x2FFE0000)!=0x20000000))

{

printf("/***** No APP! *****/ \r\n");

printf("stm32f103c8t6在线升级  \r\n");

printf("选择对应的app  bin文件 \r\n");

printf("输入 A  发送bin文件 \r\n");

printf("输入 E  进入app \r\n");

while(1)

{

if(USART_RX_CNT)

{

if(oldcount==USART_RX_CNT)//新周期内,没有收到任何数据,认为本次数据接收完成.

{

applenth=USART_RX_CNT;

oldcount=0;

USART_RX_CNT=0;

if(applenth > 100)

{

printf("用户程序接收完成!\r\n");

printf("代码长度:%dBytes\r\n",applenth);

}


}

else 

oldcount=USART_RX_CNT;

}

delay_ms(10);


if(USART_RX_BUF[0] == 'A')

{

if(applenth)

printf("\r\n 请发送bin文件 \r\n");

app_bin = 1;

applenth=0;

}

else if(app_bin)

{


if(applenth)

{

printf("开始更新固件...\r\n");

printf("Copying APP2FLASH...");


if(((*(vu32*)(0X20000400+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

{  

iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码   

printf("Copy APP Successed!!");

printf("固件更新完成!\r\n");

applenth = 0;

app_bin = 0;

}

}

}


if(USART_RX_BUF[0] == 'E')

{

if(applenth)

printf("\r\n 将要执行APP \r\n");

app_enter = 1;

applenth = 0;

if(app_enter)

{

printf("开始执行FLASH用户代码!!\r\n");

if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

{  

iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码

}else 

{

printf("非FLASH应用程序,无法执行!\r\n");

printf("Illegal FLASH APP!");

}

}

}

}


}


4、bootloader下进去之后,后面该是app程序了。


5、app程序就比较简单了,首先设置flash向量便宜地址0x1800


其次配置程序的启动地址



6、编译后keil下载程序就可以了,或者通过串口按照自己编写的步骤进行下载。


发送 A 提示 请发送bin文件


下面以次打开选择bin文件并发送,会打印出接收的字节数跟更新固件


最好发送E,会有开始执行提示。或者单片机直接复位也可以直接执行app,到此app在线升级完成。


关键字:STM32F103C8T6  在线升级  IAP 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机的抗干扰措施有哪些