【问题标题】:How should I initialise my stm32 ( f215 )我应该如何初始化我的 stm32 ( f215 )
【发布时间】:2020-06-29 16:12:54
【问题描述】:

我正在尝试制作一个极简的 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 进行闪烁和调试。 用已知的好代码刷新它适用于这个解决方案,但我不确定调试器是否完全正常工作。
  • 两个引导引脚均通过 1kOhm 电阻器直接接地。
  • 稍微更改代码以直接分支到循环后,我可以得出结论,无论首先是什么汇编指令,它都会锁定。返回循环的分支导致了同样的错误。
  • CFSR 和 HFSR:
(gdb) print/x *(uint32_t *) 0xE000ED28
$1 = 0x0
(gdb) print/x *(uint32_t *) 0xE000ED2C
$2 = 0x0
  • 我几乎可以保证我使用的 stlink 应用程序混淆了 sp 和 lr。一个已知的好程序没有 sp=0x8f0d180 和 lr=0x2001ff88。明天会考虑改用 openocd。

【问题讨论】:

  • 这里的硬件不熟悉,但我知道ARM。如果您的 ISR 登陆 ,那么它正在执行数据而不是代码。几乎 100% 确定这两个操作码是堆栈地址 (0x20002000) 和入口点 (0x08000009)。请注意,地址是奇数,因此系统采用“Thumb”指令。仔细检查这是否是您想要的。我会假设 ARM 在启动时,所以这对我来说很奇怪。 infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/…
  • 重新阅读 - 引导至0x800 0000 的别名几乎可以肯定意味着您正在执行“池”而不是从重置处理程序开始。这也意味着您可能在执行第二条指令时抛出异常,因为 R0 几乎可以肯定是垃圾。要么将第一条指令作为 的分支,将引导引脚别名为 ,要么将池从入口点移开。
  • “但是当我调试它时,我最终......” - 但是它在之前做了什么?在reset_handler 有一个断点,它甚至会停在那里吗?无论如何,将代码放在向量表中可能不是一个好主意。如果发生 NMI 或硬故障异常,它会将您的代码解释为向量并跳转到无效地址。你的reset_handler 应该位于向量表的上方。
  • 我宁愿看到它在FLASH中而不是在文件中。
  • @P__J__ : 发布的代码是反汇编而不是源文件,所以它大概闪存中的内容。

标签: arm embedded cortex-m3


【解决方案1】:

罪魁祸首已经找到了! 似乎 st-util 调试器(来自上述项目)以某种方式导致错误。 openocd 的工作原理就像一个魅力,并且上面的最小代码也可以工作。

无论如何,要写的错误报告等等......

非常感谢大家验证我的汇编程序并帮助我点出所有的 t 和交叉所有的 i!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 2011-11-04
    • 2016-03-26
    • 1970-01-01
    相关资源
    最近更新 更多