原创 Bootloader基础:让你的嵌入式设计具有前瞻性

2013-10-16 09:38 940 13 13 分类: MCU/ 嵌入式
世界上很少有什么项目能给嵌入式固件开发人员提供足够多的开发时间。事实上,嵌入式固件开发就好像气体一样,会占据它所在的整个空间。而这往往意味着项目结束阶段的测试和质量评估承受压力,进而提高风险。项目经理为如何跟上项目计划进度发愁,嵌入式设计人员和测试工程师也面临开发时间和测试覆盖质量之间的矛盾。要是所有人都能实现自己的目标该多好。要是硬件设计能在代码完成前就进一步推进该多好。要是固件测试在生产构造阶段也能继续进行该多好。要是整个团队都能明确如果设计情况不好,他们总是能够通过现场升级实现重大修改该多好。这样,所有人晚上都能睡个安稳觉,而通过适当利用嵌入式引导加载程序(bootloader),这完全有可能实现。 首先我们先明确一下有关术语。引导加载程序是一段常驻微处理器中的代码,有时也位于只读存储器(ROM)中(在工厂制造时编写)或者位于板载闪存存储器的预留区域。可加载引导代码能载入内存并作为正常工作期间在微处理器上运行的主应用代码。可加载引导代码可通过引导加载程序更新。产品固件的现场升级正是通过板载引导加载程序实现的。 那么,什么是引导加载程序呢?引导加载程序就是位于给定微控制器上受保护程序存储器中的一部分代码。它通常是加电启动或重启后运行的第一个软件,往往针对具体处理器和电路板。引导加载程序可视为一种“笨”代码,因为它并不了解需要执行什么应用,甚至也不了解器件功能是什么。引导加载程序专门用来理解如果通过任意数量的通讯协议与外部进行通讯(这些协议包括UART、I2C、SPI、CAN、以太网等),也可用来了解微控制器的存储器映射。引导加载程序在发挥作用时,负责与外部或主机进行通讯;读取主机发送的数据文件;更新它所在的微处理器,从而运行所提供的最新应用代码。

bootloader101-fig-1.jpg
图1:典型的嵌入式硬件架构。

引导加载程序可以在接收到人工操作员(也就是手动重启)或外设设备(即系统主机)的启动信号后开始工作,视具体嵌入式系统而定。引导加载程序信号首先确认引导加载程序本身是否有效,明确当前器件应用是否有效,与主机通讯并载入提交的新应用,随后根据指令执行应用闪存重写。大多数现代微控制器都能对自己的闪存重新编程。典型的引导加载程序在几微秒内就能完成这一工作。不过,存储器尺寸较大情况下,该时间就会大幅延长,有时甚至要花几秒钟才能完成一次更新。一旦完成加载引导,引导加载程序必须确认加载引导镜像,并将控制权交给加载引导代码。用于中断矢量的指针也必须进行设置。典型情况下,引导加载程序将进行软重启,以便让应用掌握控制。图2给出了引导加载程序的逻辑流程实例。

bootloader101-fig-2.jpg
图2:引导加载程序的逻辑流程。

由于引导加载程序是在制造过程中被编程到器件中,并且不是器件工作所必需的首要应用,因此实际上可以把它看作是“开销”代码。项目经理和嵌入式设计人员必须要考虑引导加载程序所带来的风险保护功能与其所占用的代码空间相比是否值得。由于这段代码要占用空间,许多设计人员需要尽可能减小引导加载程序的存储器占用量,从而将用于应用代码的存储器空间实现最大化。引导加载程序至少应提供:通讯通道、擦写并重新编程闪存存储器的方法以及确认和执行新应用代码的方法。 此外,引导加载程序应该能够检测、报告和处理加载引导操作过程中出现的错误,如断电、通讯损失、闪存写入错误等。一般通过存储应用的校验和或循环冗余代码(CRC)来实现闪存错误保护功能。加载引导操作开始后,这些位就会被清空。如果新的应用成功下载并安装,校验和就会被更新。如果下载过程中出错(通讯损失、断电等),那么引导加载程序会检测无效的校验位,且不会开始应用操作,而是与主机通讯,等待有效的加载引导操作。 《电子设计技术》网站版权所有,谢绝转载 还有一个重要的加载引导考虑因素,那就是避免代码本身覆盖引导加载程序所在的区域。如果引导加载程序尝试或无意中确实覆盖了自身,并出现了某种错误事件,那么引导加载程序会无法工作。下次处理器启动时,引导加载程序很可能会损坏。这种情况造成的影响可能有不同反映。引导加载程序可能无法打开到主机的通讯通道,或者系统可能无法将控制权交给上次有效的加载引导镜像。不管是什么情况,结果都需要对整个系统进行再编程。再编程通常需要由合格的技术人员利用可插入板上的开发工具来完成。这可能会影响人们对引导加载程序的兴趣。开发引导加载程序时,必须对器件存储器位置进行适当的控制,特别要注意确保存储器位置得到妥善管理,同时应用大小的变化不会错误地擦写或重写引导加载程序的存储区域。为了避免潜在的重写问题,某些微控制器甚至把引导加载程序放到硬编码的加载引导只读存储器(ROM)中,实现与闪存相分离,如图3所示。 下图显示了四个存储器空间实例。最左边的图是正常的非引导加载程序应用程序,典型的工具链将把应用代码放在地址0上,整个闪存存储器阵列都能作为应用代码空间。如果这种类型的系统作为发布产品进行实地使用,将无法实现远程修改。重启后,应用代码将开始执行。应用代码中的任何问题或瑕疵都将是永久性的。

