标题:
STM32的BootLoader 从SD卡更新固件
[打印本页]
作者:
yuyang911220
时间:
2015-3-29 12:03
标题:
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
那里。
具体实现下面会再介绍,接下来介绍分散加载文件相关内容。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0