ARM M4 复位后立即跳转到不可读地址
ARM M4 branches to unreadable address immediately after reset
我正在 Silicon Labs Thunderboard React (RD0057) 上进行一个项目,它上面有一个 EFR32BG1xxxF256 处理器 (Cortex M4)。
最近去烧写板子调试,代码在进入main之前就直接硬故障了。 (IACCVIOL 和 STKERR 均已设置)。
我已经:
- 将代码还原为我知道已编译的先前版本并且 运行
- 尝试了我的另一块板
- 使用 J-Link 适配器完全擦除闪存并重新编程
- 尝试了一个空的示例项目
所有结果相同
然后我单步执行代码并在重置代码后看到:
- 从地址 0xf210000 开始
- 一些运行dom看似无关的东西(4行)
- 用 0x4 加载 R3
- 用 R3 加载 R2(执行此 R2 后在调试器中显示 0xFFFFF)
- bx R2(b运行ches 到 ffffffe0,表示 "Fail to read memory" 并触发硬故障)
工具:
- 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,这导致了之前的硬故障,但现在在其他地方遇到了另一个硬故障。
- 需要确定 IDE 编程代码失败的原因。假设偏移量设置有误,因为它似乎完全缺少闪存地址 运行ge。
- 需要确定这个新的硬故障发生在哪里,是我的代码错误还是其他奇怪的事情。
如果您有为 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 和一些重置代码。
我正在 Silicon Labs Thunderboard React (RD0057) 上进行一个项目,它上面有一个 EFR32BG1xxxF256 处理器 (Cortex M4)。
最近去烧写板子调试,代码在进入main之前就直接硬故障了。 (IACCVIOL 和 STKERR 均已设置)。
我已经:
- 将代码还原为我知道已编译的先前版本并且 运行
- 尝试了我的另一块板
- 使用 J-Link 适配器完全擦除闪存并重新编程
- 尝试了一个空的示例项目
所有结果相同
然后我单步执行代码并在重置代码后看到:
- 从地址 0xf210000 开始
- 一些运行dom看似无关的东西(4行)
- 用 0x4 加载 R3
- 用 R3 加载 R2(执行此 R2 后在调试器中显示 0xFFFFF)
- bx R2(b运行ches 到 ffffffe0,表示 "Fail to read memory" 并触发硬故障)
工具: - 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,这导致了之前的硬故障,但现在在其他地方遇到了另一个硬故障。
- 需要确定 IDE 编程代码失败的原因。假设偏移量设置有误,因为它似乎完全缺少闪存地址 运行ge。
- 需要确定这个新的硬故障发生在哪里,是我的代码错误还是其他奇怪的事情。
如果您有为 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 和一些重置代码。