arm - Atmel SAM3X 双组切换不起作用

标签 arm atmel atsam3x

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

数据表指出,我需要设置 GPNVM2 位,然后 MCU 将重新映射内存,因此 Flash 1 现在位于 0x80000,Flash 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 Flash Service API) 设置 GPNVM2 时,它仍然会从 Flash 0 中的程序启动,并且新程序仍将驻留在 Flash 1 的偏移处0xC0000。 GPNVM2 的状态已经通过 flash_is_gpnvm_set(2) 验证

将固件本身刷新到 Flash1 组可以完美地工作,这已经通过使用 SAM-BA 转储整个闪存进行了验证。

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

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

最佳答案

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

经过更多研究,我找到了一份应用说明(链接: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 页):
Booting behaviour SAM3X

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

正如应用说明所述,其他一些 Atmel 微 Controller 能够真正重新映射闪存组(例如 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.



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

干杯
卢卡斯

关于arm - Atmel SAM3X 双组切换不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47078293/

相关文章:

linux - 尝试在 64 位上运行 32 位应用程序时出错。使用 sudo 运行效果很好

assembly - ARM 汇编中的 "Change instruction set"- 这究竟是什么意思?

c - Uart 接收到正确的字节,但顺序困惑

embedded - AT91SAM7X512复位类型问题

arm - Arduino Due 中的定时器

c - 为什么这个函数不能正确地打开和关闭 LED?

c++ - 在 armv7l (Odroid XU4) 上编译时出现 OpenCV "conflicting declaration"问题

c - ARM Cortex A9 双核(Linux 或 VxWorks)上的多线程