C calling the build procedure - ARM

I am currently working on a bootloader for ARM Cortex M3.

I have two functions: one in C and one in the assembly, but when I try to call the assembly function, my program freezes and generates some kind of error.

The functions are as follows:

WITH

extern void asmJump(void* Address) __attribute__((noreturn)); void load(void* Address) { asmJump(Address); } 

Assembly:

 .section .text .global asmJump asmJump: @ Accepts the address of the Vector Table @ as its first parameter (passed in r0) ldr r2, [r0] @ Move the stack pointer addr. to a temp register. ldr r3, [r0, #4] @ Move the reset vector addr. to a temp register. mov sp, r2 @ Set the stack pointer bx r3 @ Jump to the reset vector 

And my problem is this:

The code prints "Hello" at the serial number, and then calls load . The downloaded code prints "Good Bye" and then resets the chip.

If I slowly asmJump part where load calls asmJump , everything works fine. However, when I run the code, my code experiences a "memory error". I know this is a memory error, because it causes Hard Fault in some way (the Hard Fault handler runs an infinite while loop when paused after 4 or 5 seconds).

Has anyone experienced this problem before? If so, can you tell me how to solve it?

As you can see, I tried to use the attributes of the function to fix the problem, but so far I could not find a solution. I hope someone can help me understand what the problem is in the first place.

Edit:

Thanks to @JoeHass for your answer and @MartinRosenau for your comment, I have since found this SO answer , which has a very detailed explanation of why I need this shortcut. It takes a very long time to read, but worth it.

+6
source share
3 answers

I think you need to tell the assembler to use a unified syntax and explicitly declare your function as a thumb function. The GNU builder has directives for this:

  .syntax unified .section .text .thumb_func .global asmJump asmJump: 

The .syntax unified directive tells the assembler that you are using modern syntax for assembly code. I think this is an unsuccessful relic of some outdated syntax.

The .thumb_func directive tells the assembler that this function will be executed in thumb mode, so the value that is used for the asmJump character has its own LSB set to one. When Cortex-M executes the branch, it checks the LSB of the destination address to see if it is one. If so, then the target code is executed in thumb mode. Since this is the only mode supported by Cortex-M, it will fail if the LSB of the destination address is zero.

+7
source

Since you mention that you have a debugger running, use it!

Look at the fault status registers to determine the source of the trouble . Perhaps this is not asmJump crash, but the code you are calling.

+1
source

If this is your all your code .. I believe that your change of SP caused a segment error or something like that. You must save your SP before replacing it and restore it after use.

 ldr r6, =registerbackup str sp, [r6] #your code ... ldr r6, =registerbackup ldr sp, [r6] 
0
source

Source: https://habr.com/ru/post/953958/


All Articles