0

我似乎是从这里这里重申这个问题。当我在将固件刷入对面的闪存库后重新启动系统时,VTOR 为 0(意味着它不会从闪存启动)并且我无法运行新固件。

我使用 EFC 控制器将固件二进制程序编程到第二个闪存库中。例如,活动固件位于 Flash0,位于 0x0008_0000。实施指南说 Flash1 位于 0x000C_0000。我可以看到要刷新的完整固件包含在 0x000C_0000 处,没有错误。加载并验证固件后,我切换 GPNVM 引导库:

efc_perform_command(EFC0, EFC_FCMD_SGPB, 1); //set GPNVM bit 1
efc_perform_command(EFC0, EFC_FCMD_SGPB, 2); //set GPNVM bit 2
/* Now check to make sure the bit has flipped) */
efc_perform_command(EFC0, EFC_FCMD_GGPB, 0);
status = efc_get_result(EFC0);
printf("GPNVM is now %d\n", status);

/* Now set the VTOR to the flash1 start address) */
__DSB();
__ISB();
SCB->VTOR = ((uint32_t)FLASH1_ADDRESS & SCB_VTOR_TBLOFF_Msk);
/* Checking the VTOR value here shows a result of 0x000C_0000 */
__DSB();
__ISB();

/* Now reset the device by pulling NRSTB pin low */
reset_pull_NRSTB_low();
while(1); 

执行此代码后,我再次检查 0xE000_ED08 处的 VTOR 寄存器,该值现在为 0x0000_0000。固件似乎没有加载,因为芯片寻找地址 0x0000_0000 来启动固件。

会不会是我错误地设置了 GPNVM 位并且它正在寻找 ROM 向量?如果是这种情况,要设置的正确 GPNVM 位是多少?根据引导加载程序文档第 33 页上的表格,GPNVM 位应为“0b110”,因此 GPNVM[1] 为 1,GPNVM[2] 为 1——这意味着固件将从 Flash Bank 1 开始。这是一个正确的解释?

4

1 回答 1

0

好吧,我当然知道找到解决方案会让我觉得自己很愚蠢。但是在这里...我最终更改了 Atmel 提供的 Device_Startup 文件夹中的链接器脚本并编译了两次;每个都分别具有 FLASH0 和 FLASH1 地址,没有对固件进行其他更改。而且...固件二进制文件是相同的!但根据爱特梅尔的说法,情况不应该如此。

我一直很困惑,因为它说内存是镜像的,这让我相信设置 GPNVM 只指向同一地址的闪存库的开始,并根据 GPNVM2 重新映射后半部分。相反,它似乎实际上是从固件二进制文件的第二个字(SP 和 PC)加载向量表。

因此,确实需要告知在连续闪存库内跳转的位置。我进入 ASF 解决方案属性以查找 ARM/GNU 链接器首选项,并在标签部分找到了真正的链接器文件。这不是我的项目中似乎引用的那个。我根据上面提到的指南对其进行了更改,并成功切换以在对面银行上运行固件。

轻松解决看似晦涩难懂的硬件问题。谢谢你的帮助!

于 2018-12-20T01:35:32.027 回答