什么是引导加载程序,我将如何开发它?

电器工程 微控制器 avr 引导加载程序
2022-01-20 00:52:44

我遇到过许多项目,其中 AVR 微控制器与引导加载程序(例如 Arduino)一起使用,但我不太了解这个概念。

如何制作引导加载程序(适用于任何微控制器)?

写完我的引导加载程序后,它是如何编程到微控制器的(就像在 AVR 的闪存 rom 上烧录的任何 .hex 程序,或其他方法一样)?

3个回答

引导加载程序是在要编程的微控制器中运行的程序。它通过某种通信方式从外部接收新的程序信息,并将该信息写入处理器的程序存储器。

这与将程序输入微控制器的正常方式形成对比,后者是为此目的通过微控制器中内置的特殊硬件。在 PIC 上,这是一个类似 SPI 的接口。如果我没记错的话,AVR 使用 Jtag,或者至少其中一些使用 Jtag。无论哪种方式,这都需要一些外部硬件来正确摆动编程引脚以将信息写入程序存储器。描述程序存储器内容的 HEX 文件源自通用计算机,因此该硬件一方面连接到计算机,另一方面连接到微控制器的特殊编程引脚。我的公司把PIC 程序员作为副业,所以我对 PIC 的这个过程非常熟悉。

通过专用硬件进行外部编程的重要一点是,无论程序存储器的现有内容如何,​​它都可以工作。微控制器开始时程序存储器被擦除或处于未知状态,因此外部编程是将第一个程序放入微控制器的唯一方法。

如果您确定要加载到您的产品中的程序并且您的数量足够高,您可以为您提供制造商或分销商程序芯片。该芯片像任何其他芯片一样被焊接到板上,并且该单元已准备就绪。例如,这可能适用于玩具之类的东西。一旦固件完成,它就已经完成了,它将被大量生产。

如果您的产量较低,或者更重要的是,您希望持续进行固件开发和错误修复,您就不想购买预编程芯片。在这种情况下,空白芯片安装在电路板上,作为生产过程的一部分,固件必须加载到芯片上。在这种情况下,必须以某种方式使硬件编程线可用。如果您愿意创建生产测试夹具,这可以通过显式连接器或 pogo pin pads 实现。通常此类产品必须经过测试并且可能无论如何都要校准,因此将程序写入处理器的额外成本通常是最小的。有时,当使用小型处理器时,首先将特殊的生产测试固件加载到处理器中。这用于方便测试和校准单元,然后在已知硬件良好后加载真正的固件。在这种情况下,有一些电路设计考虑允许充分访问编程线以使编程过程工作,但也不会给电路带来太多不便。有关这方面的更多详细信息,请参阅我的在线编程写作。

到目前为止一切顺利,不需要引导加载程序。但是,考虑一个固件相对复杂的产品,您希望可以现场升级,甚至允许最终客户升级。即使您提供了一个,您也不能期望最终客户拥有一个程序员小工具,或者知道如何正确使用它。实际上,我的一位客户就是这样做的。如果您购买他们的特殊领域定制选项,您会得到我的一位程序员使用该产品。

但是,在大多数情况下,您只希望客户在 PC 上运行程序并神奇地更新固件。这就是引导加载程序的用武之地,特别是如果您的产品已经有一个可以轻松与 PC 连接的通信端口,例如 USB、RS-232 或以太网。客户运行一个 PC 程序,该程序与微控制器中的引导加载程序对话。这会将新的二进制文件发送到引导加载程序,引导加载程序将其写入程序存储器,然后运行新代码。

听起来很简单,但事实并非如此,至少如果您希望此过程稳健,则不会。如果发生通信错误并且新固件在到达引导加载程序时已损坏怎么办?如果在启动过程中电源中断怎么办?如果引导加载程序本身有错误和废话怎么办?

一个简单的场景是引导加载程序总是从复位运行。它尝试与主机通信。如果主机响应,那么它要么告诉引导加载程序它没有任何新内容,要么向它发送新代码。随着新代码的到来,旧代码被覆盖。您总是在上传的代码中包含校验和,因此引导加载程序可以判断新应用程序是否完好无损。如果不是,它会停留在引导加载程序中,不断请求上传,直到具有有效校验和的内容被加载到内存中。这对于始终连接的设备以​​及可能在响应引导加载程序请求的主机上运行后台任务的设备来说可能是可以接受的。这种方案对于很大程度上是自主的并且只是偶尔连接到主机的单元没有好处。

通常如上所述的简单引导加载程序是不可接受的,因为没有故障安全。如果没有完整接收到新的应用图像,您希望设备继续运行旧图像,而不是在成功上传之前死机。出于这个原因,通常固件中实际上有两个特殊模块,一个上传器和一个引导加载器。上传器是主应用程序的一部分。作为与主机定期通信的一部分,可以上传新的应用程序图像。这需要与主应用程序映像分开的内存,例如外部 EEPROM 或使用更大的处理器,以便可以分配一半的程序内存空间来存储新的应用程序映像。上传者只是将接收到的新应用图像写入某处,但不运行它。当处理器复位时,这可能发生在上传后主机的命令下,引导加载程序运行。现在这是一个完全独立的程序,不需要外部通信能力。它比较当前和上传的应用程序版本,检查它们的校验和,如果版本不同,则将新图像复制到应用程序区域并检查新图像校验和。如果新图像损坏,它会像以前一样运行旧应用程序。

