【问题标题】:Bootloader. ARM CORTEX M0+ relocating Interrupt Table assembly ERROR引导加载程序。 ARM CORTEX M0+ 重新定位中断表组件错误
【发布时间】:2016-10-29 04:23:57
【问题描述】:

我目前正在尝试为 Atmel SAM R21 开发自己的引导加载程序。 我的想法是首先运行引导加载程序,因此它将决定是否需要执行更新或只是跳转到应用程序。主要问题是中断向量表位于 0x0000_0000 地址,因此它需要在应用程序代码之前重新定位,因此如果引导加载程序在链接器文件中设置了 8KB 空间并以这种方式使用 BOOTPROT 熔断器(设置这个熔断器应该对通过熔断器选择的内存量有一些保护),向量表应该从 0x0000_2000 地址开始。 为了重新定位向量表,我假装使用 VTOR 寄存器,它是应用于原始表地址 (0x0000_0000) 的偏移量。 汇编代码如下:

  asm(" LDR R0,=0xE000ED08 "); //VTOR ADDRESS
  asm("LDR R1,=0x00002000");   //OFFSET
  asm(" STR R1, [R0]");
  asm(" LDR R0,[R1] ");
  asm(" MOV SP, R0"); 
  asm(" LDR R0,[R1, #4]");
  asm(" BX R0");

LDR 指令给我以下错误: 错误[Og006]:内联汇编中的语法错误:“错误[401]:操作数语法错误”

我做错了什么?也许我正在尝试使用 ARM 指令而不是 Thumb 指令?

我将非常感谢任何建议。

我也怀疑一旦我重新定位了中断向量表,我是否也应该计算初始 MSP 值?我的意思是,如果中断向量表在重定位后从地址 0x0000_2000 开始,我应该计算 4(字节)* 中断,以便知道哪个应该是初始应用程序地址,不是吗?如果有人对此有所了解,那就太好了。我知道我很接近(或者我认为是),但我需要澄清这些观点。

于 16 年 6 月 27 日 13:04 编辑。 该指令有效 LDR R0,[R1] 所以我想这与将 32 位地址接收到寄存器中有关,但我不明白为什么它会抱怨这个。

解决方案:

作为对我的问题的回答,有人发布了并非所有汇编指令都可以内联使用,因此我需要创建一个汇编文件 my_file.s 在这个文件中应该创建一个从外部调用的函数,如下所示:

#define _PORT_ASM_ARM_SRC
#define __ASSEMBLY__

;/****************************************************************************
;**                                                                         **
;**                           ASSEMBLY FUNCTIONS                            **
;**                                                                         **
;****************************************************************************/

  NAME   start_app

  RSEG   CODE:CODE(2)
  THUMB

  PUBLIC jump_to_app

;/***************************************************************************/
;/***************************************************************************/
;/* jump_to_app()
; * Jump to application function.
; */

jump_to_app:
  LDR R0,=0xE000ED08 ; Set R0 to VTOR address
  LDR R1,=0x00010000 ; User’s flash memory based address
  STR R1, [R0] ; Define beginning of user’s flash memory as vector table
  LDR R0,[R1] ; Load initial MSP value
  MOV SP, R0 ; Set SP value (assume MSP is selected)
  LDR R0,[R1, #4] ; Load reset vector
  BX R0 ; Branch to reset handler in user’s flash


  END

完成此操作后,应将函数原型作为普通函数包含到项目的 .h 文件中,使用如下所示:

void jump_to_app(void);

最好的问候,

伊万。

【问题讨论】:

  • 其中一行与其他行不同...通过搜索这些错误代码,您似乎正在使用 IAR 工具链;检查 IAR ARM 汇编器手册,了解其语法中空格的重要性。
  • 你好,不喜欢那个。问题是我已经尝试过相同的格式。例如,STR 不报告任何错误,仅在 LDR 中发生。反正我要去查IAR ARM汇编手册。
  • 我说的是带有无意义指令R1,=0x00002000 的那一行,它恰好有 label "LDR" ;)
  • 你好。荒谬?我需要应用程序起始地址来设置 MSP,然后再设置复位向量地址,该地址将包含要执行的第一条指令的地址。我不知道我是否理解你,对不起:(
  • @Notlikethat 试图指出您在第二行的“LDR”之前没有空格字符。也许这很重要,因为没有空格,“LDR”可能会被视为标签而不是指令。

标签: c assembly embedded interrupt-handling cortex-m


【解决方案1】:

上面的汇编代码在语法上没有任何问题。如果你把汇编代码放到一个asm文件中并汇编它,它就会构建(至于它是否符合你的意图我没有检查过)。

由于某种原因,内联汇编器不喜欢LDR Rd, =expr

请参阅 IAR Embedded Workbench 帮助中的以下引用:

伪指令 LDR Rd, =expr 不能从内联汇编器中获得

同样来自 ARM:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472j/chr1359124248868.html

【讨论】:

    【解决方案2】:

    解决方案:

    作为对我的问题的回答,有人发布了并非所有汇编指令都可以内联使用,所以我需要创建一个汇编程序文件 my_file.s 在这个文件中应该创建一个从外部调用的函数,例如这个:

    #define _PORT_ASM_ARM_SRC
    #define __ASSEMBLY__
    
    ;/****************************************************************************
    ;**                                                                         **
    ;**                           ASSEMBLY FUNCTIONS                            **
    ;**                                                                         **
    ;****************************************************************************/
    
      NAME   start_app
    
      RSEG   CODE:CODE(2)
      THUMB
    
      PUBLIC jump_to_app
    
    ;/***************************************************************************/
    ;/***************************************************************************/
    ;/* jump_to_app()
    ; * Jump to application function.
    ; */
    
    jump_to_app:
      LDR R0,=0xE000ED08 ; Set R0 to VTOR address
      LDR R1,=0x00010000 ; User’s flash memory based address
      STR R1, [R0] ; Define beginning of user’s flash memory as vector table
      LDR R0,[R1] ; Load initial MSP value
      MOV SP, R0 ; Set SP value (assume MSP is selected)
      LDR R0,[R1, #4] ; Load reset vector
      BX R0 ; Branch to reset handler in user’s flash
    
    
      END
    

    完成此操作后,应将函数原型作为普通函数包含到项目的 .h 文件中,使用如下所示:

    void jump_to_app(void);
    

    最好的问候,

    伊万。

    【讨论】:

      猜你喜欢
      • 2015-09-15
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 2016-10-22
      • 2011-07-26
      • 2012-09-24
      相关资源
      最近更新 更多