我应该如何初始化我的 stm32 ( f215 )
How should I initialise my stm32 ( f215 )
我正在尝试制作一个极小的 stm32f215 固件来自学其启动的复杂性。现在我有了这个转储,据我所知,它应该将堆栈地址写入 r0 并永远循环:
firmware-d: file format elf32-littlearm
Disassembly of section .isr_vector:
08000000 <vector>:
8000000: 20002000 andcs r2, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 <reset_handler>:
8000008: f85f 00c ldr.w r0, [pc, #-12] ; 8000000 <vector>
0800000c <loop>:
800000c: e7fe b.n 800000c <loop>
但是当我调试它时,我最终得到 PC = 0xFFFFFFFF、LR = 0x20002000、R0 = 0x0 和 SP = 0x0。
而且,CFSR 中也没有任何内容可以暗示哪里出了问题...
这里有没有经验丰富的编码员知道线索?
(PS: 硬件引导引脚设置为别名 0x0 到 0x800 0000)
编辑:我刚刚意识到 CPSR 设置了溢出标志。但是仍然不知道为什么。
编辑2:
- 我找到的所有信息都表明 cortex-m3 只能执行 thumb 并且如果被告知执行 arm 将出现硬故障。
- 我知道从长远来看,将我的代码放在 isr_vector 中不是一个好主意。我试过用地址填充它以“循环”,但它没有改变。我有这个代码作为一个最小的例子。
- “有断点...”到目前为止,我还不能让它在任何断点处停止。唯一有效的是“starti”,它在分支到“reset_handler”之前停止它。那里的“stepi”让我直接进入所描述的状态。
- 这是 elf 文件的转储,因为它看起来比 GDB 的输出更漂亮。我已验证此数据存在于芯片上的 0x0 和 0x800 0000 中。
- 来自卡的数据、新鲜闪存和“starti”:
(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x6d8d1d05 1837964549
r3 0x7fbf 32703
r4 0x8000008 134217736
r5 0x8000008 134217736
r6 0x8000008 134217736
r7 0x8000008 134217736
r8 0x8000008 134217736
r9 0x8000008 134217736
r10 0x8000008 134217736
r11 0x8000008 134217736
r12 0x8000008 134217736
sp 0x8000008 0x8000008
lr 0x8000008 134217736
pc 0x8000008 0x8000008
cpsr 0x8000008 134217736
(gdb) disassemble /r 0x0,0x10
Dump of assembler code from 0x0 to 0x10:
0x00000000: 00 20 movs r0, #0
0x00000002: 00 20 movs r0, #0
0x00000004: 09 00 movs r1, r1
0x00000006: 00 08 lsrs r0, r0, #32
0x00000008: 00 48 ldr r0, [pc, #0] ; (0xc)
0x0000000a: fe e7 b.n 0xa
0x0000000c: 68 46 mov r0, sp
(如您所见,0xc 中的值当前是死代码。)
(gdb) disassemble /r 0x8000000,0x8000010
Dump of assembler code from 0x8000000 to 0x8000010:
0x08000000 <vector+0>: 00 20 movs r0, #0
0x08000002 <vector+2>: 00 20 movs r0, #0
0x08000004 <vector+4>: 09 00 movs r1, r1
0x08000006 <vector+6>: 00 08 lsrs r0, r0, #32
=> 0x08000008: 00 48 ldr r0, [pc, #0] ; (0x800000c <reset_handler_c>)
0x0800000a: fe e7 b.n 0x800000a
0x0800000c <reset_handler_c+0>: 68 46 mov r0, sp
- 该板是基于stm32f215的定制板。我使用 st-link (v2) 通过 https://github.com/stlink-org/stlink 进行刷写和调试。
用已知好的代码刷写它适用于这个解决方案,但我不确定调试器是否完全正常工作。
- 两个boot脚直接通过1kOhm电阻接地
- 在稍微更改代码以直接跳转到循环后,我可以得出结论,无论第一个汇编指令是什么,它都会锁定。返回循环的分支导致了同样的错误。
- CFSR 和 HFSR:
(gdb) print/x *(uint32_t *) 0xE000ED28
= 0x0
(gdb) print/x *(uint32_t *) 0xE000ED2C
= 0x0
- 我几乎可以保证我使用的 stlink 应用程序混淆了 sp 和 lr。一个已知的好程序没有 sp=0x8f0d180 和 lr=0x2001ff88。明天会考虑改用 openocd。
罪魁祸首已经找到!
似乎 st-util 调试器(来自上述项目)以某种方式导致错误。 openocd 的工作就像一个魅力,上面的最小代码工作。
无论如何,要编写错误报告等等...
非常感谢大家验证我的汇编程序并帮助我点缀所有的 t 和交叉所有的 i!
我正在尝试制作一个极小的 stm32f215 固件来自学其启动的复杂性。现在我有了这个转储,据我所知,它应该将堆栈地址写入 r0 并永远循环:
firmware-d: file format elf32-littlearm
Disassembly of section .isr_vector:
08000000 <vector>:
8000000: 20002000 andcs r2, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 <reset_handler>:
8000008: f85f 00c ldr.w r0, [pc, #-12] ; 8000000 <vector>
0800000c <loop>:
800000c: e7fe b.n 800000c <loop>
但是当我调试它时,我最终得到 PC = 0xFFFFFFFF、LR = 0x20002000、R0 = 0x0 和 SP = 0x0。 而且,CFSR 中也没有任何内容可以暗示哪里出了问题...
这里有没有经验丰富的编码员知道线索?
(PS: 硬件引导引脚设置为别名 0x0 到 0x800 0000)
编辑:我刚刚意识到 CPSR 设置了溢出标志。但是仍然不知道为什么。
编辑2:
- 我找到的所有信息都表明 cortex-m3 只能执行 thumb 并且如果被告知执行 arm 将出现硬故障。
- 我知道从长远来看,将我的代码放在 isr_vector 中不是一个好主意。我试过用地址填充它以“循环”,但它没有改变。我有这个代码作为一个最小的例子。
- “有断点...”到目前为止,我还不能让它在任何断点处停止。唯一有效的是“starti”,它在分支到“reset_handler”之前停止它。那里的“stepi”让我直接进入所描述的状态。
- 这是 elf 文件的转储,因为它看起来比 GDB 的输出更漂亮。我已验证此数据存在于芯片上的 0x0 和 0x800 0000 中。
- 来自卡的数据、新鲜闪存和“starti”:
(gdb) info registers
r0 0x0 0
r1 0x0 0
r2 0x6d8d1d05 1837964549
r3 0x7fbf 32703
r4 0x8000008 134217736
r5 0x8000008 134217736
r6 0x8000008 134217736
r7 0x8000008 134217736
r8 0x8000008 134217736
r9 0x8000008 134217736
r10 0x8000008 134217736
r11 0x8000008 134217736
r12 0x8000008 134217736
sp 0x8000008 0x8000008
lr 0x8000008 134217736
pc 0x8000008 0x8000008
cpsr 0x8000008 134217736
(gdb) disassemble /r 0x0,0x10
Dump of assembler code from 0x0 to 0x10:
0x00000000: 00 20 movs r0, #0
0x00000002: 00 20 movs r0, #0
0x00000004: 09 00 movs r1, r1
0x00000006: 00 08 lsrs r0, r0, #32
0x00000008: 00 48 ldr r0, [pc, #0] ; (0xc)
0x0000000a: fe e7 b.n 0xa
0x0000000c: 68 46 mov r0, sp
(如您所见,0xc 中的值当前是死代码。)
(gdb) disassemble /r 0x8000000,0x8000010
Dump of assembler code from 0x8000000 to 0x8000010:
0x08000000 <vector+0>: 00 20 movs r0, #0
0x08000002 <vector+2>: 00 20 movs r0, #0
0x08000004 <vector+4>: 09 00 movs r1, r1
0x08000006 <vector+6>: 00 08 lsrs r0, r0, #32
=> 0x08000008: 00 48 ldr r0, [pc, #0] ; (0x800000c <reset_handler_c>)
0x0800000a: fe e7 b.n 0x800000a
0x0800000c <reset_handler_c+0>: 68 46 mov r0, sp
- 该板是基于stm32f215的定制板。我使用 st-link (v2) 通过 https://github.com/stlink-org/stlink 进行刷写和调试。 用已知好的代码刷写它适用于这个解决方案,但我不确定调试器是否完全正常工作。
- 两个boot脚直接通过1kOhm电阻接地
- 在稍微更改代码以直接跳转到循环后,我可以得出结论,无论第一个汇编指令是什么,它都会锁定。返回循环的分支导致了同样的错误。
- CFSR 和 HFSR:
(gdb) print/x *(uint32_t *) 0xE000ED28
= 0x0
(gdb) print/x *(uint32_t *) 0xE000ED2C
= 0x0
- 我几乎可以保证我使用的 stlink 应用程序混淆了 sp 和 lr。一个已知的好程序没有 sp=0x8f0d180 和 lr=0x2001ff88。明天会考虑改用 openocd。
罪魁祸首已经找到! 似乎 st-util 调试器(来自上述项目)以某种方式导致错误。 openocd 的工作就像一个魅力,上面的最小代码工作。
无论如何,要编写错误报告等等...
非常感谢大家验证我的汇编程序并帮助我点缀所有的 t 和交叉所有的 i!