4

我写了(IMO)几乎最简单的 ARM 应用程序,但它没有用 :) 可能有什么问题?错过了什么?

在闪存写入和 CPU 复位后,寄存器中有垃圾。

请善待,如果你知道,请告诉我在 STM32F1 上运行最简单的应用程序需要做什么。

可能有人可以列举在应用程序开始之前必须做的事情,即。

  1. 初始化堆栈(有必要吗?)
  2. 设置一些东西。
  3. 设置别的东西。

应用程序:

@Directives
    .thumb                  @.code 16
    .syntax unified

.section .text
    .org 0                  @ Alters location of pointer - in this case set to zero

vectors:                    @ Define basic vectors for specific capabilities
    .word _start + 1        @ Set - start address and increment pointer
    .word _nmi_handler + 1  @ Below all other vectors will be declared:
    .word _hard_fault + 1
    .word _memory_fault + 1
    .word _bus_fault + 1
    .word _usage_fault + 1

_start:
    mov r0, #5
    mov r1, #4
    add r2, r0, r1

_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:

也许有人知道任何关于链接器脚本、cpu 初始化等的教程或书籍?

处理器为:STM32F103VBT6

编程者:OpenOCD。

提前致谢。

4

2 回答 2

8

来自M3 文档

The vector table at location 0 is only required to have four values:

Stack top address
Reset routine location
NMI ISR location
Hard Fault ISR location.

栈顶地址应该是地址 0,好像你错过了它。

于 2012-03-05T11:48:44.013 回答
7

我有很多基于拇指和 cortex-m 的示例http://github.com/dwelch67

正如 Joachim 指出的那样,您缺少向量表中的第一个条目,即堆栈指针。cortex-m 没有与 arm 相同的向量表,即使用 arm 指令以 arm 模式启动的向量表。

不过,要完成答案,对于 cortex-m,您可以通过将堆栈指针的起始值放在第一个单词位置来设置堆栈

.cpu cortex-m3
.thumb

.word   0x10008000  /* stack top address */
.word   _start      /* 1 Reset */
.word   hang        /* 2 NMI */
.word   hang        /* 3 HardFault */
.word   hang        /* 4 MemManage */

您当然可以在运行后手动设置堆栈指针,就像使用 arm 模式或大多数其他处理器一样。

我会让你的代码陷入无限循环,这样,正如所写的那样,你不会陷入未定义的指令等(应该是 0xFFs,在我认为的 cortex-m0 上是未定义的,在 -m3 或 -m4 上armv7 thumb2 支持它可能是一个真正的指令)。

请注意,我没有在矢量上使用 +1。你需要知道你的工具。您需要设置 lsbit 来指示分支上的拇指地址/拇指模式。尽管我从中吸取了教训(必须找到so问题)

Arm/Thumb:在 Thumb 代码中使用 BX,调用 Thumb 函数,或跳转到另一个函数中的 Thumb 指令

使用 gnu 汇编器,如果您将指令 .thumb_func 放在标签之前,则该标签被标记为拇指标签,然后 gnu 工具将使用地址|1。

.thumb_func
.globl _start
_start:

您需要不时地构建和反汇编,以确保您的表正在正确构建并且分支等使用正确的地址。

   0:   10008000    andne   r8, r0, r0
   4:   0000005b    andeq   r0, r0, fp, asr r0
   8:   00000050    andeq   r0, r0, r0, asr r0
   c:   00000050    andeq   r0, r0, r0, asr r0
  10:   00000050    andeq   r0, r0, r0, asr r0

看,显然我的一个例子中有一个错误......它除了重置之外什么都不做(例子中没有使用中断,所以这就是我不知道的方式)。忘记了 .thumb_func

hang:   b .

生产

00000050 <hang>:
  50:   e7fe        b.n 50 <hang>

改成

.thumb_func
hang:   b .

向量表转到

00000000 <hang-0x50>:
   0:   10008000    andne   r8, r0, r0
   4:   0000005b    andeq   r0, r0, fp, asr r0
   8:   00000051    andeq   r0, r0, r1, asr r0
   c:   00000051    andeq   r0, r0, r1, asr r0
  10:   00000051    andeq   r0, r0, r1, asr r0
  14:   00000051    andeq   r0, r0, r1, asr r0

这很有趣,将代码更改为

.cpu cortex-m3
.thumb

.word   0x10008000  /* stack top address */
.word   _start+1      /* 1 Reset */
.word   hang+1        /* 2 NMI */
.word   hang+1        /* 3 HardFault */
.word   hang        /* 4 MemManage */
.word   hang        /* 5 BusFault */

它并没有真正做一个加一,而是一个或一。

00000000 <hang-0x50>:
   0:   10008000    andne   r8, r0, r0
   4:   0000005b    andeq   r0, r0, fp, asr r0
   8:   00000051    andeq   r0, r0, r1, asr r0
   c:   00000051    andeq   r0, r0, r1, asr r0
  10:   00000051    andeq   r0, r0, r1, asr r0

这有点令人不安。最重要的是,有两件事,使用 cortex-m 您可以在向量表中设置堆栈指针,第二,在开始新项目时反汇编并检查向量表以确保它是您所期望的。特别是如果它没有做你认为它应该做的事情。

于 2012-03-05T15:40:13.007 回答