stm32f407 iap 需要做两个工程吗

STM32 STM32开发指南 IAP 串口 战舰 - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 2125|回复: 1
STM32 STM32开发指南 IAP 串口 战舰
主题帖子积分
初级会员, 积分 56, 距离下一级还需 144 积分
初级会员, 积分 56, 距离下一级还需 144 积分
串口IAP实验
IAP,即在应用编程。很多单片机都支持这个功能,STM32也不例外。在之前的FLASH模拟EEPROM实验里面,我们学习了STM32的FLASH自编程,本章我们将结合FLASH自编程的知识,通过STM32的串口实现一个简单的IAP功能本章分为如下几个部:
53.1 IAP简介
53.2 硬件设计
53.3 软件设计
53.4 下载验证
&div style=&layout-grid:&&15.6pt none&&IAP简介
IAP(In Application Programming)即在应用编程,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。 通常实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信方式(如USB、USART)接收程序或数据,执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。这两部分项目代码都同时烧录在User Flash中,当芯片上电后,首先是第一个项目代码开始运行,它作如下操作:   
1)检查是否需要对第二部分代码进行更新   
2)如果不需要更新则转到4)   
3)执行更新操作   
4)跳转到第二部分代码执行   
第一部分代码必须通过其它手段,如JTAG或ISP烧入;第二部分代码可以使用第一部分代码IAP功能烧入,也可以和第一部分代码一起烧入,以后需要程序更新是再通过第一部分IAP代码更新。  
我们将第一个项目代码称之为Bootloader程序,第二个项目代码称之为APP程序,他们存放在STM32 FLASH的不同地址范围,一般从最低地址区开始存放Bootloader,紧跟其后的就是APP程序(注意,如果FLASH容量足够,是可以设计很多APP程序的,本章我们只讨论一个APP程序的情况)。这样我们就是要实现2个程序:Bootloader和APP。 
STM32的APP程序不仅可以放到FLASH里面运行,也可以放到SRAM里面运行,本章,我们将制作两个APP,一个用于FLASH运行,一个用于SRAM运行。
我们先来看看STM32正常的程序运行流程,如图53.1.1所示:
图53.1.1 STM32正常运行流程图
STM32的内部闪存(FLASH)地址起始于0x,一般情况下,程序文件就从此地址开始写入。此外STM32是基于Cortex-M3内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而这张“中断向量表”的起始地址是0x,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。
在图53.1.1中,STM32在复位后,先从0X地址取出复位中断向量的地址,并跳转到复位中断服务程序,如图标号①所示;在复位中断服务程序执行完之后,会跳转到我们的main函数,如图标号②所示;而我们的main函数一般都是一个死循环,在main函数执行过程中,如果收到中断请求(发生重中断),此时STM32强制将PC指针指回中断向量表处,如图标号③所示;然后,根据中断源进入相应的中断服务程序,如图标号④所示;在执行完中断服务程序以后,程序再次返回main函数执行,如图标号⑤所示。
当加入IAP程序之后,程序运行流程如图53.1.2所示:
图53.1.2 加入IAP之后程序运行流程图
在图53.1.2所示流程中,STM32复位后,还是从0X地址取出复位中断向量的地址,并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到IAP的main函数,如图标号①所示,此部分同图53.1.1一样;在执行完IAP以后(即将新的APP代码写入STM32的FLASH,灰底部分。新程序的复位中断向量起始地址为0X+N+M),跳转至新写入程序的复位向量表,取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数,如图标号②和③所示,同样main函数为一个死循环,并且注意到此时STM32的FLASH,在不同位置上,共有两个中断向量表。
在main函数执行过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0X中断向量表处,而不是新程序的中断向量表,如图标号④所示;程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示;在执行完中断服务程序后,程序返回main函数继续运行,如图标号⑥所示。
通过以上两个过程的分析,我们知道IAP程序必须满足两个要求:
1) 新程序必须在IAP程序之后的某个偏移量为x的地址开始;
2) 必须将新程序的中断向量表相应的移动,移动的偏移量为x;
本章,我们有2个APP程序,一个为FLASH的APP,另外一个位SRAM的APP,图53.1.2虽然是针对FLASH APP来说的,但是在SRAM里面运行的过程和FLASH基本一致,只是需要设置向量表的地址为SRAM的地址。
1.APP程序起始地址设置方法
随便打开一个之前的实例工程,点击Options for TargetàTarget选项卡,如图53.1.3所示:
图53.1.3 FLASH APP Target选项卡设置
默认的条件下,图中IROM1的起始地址(Start)一般为0X,大小(Size)为0X80000,即从0X开始的512K空间为我们的程序存储区。而图中,我们设置起始地址(Start)为0X,即偏移量为0X5000(20K字节),因而,留给APP用的FLASH空间(Size)只有0X0=0X7B000(480K字节)大小了。设置好Start和Szie,就完成APP程序的起始地址设置。
这里的20K字节,需要大家根据Bootloader程序大小进行选择,比如我们本章的Bootloader程序为18K左右,理论上我们只需要确保APP起始地址在Bootloader之后,并且偏移量为0X200的倍数即可(相关知识,请参考:)。这里我们选择20K(0X5000)字节,留了一些余量,方便Bootloader以后的升级修改。
这是针对FLASH APP的起始地址设置,如果是SRAM APP,那么起始地址设置如图53.1.4所示:
图53.1.4 SRAM APP Target选项卡设置
这里我们将IROM1的起始地址(Start)定义为:0X,大小为0XA000(40K字节),即从地址0X偏移0X1000开始,存放APP代码。因为整个STM32F103ZET6的SRAM大小为64K字节,所以IRAM1(SRAM)的起始地址变为0X,大小只有0X5000(20K字节)。这样,整个STM32F103ZET6的SRAM分配情况为:最开始的4K给Bootloader程序使用,随后的40K存放APP程序,最后20K,用作APP程序的内存。这个分配关系大家可以根据自己的实际情况修改,不一定和我们这里的设置一模一样,不过也需要注意,保证偏移量为0X200的倍数(我们这里为0X1000)。
2.中断向量表的偏移量设置方法
此步,我们通过修改sys.c里面的MYRCC_DeInit函数实现,该函数代码如下:
void MYRCC_DeInit(void)
RCC-&APB1RSTR = 0x;//复位结束
RCC-&APB2RSTR = 0x;
RCC-&AHBENR = 0x;
//睡眠模式闪存和SRAM时钟使能.其他关闭.
RCC-&APB2ENR = 0x; //外设时钟关闭.
RCC-&APB1ENR = 0x;
RCC-&CR |= 0x;
//使能内部高速时钟HSION
RCC-&CFGR &= 0xF8FF0000;
//复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC-&CR &= 0xFEF6FFFF;
//复位HSEON,CSSON,PLLON
RCC-&CR &= 0xFFFBFFFF;
//复位HSEBYP
RCC-&CFGR &= 0xFF80FFFF;//复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
RCC-&CIR = 0x;
//关闭所有中断
//配置向量表
VECT_TAB_RAM
MY_NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);
该函数我们只需要修改最后两行代码,默认的情况下VECT_TAB_RAM是没有定义的,所以执行:MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);这是正常情况的向量表偏移量(为0),本章,我们修改这句代码为:MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH,0X5000);偏移量为0X5000。其中NVIC_VectTab_RAM和NVIC_VectTab_FLASH是在stm32f10x_nvic.h里面定义的两个宏定义,代表RAM和FLASH的起始地址。
以上是FLASH APP的情况,当使用SRAM APP的时候,我们需要定义VECT_TAB_RAM,点击Options for TargetàC/C++选项卡,在Preprocessor Symblols栏定义:VECT_TAB_RAM,如图54.1.5所示:
图53.1.5 SRAM APP C/C++选项卡设置
通过这个设置,我们定义VECT_TAB_RAM,故在执行MYRCC_DeInit函数的时候,会执行MY_NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 这里的0X0是默认的设置,本章我们修改此句代码为:MY_NVIC_SetVectorTable(NVIC_VectTab_SRAM,0X1000);即设置偏移量为0X1000。
这样,我们就完成了中断向量表偏移量的设置。
通过以上两个步骤的设置,我们就可以生成APP程序了,只要APP程序的FLASH和SRAM大小不超过我们的设置即可。不过MDK默认生成的文件是.hex文件,并不方便我们用作IAP更新,我们希望生成的文件是.bin文件,这样可以方便进行IAP升级(至于为什么,请大家自行百度HEX和BIN文件的区别!)。这里我们通过MDK自带的格式转换工具fromelf.exe,来实现.axf文件到.bin文件的转换。该工具在MDK的安装目录\ARM\BIN40文件夹里面。
fromelf.exe转换工具的语法格式为:fromelf [options] input_file。其中options有很多选项可以设置,详细使用请参考光盘《mdk如何生成bin文件.pdf》.
本章,我们通过在MDK点击Options for TargetàUser选项卡,在Run User Programs After Build/Rebuild 栏,勾选Run#1和DOS16,并写入:D:\Keil3.80a\ARM\BIN40\fromelf.exe
..\OBJ\TEST.bin ..\OBJ\TEST.axf ,如图53.1.6所示:
通过这一步设置,我们就可以在MDK编译成功之后,调用fromelf.exe(注意,我的MDK是安装在D:\Keil3.80A文件夹下,如果你是安装在其他目录,请根据你自己的目录修改fromelf.exe的路径),根据当前工程的TEST.axf,生成一个TEST.bin的文件。并存放在axf文件相同的目录下,即工程的OBJ文件夹里面。在得到.bin文件之后,我们只需要将这个bin文件传送给单片机,即可执行IAP升级。
最后再来看看APP程序的生成步骤:
1)设置APP程序的起始地址和存储空间大小
对于在FLASH里面运行的APP程序,我们只需要设置APP程序的起始地址,和存储空间大小即可。而对于在SRAM里面运行的APP程序,我们还需要设置SRAM的起始地址和大小。无论哪种APP程序,都需要确保APP程序的大小和所占SRAM大小不超过我们的设置范围。
2)设置中断向量表偏移量
此步,通过在MYRCC_DeInit函数里面调用MY_NVIC_SetVectorTable函数,实现对中断向量表偏移量的设置。这个偏移量的大小,其实就等于程序起始地址相对于0X或者0X的偏移。对于SRAM APP程序,我们还需要在C/C++选项卡定义VECT_TAB_RAM,以申明中断向量表是在SRAM里面。
3)设置编译后运行fromelf.exe,生成.bin文件.
通过在User选项卡,设置编译后调用fromelf.exe,根据.axf文件生成.bin文件,用于IAP更新。
以上3个步骤,我们就可以得到一个.bin的APP程序,通过Bootlader程序即可实现更新。
本章实验(Bootloader部分)功能简介:开机的时候先显示提示信息,然后等待串口输入接收APP程序(无校验,一次性接收),在串口接收到APP程序之后,即可执行IAP。如果是SRAM APP,通过按下KEY0即可执行这个收到的SRAM APP程序。如果是FLASH APP,则需要先按下WK_UP按键,将串口接收到的APP程序存放到STM32的FLASH,之后再按KEY2既可以执行这个FLASH APP程序。通过KEY1按键,可以手动清除串口接收到的APP程序。DS0用于指示程序运行状态。
本实验用到的资源如下:
1) 指示灯DS0
2) 四个按键(KEY0/KEY1/KEY2/WK_UP)
4) TFTLCD模块
这些用到的硬件,我们在之前都已经介绍过,这里就不再介绍了。
本章,我们总共需要3个程序:1,Bootloader;2,FLASH APP;3)SRAM APP;其中,我们选择之前做过的RTC实验(在第二十章介绍)来做为FLASH APP程序(起始地址为0X),选择触摸屏实验(在第三十一章介绍)来做SRAM APP程序(起始地址为0X)。Bootloader则是通过TFTLCD显示实验(在第十八章介绍)修改得来。本章,关于SRAM APP和FLASH APP的生成比较简单,我们就不细说,请大家结合光盘源码,以及53.1节的介绍,自行理解。本章软件设计仅针对Bootloader程序。
复制第十八章的工程(即实验13),作为本章的工程模版(命名为:IAP Bootloader V1.0),并复制第三十九章实验(FLASH模拟EEPROM实验)的STMFLASH文件夹到本工程的HARDWARE文件夹下,打开本实验工程,并将STMFLASH文件夹内的stmflash.c加入到HARDWARE组下,同时将STMFLASH加入头文件包含路径。
在HARDWARE文件夹所在的文件夹下新建一个IAP的文件夹,并在该文件夹下新建iap.c和iap.h两个文件。然后在工程里面新建一个IAP的组,将iap.c加入到该组下面。最后,将IAP文件夹加入头文件包含路径。
打开iap.c,输入如下代码:
#include &sys.h&
#include &delay.h&
#include &usart.h&
#include &stmflash.h&
#include &iap.h&
iapfun jump2
u16 iapbuf[1024];
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
u32 fwaddr=//当前写入的地址
本帖子中包含更多资源
您需要 才可以下载或查看,没有帐号?
主题帖子积分
新手上路, 积分 7, 距离下一级还需 43 积分
新手上路, 积分 7, 距离下一级还需 43 积分
RE:STM32 STM32开发指南 IAP 串口 战舰
您这个例程能用吗?
站长推荐 /1
欢迎大家分享基于STM32 Nucleo板的设计方案,社区将提供500-3000元不等的开发经费支持——赶紧来赢取ST MCU社区赞助吧!
Tel: 3-8056
备案号: 苏ICP备号-2
Powered by上海银洋电子有限公司_STM32F0\应用笔记\使用STM32F0xx系列微控制器的USART模块实现IAPSTM32用户基于IAP的程序更新技术STM32系列基于专为要求高性能、低成本、低功耗..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
STM32用户基于IAP的程序更新技术
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口STM32运行两个工程,互不干扰,这个要怎么做?
40dwiller]
编辑:www.fx114.net
本篇文章主要介绍了"STM32运行两个工程,互不干扰,这个要怎么做?
40dwiller]",主要涉及到STM32运行两个工程,互不干扰,这个要怎么做?
40dwiller]方面的内容,对于STM32运行两个工程,互不干扰,这个要怎么做?
40dwiller]感兴趣的同学可以参考一下。
如题,有没有谁有这样的例子或者思路给我参考下,
想了2天也不知道改怎么做
谢了!UcOS&II&任务调度引用&1&楼&zhujinqiang&的回复:UcOS&II&任务调度估计我没表述清楚,
我就想把IAP和APP放在同一工程下,而不是弄成2个独立的工程引用&2&楼&dwiller&的回复:Quote: 引用&1&楼&zhujinqiang&的回复:
UcOS&II&任务调度估计我没表述清楚,
我就想把IAP和APP放在同一工程下,而不是弄成2个独立的工程2者建一个keil工程?引用&3&楼&zhxianbin&的回复:Quote: 引用&2&楼&dwiller&的回复:
Quote: 引用&1&楼&zhujinqiang&的回复:
UcOS&II&任务调度估计我没表述清楚,
我就想把IAP和APP放在同一工程下,而不是弄成2个独立的工程2者建一个keil工程?
是的!引用&3&楼&zhxianbin&的回复:Quote: 引用&2&楼&dwiller&的回复:
Quote: 引用&1&楼&zhujinqiang&的回复:
UcOS&II&任务调度估计我没表述清楚,
我就想把IAP和APP放在同一工程下,而不是弄成2个独立的工程2者建一个keil工程?
不清楚STM32是不是可以在APROM中更新APROM,是的话理论上应该可以不过就麻烦点,IAP一个任务.APP一个任务,地址指定,更新时锁定任务调度只执行IAP任务,让IAP去更新APP.没这样做过,实际行不行我也不知道
我用的一个是不行的,想实现自动更新必须得2个工程1.新建一个工程专门用来做IAP&的
2.一个普通的应用代码
3.将两个工程生成的Hex或者bin合并.合并的方法就先学习一下map的原理
4.普通应用代码需要升级的时候直接将PC跳转到IAP部分的代码.(IAP的地址在合成的时候你自己就应该要知道的)/thread--1.html宏定义---条件编译keil包含这个功能
project-&manage-&componet&新建一个TARGET&
使用时直接切换TARGET就行了引用&7&楼&zhxianbin&的回复:/thread--1.html
这个帖子我看过,2个工程的我可以实现IAP引用&5&楼&wangfan027&的回复:Quote: 引用&3&楼&zhxianbin&的回复:
Quote: 引用&2&楼&dwiller&的回复:
Quote: 引用&1&楼&zhujinqiang&的回复:
UcOS&II&任务调度估计我没表述清楚,
我就想把IAP和APP放在同一工程下,而不是弄成2个独立的工程2者建一个keil工程?
不清楚STM32是不是可以在APROM中更新APROM,是的话理论上应该可以不过就麻烦点,IAP一个任务.APP一个任务,地址指定,更新时锁定任务调度只执行IAP任务,让IAP去更新APP.没这样做过,实际行不行我也不知道
我用的一个是不行的,想实现自动更新必须得2个工程
我也想这么做,就是把FLASH分成2段,一段用启动代码,还有一段自己写个启动代码,就可以把这两段衔接起来了,就是没什么具体的例子,牵涉的汇编比较多,在尝试........引用&6&楼&zhong&的回复:1.新建一个工程专门用来做IAP&的
2.一个普通的应用代码
3.将两个工程生成的Hex或者bin合并.合并的方法就先学习一下map的原理
4.普通应用代码需要升级的时候直接将PC跳转到IAP部分的代码.(IAP的地址在合成的时候你自己就应该要知道的)
难道我理解错了意思,只能两个工程来做我用STM32f103是只能两个工程的,一个IAP,一个APP,编译好的bin文件可以合并为一个的我也是使用两个工程来做的。感觉像是IAP类似的功能。如果你是想在Flash中存放两个独立的程序,例如A和B,按某个条件来决定当前是运行A还是B。那么建议你写个用户boot程序,判断了这个条件后再决定运行A还是B。
这里关键要注意中断向量表的重映射(除非你完全不会用到任何和中断向量表相关的东西,但这几乎不可能),后面就跳转到A或B就玩了。
甚至A在编译时知道B中某个函数的地址时,也可以在运行A时去调用这个B中的函数,有点像动态链接的感觉。引用&15&楼&lr2131&的回复:感觉像是IAP类似的功能。如果你是想在Flash中存放两个独立的程序,例如A和B,按某个条件来决定当前是运行A还是B。那么建议你写个用户boot程序,判断了这个条件后再决定运行A还是B。
这里关键要注意中断向量表的重映射(除非你完全不会用到任何和中断向量表相关的东西,但这几乎不可能),后面就跳转到A或B就玩了。
甚至A在编译时知道B中某个函数的地址时,也可以在运行A时去调用这个B中的函数,有点像动态链接的感觉。
我其实就是在写IAP,那根据你的意思是不是要分成3段,boot程序占开始的一段,然后A,B分别存放在FLASH的另外两段??
请问你有STM32&这种方法的IAP程序吗?能参考下吗,谢了!流程图也行引用&16&楼&dwiller&的回复:Quote: 引用&15&楼&lr2131&的回复:
感觉像是IAP类似的功能。如果你是想在Flash中存放两个独立的程序,例如A和B,按某个条件来决定当前是运行A还是B。那么建议你写个用户boot程序,判断了这个条件后再决定运行A还是B。
这里关键要注意中断向量表的重映射(除非你完全不会用到任何和中断向量表相关的东西,但这几乎不可能),后面就跳转到A或B就玩了。
甚至A在编译时知道B中某个函数的地址时,也可以在运行A时去调用这个B中的函数,有点像动态链接的感觉。
我其实就是在写IAP,那根据你的意思是不是要分成3段,boot程序占开始的一段,然后A,B分别存放在FLASH的另外两段??
请问你有STM32&这种方法的IAP程序吗?能参考下吗,谢了!流程图也行
是分成3个程序,第一个是用户boot程序,也就是系统启动后运行的第一个用户程序。
然后是A和B两个程序。这3个程序都是分开用独立的工程来编写和编译,烧写时当然也可以分开3次烧写,或者整合到一个大的烧写文件中烧写。
如果需要升级,在用户boot程序中完成升级切跳转到新程序的功能,如果不需要升级,就按条件跳转到A或是B中。我列出解决这种问题的简单架构和流程吧:
Flash中存放有用户boot程序、用户A程序和用户B程序。A和B程序一般是解决主体需求的用户程序,假如说xp操作系统就是A,ubuntu就是B。用户boot程序是用来升级和跳转引导程序,类似于双系统中的grub。
flash中某个地址M存放一个数据,用来标记当前是否需要升级。
flash中某个地址N存放一个数据,用来标记当前跳转到哪里。
一、用户boot程序:
&&&&上电后最先运行的用户程序,前面一般要运行系统的boot程序,这里不需要讨论它。
&&&&1).先检测在地址M处的标记,如果是0,表示当前不需要升级。
&&&&2)那么接下来就需要跳转到用户的应用程序程序A或是B中,这只需要读一下地址N处的数据就可以了。
&&&如果在步骤1)中读到的标记是需要升级,接下来的步骤是:
&&&&2)把M处的数据改写为不需要升级了,接下来的工作就是升级工作。
&&&&3)把另一个不会被擦掉的地址标记写到N中,这样如果后面的升级工作失败,用户boot程序就不会跳转到这个升级失败的地址中,也就不会出问题了。
&&&&4)通过串口或者其他通信方式,USB或SD也是可以的,把升级数据从外部获取到。
&&&&5)把升级数据写入到flash中
&&&&6)最后烧写成功就把N标记为烧写成功的新地址,以后用户boot程序选择从这个烧写成功的地址引导程序。
&&&&7)和上面不升级的第2)步一样,跳转到新程序中。
二,用户A和B程序
A和B的主体功能可能一样也可能不一样,这不讨论,但是一般要求当前不管是在A中还是B中都支持升级,那么A和B都有一部分一样的代码,也就是升级功能的前半部分代码:
&&&&&1)当前收到控制命令,需要升级。那么先把地址M处的数据改写为1,表示要升级。
&&&&&2)软复位到用户boot程序的首地址,或者硬复位也可以。
主要是理清楚M和N在什么时候什么地方读和写,读到是多少该怎么处理,写成多少表示什么意思。
没有给出实际的工程代码,不过个人觉得以上的描述应该差不多了。参考地址:
/thread--1.html
所有代码开源引用&19&楼&u&的回复:参考地址:
/thread--1.html
所有代码开源
我注册不了阿莫的论坛,这个好像隐藏了很多附件引用&18&楼&lr2131&的回复:我列出解决这种问题的简单架构和流程吧:
Flash中存放有用户boot程序、用户A程序和用户B程序。A和B程序一般是解决主体需求的用户程序,假如说xp操作系统就是A,ubuntu就是B。用户boot程序是用来升级和跳转引导程序,类似于双系统中的grub。
flash中某个地址M存放一个数据,用来标记当前是否需要升级。
flash中某个地址N存放一个数据,用来标记当前跳转到哪里。
一、用户boot程序:
&&&&上电后最先运行的用户程序,前面一般要运行系统的boot程序,这里不需要讨论它。
&&&&1).先检测在地址M处的标记,如果是0,表示当前不需要升级。
&&&&2)那么接下来就需要跳转到用户的应用程序程序A或是B中,这只需要读一下地址N处的数据就可以了。
&&&如果在步骤1)中读到的标记是需要升级,接下来的步骤是:
&&&&2)把M处的数据改写为不需要升级了,接下来的工作就是升级工作。
&&&&3)把另一个不会被擦掉的地址标记写到N中,这样如果后面的升级工作失败,用户boot程序就不会跳转到这个升级失败的地址中,也就不会出问题了。
&&&&4)通过串口或者其他通信方式,USB或SD也是可以的,把升级数据从外部获取到。
&&&&5)把升级数据写入到flash中
&&&&6)最后烧写成功就把N标记为烧写成功的新地址,以后用户boot程序选择从这个烧写成功的地址引导程序。
&&&&7)和上面不升级的第2)步一样,跳转到新程序中。
二,用户A和B程序
A和B的主体功能可能一样也可能不一样,这不讨论,但是一般要求当前不管是在A中还是B中都支持升级,那么A和B都有一部分一样的代码,也就是升级功能的前半部分代码:
&&&&&1)当前收到控制命令,需要升级。那么先把地址M处的数据改写为1,表示要升级。
&&&&&2)软复位到用户boot程序的首地址,或者硬复位也可以。
主要是理清楚M和N在什么时候什么地方读和写,读到是多少该怎么处理,写成多少表示什么意思。
没有给出实际的工程代码,不过个人觉得以上的描述应该差不多了。
非常感谢!比较明白了,还有一个问题:就是分散加载的时候,是配置成一个加载域多个执行域,还是多个加载域??就是boot程序,A程序各分配一个加载域,还是一个加载域,各分配一个执行域呢??boot、A和B都是各自独立的工程,分散加载脚本的写法就用一般的最好,都是一个加载域和一个运行域。当然,代码的加载域一定都是在ROM中(说flash也行),运行域可以在ROM中,也可以在RAM中。如果运行域在ROM中,那么运行域和加载域就一样了。如果运行域在RAM中的话,编译时,编译器会在启动代码中的汇编部分来完成拷贝加载域到运行域的工作,不需要用户关心。在RAM中运行代码的话一般比在ROM中快。引用&22&楼&lr2131&的回复:boot、A和B都是各自独立的工程,分散加载脚本的写法就用一般的最好,都是一个加载域和一个运行域。当然,代码的加载域一定都是在ROM中(说flash也行),运行域可以在ROM中,也可以在RAM中。如果运行域在ROM中,那么运行域和加载域就一样了。如果运行域在RAM中的话,编译时,编译器会在启动代码中的汇编部分来完成拷贝加载域到运行域的工作,不需要用户关心。在RAM中运行代码的话一般比在ROM中快。
难道一定要分成好几个工程?
我是这么想的,放在一个工程中,通过分散加载来定位不同的FLASH段。
int&main(void)
&&&boot程序
&&&while(1)
&&&&&&&用户程序
但是我也就在想,如果跳转到用户程序去了(因为boot程序已经改动过芯片的配置),那个时钟,GPIO端口,中断向量等就需要重新配置了?是不是跳转到用户程序的时候,也需要复位时钟,配置中断向量等啊??如果你是想按你上面那样的伪代码方式来做,A和B两个功能代码都在一个工程中,或者说可以直接切换,那为什么又不愿意像上面的人说的那样用UCOS2操作系统提供的多任务来做了。
实在不知道你的需求是什么?或许是多个人有不同的说法,把你的思路弄乱了。
如果按你上面那样安排,当然这其实和IAP是没有什么关系的。也不需要有什么用户boot程序的选择性跳转了。但如果是做成多个工程,那个时钟,GPIO端口,中断向量重映射等等要再次初始化就初始化呗,也没什么坏处和难处吧。引用&24&楼&lr2131&的回复:如果你是想按你上面那样的伪代码方式来做,A和B两个功能代码都在一个工程中,或者说可以直接切换,那为什么又不愿意像上面的人说的那样用UCOS2操作系统提供的多任务来做了。
实在不知道你的需求是什么?或许是多个人有不同的说法,把你的思路弄乱了。
如果按你上面那样安排,当然这其实和IAP是没有什么关系的。也不需要有什么用户boot程序的选择性跳转了。但如果是做成多个工程,那个时钟,GPIO端口,中断向量重映射等等要再次初始化就初始化呗,也没什么坏处和难处吧。
其实我也想弄成好几个工程的,只是领导规定要这样,我也没办法,谢谢你了!领导都管这个了,哎,做出来能用不就好了嘛
本文标题:
本页链接:}

我要回帖

更多关于 stm32f107 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信