Cortex M7:启动后立即分支

问题描述

我正在使用ATSAMV71Q21B MCU,该MCU使用cortex-M7处理器。为了增加冗余,我想拥有多个启动加载程序,并在启动微控制器后立即进入其中一个启动加载程序。最终,ARM处理器在复位向量位置0x00000000开始执行。我无法选择要从哪里开始。

我想知道是否有可能使用少量说明分支到我的一个引导加载程序。

目前,我试图生成所有百条指令的所有解决方案对我来说都是太多了。我想我需要手动将分支指令添加到向量位置0x00000000。虽然,但我不确定应该在哪里分支,以及是否可以这样做。

确实,我不确定我是否真的了解生成的汇编代码的开头。因此,我不确定在哪里分支。

以下是程序开头的示例:

0x00400000  70 0a 40 20 d9 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 00 00 00 00  p.@ Ù.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.....
0x00400020  00 00 00 00 00 00 00 00 00 00 00 00 d5 01 40 00 d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00  ............Õ.@.Õ.@.....Õ.@.Õ.@.
0x00400040  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400060  d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.....Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400080  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x004000A0  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x004000C0  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x004000E0  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400100  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 00 00 00 00 00 00 00 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.........
0x00400120  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400140  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400160  d5 01 40 00 d5 01 40 00 10 b5 05 4c 23 78 33 b9 04 4b 13 b1 04 48 af f3 00 80 01 23 23 70 10 bd  Õ.@.Õ.@..µ.L#x3..K.±.H¯ó.€.##p..
0x00400180  2c 04 40 20 00 00 00 00 28 04 40 00 0c 4b 43 b1 0c 48 0d 49 10 b5 af f3 00 80 0c 48 03 68 23 b9,.@ ....(.@..KC±.H.I.µ¯ó.€.H.h#.
0x004001A0  10 bd 0a 48 03 68 33 b9 70 47 09 4b 00 2b f7 d0 bd e8 10 40 18 47 06 4b 00 2b f5 d0 18 47 00 bf  ...H.h3.pG.K.+÷Ð.è.@.G.K.+õÐ.G.¿
0x004001C0  00 00 00 00 28 04 40 00 30 04 40 20 28 04 40 00 00 00 00 00 fe e7 00 bf 16 49 17 4a 91 42 08 b5  ....(.@.0.@ (.@.....þç.¿.I.J‘B.µ

如果我正确理解,这是一个向量表,我不应该在这里分支。那是正确的吗?

解决方法

0x00400000  70 0a 40 20 d9 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 00 00 00 00  p.@ Ù.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.....
0x00400020  00 00 00 00 00 00 00 00 00 00 00 00 d5 01 40 00 d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00  ............Õ.@.Õ.@.....Õ.@.Õ.@.
0x00400040  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400060  d5 01 40 00 00 00 00 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.....Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.
0x00400080  d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00 d5 01 40 00  Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.Õ.@.

所以看起来不错,第一个是堆栈指针加载值

0x20400a70 

也许是一个奇怪的数字,但是此部分具有0x80000字节的ram,因此它是有效的。因此很可能是链接描述文件生成的值(链接描述文件中的堆栈设置,而不仅仅是从ram顶部开始)。

重置向量为

0x004001d9 

关于它指向您的内容的正确格式(已设置lsbit),尚未提供。

其他许多人

0x004001d5

根据与复位向量的接近程度,正确格式化的格式也可能是一个无限循环,但谁知道得看一下代码。引导并不重要。

芯片/家族doc指示用户闪存的地址为0x00400000,对于这些部件而言,它很大,因此,此转储左侧的地址和复位向量都很好。

有迹象表明在某个地址0x00800000或0x08000000上有一个sam-ba引导程序,或者我记得,可以查一下。现在,我使用了其他Atmel零件,这些零件没有从Atmel闪存中烧录引导加载程序,而是使用sam-ba进行构建和使用(为什么要使自己的体积更简单,体积更小),但是我遇到了问题这种方法是如何锁定或不锁定闪光灯的,如何轻松解锁和擦除的,那又有什么意义呢?使用SWD。在这种情况下,文档中的此注释可能表示已被刻录,然后您需要查看如何选择启动该应用程序而不是用户应用程序,因为这两种情况都表明了特定的地址。如果用户可以更改它,则可能是您想要放置引导加载程序的地方,或者如果固定且不可更改,则只需将其用作引导加载程序。

关于通常将引导装载程序放在哪里,选择设计,引导装载程序的含义,哪些功能等,通常会被误用,但该术语意味着既引导零件又有加载其他零件的方式以某种方式运行应用程序(在ram中运行一个,对用户/引导/应用程序闪存进行重新编程等)。您需要查看的是闪存在此设备上的工作原理,假设您希望能够用新固件重写其中的一部分。有时您可以同时执行并执行闪存操作,但是更有可能这样做,因为它们使用多个闪存组,因此您可以在其中一个运行并修改另一个闪存组,这导致它们的引导方案是什么,它始终只能在一个引导上进行引导。而且从没有其他选择,因此您要么必须永久保持引导加载程序不变,要么要制定一个方案,还必须有一个方案来选择在引导加载程序启动后,哪些存储库上的哪个映像作为默认固件。

这些内核通常可以在ram中运行代码,因此没有理由期望不在这里(它不是内核,这是芯片供应商的重要实现),因此可以将一部分引导程序复制并跳转到ram,以免在闪存上运行,使您可以对任何闪存进行重新编程,但是如果闪存故障或断电,则可能使自己处于危险之中。

如果芯片供应商尚未使用工厂引导程序完成此操作,并且该工厂加载程序对于现场使用而言是理想的,则它可以使用I / O引脚来确定哪个引导程序,必须查看文档。如果您选择自己执行此操作,那么让gpio引脚选择两条引导路径并不是不明智的选择,那么您可以拥有一个很小的,理想的无缺陷的十几行汇编行来读取gpio引脚并分支到固定点。例如,根据您认为应用程序的实际大小,您可以选择说0x00500000和0x00600000。然后,如果用户希望加载闪光灯,则可以进行复制并跳入ram,然后可以选择加载其中一个。几行代码可以是几十行,并对所选存储体进行某种校验和,如果所选的存储体不好并且没有完成,则不进行选择。或您提供的第三个引导程序,以防两者不进行校验和。

大量解决方案,通常,如果您没有单独存储的闪存,则需要分支以进行夯实,并在设计内存空间方面有更大的自由度(假定可以在页面中擦除闪存)。否则,您可能只想使用芯片供应商的银行解决方案。

因此,在开始使用此设备之前,所有这些信息都应记录在来自arm和Atmel(微芯片)的文档中。在任何一种情况下,与arm唯一远程相关的是向量表的工作方式。其余的所有地址,大小等都是芯片供应商的实现。因此,您的大部分阅读都来自芯片供应商的文档,在这种情况下,他们拥有庞大的数据手册方法(而不是单独的数据手册和参考手册方法)。

如果您想使用sam-ba,请重新阅读我对sam-ba的了解,以及Flash实现的性质,是否可以在应用程序中编程等等。然后,您不仅要设计Bootloader的功能,但地址空间,无论它是在Flash还是ram中执行。

编辑

万一我不明白这个问题。

arm复位向量位于0x00000004,而不是0x00000000(对于cortex-ms),它是处理程序ORRED的地址,其值为1。地址0x00000000是堆栈指针初始化值,如果您选择在代码中初始化堆栈指针而不使用此机制,则可以在其中放置所需的任何内容。

如果要更改重置处理程序地址,则必须修改0x00000004,在某些部分上可以更改而无需擦除(通常通过擦除为全1来闪烁或正常工作,然后您可以写入0,不能写入1但可以更改)在每个字节/字/块的基础上为1)。因此,要更改此设置,您可能需要保存它以擦除块/页面,更改所需的位并写回。例如,您也许可以将其从0x004001d9更改为sah 0x004101d9或0x004000d9,但不值得这样做。该值是处理程序ORRED的地址,其值为1。

这不是分支,因为此时代码未执行(通常/假定),这是读取该位置并将其作为起点的逻辑,第一个获取不是分支。

并指出要查看向量表在项目中的位置,然后对其进行修改以指向备用重置处理程序。可能是这样的代码

.word STACK_END
.word reset_handler
.word 

在这种情况下,其余的一些填充/虚拟矢量。只需替换reset_handler或您在处理程序中找到的任何内容,请记住这是一个引导程序,如果打算调用任何C函数,则需要引导C,如果使用C ++或其他语言,则更糟。