一、STM32编程方式
(1)在线编程(ICP,in circuit programming)
系统存储器:留给ST写启动程序代码,启动程序代码通过串口1接口实现对闪存存储器的编程。
(2)在程序中编程(IAP,in application programming)
二、FLASH结构
三、 STM32F4 正常运行流程图
- STM32的内部闪存(FLASH)地址起始于Ox08000000,般情况下,程序文件就从此地址开始1写入。
- Ox08000004开始存放中断向量表。
- 当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。
- ①STM32复位后,从O×08000004地址取出复位中断向量的地址,并跳转到复位中断服务程序。
- ②在复位中断服务程序执行完之后,会跳转到我们的main函数
- ③main函数执行过程中,如果收到中断请求(发生重中断),此时STM32强制将PC指针指回中断向量表处。
- ④根据中断源进入相应的中断服务程序
- ⑤在执行完中断服务程序以后,程序再次返回main函数执行
四、IAP升级应用程序过程
- 1)检查是否需要对第二部分代码(实际的应用程序代码)进行更新
- 2)如果不需要更新则转到4
- 3)执行更新操作
- 4)跳转到第二部分代码执行
我们将第一个项目代码称之为Bootloader程序,第二个项目代码称之为APP程序,他们存放在STM32 FLASH的不同地址范围,一般从最低地址区开始存放Bootloader,紧跟其后的就是APP程序(注意,如果FLASH容量足够,是可以设计很多APP程序的)
五、IAP代码书写
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
iapfun jump2app;
u32 iapbuf[512]; //2K字节缓存
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
u32 t;
u16 i=0;
u32 temp;
u32 fwaddr=appxaddr;//当前写入的地址
u8 *dfu=appbuf;
for(t=0;t<appsize;t+=4)
{
temp=(u32)dfu[3]<<24;
temp|=(u32)dfu[2]<<16;
temp|=(u32)dfu[1]<<8;
temp|=(u32)dfu[0];
dfu+=4;//偏移4个字节
iapbuf[i++]=temp;
if(i==512)
{
i=0;
STMFLASH_Write(fwaddr,iapbuf,512);
fwaddr+=2048;//偏移2048 512*4=2048
}
}
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.
}
}
#ifndef __IAP_H__
#define __IAP_H__
#include "sys.h"
typedef void (*iapfun)(void); //定义一个函数类型的参数.
#define FLASH_APP1_ADDR 0x08010000 //第一个应用程序起始地址(存放在FLASH)
//保留0X08000000~0X0800FFFF的空间为Bootloader使用(共64KB)
void iap_load_app(u32 appxaddr); //跳转到APP程序执行
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 applen); //在指定地址开始,写入bin
#endif
六、APP程序的生成步骤
1设置APP程序的起始地址和存储空间大小
2设置中断向量表偏移量,设置SCB->VTOR的值即可。
SCB->VTOR = 0x08000000|0x10000;
3设置MDK编译后运行fromelf.exe,生成.bin文件.通过在MDK User选项卡,设置编译后调用fromelf.exe,根据.axf文件生成.bin文件,用于IAP更新。
fromelf --bin -o "$L@L.bin" "#L"