cancel
Showing results for 
Search instead for 
Did you mean: 

M0 in-line assembler moving from bootloader to main app

DiBosco
Senior II

Folks,

I have a bootloader for an M0 which works without using interrupts. It works in that it loads the new app, the CRC in the new app matches and I then try and jump to 0x8004000.

In the past I have used a couple of different methods with M3/4 to boot to the app from bootloader dependent on what compiler/IDE I was using, but the M0 is slightly different due to how the vector table is not relocatable. So we've come up with a method to get round that and "all" I need to do is jump to 0x8004000.

I *think I need something like this:

void jump_to_normal_application(void)
{

    u32 jump_address;

    jump_address = *(volatile u32*) (MAIN_PROG_START_ADDRESS + 4);
    jump_to_application = (pFunction) jump_address;

    asm("ldr sp, =0x20002000");

    jump_to_application();

}


I'm getting the error:

Error: lo register required -- `ldr sp,=0x20002000'

I've searched this and although I can find many hits  I can't see anything vaguely relevant to my situation.

Also, I would like to make 0x20002000 on line 9 top be a #define or loading from a C variable


Can anyone help me with this please? __Set_MSP is not available to me due to the, errr, "individual" setup I am forced to use.

What is the way to do this and are any of my assumptions above even vaguely correct? Am using gcc.

22 REPLIES 22

This is super ultra simple things - running MCU from required address in assembler - much more you make self tired by adding so many definitions and typecastings in C.

Without problem should be working in depends what is under 0x08004004 - pointer to running program or immediatelly code - so you know before how to treat it - I'd show. Go back here and tell to as "IT WORK"

Ok, fair enough

What's at 0x08004000 ? Executable code or an indirect address to an entry point?

  .word EntryPoint ; 32-bit pointer to function

or

 .thumb_func
 .global EntryPoint
 .type   EntryPoint, %function

  ldr r0, =0x20002000
  movs sp, r0
...
 .size EntryPoint, .-EntryPoint

or

void EntryPoint(void)
{
...
}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
wegi01
Associate III

@DiBosco When I sometimes want to look to value I use my small function which convert data from R1 register to ASCII HEX string to buffer pointed in R0 register.
Declaration in C looks:

extern void my_htoa32(char * buf, uint32_t data);

 

But if you want invoke this from assembler you should to do:

     ldr r0, = 0x20000369 // for example a free area for use as buffer 11 bytes
     ldr r1, = 0x42408200 // value for tested
     BL  my_htoa32
 lll:
     b lll  // neverending loop

 

Function my_htoa32:

    .syntax unified
    .cpu cortex-m0
    .fpu softvfp
    .thumb

    .thumb_func
    .global my_htoa32
    .type   my_htoa32, %function


    .text
//----------------

//======================================================
// HEX 32BIT value convert to string
//====================================
       // INPUT:
       //    R0, =  ; POINTER TO OUTPUT char DATA BUFFER
       //    R1, =  ; VALUE TO HEXADECIMAL CONVERT

       // output: no output, data in buffer are output
//=======================================================
//=========================
my_htoa32:

        MOV    R3, 0x7830     // "0x"
        STRH   R3, [R0]       // STORE "0x" TO BUFFER
        MOVS   R3, 2          // output data 2 bytes after start buffer
//--
LP01:
        LSRS   R2, R1, #28    // R2 = OUR DATA TO STRING CONVERT 1 BYTE = NYBBLE 0..F
        LSLS   R1, R1, #4     // R1 * 16 = R1 << 4
        ADDS   R2, R2, #0x30  // CONVERT TO NUMBER
        CMP    R2, #0x3A
        BCC    LP01A          // if data < than 0x3a don't  add #7
        ADDS   R2,R2, 0x07    // CONVER TO LETTER
LP01A:
        STRH   R2, [R0, R3]   // STRH store byte and zero terminated
        ADDS   R3, R3, #1
        CMP    R3, #10
        BNE    LP01
//---
        BX     LR
//=============================================================

 

The result you can observe in STM32 Link Utility or in Cube Programmer:

 

utility.jpg