STM32的BootLoader 从SD卡更新固件.docx
- 文档编号:24650169
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:11
- 大小:190.24KB
STM32的BootLoader 从SD卡更新固件.docx
《STM32的BootLoader 从SD卡更新固件.docx》由会员分享,可在线阅读,更多相关《STM32的BootLoader 从SD卡更新固件.docx(11页珍藏版)》请在冰豆网上搜索。
STM32的BootLoader从SD卡更新固件
一、什么是BootLoader
这个大家可以上网查一下,我在这里说说我自己比较片面的理解。
BootLoader就是单片机启动时候运行的一段小程序,这段程序负责单片机固件更新,也就是单片机选择性的自己给自己下程序。
可以更新也可以不更新,更新的话,BootLoader更新完程序后,跳转到新程序运行;不更新的话,BootLoader直接跳转到原来的程序去运行。
BootLoader下载新程序后并不擦除自己,下次启动依然先运行BootLoader程序,又可以选择性的更新或者不更新程序,所以BootLoader就是用来管理单片机程序的更新。
我的大概理解是这样,大家自己网上搜搜详细介绍吧。
二、BootLoader的作用
BootLoader使单片机能自己给自己下载程序,所以在程序升级方面非常有作用。
比如我们的BootLoader是通过GSM更新程序的,我们在升级单片机程序的时候,只要把新程序通过GSM发送给单片机,单片机自己实现程序更新,然后跳转到新程序执行,这样就省去我们很多升级的功夫啦。
可以想象一下如果把单片机安装在非常高的地方,或者危险的工业现场,或者封装得很难拆下来,我们很难直接给单片机下载程序,那么BootLoader的作用就体现出来了。
简单的说,有了BootLoader,我们省心又省力。
三、BootLoader预备知识
我们这里是为ARM的Cortex-M3单片机写的BootLoader,需要了解一下M3内核的架构,并且要了解M3是怎么启动的等等。
这个方面的知识,可以参考《Cortex-M3权威指南》,这里的话我只是简单介绍一下,大家有什么不清楚请参考权威指南。
并且这里是以STM32为例说明问题的,并且使用的开发环境是RVMDK。
3.1复位序列
这里参考的是《Cortex-M3权威指南》的3.8节,复位序列。
M3单片机复位后,从0x00000000取栈指针(SP),从0x00000004取复位向量(PC),有了栈指针和复位向量后,单片机就按照正常流程运行了,在BootLoader里面,我们更新完程序后需要做的步骤之一就是设置栈指针,跳转到复位向量。
3.2重定位中断向量表
这里参考《Cortex-M3权威指南》的7.3节,向量表。
BootLoader是一个完整的程序,下载的新程序也是一个完整的程序。
都包含中断向量表,所以的话,我们是有两个中断向量表。
单片机启动默认先运行BootLoader,所以默认的中断向量表位置是BootLoader的中断向量表。
为了新下载的程序可以正常运行,下载完新的程序后,我们需要把中断向量表重新定位到新下载的程序那里。
Cortex-M3单片机有一个管理中断向量表的寄存器,叫做向量表偏移量寄存器(VTOR)(地址:
0xE000_ED08)。
具体可以看看截图:
STM332的BootLoader程序一般是在0x08000000,不是在0x00000000是因为STM32的重映射技术(不符合Cortex-M3,有点搞另类的感觉),所以BootLoader的中断向量表在0x08000000那里。
如果我们新下载的程序在0x08060000,并且新程序的中断向量表在起始地址,那么下载完程序,为了新程序能正确运行,我们需要把中断向量表重定位到0x08060000那里,再跳转到新程序运行。
3.3C语言函数的地址
这一节设计的内容主要属于分散加载文件,大家具体上网了解,我只是简单介绍。
我们知道C语言名就是函数的地址,并且STM32单片机ROM的其实地址是0x08000000,那么使用编译器编(我使用的是RVMDK)译程序的话,函数的地址默认都在以0x08000000为首的一段内容里面了。
比如有可能我们一个函数的地址是0x08000167。
我们需要注意的问题是,如果不修改程序默认的起始地址的话,那么BootLoader和新下载的程序的起始地址都是0x08000000,也就是他们重叠了,这样的话肯定相互之间有影响,程序是不能正常工作的。
我这里的解决方法是,BootLoader程序依然占用0x08000000为首的那段ROM,因为STM32的Cortex-M3默认就是从0x08000000运行程序的,保持BootLoader程序先能正确运行。
然后新程序使用除BootLoader占用ROM以外的空间。
这里需要知道BootLoader到底占用了多少ROM,很简单,查看MAP文件就行了。
这里以我的BootLoader的MAP文件为例说明一下,看截图:
主要是这句话“Base:
0x08000000,Size:
0x00006da4,Max:
0x00080000”,我的BootLoader程序是从0x08000000开始,占用了0x00006DA4大小。
只要我们的新程序不要和BootLoader程序冲突就可以了。
编译新程序的时候,我们要修改程序的起始地址,我的修改方法如下(开发环境是RVMDK):
打开TargetOption...,切换到Target选项卡,如下
修改IROM1的起始地址和长度:
比如,为了不产生地址冲突,我将将下面的
修改成
再编译新程序。
注意:
BootLoader程序是不需要修改的,只是新程序需要修改(新程序就是使用BootLoader下载的程序)。
3.4hex文件和bin文件
平时我们用j-Link或者串口下载程序的话,都是打开hex文件下载的,因为hex文件包含地址信息,可以知道应该下载到哪个地址。
也就是hex文件是不能直接写进ROM的,一边写需要一边转换。
然后介绍一下bin文件,很好理解,bin文件是直接下载的,也就是bin文件的内容跟下载ROM里面的内容是一样的。
但是bin文件没有包含地址信息,所以在下载之前要知道具体下载到哪个地址。
我们的BootLoader下载的是bin文件,直接写进STM32的Flash里面,地址信息的话就是上一节的IROM,0x08070000,连续写入,中间不间断。
下面再介绍使用生成bin文件,工具的话是使用fromelf,熟悉命令行的同学可能会选择直接敲命令,不过这里我是使用RVMDK提供的用户命令。
打开TargetOption...,切换到User选项卡,如下
主要是在运行用户命令,Run#1
具体命令是:
C:
\Keil\ARM\ARMCC\bin\fromelf.exe--bin-o.\Output\MY_STM32.bin.\Output\MY_STM32.axf
简化一下是fromelf--bin-oxxx.binxxx.axf
1、fromelf的地址,我的地址是C:
\Keil\ARM\ARMCC\bin\fromelf.exe
2、--bin,生成bin文件
3、-o,输出
4、.\Output\MY_STM32.bin,生成的bin文件名
5、.\Output\MY_STM32.axf,源axf文件名,将axf转换成bin
四、分几步实现BootLoader
有了前面的基础知识后,应该是比较容易理解BootLoader需要怎么实现了。
这一章,我们分几个步骤,慢慢实现BootLoader。
4.1跑FAT文件系统
我们的BootLoader是从SD卡更新程序的,把在电脑上编译后的程序,也就是bin文件,复制到SD卡中,然后让单片机可以读取相应的bin文件,就可以实现程序的更新。
我跑的文件系统是FATFS_R0.07c,很经典的一个版本。
如果大家对文件系统方面不了解的话,自己网上查找教程,或者说很多同学对这一步应该已经很熟悉啦。
单片机上实现读取bin文件,结合Flash写入程序,就可以实现程序更新。
4.2读写Flash程序
要实现BootLoader,当然前提是可以写入Flash了。
STM32的话是很容易实现的,因为我们有官方库。
我使用的是3.0.0版本,参考官方例程,很容易实现Flash的读写,这里简单介绍一下。
第一步是解锁Flash,然后写入前先擦除Flash,再写入,最后读取校验写入是否正确。
调用了几个官方的库函数。
1、voidFLASH_Unlock(void),Flash解锁
2、FLASH_StatusFLASH_ErasePage(uint32_tPage_Address),Flash擦除
3、FLASH_StatusFLASH_ProgramWord(uint32_tAddress,uint32_tData),Flash写入
我只是稍微封装了一下几个函数,实现Flash的读写验证,具体我实现的接口函数为一下截图,大家可以大概参考一下:
4.3跳转到新程序运行
这一节要结合上面提到过的,Cortex-M3启动做了什么事情,然后我们更新程序后,就去做新程序需要做的事情,就算是调到新程序运行了。
主要有三个步骤:
1、重定位中断向量表
2、设置栈指针
3、跳转到复位向量
我的实现如下,看截图:
注意93行的((void(*)())(Reset))();是一去就不返回的,所以95行的returnFuncErr;只是形式而已,实际并不运行,而是在93行就直接跳转到新程序运行的。
至此,BootLoader实现步骤完了,相信熟悉了这几个步骤后,大家可以自己给自己的单片机写个BootLoader。
顺便说一下,Cortex-M4的BootLoader跟Cortex-M3几乎是一样的。
我在STM32上的实现完全是参考自己上次在飞思卡尔Cortex-M4上的实现。
下面形式的说一下我的主函数吧,看看具体流程。
五、具体流程
先看看我的主函数,再啰嗦一下具体流程,可能有的同学已经有点厌烦啦,其实感觉有点多余。
5.1主函数流程
1、时钟初始化
2、LED初始化(无关紧要)
3、调试接口初始化(无关紧要)
4、Flash初始化(解锁Flash)
5、FAT初始化(挂载文件系统)
6、我们的BootLoader(重点,下面展开继续介绍)
7、主循环(实际不会运行到这里)
5.2BootLoader流程
老样子,先上截图:
1、打开bin文件,检查文件打开是否正确
2、设置Flash下载起始地址(新程序起始地址)
3、读取文件,检查读取是否正确
4、获取栈指针和复位向量
5、进入循环,条件为如果读取文件字节数不为零
6、将读取到的bin写入Flash,并判写入状态
7、调整Flash地址
8、继续读取bin文件,检查读取是否正确,回到5继续循环
9、这里已经将bin写入Flash完成了,准备跳转到新程序运行
5.3跳转到新程序流程
其实上面已经讲过了,这里继续啰嗦,截图:
1、重定位中断向量
2、设置栈指针
3、跳转到复位向量(开始运行新程序)
啰嗦了又一遍,BootLoader完全结束,感谢大家都支持啦~
六、参考文献
【1】《CM3权威指南CnR2》JosephYiu著宋岩译
【2】ST官方库3.0.0
【3】《C和指针》KennethA.Reek著徐波译
【4】FATFS文件系统
其他互联网资料
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32的BootLoader 从SD卡更新固件 STM32 BootLoader SD 更新
![提示](https://static.bdocx.com/images/bang_tan.gif)