OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4382|回复: 10

基于STM32F103RBT6和V3.5固件库的Boot升级与APP回跳总结心得

[复制链接]

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
发表于 2016-9-20 21:56:10 | 显示全部楼层 |阅读模式
基于STM32F103RBT6V3.5固件库的Boot升级与APP
总结心得
这是我第一次写Bootloader,之前也只听说过这个,一直没有去做过。由于在网上看到的都是千篇一律的手册介绍,很少有干粮。为了后人少走弯路,故写下这篇文章,还望多指教。整个学习与编写分为三个过程:理论学习、学习例程以及动手编写代码;
学习期间主要看了原子哥的串口IAP程序以及ST官方例程。由于STM32F103RBT6SRAM只有20K,因此无法通过数组接收数据。我们采用的方案是串口中断接收,每满一页数据就写入一页,这样对SRAM的要求比较低。
首先,明确要实现的功能:
1) Bootloader中升级APP
2) APP运行过程中回跳到Bootloader
3) 我们系统的升级框架如下:
图片1.png
一、Boot升级
1. 为什么要用Bootloader?
我认为,在一定程度上选用Bootloader能够方便我们产品在量产后方便升级更新。当然还有就是觉得比较高大上吧~
2. 为什么要用hex文件升级,而不用bin文件?
很多人采用的是bin文件升级,而我们采用的是hex文件。之所以要选用hex文件升级的原因有很多,最重要的是hex的文件格式的特点。Hex文件是一行一行的,便于接收,而bin文件是二进制数据流。
详细的格式可以直接找度娘。我这仅简述一下我们用到的一些特点:
1) hex文件是一行一行的数据;可以用记事本或者UE打开看;
2) 每行数据组成为:’:’(行首)+Byte0(本行数据长度) + Byte1(本行数据起始地址MSB) + Byte2(本行数据起始地址LSB)+ Byte3(数据类型)+…(数据内容)+ Bytex(本行数据校验和)
3) 数据类型为0x01即表示此行代码为hex文件的最后一行。(文件结束)
3. hex校验和怎么计算?
Hex文件行尾为本行的校验和,校验和=0x100-累加和;累加和为从Byte0到校验和前一个字节数据的累加值(此处应注意,我们只取低16位)
4. 需要哪些基础知识?
基础知识主要还是参考CM3的手册
1) Bootloader简单的说就是接收升级文件,然后把升级文件写进Flash中,最后程序跳转到APP
2) STM32中小容量是1K1,而大容量则是以2K1页;同时,STM32写保护的基本单位是4K。官方手册上说的是“对于小容量和中容量的产品为4页;对于大容量的产品为2页。”
3) 其他的有关中断向量之类的理论请查阅手册。我就不在此赘述了。
5. 对Flash怎么操作?
通过Boot升级,对Flash的操作主要包括四部分:
1) 解锁Flash
通常情况下,我们为了防止程序被修改,会将Flash上锁;通过Boot升级时需要往Flash中写入数据,因此我们需要解锁Flash。通过调用库函数中的FLASH_Unlock()Flash解锁。FLASH_Unlock()中主要是打开FPEC模块。FLASH_KEYR寄存器中写入的KEY1=0x45670123,KEY2 = 0xCDEF89AB。错误的操作序列都会在下次复位前锁死FPEC模块和FLASH_CR寄存器。
图片2.png
2) 擦除Flash
由于我们参考了ST官方给出的例程,可以调用ymodem.c文件中的Erase_DataFlash()实现擦除Flash数据。
3) 写Flash
通过调用ymodem.c文件中的write_one_page来实现一页数据的写入
4) 上锁Flash
在操作完Flash后,需要对Flash上锁,同时在跳转前,需要关闭所有中断。
6. 如何实现?
通过上面讲述基本上对Bootloader会有一个较为清晰的认识;下面讲述其详细实现过程:
1) 在IAR环境下,设置产生HEX文件,OptionàOutput ConverteràOutput format选择Intel extended,详细过程请百度IAR环境下如何生成hex文件;
图片3.png
2) 设置Flash写入首地址,改地址就是APP的起始地址,在BOOTAPP程序中一定要对应起来,我们选用的APP址为0x8002000开始。
图片4.png
3) 设置一页数据的大小,我们设置的为1024
4) 解析图像发送过来的数据;图像发送给我的数据为“命令头+长度+设备号+内容+命令尾”
5) 当接收到得命令尾“K”则跳出循环,直接跳转到APP运行;若接收到的数据为“I”,则给图像发送“I”,表示我已经收到“I”,可以升级;
6) 当收到“I”后,发送“C”,让图像板发送hex文件头;
7) 解析文件头,看文件头是否跟我匹配,匹配则正式进入升级,若不匹配,则返回“E”,退出升级;
8) 解锁Flash,擦除Flash数据,随后发送“C”让图像发送下一行数据给我;
9) 将接收到得数据合并、重排,并进行校验和,若校验正确,则保存数据,发送“C”;若错误,则让图像重发,发送“E;
10) 一边接收一遍判断数据类型,若为0x01,则把当前已经缓存的数据写入Flash,跳转到12)步骤;若不是,跳转到11)步骤;
11) 判断当前接收数据是否满一页,若满一页则将缓存的数据写入Flash,跳转到9)步骤;若没满一页,则将接收到的数据缓存下来,跳转到9)步骤;
12) Flash上锁,关中断,跳转到APP
二、APP回跳到Boot
APP程序中,当接收到指令‘B’,我们需要跳转到Boot程序中进行升级;在此,提出两种方案,一是boot类似的回跳,二是软件复位
两种方法我都试了,但是,通过回跳方式跳过去以后MCU卡死,这个不知道怎么解决;因此最后选用软件复位方式,实现的;
void SoftReset(void)
{
  __set_FAULTMASK(1);      // 关闭所有中端
  NVIC_SystemReset();// 复位
}
该函数调用的两个子函数都为ST提供的(V3.5固件库)

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
 楼主| 发表于 2016-9-20 22:00:58 | 显示全部楼层