我做了很多引导加载程序,没有两个是相同的。尽管一些微控制器公司希望您相信,但没有通用引导加载程序。每个设备在与主机打交道时都有自己的要求和特殊情况。以下是我使用的一些引导加载程序和有时上传程序的配置:

  1. 基本引导加载程序。该设备有一条串行线,可以连接到主机并根据需要打开。引导加载程序从复位运行,并向主机发送了一些上传请求响应。如果上传程序正在运行,它会响应并发送一个新的应用程序图像。如果它在 500 毫秒内没有响应,则引导加载程序将放弃并运行现有的应用程序。因此,要更新固件,您必须先在主机上运行更新程序应用程序,然后连接并打开设备电源。

  2. 程序内存上传器。在这里,我们使用了下一个尺寸的 PIC,它具有两倍的程序内存。程序内存大致分为 49% 的主应用程序、49% 的新应用程序映像和 2% 的引导加载程序。引导加载程序将从重置开始运行,并在适当的条件下将新应用映像复制到当前应用映像。

  3. 外部 EEPROM 映像。与 #2 类似,只是使用了外部 EEPROM 来存储新的应用程序映像。在这种情况下,具有更多内存的处理器在物理上也会更大,并且属于不同的子系列,没有我们需要的外围设备组合。

  4. TCP 引导加载程序。这是其中最复杂的。使用了大型 PIC 18F。最后 1/4 左右的内存存放着引导加载程序,它有自己完整的 TCP 网络堆栈副本。引导加载程序从复位运行并尝试连接到先前配置的 IP 地址的已知端口上的特殊上传服务器。这适用于整个系统始终有专用服务器机器的大型安装。每台小型设备在重置后都会与上传服务器签入,并会酌情获得一个新的应用程序副本。引导加载程序将使用新副本覆盖现有应用程序,但仅在校验和检查时运行它。如果没有,它将返回上传服务器并重试。

    由于引导加载程序本身就是一段复杂的代码,其中包含完整的 TCP 网络堆栈,因此它也必须是可现场升级的。我们这样做的方法是让上传服务器向它提供一个特殊的应用程序,其唯一目的是在引导加载程序执行后覆盖它,然后重置机器以便新的引导加载程序运行,这将导致上传服务器发送最新的主应用程序图像。从技术上讲,在特殊应用程序通过引导加载程序复制新图像所需的几毫秒内出现电源故障将是不可恢复的故障。在实践中,这从未发生过。我们认为这种可能性很小,因为这些设备是大型安装的一部分,已经有人对系统进行维护,这有时意味着无论如何都要更换嵌入式设备。

希望您能看到还有许多其他可能性,每种可能性都有自己的风险、速度、成本、易用性、停机时间等权衡。

引导加载程序的概念是什么?

想象一下这种情况:您的微控制器上有相当多的存储空间 - 足以存储超过 2-3 个相互独立的程序或应用程序。假设当您启动设备时,您可能希望能够选择运行哪一个。那么你需要什么来支持这一点?您需要一个启动程序,然后允许您在启动时在其他程序之间进行选择。

这个怎么运作?

引导加载程序就是那个程序——它是第一个运行的程序,它可以将其他应用程序加载到内存中的特定位置(或者像闪存一样持久,或者像 RAM 那样易失性),然后跳转到所需的程序,然后它将从那里接管执行.

如何制作 avr 引导加载程序(或任何微控制器)?

我从未制作过引导加载程序,但我认为我会这样做:像往常一样开始编写固件程序 - 但确保将其放置在一个区域,以便它始终是第一个运行时设备启动。在我的脑海中,我想从这个小程序中获得一些功能:将新程序上传到内存中的可用位置,删除以前上传的程序,选择要运行的程序(如果有超过一),并具有某种存储数据结构(可增长的跳转表?)能够记住其他程序的位置并跳转到它们。交互可以通过 UART 完成,它可以为您提供一个非常简单的终端菜单以及通过同一通道上传固件的能力。

它是如何编程到微控制器的(就像在 avr 的闪存 rom 上烧录的任何 .hex 程序,或其他方法一样)?

如果它是一个完全空白的芯片,没有可以更新自身的现有引导加载程序,那么您需要像您描述的那样使用完成该操作所需的任何技术(在 AVR 的情况下为 ICSP)烧录到 FLASH。

这绝不是全面的“引导加载程序”是什么。根据您想要从一个或它们设计的系统中得到什么,您可以设计一个将内容上传到 RAM 中的指定位置而不是 FLASH,并在任意内存位置开始执行。或者,您可能想要一个能够在您的 PC 启动时选择要加载的操作系统(例如,参见grub )。8 位微控制器的引导加载程序往往非常简单。

关于 Arduino 的说明:此引导加载程序仅管理一个程序 AFAIK,它还接管串行端口来管理固件上传和其他东西

“引导”加载程序的概念类似于“启动”泵的概念。换句话说,您需要将程序加载到给定地址然后开始在该给定地址执行程序的“东西”。那东西,就是引导加载程序。在最简单的情况下,引导加载程序“出现”在 CPU 的指定起始地址(零,最有可能),将程序加载到所需的内存段,将控制权转移给它,然后“消失”。出现和消失由“外部”硬件控制。一种可能的实现方式是使用通过“硬件”重置激活并通过“软件”重置停用的 ROM。ROM中的加载器可以根据需要简单或复杂,并且需要以特定 CPU 理解的二进制形式编写。如果不需要 ROM 使用的地址空间,则不需要 ROM 去激活。显然,可以使用 EEPROM、ePROM、闪存 PROM 等来代替 ROM。