ARM M4 复位后立即跳转到不可读地址

ARM M4 branches to unreadable address immediately after reset

我正在 Silicon Labs Thunderboard React (RD0057) 上进行一个项目,它上面有一个 EFR32BG1xxxF256 处理器 (Cortex M4)。

最近去烧写板子调试,代码在进入main之前就直接硬故障了。 (IACCVIOL 和 STKERR 均已设置)。

我已经:

所有结果相同

然后我单步执行代码并在重置代码后看到:

工具: - Thunderboard React RD0057 - WSTK 4001A Rev A01(用作 J-Link 适配器) - 简单工作室 - 蓝牙 SDK 2.10.1

今晚晚些时候我需要想办法 post 我的代码,但是这个问题对任何人来说听起来很熟悉吗?我认为它可能与代码无关,因为它发生在项目的已知良好版本和空示例项目中。感谢任何帮助。

更新 1:

Pastebin of Start of Binary,摘录前三个条目:

007c 0020 4da0 0000 49a0 0000 49a0 0000
49a0 0000 49a0 0000 49a0 0000 49a0 0000
49a0 0000 49a0 0000 49a0 0000 49a0 0000

我按照建议检查了二进制文件,前几个条目似乎是一个向量 table(一堆 0x49A0,我相信 t运行 会将地址加载到寄存器中)。

然后我用J-link"J-Mem"读出了芯片的内存。在使用 IDE(空白芯片)对芯片进行编程后,这显示了所有 0xFFFF。然后,我使用 J-Link 命令行实用程序来刷新起始地址设置为 0x00 的二进制文件。然后再读回内存,好像成功了,内容和bin文件匹配。执行此操作表明我已经过了第一个负载和 b运行ch,这导致了之前的硬故障,但现在在其他地方遇到了另一个硬故障。

如果您有为 arm/thumb 构建的 gnu binutils,请使用这个

.thumb
.thumb_func
.global _start
_start:
.word 0x20001000
.word reset
.word hang
.word hang
.word hang
.thumb_func
reset:
    nop
    nop
    nop
    nop
    nop
    b reset
.thumb_func
hang:   b .

建造它

arm-none-eabi-as flash.s -o flash.o
arm-none-eabi-ld -Ttext=0 flash.o -o flash.elf
arm-none-eabi-objdump -D flash.elf > flash.list
arm-none-eabi-objcopy flash.elf -O binary flash.bin

不必是 arm-none-eabi- 它可以是 arm-linux-gnueabi 或任何 arm-something-something.

检查列表文件,这就是您要启动 cortex-m 的文件。

00000000 <_start>:
   0:   20001000    andcs   r1, r0, r0
   4:   00000015    andeq   r0, r0, r5, lsl r0
   8:   00000021    andeq   r0, r0, r1, lsr #32
   c:   00000021    andeq   r0, r0, r1, lsr #32
  10:   00000021    andeq   r0, r0, r1, lsr #32

00000014 <reset>:
  14:   46c0        nop         ; (mov r8, r8)
  16:   46c0        nop         ; (mov r8, r8)
  18:   46c0        nop         ; (mov r8, r8)
  1a:   46c0        nop         ; (mov r8, r8)
  1c:   46c0        nop         ; (mov r8, r8)
  1e:   e7f9        b.n 14 <reset>

00000020 <hang>:
  20:   e7fe        b.n 20 <hang>

Flash 中的第一个字会为您加载到堆栈指针中,您可以根据需要在 bootstrap 代码中更改堆栈指针,这只是节省了一步。接下来是用 1 复位的地址,必须设置 lsbit。重置位于上面的 0x0014,因此重置向量需要具有 0x0014|1 = 0x0015.

其余的向量不会让你启动。这个把它放在一个简单的无限循环中,你可以用你的调试器暂停和恢复,并希望在你重复暂停和恢复时在不同的地址找到它。

使用调试器加载 elf 文件可能比加载 bin 文件更容易。但同时该工具可能无法正确写入闪存,请使用该工具转储从 0x00000000

开始的几个字

如果您的二进制文件不是以矢量开头 table and/or 如果矢量 table 中有偶数地址,您将在 rails 之后立即离开重置。

如果确实如此,那么我们需要进一步挖掘。请 post 至少在你的二进制文件的开头,最好是程序的反汇编,一些矢量 table 和一些重置代码。