简体   繁体   English

引导程序。 ARM CORTEX M0 +重定位中断表程序集错误

[英]Bootloader. ARM CORTEX M0+ relocating Interrupt Table assembly ERROR

I am currently trying to develop my own bootloader for an Atmel SAM R21. 我目前正在尝试为Atmel SAM R21开发自己的引导程序。 My idea is to run the bootloader firstly, so it will decide if an update is needed to be performed or just jumping to the application. 我的想法是首先运行引导加载程序,因此它将决定是否需要执行更新或仅跳转到应用程序。 The main problem is that the Interrupt Vector Table is located at the 0x0000_0000 address, so it needs to be relocated just before the application code, so if the bootloader has a 8KB space set in the linker file and using the BOOTPROT fuse in that way (setting this fuse it is supposed that there will be some protection to the amount of memory selected through the fuse), the vector table should start at the 0x0000_2000 address. 主要问题是中断向量表位于0x0000_0000地址,因此需要在应用程序代码之前将其重新放置,因此,如果引导加载程序在链接器文件中设置了8KB空间,并以这种方式使用BOOTPROT保险丝(设置此保险丝后,假设对通过保险丝选择的内存量会有一定的保护),向量表应从0x0000_2000地址开始。 In order to relocate the vector table I pretend to use the VTOR register, which is an offset applied to the original table address (0x0000_0000). 为了重新定位向量表,我假装使用VTOR寄存器,该寄存器是应用于原始表地址(0x0000_0000)的偏移量。 The assembly code is the following: 汇编代码如下:

  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 instruction gives me the following error: Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" LDR指令给我以下错误:错误[Og006]:内联汇编中的语法错误:“错误[401]:操作数语法错误”

What am I doing wrong? 我究竟做错了什么? Maybe I am trying to use ARM instruction instead of a Thumb one? 也许我正在尝试使用ARM指令而不是Thumb指令?

I will very appreciate any advise. 我将不胜感激任何建议。

I am also doubting if once I get the Interrup Vector Table relocated, should I count with the Initial MSP value also? 我还怀疑是否一旦重定位了Interrup向量表,是否也应该使用初始MSP值进行计数? I want to mean, if the Interrupt Vector table starts at address 0x0000_2000 after being relocated, I should count 4(bytes) * Interrupt in order to know which should be the initial application address, shouldn't I? 我的意思是,如果中断向量表在重定位后从地址0x0000_2000开始,我应该计数4(bytes)*中断以便知道哪个应该是初始应用程序地址,不是吗? If someone knows something about this it would be nice. 如果有人对此有所了解,那就太好了。 I know I am close (or I think so), but I need to clarify those points. 我知道我已经接近(或者我认为是这样),但是我需要澄清这些观点。

Edited 27/06/16 at 13:04. 编辑于2016年6月27日13:04。 This instruction works LDR R0,[R1] So I guess it is something related to receive the 32 bits address into the register, but I don't understand why it is complaining about this. 该指令的工作方式为LDR R0,[R1],所以我想这与将32位地址接收到寄存器有关,但是我不明白为什么它对此有所抱怨。

SOLUTION: 解:

As an answer to my question, someone posted that not all assembly directives can be used inlined, so I needed to create an assembler file, my_file.s In this file should be created a function to be called from outside, something like this: 为了回答我的问题,有人发布了并非所有汇编指令都可以内联使用的功能,因此我需要创建一个汇编程序文件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

After doing this, the function prototipe should be included into a .h file of your project as a normal function, using something like this: 完成此操作后,函数原型应作为普通函数包含在项目的.h文件中,方法如下:

void jump_to_app(void);

Best regards, 最好的祝福,

Iván. 伊万。

There is nothing syntactically wrong with the assembly code above. 上面的汇编代码在语法上没有错。 If you put the assembly code into an asm file and assemble it, it will build (as to whether it does what you intended I have not checked). 如果将汇编代码放入一个asm文件中并进行汇编,它将生成(关于它是否达到了我未检查的目的)。

For some reason the inline assembler does not like LDR Rd, =expr . 出于某种原因,内联汇编器不喜欢LDR Rd, =expr

See the following quote from the IAR Embedded Workbench Help: 请参阅IAR Embedded Workbench帮助中的以下报价:

The pseudo-instruction LDR Rd, =expr is not available from inline assembler 内联汇编器不提供伪指令LDR Rd = expr

Also from ARM: 同样来自ARM:

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

SOLUTION: 解:

As an answer to my question, someone posted that not all assembly directives can be used inlined, so I needed to create an assembler file, my_file.s In this file should be created a function to be called from outside, something like this: 为了回答我的问题,有人发布了并非所有汇编指令都可以内联使用的功能,因此我需要创建一个汇编程序文件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

After doing this, the function prototipe should be included into a .h file of your project as a normal function, using something like this: 完成此操作后,函数原型应作为普通函数包含在项目的.h文件中,方法如下:

void jump_to_app(void);

Best regards, 最好的祝福,

Iván. 伊万。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM