基于STM32的IAP设计文档Word格式.docx
- 文档编号:20316942
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:9
- 大小:165.32KB
基于STM32的IAP设计文档Word格式.docx
《基于STM32的IAP设计文档Word格式.docx》由会员分享,可在线阅读,更多相关《基于STM32的IAP设计文档Word格式.docx(9页珍藏版)》请在冰豆网上搜索。
2Bootloader实现原理
我们先来看看STM32正常的程序运行流程,如图2.1所示:
图2.1STM32正常运行流程图
STM32的部闪存(FLASH)地址起始于0x08000000,一般情况下,程序文件就从此地址开始写入。
此外STM32是基于Cortex-M3核的微控制器,其部通过一“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而这“中断向量表”的起始地址是0x08000004,当中断来临,STM32的部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。
在图2.1中,STM32在复位后,先从0X08000004地址取出复位中断向量的地址,并跳转到复位中断服务程序,如图标号①所示;
在复位中断服务程序执行完之后,会跳转到我们的main函数,如图标号②所示;
而我们的main函数一般都是一个死循环,在main函数执行过程中,如果收到中断请求(发生重中断),此时STM32强制将PC指针指回中断向量表处,如图标号③所示;
然后,根据中断源进入相应的中断服务程序,如图标号④所示;
在执行完中断服务程序以后,程序再次返回main函数执行,如图标号⑤所示。
当加入IAP程序之后,程序运行流程如图2.2所示:
图2.2加入IAP之后程序运行流程图
在图2.2所示流程中,STM32复位后,还是从0X08000004地址取出复位中断向量的地址,并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到IAP的main函数,如图标号①所示,此部分同图2.1一样;
在执行完IAP以后(即将新的APP代码写入STM32的FLASH,灰底部分。
新程序的复位中断向量起始地址为0X08000004+N+M),跳转至新写入程序的复位向量表,取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数,如图标号②和③所示,同样main函数为一个死循环,并且注意到此时STM32的FLASH,在不同位置上,共有两个中断向量表。
在main函数执行过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0X08000004中断向量表处,而不是新程序的中断向量表,如图标号④所示;
程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示;
在执行完中断服务程序后,程序返回main函数继续运行,如图标号⑥所示。
通过以上两个过程的分析,我们知道IAP程序必须满足两个要求:
1)新程序必须在IAP程序之后的某个偏移量为x的地址开始;
2)必须将新程序的中断向量表相应的移动,移动的偏移量为x;
3APP实现与配置
本章设计3个APP的情况,因为就是分配的flash扇区不同,所以就举例其中的一个。
3.1APP1程序起始地址设置方法
随便打开一个之前的实例工程,点击OptionsforTarget→Target选项卡,如图3.1所示:
图3.1FLASHAPP1Target选项卡设置
默认的条件下,图中IROM1的起始地址(Start)一般为0X08000000,大小(Size)为0X80000,即从0X08000000开始的512K空间为我们的程序存储。
而图中,我们设置起始地址(Start)为0X08010000,即偏移量为0X10000(64K字节),因而,留给APP用的FLASH空间(Size)只有0X80000-0X10000=0X70000(448K字节)大小了。
设置好Start和Szie,就完成APP1程序的起始地址设置。
APP2则为0X08020000+0X60000;
App3则为0X08030000+0X50000;
其实就是为每个app程序分配了4k的空间。
3.2中断向量表的偏移量设置
之前我们讲解过,在系统启动的时候,会首先调用systemInit函数初始化时钟系统,同时systemInit还完成了中断向量表的设置,我们可以打开systemInit函数,看看函数体的结尾处有这样几行代码:
#ifdefVECT_TAB_SRAM
SCB->
VTOR=SRAM_BASE|VECT_TAB_OFFSET;
/*VectorTableRelocationinInternalSRAM.*/
#else
CB->
VTOR=FLASH_BASE|VECT_TAB_OFFSET;
/*VectorTableRelocationinInternalFLASH.*/
#endif
从代码可以理解,VTOR寄存器存放的是中断向量表的起始地址。
默认的情况VECT_TAB_SRAM是没有定义,所以执行SCB->
对于FLASHAPP,我们设置为FLASH_BASE+偏移量0x10000,所以我们可以在FLASHAPP的main函数最开头处添加如下代码实现中断向量表的起始地址的重设:
VTOR=FLASH_BASE|0x10000;
如果是APP2可以设置为SCB->
VTOR=FLASH_BASE|0x20000;
如果是APP3可以设置为SCB->
VTOR=FLASH_BASE|0x30000;
这样,我们就完成了中断向量表偏移量的设置。
3.3*bin文件生成
不过MDK默认生成的文件是.hex文件,并不方便我们用作IAP更新,我们希望生成的文件是.bin文件,这样可以方便进行IAP升级。
这里我们通过MDK自带的格式转换工具fromelf.exe,来实现.axf文件到.bin文件的转换。
该工具在MDK的安装目录\ARM\BIN40文件夹里面。
本章,我们通过在MDK点击OptionsforTargetUser选项卡,在RunUserProgramsAfterBuild/Rebuild栏,勾选Run#1和DOS16,并写入:
D:
\Keil3.80a\ARM\BIN40\fromelf.exe--bin-o..\OBJ\TEST.bin..\OBJ\TEST.axf,如图3.2所示:
图3.2*bin文件生成设置
通过这一步设置,我们就可以在MDK编译成功之后,调用fromelf.exe(注意,我的MDK是安装在D:
\Keil3.80A文件夹下,如果你是安装在其他目录,请根据你自己的目录修改fromelf.exe的路径),根据当前工程的TEST.axf(如果是其他的名字,请记住修改,这个文件存放在OBJ目录下面,格式为xxx.axf),生成一个TEST.bin的文件。
并存放在axf文件相同的目录下,即工程的OBJ文件夹里面。
在得到.bin文件之后,我们只需要将这个bin文件传送给单片机,即可执行IAP升级。
3.4步骤总结
1)设置APP程序的起始地址和存储空间大小
2)设置中断向量表偏移量
3)设置编译后运行fromelf.exe,生成.bin文件.
4关键点
1)IAP程序必须满足两个要求:
1.新程序必须在IAP程序之后的某个偏移量为x的地址开始;
2.必须将新程序的中断向量表相应的移动,移动的偏移量为x;
2)STM32是按照半字读写数据到FLASH里面,所以串口收发数据时,必须设置一个收发完成标志,只有数据全部接受后方可执行更新。
而且接收完成到收发数据之间也必须设置一个延时才行。
3)必须先更新后执行,程序中相应的设置一个标志位。
Flag。
重点:
一定要为每个app分配好偏移地址。
//保留0X08000000~0X0800FFFF的空间为IAP使用
#defineFLASH_APP1_ADDR0x08010000//第一个应用程序起始地址(存放在FLASH)
#defineFLASH_APP2_ADDR0x08020000//第二个应用程序起始地址(存放在FLASH)
#defineFLASH_APP3_ADDR0x08030000//第三个应用程序起始地址(存放在FLASH)
附件:
函数一:
写入指定起始地址的FLASH空间
//appxaddr:
应用程序的起始地址
//appbuf:
应用程序CODE.
//appsize:
应用程序大小(字节).
voidiap_write_appbin(u32appxaddr,u8*appbuf,u32appsize)
{
u16t;
u16i=0;
u16temp;
u32fwaddr=appxaddr;
//当前写入的地址
u8*dfu=appbuf;
for(t=0;
t<
appsize;
t+=2)
{
temp=(u16)dfu[1]<
<
8;
temp+=(u16)dfu[0];
dfu+=2;
//偏移2个字节
iapbuf[i++]=temp;
if(i==1024)
{
i=0;
STMFLASH_Write(fwaddr,iapbuf,1024);
fwaddr+=2048;
//偏移204816=2*8.所以要乘以2.
}
}
if(i)STMFLASH_Write(fwaddr,iapbuf,i);
//将最后的一些容字节写进去.
}
函数二:
跳转执行FLASH
//跳转到应用程序段
用户代码起始地址.
voidiap_load_app(u32appxaddr)
{
if(((*(vu32*)appxaddr)&
0x2FFE0000)==0x20000000)//检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4);
//用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr);
//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app();
//跳转到APP.
函数三:
串口中断服务函数
if(USART_GetITStatus(USART1,USART_IT_RXNE)!
=RESET)//接收到数据
//USART_SendData(USART1,'
r'
);
res=USART_ReceiveData(USART1);
if(USART_RX_T<
USART_REC_LEN)
USART_RX_BUF[USART_RX_T]=res;
USART_RX_T++;
全局变量:
u8USART_RX_BUF[USART_REC_LEN]__attribute__((at(0X20001000)));
//串口接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20001000.
u16USART_RX_STA=0;
//接收状态标记
u16USART_RX_T=0;
//接收的字节数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STM32 IAP 设计 文档