Atmel SAM3X 双银行切换不工作

Atmel SAM3X dual bank switching not working

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

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

引用数据表:

The GPNVM2 is used only to swap the Flash 0 and Flash 1. If GPNVM2 is ENABLE, the Flash 1 is mapped at address 0x0008_0000 (Flash 1 and Flash 0 are continuous). If GPNVM2 is DISABLE, the Flash 0 is mapped at address 0x0008_0000 (Flash 0 and Flash 1 are continuous).

[...]

GPNVM2 enables to select if Flash 0 or Flash 1 is used for the boot. Setting GPNVM bit 2 selects the boot from Flash 1, clearing it selects the boot from Flash 0.

但是当我通过 SAM-BA 或我自己的固件使用 flash_set_gpnvm(2)(ASF SAM 闪存服务 API)设置 GPNVM2 时,它仍然会从 Flash 0 中的程序启动,新程序仍将驻留在 Flash 1 的偏移量 0xC0000 处。 flash_is_gpnvm_set(2)

验证了GPNVM2的状态

将固件本身刷写到 Flash1 bank 工作完美,已通过使用 SAM-BA 转储整个闪存验证。

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

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

我遇到了同样的问题(参见此处:Atmel SAM3X8E dual bank switching for booting different behaviour)。

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

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

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

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

编辑:

这是 Microchip 支持人员的回答:

Setting the GPNVM2 bit in SAM3X will merely make the CPU 'jump to' or start from flash bank 1 i.e. 0xC0000. No actual swap of memory addresses will take place.

To use flash bank 1, you will need to change the linker file (flash.ld) to reflect the flash start address 0xC0000.

For flash bank 0 application, change: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K / to: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00040000 / Flash, 256K */

For flash bank 1 application, change: rom (rx) : ORIGIN = 0x00080000, LENGTH = 0x00080000 /* Flash, 512K / to: rom (rx) : ORIGIN = 0x000C0000, LENGTH = 0x00040000 / Flash, 256K */

If this is not done, the reset handler in the flash 1 application will point to an address in the flash 0 application. So, although code will start execution in flash 1 (if GPNVM2 is set), it will jump back to the flash 0 application. The errata stating the 64kb limitation can be ignored.

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

干杯 卢卡斯