【新定义TBK-RD8T3x 触摸滑条和按键评估板】五、BootLoader原理深度解析
[复制链接]
- BootLoader理论内容
1.程序烧录方式
古老的烧录方式单片机诞生于20世纪80年代,以 51 为代表开始广泛应用于工业控制、家电等很多行业中。起初对于单片机的烧录,也就是将可执行的程序写入到其内部的ROM中,不是一件容易的事情,而且成本不低,因为需要依赖于专门的烧录设备。由于受到半导体技术与工艺的限制,对于ROM的烧写大多需要高压。这种境况一直持续到2000年左右,如图所示。
< class="p" align="center" style="">
ISP与ICP烧录方式随着低压电可擦写ROM的成熟,单片机开始集成可通过数字电平直接读写的存储介质。其最大的优势在于可实现在系统或在电路直接烧录程序,而无需像以前一样把单片机芯片从电路中拿出来,放到编程器上,这种烧录方式就是 ISP(In System Programming) 或 ICP(In Circuit Programming),如图所示。
< class="p" align="center" style="">
有人问过这样一个问题:“ISP和ICP我都听说过,都说是可以在电路板上直接烧录程序,而无需拿下芯片,那ISP和ICP有什么区别?”从广义上来说,两者没有区别,平时我们把其意义混淆也毫无问题。非要刨根问底的话,那可以这样来理解:ISP要求单片机中驻留有专门的程序,用以与上位机进行通信,接收固件数据并烧录到自身的ROM中,很显然ISP的单片机是需要可运行的,即要具备基本的最小系统电路(时钟和复位)。而 ICP 可以理解为 MCU 就是一块可供外部读写的存储电路,它不需要预置任何程序,也不需要单片机芯片处于可运行的状态。支持 ISP 或 ICP 的芯片,以AT89S51最为经典,当时从 AT89C51 换成 S51,多少人因此不再依赖烧录器而大呼爽哉。这种并口下载线非常流行,如图3.3,网上还有各种ISP小软件,可以说它降低了很多人入门单片机的门槛,让单片机变得喜闻乐见。一台电脑、一个S51最小系统板、一条并口ISP下载线,齐了!
< class="p" align="center" style="">
2.更方便的ISP烧录方式
串口ISP后来我们发现带有并口的电脑越来越少。那是在2005年前后,STC单片机开始大量出现,在功能上其实与S51相差无几,甚至比同期的一些高端51单片机还要逊色。但是它凭借一个优势让人们对它爱不释手,进一步降低了单片机的学习门槛。这个优势就是--串口ISP,这是真正意义上的 ISP,如图所示。
< class="p" align="center" style="">
各种USB ISP
串口ISP固然方便,但是下载速度是它的硬伤,当固件体积比较大的时候,比如一些大型嵌入式项目的固件动辄几百K,甚至几M,再用串口ISP就未免太慢了。所以一些单片机配有专门的USB ISP下载器。以下列举几种比较主流单片机及其USB ISP下载器。1) AVRAVR 单片机曾经盛极一时,但经历了 2016 年的缺芯风波之后,加之 STM32 的冲击,开始变得一蹶不振,鲜有人用了。与之配套的USB ISP下载器非常多样,有些是官方发布的,更多的是爱好者开源项目的成果,如图所示。
< class="p" align="center" style="">
2) C8051F
< class="p" align="center" style="">
3) MSP430
< class="p" align="center" style="">
我们会发现,一个具体良好生态的主流单片机,一定有配套的高效便捷的烧录下载工具。可见一种好的烧录方式,对单片机开发是多么重要。不论是串口 ISP 还是各种专用的 ISP 下载器,都有一些共同的弊端。
< class="p" style="">1、依赖于专门的上位机或下载器硬件,不能作到统型;
2、下载器价格仍然比较高,尤其是原厂的,这也是为什么有些单片机催生出很多第三方的下载器,比如 AVR;3、下载的时候通常需要附加额外的操作,比如STC要重新上电、STM32需要设置BOOT引脚电平等等。这些额外的操作都增加了烧录的复杂性。尤其是在产品形态下要去重新烧录程序,比如嵌入式升级,就要打开外壳,或将附加信号引出到壳外。这都是非常不高效,不友好的作法。如果有一种烧录方法,对于任何一种单片机:
< class="p" style="">1、通信方式统一(比如一律都用串口));
< class="p" style="">2、提供一个友好的操作界面(比如命令行方式);
< class="p" style="">3、高效快速,没有附加操作,最好一键自动化烧录;
< class="p" style="">4、另外再增加一些嵌入式固件管理的功能(比如固件版本管理)。
这一定会让我们事半功倍。Bootloader 就能实现上述的这一切!
< class="p" align="center" style="">
< class="p" align="center" style="">
再后来,9针串口都很少见了,只有USB。这促使一个烧录和调试神器炙手可热 -- USB TTL串口。这下232转换芯片省掉了,直接通过USB进行烧录。这种方式造福了无数的单片机学习者和工程师。多年来,在串口与单片机的交互上,我动了很多脑筋,这也是我乐于开发 Bootloader 的一个原因。我希望“USB串口在手,一切全有!”STC 并不是第一个使用串口 ISP 烧录程序的,但它是最成功和最深入人心的。与之同期的很多单片机,包括时至今日仍然应用最广泛的 STM32 全系列也都支持了串口 ISP,它成为了一种标配的、非常普遍的程序烧录手段。
3.关于Bootloader
Bootloader的基本形态
直接看图
< class="p" align="center" style="">
< class="p" style="">可以看到BL就是一段存储在ROM中的程序,它主要实现4个功能:
< class="p" style="">1、通过某种途径获取要烧录的固件数据;
< class="p" style="">2、将固件数据写入到ROM的APP区中;
< class="p" style="">3、跳转到APP区运行,将烧录进去的用户程序引导起来;
4、在此过程中,提供必要而友好的人机交互界面。这么说可能不好理解,我们还是通过实例来进行讲解。
Bootloader的两个设计实例
下面的两个实例,用于说明BL的实际应用形态,不涉及具体的实现细节,旨在让大家了解 BL 实际是如何运行的。带Shell命令行的串口BL
< class="p" style="">基本的操作逻辑如下:
< class="p" style="">1、通过超级终端、SecureCRT 或 Xshell 之类的串口终端输入命令 program;
< class="p" style="">2、BL 接收到命令后,开始等待接收固件文件数据;
< class="p" style="">3、串口终端通过某种文件数据传输协议(例如 X/Y/Zmodem协议)将固件数据传给BL;
< class="p" style="">4、BL 将固件数据写入到 ROM 的 APP 区中;
5、BL 将 APP 区中的程序引导运行起来。更具体的示意如图所示。
< class="p" align="center" style="">
这里把操作逻辑说得很简单,实际实现起来却并不容易,我们放在后面去细究其具体实现。插SD卡即烧录的BL
< class="p" style="">基本的操作逻辑如下:
< class="p" style="">1、将待烧录的固件拷贝到SD卡中;
< class="p" style="">2、将SD卡插入到卡槽中;
< class="p" style="">3、BL 检测到 SD 卡插入,搜索卡中 BIN 文件;
< class="p" style="">4、将 BIN 文件数据读出写入到 ROM 的 APP 区中;
5、BL 将 APP 区中的程序引导运行起来。 如图所示。
< class="p" align="center" style="">
通过这两个设计实例,大家应该已经了解BL是什么了吧。有没有感受到 BL 是比 ISP 烧录器更通用、更灵活、更友好、功能更强大的固件烧录和管理手段呢?有人可能知道 Linux 下的 Uboot,它就是一个强大的 BL,它提供非常强大的刷机(烧录操作系统镜像)的功能以及完备而灵活的Shell界面,如图所示。其实我们电脑的BIOS也是一种广义的BL。
< class="p" align="center" style="">
那如何实现一个BL呢?别急,要实现BL是需要满足一些基本要求的。
4.BL实现的要点
首先要说,并不是任何一个单片机都可以实现BL的,要满足几个要点。芯片体系架构要支持来看图
< class="p" align="center" style="">
我们知道单片机程序的最开头是中断向量表,包含了程序栈顶地址以及Reset程序入口,通过它才能把程序运行起来。很显然在从BL向APP跳转的时候,APP程序必须有自己的中断向量,并且而且单片机体系架构上要允许中断向量表的重定向。传统51单片机的中断向量表只允许放到ROM开头,而不能有偏移量,所以传统51单片机是不能支持BL的。有人要问“你这不是自相矛盾吗?你前面说STC的51单片机是支持串口ISP的,那它应该内置有ISP程序,我理解它应该和BL是一个道理。”没错,它内置的 ISP 程序就是一种 BL。STC 之所以可以实现 BL 功能,是因为宏晶半导体公司对它的硬件架构进行了改进,请看图
< class="p" align="center" style="">
可以看到,STC51 单片机多出了一块专门存放 BL 的 ROM,称为 BOOTROM。网上有一位叫 shaoziyang 的网友为 AVR 单片机写了一个 BL,还配套开发了一款叫 AVRUBD 的上位机,如图。(AVRUBD是很有用的,它可以让我们实现隔空烧录),实现了AVR单片机的串口烧录,让很多人摆脱了对USBISP之类ISP下载器的依赖(虽然ISP下载器已经很方便了,但它毕竟还需要银子嘛)。
< class="p" align="center" style="">
AVR 在硬件架构上与 STC51 是一个套路,如图所示。
< class="p" align="center" style="">
通过配置AVR的熔丝位可以控制复位入口地址以及BOOT区的大小和开始地址,如图所示。
< class="p" align="center" style="">
讲到这里,有人会说:“那有没有一种单片机,程序放在ROM的任何位置都可以运行起来,也就是中断向量表可以重定位?”当然有,这种单片机还很多,其中最典型的就是 STM32。它的程序之所以可以放之各地皆可运行,是因为在它的 NVIC 控制器中提供了中断向量表偏移量的相关配置,这个后面我们再详细说。ROM 要支持 IAP这也是需要单片机硬件支持的。很好理解,在 BL 获取到固件数据之后,需要将它写入到 ROM 的 APP 区中,所以说单片机需要支持 IAP 操作,所谓 IAP 就是 In Application Programming,即在应用烧录。也就是在程序运行过程中,可以对自身ROM进行擦除和编程操作。大家仔细想想是不是这样?似乎支持串口ISP的单片机都支持IAP功能。STC还把这一功能包装成了它的一大特色,可以用内部ROM来充当EEPROM的功能,可以在运行时记录一些掉电不丢失的参数信息。STM32 的 ROM 擦写在配套的固件库(标准库或HAL库)中已经有实现,大家可以参考或直接使用。APP程序的配套修改为了让BL可以顺利的将APP程序引导运行起来,APP 程序在开发的时候需要配合BL作出相应的修改。最重要的就是 APP 程序的开始地址(即中断向量表的开始地址)以及对中断控制器的相应配置。对于51、AVR这类单片机APP程序不用修改,具体原因大家应该明白。这里主要对 STM32 APP程序如何修改进行详细讲解。我们依然是结合实例,请看图所示。
< class="p" align="center" style="">
假设我们所使用的 STM32 的 ROM 总大小为 128KB,BL程序的体积是16K,APP程序紧邻BL,那么APP区的开始地址为0X08004000,也就是APP程序的中断向量表偏移地址为0X4000。如果我们使用MDK作为开发环境的话,需要修改这里,如图所示。
< class="p" align="center" style="">
而如果我们使用的是 gcc 的话,则需要对 link.ld 链接文件进行修改,如图3.18。
< class="p" align="center" style="">
然后我们还需要对NVIC的中断向量表相关参数进行配置,主要是中断向量表的偏移量,如下代码。
#define VECT_TAB_OFFSET 0x4000
OK,经过修改后的程序,我们把它放到 ROM 的 0X08004000 开始地址上,然后再让BL跳转到这个地址,我们的程序就能运行起来了。有人又会问:“BL中的跳转代码怎么写?”别急,这是我们要讲的下一个要点。BL中的跳转代码跳转代码是 BL 要点中的关键,直接关系到 APP 程序能否正常运行,如图
< class="p" align="center" style="">
我直接给出 STM32 的 jump_app 函数代码。
typedef void (*iapfun)(void);
iapfun jump2app;
void MSR_MSP(u32 addr)
{
__ASM volatile("MSR MSP, r0"); //set Main Stack value*
__ASM volatile("BX r14");*
}
void load_app(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)//**检查栈顶地址合法*
{
//**用户代码区第二个字为程序开始地址(**复位地址)
jump2app=(iapfun)\*(vu32\*)(appxaddr+4);
//**初始化APP**堆栈指针(**用户代码区的第一个字用于存放栈顶地址)
MSR_MSP(*(vu32*)appxaddr);
jump2app(); //**跳转到APP.
}
}这段代码大家自行研究,如果展开讲就属于赘述了。到这里BL相关的要点就介绍完了,大家应该有能力去完成一个简单的BL了。基于 STM32 设计的一个小实验,大家有兴趣可以小试牛刀一下,如图
< class="p" align="center" style="">
我们将 BL 程序用 Jlink 烧录到 0X08000000 位置,而把 APP 程序烧录到 0X08002000 开始位置,然后复位,如果串口打印了 hello world 或流水灯亮起来了,就说明我们的 BL 成功了。
- 本芯片BootLoader基本理论
- 基本介绍
在实现 Bootloader 功能时,需要把单片机的存储空间划成两大块,Bootloader 代码实现区域 LDROM 和用户代码区域 APROM。LDROM 用于存放 Bootloader 实现的一些 相关代码,如当前工作状态检查、程序跳转条件判断、通讯程序、烧写程序等,这部分的程序是用于完成对APROM 更新的程序,在应用中不可对其改写。APROM 就是用户的应用程序,该部分代码可通过 LDROM 里的 Bootloader 程序进行更新,在 RD8 系列单片中硬件划分了 LDROM 区域,使用硬件 LDROM 区域可以大幅度降低开发难度
BootLoader实现结构如下图:
BootLoader 程序被放在 LDROM 区,上电先执行 LDROM 中的 BootLoader 程序,BootLoader 程序会判断是否有更新命令到来,如果一段时间没有收到更新命令则进入 APROM 执行用户程序,收到更新命令后则继续执行 BootLoader 程序,将应用程序内容搬移到 APROM 区,在执行用户程序时如果收到更新命令则跳转到 BootLoader 程序。
- 程序设计流程
Bootloader 程序主要分为以下 3 个部分:
1、Bootloader 模式进入程序:用户可通过通讯命令或按键等方法进入该模式,进入该模式后允许用户对用户代码做更新处理,该程序位于 APP 中,用户在更新程序的时候务必保证更新的 APP 中具有此程序。本示例通过 UART 串口接收命令来进入 Bootloader 模式。
2、IAP 操作程序:实现对 APROM 指定区域进行 IAP 读写操作的代码。
3、通讯程序:用户可以采用串口传入更新代码,在本例程中使用 UART 串口做数据传输。
- 程序开发
前面一大堆的基础理论,现在开始实际操作,官方提供了BootLoader硬件程序和上位机软件,又芯片设计便配有BootLoader的程序空间等功能,这绝对是8051中非常优秀的设计了。
-
- BootLoader程序
- 开发串口通讯功能
- 程序代码交互的通讯协议,代码传输过程中,同样是使用十六进制的格式进行传递。以及需要有功能指令。
- 程序空间的存储,将接收到的APP程序存放在指定的地址空间当中。
- 基本功能逻辑,比如接收存放完成,运行APP程序,接收到程序更新命令,启动BootLoader升级程序。(IAP_S_lib中应该更新功能内容)
- 有的时候比如有显示屏,需要将升级的进度显示,等其他功能要求。(项目需求自行开发。。。)
3.2APP应用开发
- 程序运行到APP程序后BootLoader程序将会进入到一种停机的状态,因为它会将所有权限给到APP程序。那么所有APP需要开发BootLoader相关指令检测程序。
- 因为要检测BootLoader程序,顾需要初始化串口通讯。如果是spi升级那就要在写一下spi的,如果CAN升级也要写下CAN通讯的初始化化配置。
- 程序跳转,如果接收到程序升级指令,那么APP程序要将程序运行的起始地址跳转到BootLoader程序的起始地址,这样app程序停止运行,开始运行BootLoader升级程序。
- 至此,就可以开始其余功能开发。。如果没有以上的操作,那么程序将不可以重复升级。
3.3根据官方的程序进行验证
- BootLoader程序使用下载器link进行下载
- 注意事项,BootLoader程序下载的位置
- APP程序使用上位机软件下载,链接开发板上的TPYE—C接口
参考文献:
深入浅出BootLoader
https://mp.weixin.qq.com/s/rOjvERrcyfs4E9hfco5-pw
RD硬件Bootloader功能实现应用指南V1.0
|