我似乎在here和here中重申了这个问题。将固件刷新到相对的闪存组后重新启动系统时,VTOR为0(表示它不从闪存启动),并且我无法运行新固件。
我使用EFC控制器将固件二进制文件编程到第二个Flash库中。 例如,活动固件在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);
执行此代码后,我再次检查VTOR寄存器0xE000_ED08,现在的值为0x0000_0000。固件似乎未加载,因为芯片的地址为0x0000_0000以启动固件。
是否可能是我设置的GPNVM位不正确,并且它正在寻找ROM向量?如果是这种情况,应设置哪些正确的GPNVM位?根据引导加载程序文档第33页上的表,GPNVM位应为“ 0b110”,以便GPNVM [1]为1且GPNVM [2]为1-意味着固件将从Flash Bank 1开始。正确的解释?
答案 0 :(得分:0)
好的,我当然知道找到解决方案会使我感到愚蠢。但是你去... 最终,我更改了Atmel提供的Device_Startup文件夹中的链接描述文件,并对其进行了两次编译。每个都分别具有FLASH0和FLASH1地址,而固件没有其他更改。而且...固件二进制文件是相同的!但是Atmel认为情况并非如此。
我很困惑,因为它说内存是镜像的,这使我相信设置GPNVM仅指向闪存库的起始地址是相同的地址,并根据GPNVM2重新映射后半部分。相反,似乎它实际上是从固件二进制文件的第二个字(SP,然后是PC)加载向量表的。
因此,确实需要告知要在连续闪存组中跳转的位置。 我进入ASF解决方案属性以查找ARM / GNU链接器首选项,并在标签部分中找到了真正的链接器文件。在我的项目中似乎没有引用过它。我根据上面提到的指南对其进行了更改,并成功切换到对面的库中运行固件。
轻松解决看似晦涩的硬件问题。感谢您的帮助!