我目前正在使用具有双组 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),所以这应该不是问题。
我没有发现任何其他人遇到此问题,也没有任何示例如何使用它,所以也许有人可以告诉我我是否在这里做错了什么,或者还有什么要检查的。