哈佛架构微控制器
许多小型微控制器(Microchip PIC、Atmel AVR、Intel 8051、Cypress PSoC 等)都具有哈佛架构。它们只能执行程序存储器(闪存或 ROM)中的代码。可以将任何字节从程序存储器复制到 RAM。然而,(2)将可执行指令从 ROM 复制到 RAM 并不是解决办法——对于这些小型微控制器,程序计数器总是指向程序存储器中的某个地址。无法在 RAM 中执行代码。
将数据从 ROM复制到 RAM 是很常见的。首次上电时,典型的固件应用程序会将所有 RAM 清零,然后在 main() 启动之前将非常量全局变量和静态变量的初始值从 ROM 复制到 RAM 中。每当应用程序需要将固定字符串从串行端口推出时,它就会从 ROM 中读取该字符串。
对于这些微控制器的早期版本,连接到微控制器的外部“设备编程器”是更改程序的唯一方法。在正常操作中,该设备远不及“设备编程器”。如果在微控制器上运行的软件需要写入程序存储器 ROM——对不起,太糟糕了——那是不可能的。许多嵌入式系统都有代码可以写入的非易失性 EEPROM——但这仅用于存储数据值。微控制器只能执行程序 ROM 中的代码,不能执行 EEPROM 或 RAM。人们用这些微控制器做了很多好事,包括 BASIC 解释器和字节码 Forth 解释器。所以显然(1)代码永远不需要写入程序内存。
对于最近的一些“自编程”微控制器(来自 Atmel、Microchip、Cypress 等),芯片上有特殊的硬件,允许在微控制器上运行的软件擦除和重新编程其自己的程序存储器闪存的块。一些应用程序使用这种“自编程”功能来读取和写入数据到“额外的”闪存块 - 从未执行的数据,因此它不算作自修改代码 - 但这并没有做任何事情您无法使用更大的 EEPROM。到目前为止,我只见过两种在哈佛架构微控制器上运行的软件,它们将新的可执行软件写入自己的程序 Flash:引导加载程序和 Forth 编译器。
当 Arduino 引导加载程序(引导加载程序)运行并检测到新的应用程序固件映像可用时,它会下载新的应用程序固件(到 RAM),并将其写入闪存。下次打开系统时,它现在正在运行闪亮的新版本 16.98 应用程序固件,而不是笨重的旧版本 16.97 应用程序固件。(当然,包含引导加载程序本身的闪存块保持不变)。如果没有写入程序存储器的“自编程”功能,这将是不可能的。
一些 Forth 实现在小型微控制器上运行,编译新的可执行代码并使用“自编程”功能将其存储在程序 Flash 中——这个过程有点类似于 JVM 的“即时”编译。(所有其他语言似乎都需要一个太大而复杂的编译器,无法在小型微控制器上运行,因此编辑-编译-下载-运行周期需要更多的挂钟时间)。