这是我自己写的心得体会,还请各位指出问题,由于刚进公司,且签订了保密协议,程序不敢提交,学习是以原子哥的程序入门,主要参考了ST的例程
回复 支持 反对

使用道具 举报

0

主题

20

帖子

0

精华

高级会员

Rank: 4

积分
847
金钱
847
注册时间
2012-6-16
在线时间
225 小时
发表于 2016-9-20 22:25:17 | 显示全部楼层
写的不错,很详细,赞
回复 支持 反对

使用道具 举报

5

主题

100

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
361
金钱
361
注册时间
2012-8-10
在线时间
40 小时
发表于 2016-9-23 07:36:58 来自手机 | 显示全部楼层
很详细,感谢分享!
回复 支持 反对

使用道具 举报

58

主题

359

帖子

0

精华

高级会员

Rank: 4

积分
987
金钱
987
注册时间
2014-9-29
在线时间
261 小时
发表于 2016-9-23 08:43:26 | 显示全部楼层
正常情况,开始运行后没有事件触发 会从bootloader直接跳到APP
你从app跳回去,bootloader怎么进行的?
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
 楼主| 发表于 2016-9-24 15:01:10 | 显示全部楼层
yuangaoping 发表于 2016-9-20 22:25
写的不错,很详细,赞

谢谢,只是懂了个皮毛,往深研究还是有很多不懂得
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
 楼主| 发表于 2016-9-24 15:04:29 | 显示全部楼层
闪电之舞 发表于 2016-9-23 08:43
正常情况,开始运行后没有事件触发 会从bootloader直接跳到APP
你从app跳回去,bootloader怎么进行的?

我做的这个是在接收到图像发送过来的指令后才从BOOT跳转到APP;而从APP跳转到BOOT,我最开始是想通过地址的跳转来实现(类似于boot跳app),但是后来发现跳转过去后直接卡死;所有的中断也关了,找不出原因。最终,使用一种比较流氓的做法,就是通过软件复位来实现,在APP中接收到命令后,通过软件复位,就跳转到了boot
回复 支持 反对

使用道具 举报

58

主题

359

帖子

0

精华

高级会员

Rank: 4

积分
987
金钱
987
注册时间
2014-9-29
在线时间
261 小时
发表于 2016-9-24 17:15:27 | 显示全部楼层
本帖最后由 闪电之舞 于 2016-9-24 17:17 编辑
cs1222 发表于 2016-9-24 15:04
我做的这个是在接收到图像发送过来的指令后才从BOOT跳转到APP;而从APP跳转到BOOT,我最开始是想通过地址 ...

哦,这样啊
那每次一开机,不就一直等图像?
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
 楼主| 发表于 2016-10-16 09:45:38 | 显示全部楼层
闪电之舞 发表于 2016-9-24 17:15
哦,这样啊
那每次一开机,不就一直等图像?

没错,工作机制就是这样的
回复 支持 反对

使用道具 举报

13

主题

314

帖子

0

精华

高级会员

Rank: 4

积分
713
金钱
713
注册时间
2012-7-20
在线时间
102 小时
发表于 2016-10-16 10:37:42 | 显示全部楼层
APP跳boot会卡死,是APP中用了boot里没使用的中断,没有指向向量.
互联网,智能设备爱好者,欢迎讨论任何有意思的想法。
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
136
金钱
136
注册时间
2015-3-21
在线时间
20 小时
 楼主| 发表于 2016-10-22 10:06:39 | 显示全部楼层
shibusha 发表于 2016-10-16 10:37
APP跳boot会卡死,是APP中用了boot里没使用的中断,没有指向向量.

app跳boot使用软件复位的话,是关闭了所有的中断的呀
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 06:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表