bootloader101-fig-3.jpg
图3:引导加载程序和应用位置的存储器映射实例。

中间靠左的引导加载程序具备在ROM中存储的可加载引导镜像。这种配置能让全部闪存空间为应用所用,因为引导加载程序位于单独的ROM存储器中。这种方式能避免引导加载程序被错误地覆盖。不过,这种方法也无法对引导加载程序进行更新。ROM只能写入一次,如果发现瑕疵将无法再编程或修改。 中间靠右侧的图片中,引导加载程序位于地址0,重启后首先运行。一旦引导加载程序确定了可加载引导镜像有效,而且主机也没有发出对该部分进行重新镜像的命令,引导加载程序就会把控制权交给可加载引导应用。我们可以看到可加载引导镜像紧邻引导加载程序镜像结束的位置。这样能将用于可加载引导镜像的存储器空间实现最大化。在最后的镜像图中,有两部分存储器用于两种不同的加载引导事件。这种情况下,引导加载程序会根据主机要求决定在不同的启动操作下运行哪个应用。这种方法会占用双倍的闪存空间,因为它需要保存两个完整的应用程序,但它也是一种高效的设计方法,有助于工程师让单一器件在不同的主机指令条件下运行不同的工作。 《电子设计技术》网站版权所有,谢绝转载 引导加载程序最明显的优势就在于能现场解决故障。产品也能在功能升级方面受益。举例来说,我们知道客户会推出一些只提供基本功能的产品,以便加快投放市场的速度,随后再发布加载引导更新来升级操作系统驱动程序、产品功能和电源管理选项等。引导加载程序能够让设计团队在产品投放市场的同时制定未来硬件更新路线图。再举例来说,一些公司用无线电链路进行通讯,以实现设备的远程监控。这些公司发现通过无线电链路进行设备升级比让技术人员到远程站点更新固件的成本更低。可以设想一下在卡车运输领域对整个车队进行管理的情况。为代码升级改进这种小事就让一辆卡车暂停运输服务,那成本太高了。仅仅进行代码现场升级的成本就高达好几百美元。远程加载引导对需要现场更新的产品来说具有极大价值。 那么什么样的引导加载程序才是好的引导加载程序呢?这个问题会有很多答案,不过一个重要要求就是易用性。引导加载程序要能让设计人员方便地选择和连接到串行通讯端口,这非常重要。此外,要能通过简单的方法进入引导加载程序或绕开引导加载程序直接访问应用,这也非常重要。一旦创建出来,可加载引导镜像就依赖于引导加载程序。明确引导加载程序镜像在哪里结束以及应用从哪里开始,该过程非常繁琐且容易出错。好的引导加载程序应该可以自动解决这些问题,同时还要让设计人员灵活地使用多个应用镜像。可以实现双加载引导的系统有时被称为多应用引导加载程序。这种类型的引导加载程序会把新镜像载入到存储器中不同的区域。一旦确认,引导加载程序可能会复制新镜像以替代原有应用,或者直接执行新镜像。 下面看看赛普拉斯是如何在其PSoC3和PSoC5LP系列产品中支持引导加载程序的吧。如下图所示,通过下拉菜单选择通讯组件。可以设置用于进入引导加载程序的“命令等待”时间(图中为2秒)。设计人员还能选择校验和类型,这也非常方便。

bootloader101-fig4-1.jpg

bootloader101-fig4-2.jpg
图4:赛普拉斯引导加载程序配置工具。

在可加载引导侧提供识别版本修订的数字信息,这样固件就能自动确定新的可加载引导镜像是否已过期。图4显示出设计人员如何灵活地指定应用版本和ID。此外,设计人员还能手动将应用镜像移动到所需的存储器地址。最后要注意的一大关键问题就是存储器覆盖风险。工具链可自动确定引导加载程序结束和应用开始的地址,这样就能消除风险。由于使用引导加载程序的根本目的就是在战略上规避风险,因此这个功能的采用非常重要。 如果所有项目都按时进行,所有代码都完美,所有固件工程师都在硬件构造之前完成了代码,那么就无需使用引导加载程序了。但如果您与所有其他人一样处在现实世界中,那么您所在机构开发的任何嵌入式系统在采用引导加载程序后都会受益匪浅。引导加载程序能让产品在发布之后进行更新,实现灾难问题修复以及产品预订特性升级等不同需求。加载引导的主要问题在于必须考虑引导加载程序本身的灵活性和易用性,还有引导加载程序所使用的代码空间和配置。不过说到底,设计良好的引导加载程序可以挽救您的产品,挽救您的团队,帮您排忧解难。 《电子设计技术》网站版权所有,谢绝转载

文章评论0条评论)

登录后参与讨论
我要评论
0
13
关闭 站长推荐上一条 /2 下一条