2025-05-12 4:38 AM - edited 2025-05-20 7:33 AM
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.
2025-05-20 9:36 AM - edited 2025-05-20 9:46 AM
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"
2025-05-20 11:17 AM
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)
{
...
}
2025-05-20 12:17 PM
@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: