STM32的BootLoader 从SD卡更新固件
- UID
- 1029342
- 性别
- 男
|
STM32的BootLoader 从SD卡更新固件
1. 前言自从几个月前接触到有Bootloader这回事,就有一种强烈的冲动,想写一个BootLoader出来。很快在飞思卡尔的Cortex-M4单片机上实现,已经是好几个月前的事情了。然后关于BootLoader的事搁在一边好久了,这次弄个STM32的BootLoader出来,Cortex-M3的,顺便发表下博客,跟大家分享一下。
。。。
又过了大半年了吧,慢慢对BootLoader的认识也有点长进啦。特别是跟网友讨论后发现BootLoader的实现还是需要靠BootLoader程序和App程序的配合才能正常使用。在这里特别感谢网友cary_yingj ,对本BootLoader的研究后发现App程序需要重定位中断向量表,才能正常工作。
在其他网友的反馈下,本人准备再将次文档完善,把不够详细的地方写得再详细,并且力求通俗易懂一点。希望对学习BootLoader的同学们有所帮助。
2. 初识BootLoader可能有的同学听说过BootLoader,有的同学没有听说过,这个都很正常。关于BootLoader的概念大家可以上网查一下,有比较详细的说明,我在这里说说我自己比较片面的理解,并且是针对CortexM3说明的,实现平台为STM32F103VET6。
2.1 百度百科的BootLoader这里借用一下百度百科对BootLoader的解释。在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。在一个基于ARM7TDMIcore的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。
2.2 BootLoader的简单理解BootLoader就是单片机启动时候运行的一段小程序,这段程序负责单片机固件更新,也就是单片机选择性的自己给自己下程序。可以更新也可以不更新,更新的话,BootLoader更新完程序后,跳转到新程序运行;不更新的话,BootLoader直接跳转到原来的程序去运行。
需要注意的是:BootLoader下载新程序后并不擦除自己(BootLoader程序还在),下次启动依然先运行BootLoader程序,又可以选择性的更新或者不更新程序,所以BootLoader就是用来管理单片机程序的更新。
这是本人的大概理解,大家有不明白请网上搜索一下更详细介绍吧。
2.3 BootLoader的作用BootLoader使单片机能自己给自己下载程序,所以在程序升级方面非常有作用。比如我们的BootLoader是通过GSM更新程序的,我们在升级单片机程序的时候,只要把新程序通过GSM发送给单片机,单片机自己实现程序更新,然后跳转到新程序执行,这样就省去我们很多升级的功夫啦。
可以想象一下如果把单片机安装在非常高的地方,或者危险的工业现场,或者封装得很难拆下来,我们很难直接给单片机下载程序,那么BootLoader的作用就体现出来了。简单的说,有了BootLoader,我们更新程序的话是省心又省力。
想想是不是很高级,还带点小兴奋哈哈。不用急,下面我们会继续介绍,让大家都能自己实现BootLoader。至于是通过什么方式升级,这个大家自由发挥,相信会设计出丰富多彩的BootLoader升级方式呢。
3.BootLoader预备知识我们这里是为ARM的Cortex-M3单片机写的BootLoader,需要了解一下M3内核的架构,并且要了解M3单片机是怎么启动的等等。这个方面的知识,可以参考《Cortex-M3权威指南》,这里的话我只是为了实现BootLoader简单介绍一下,大家有什么不清楚的请参考权威指南。并且这里是以STM32为例说明问题的,使用的开发环境是RVMDK(Keil)。
3.1 复位序列这里参考的是《Cortex-M3权威指南》的3.8节,复位序列。
M3单片机复位后,从0x00000000取栈指针(SP),从0x00000004取复位向量(PC),有了栈指针和复位向量后,单片机就按照正常流程运行了,在BootLoader里面,我们更新完程序后需要做的步骤之一就是设置栈指针,跳转到复位向量。
3.1.1 栈指针栈是一种数据结构,后进先出LIFO。借用百度百科的解释:栈由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。它使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放。
3.1.2 复位向量复位向量是一个函数地址,在CortexM3单片机里是复位函数的地址。也就是单片机启动后第一个执行的函数。
3.2 重定位中断向量表这里参考《Cortex-M3权威指南》的7.3节,向量表。
BootLoader是一个完整的程序,下载的新程序(以下称为App)也是一个完整的程序。都包含中断向量表,所以的话,我们是有两个中断向量表,相信因为有两个向量表,大家都知道我们应该需要对这两个向量表做点什么吧。
3.2.1 STM32的中断向量表我们只看前16个向量,因为其余的向量属于外设使用,与CortexM3内核无关。
__Vectors DCD __initial_spTop ;Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
__initial_spTop就是栈指针,Reset_Handler是复位向量。这里只显示了16个向量,CortexM3单片机的话总共有256个向量,也就是从栈指针的地址开始有1KB的区域属于中断向量表。
单片机启动默认先运行BootLoader,所以默认的中断向量表位置是BootLoader的中断向量表。为了App可以正常运行,下载完App后,我们还需要把中断向量表重新定位到App程序那里。根据《CortexM3权威指南》,介绍一下怎样重定位中断向量表。
3.2.2 设置中断向量表偏移Cortex-M3单片机有一个管理中断向量表的寄存器,叫做向量表偏移量寄存器(VTOR)(地址:0xE000_ED08)。具体可以看看截图:
从SD卡更新固件">
STM332程序的起始地址一般在0x08000000。所以BootLoader程序是在0x08000000,不是在0x00000000是因为STM32的重映射技术(不符合Cortex-M3的设计,有点搞另类的感觉)。所以BootLoader的中断向量表在0x08000000那里。如果我们的App程序起始地址在0x08070000,并且App的中断向量表在起始地址,那么BootLoader程序下载App后,为了App程序能正确运行,开始App程序的运行后第一步,就要把中断向量表重定位到0x08070000那里。
具体实现下面会再介绍,接下来介绍分散加载文件相关内容。 |
|
|
|
|
|