在 ADuC702x 上实施“应用中编程”

背景

ADuC702x 精密模拟微控制器提供了用于通过标准 PC 机上的串行端口将汇编好的程序加载到片内闪存/EE 存储器的串行下载程序,但要进入这种模式,用户需要在 ADuC702x 重置或上电时手动将 BM 引脚拉低 。想要在工业环境中升级程序的用户通常无权访问此引脚,因此难以通过这种方式更新应用程序。应用中编程 (IAP) 允许在不接触电路板的情况下执行升级。本文为 ADuC702x 用户提供了轻松升级其程序的方法。

IAP 功能方法论

ADuC702x 出厂配置的引导加载程序位于闪存上端从 0x0008F800 到 0x0008FFFF 的地址范围内。如果 BM 引脚已被拉低,ADuC702x 会在重置或上电周期之后自动进入这一区域。然而,BM 引脚通常在所有程序下载到闪存/EE 后会被拉高,因此在改变 BM 逻辑之前,新的程序无法下载。

为了引入一种可以在不更改 BM 引脚硬件状态的情况下将汇编好的应用代码重新下载到所需闪存地址范围的 IAP 功能,三个程序必须定位在闪存中从 0x00080000 到 0x0008FFFF 的地址范围内,如下所示。

(1).从 0x00080000 到 0x00080FFF,IAP 功能程序。可以把它视为一个由用户设计的引导加载程序。用户可以根据 IAP 功能程序的大小更改结束地址。

(2).从 0x00081000 到 0x0008F7FF,用户应用程序。这是由用户设计的实际应用程序。当 IAP 功能运行时,此区域可由新的应用程序替换。

(3).从 0x0008F800 到 0x0008FFFF,出厂配置的引导加载程序。此代码已被隐藏,用户无法对其访问。

一旦用户将 IAP 和应用程序下载到上面所示的指定区域,将按以下步骤继续操作。当进行正常重置(BM 引脚已被拉高)时,执行程序会在出厂编程的内部配置代码中自动启动。之后,ADuC702x 会跳至中断向量地址 0x00000000 以执行用户的重置异常例程。默认情况下,闪存/EE 会被镜像至存储器阵列的底部。

接下来,ADuC702x 将执行 IAP 功能程序。这将初始化 UART 和定时器的硬件配置,并使 UART 接收和发射多个中断以及一个五秒定时器中断。在此期间,ADuC702x 将会等待五秒钟,以便主机发出升级指令。如果 ADuC702x 在五秒钟内未收到此指令,指针会跳至 0x00081040 处的用户应用程序位置,以执行用户应用程序;这是一个正常重置操作。如果 ADuC702x 在五秒钟内收到指令,例如 0xA,它将继续执行 IAP 功能程序,将 IAP 程序复制到 SRAM,然后启用 REMAP(重映射)功能。中断向量和升级功能均位于 SRAM 中。在下载期间,闪存将提供存储空间。现在,ADuC702x 预计会收到来自主机的报文消息,并将新的代码保存到闪存中从 0x00081000 到 0x0008F7FF 的用户应用程序区域。当下载完成后,IAP 功能将重置整个芯片。如果未从 UART 收到进一步的指令,指针将在五秒钟后跳至升级后的用户应用程序。

图 1 中显示了流程图:

图 1
图 1. 主程序流程图

如图 2 所示,可将两种类型的报文从主机发送到 IAP 程序:完整报文,其中第一个字节是计数器值 0xFF,随后的 256 个字节是报文内容;或者简短报文,其中第一个字节代表报文长度,随后的字节是报文内容。例如,如果计数器值为 0x10,则报文具有 16 个字节。

图 2
图 2. 升级功能流程图

下面介绍了一些有关 ARM7TDMI IAP 功能的重要注意事项。

中断矢向量表和重映射

默认情况下,ARM 中断向量会被镜像至存储器阵列的底部(0x00000000 至 0x0000001F)。链接的中断 ISR 地址位于从 0x00000020 至 0x0000003F 的区域内。默认情况下,当发生重置时,闪存/EE 会被镜像至存储器阵列的底部。当触发中断时,内核将跳至闪存以搜索 ISR 条目。然而,在升级模式下,闪存将充当可被擦除和重写的存储器,因此将中断向量定位在闪存中会导致错误。为了避免此问题,用户必须使用 REMAP 功能,以将 SRAM 镜像至存储器阵列的底部。这有助于从 SRAM(而不是闪存)中执行中断例程。要使用 REMAP 功能,用户必须首先将中断向量表从闪存复制到存储器,并且 SRAM 中最初的 64 字节将不能按正常方式使用。参见图 3。

SRAM 中运行的功能

IAP 提供的功能可以在不将 BM 引脚拉低的情况下擦除和重写闪存,但内核操作需要等至所要求的读取或擦除模式完成后才能开始。为了解决此问题,请将包括 ISR 在内的所有功能放入 SRAM,并从这里执行它们。使用 Keil uVision3 3.23 版,用户可以在 SRAM 中执行此功能,如下所示:

void Ram_Function() __ram      // __ram 属性指示代码置于 RAM 中

图 3
图 3. FIQ 和 IRQ ISR 流程图

将 RO 和 RW 段放在所需的区域。

在目标 ‘IAP_boot’”à LA 定位指令的 “Project” à “选项中,用户可以取消选中“Use Memory Layout from Target Dialog”,并按以下所示在 “User Classes” 中分配 RO 和 RW 段:

DATA (0x10040-0x11FFF),

CODE (0x80000-0x80FFF), CONST (0x80000-0x80FFF), ERAM(0x10040-0x11FFF)

通过这样的分配,从 0x10040 到 0x11FFF 的区域可以作为 RW 段,从 0x80000 到 0x80FFF 的区域可以作为 RO 段,并且可以在 SRAM 中从 0x10040 到 0x11FFF 的区域运行功能。

用户应用程序安排。

在用户的应用程序中,RO 和 RW 应合理地分配至段。

在目标 ‘IAP_boot’”à LA 定位指令的 “Project” à “选项中,用户可以取消选中“Use Memory Layout from Target Dialog”,并按以下所示在 “User Classes” 中分配 RO 和 RW 段:

DATA (0x10040-0x11FFF),

CODE (0x81000-0x8F7FF), CONST (0x81000-0x8F7FF)

通过这样的分配,从 0x10040 到 0x11FFF 的区域可以作为 RW 段,并且从 0x81000 到 0x8F7FF 的区域可以作为 RO 段。请注意,应修改启动代码以分配启动对象代码存储区域。为此,可在启动代码中进行如下修改:

AREA  STARTUPCODE, CODE, AT 0x00081000

启动对象代码将定位在以 0x00081000 为起点的区域。在主程序中,用户必须首先将中断向量表从闪存 0x00081000 复制到 0x0008103F,然后启用 REMAP 功能。然后,用户可以正常写入应用程序。

应用程序代码:
ADuC7020 应用程序代码

ADuC7026 应用程序代码