这章主要写一个简单的在线烧录IAP实验。
代码功能如下:BootLoader中串口等待接收BIN文件,当接收完成后按下key_up按键后把BIN文件转存到flash的0x08010000地址,再按下key1后就跳到flash的0x08010000地址运行(本来是从0x08000000开始运行的),跳到新地址运行被更新的APP(该APP的功能只控制两个LED灯三秒闪一次)。
1:BootLoader代码如下:
#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 t;
u8 key;
u16 oldcount=0; //老的串口接收数据值
u16 applenth=0; //接收到的app代码长度
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
delay_init(); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //初始化按键
while(1)
{
if(USART_RX_CNT)
{
if(oldcount==USART_RX_CNT)//新周期内,没有收到任何数据,认为本次数据接收完成.串口接收完.bin文件
{
applenth=USART_RX_CNT;
oldcount=0;
USART_RX_CNT=0;
}else oldcount=USART_RX_CNT;
}
t++;
delay_ms(10);
if(t==30)
{
LED0=!LED0;
}
key=KEY_Scan(0);
if(key==WKUP_PRES)
{
if(applenth)
{
if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.程序设置把串口接收来的数据从0x20001000开始存储,
{ //第一个4个字节为栈顶地址,第二个4字节为复位中断向量的入口地址
iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码,把bin文件移到0x08010000
}else
{
//
}
}else
{
//
}
LED1=!LED1;
}
if(key==KEY1_PRES)
{
//"开始执行FLASH用户代码!!\r\n
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
{
iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码,0x08010000 //第一个应用程序起始地址(存放在FLASH)
}else
{
}
LED1=!LED1;
}
if(key==KEY0_PRES)
{
//"开始执行SRAM用户代码!!
if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x20000000)//判断是否为0X20XXXXXX.
{
iap_load_app(0X20001000);//SRAM地址
}else
{
}
LED1=!LED1;
}
}
}
2:APP代码如下:
int main(void)
{
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED0=0;
LED1=0;
delay_ms(3000); //延时300ms
LED0=1;
LED1=1;
delay_ms(3000); //延时300ms
}
}
3:注意编译APP时需要设置起始地址为0x08010000,如图:
4:注意编译BIN文件需要成如下图:
命令是:
D:\MDK5\ARM\ARMCC\bin\fromelf.exe --bin --output ../OBJ/RTC.bin ../OBJ/RTC.axf