3

我目前正在使用具有双组 2 x 256KB 闪存的 Atmel SAM3X8 ARM 微控制器。我正在尝试实现固件更新功能,将新固件放入当前未使用的闪存库中,并在完成后使用闪存重新映射交换库以运行新固件。

数据表指出,我需要设置 GPNVM2 位,然后 MCU 将重新映射内存,因此 Flash 1 现在位于 0x80000,Flash 0 位于 0xC0000。这也会导致 MCU 从 Flash 1 开始执行代码。

引用数据表:

GPNVM2 仅用于交换 Flash 0 和 Flash 1。如果 GPNVM2 为 ENABLE,则 Flash 1 映射到地址 0x0008_0000(Flash 1 和 Flash 0 是连续的)。如果 GPNVM2 为 DISABLE,则 Flash 0 映射到地址 0x0008_0000(Flash 0 和 Flash 1 是连续的)。

[...]

GPNVM2 可以选择使用 Flash 0 还是 Flash 1 进行引导。设置 GPNVM 位 2 选择从 Flash 1 启动,清除它选择从 Flash 0 启动。

但是当我通过 SAM-BA 或我自己的固件使用flash_set_gpnvm(2) (ASF SAM Flash Service API) 设置 GPNVM2 时,它仍会从 Flash 0 中的程序启动,并且新程序仍将驻留在 Flash 1 的偏移处0xC0000。GPNVM2 的状态已通过flash_is_gpnvm_set(2)验证

将固件本身刷入 Flash1 库可以完美运行,这已通过使用 SAM-BA 转储整个闪存来验证。

Atmel 有一个关于一个问题的勘误表,即闪存重新映射仅适用于小于 64KB 的部分。我的代码小于那个(40KB),所以这应该不是问题。

我没有发现任何其他人遇到此问题,也没有任何示例如何使用它,所以也许有人可以告诉我我是否在这里做错了什么,或者还有什么要检查的。

4

1 回答 1

3

我有同样的问题(见这里:Atmel SAM3X8E dual bankswitching for booting different behavior)。

经过更多研究,我发现了一个应用笔记(链接:http ://ww1.microchip.com/downloads/en/AppNotes/Atmel-42141-SAM-AT02333-Safe-and-Secure-Bootloader-Implementation-for-SAM3- 4_Application-Note.pdf ),它以更清晰的方式解释了 SAM3X 的启动行为。问题是数据表有点误导(至少我也很困惑)。SAM3X 无法重新映射闪存组。引导行为有点不同(参见链接中的图片,它是从应用说明中截取的,第 33/34 页): 引导行为 SAM3X

图 3-9 显示了 SAM3X 在启动时的行为。GPNVM 位 1 和 2 仅确定哪个存储器部分(ROM/Flash0/Flash1)镜像到引导存储器(位于 0x00000000)。Flash bank 的映射没有改变。因此 Flash0 仍然映射到 0x00080000 和 Flash1 到 0x000C0000)。

正如应用笔记所述,其他一些 Atmel 微控制器能够真正重新映射闪存组(例如 SAM3SD8 和 SAM4SD32/16)。如图 3-10 所示,这些处理器改变了 Flash bank 的位置。

因此,为了能够更新您的固件,有必要实现某种引导加载程序。我自己实现了一个,即使完全不使用 GPNVM 位也能够更新我的固件。我还在 Microchip 上开了一张支持票以澄清引导行为。当我收到答案时,我希望能告诉你更多。

编辑:

这是来自 Microchip 支持的答案:

在 SAM3X 中设置 GPNVM2 位只会使 CPU “跳转到”或从 flash bank 1 (即 0xC0000)开始。不会发生实际的内存地址交换。

要使用闪存库 1,您需要更改链接器文件 (flash.ld) 以反映闪存起始地址 0xC0000。

对于 flash bank 0 应用,更改: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K / to: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00040000 / Flash, 256K */

对于 flash bank 1 应用,更改: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K / to: rom (rx) : ORIGIN = 0x000C0000, LENGTH = 0x00040000 / Flash, 256K */

如果不这样做,闪存 1 应用程序中的复位处理程序将指向闪存 0 应用程序中的地址。因此,虽然代码将在闪存 1 中开始执行(如果设置了 GPNVM2),但它会跳回到闪存 0 应用程序。可以忽略说明 64kb 限制的勘误表。

因此,应用说明是正确的,并且没有执行内存映射的实际更改。

干杯卢卡斯

于 2018-05-18T12:17:38.083 回答