2014-04-03 08:49 AM
Hello,
I'm trying to create a bootloader into the component STM32f106RDT with 384KO of Flash. I have mapped the memory like this: 0x08000000 - 0x0802DFFF for main software (first binary) 0x0802F000 - 0x08030FFF reserved 0x08031000 - 0x0805FFFF for the temp binary (second binary) My function of bootloader() to jump at selected main address is in flash. When I debug with keil the pc is in the file startup_stm32f10x_hd.s, then i want to go into my function bootloader so IMPORT the function like this : ; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit IMPORT FLASH_Bootloader /*my add*/ LDR R0, =SystemInit BLX R0 LDR R0, =FLASH_Bootloader /*my add*/ BLX R0 /*my add*/ ;LDR R0, =__main ;BX R0 ENDP The problem is that i want to jump on one of the two binary file. How do i get the flash address of the main() function? If i jump on 0x08000000+4 the beginning of the first binary mapping it does nothing. Somebody have an idea to select one of my 2 apps and run it? Thank you. #stm32 #bootloader2014-04-03 09:11 AM
Presuming your secondary code is built with it's own vector table.
LDR R0,=0x08031000 /* Or 0x0800000 for the base image */
LDR R0, [R0, #4] /* Vector+4 for PC */
BX R0
Plucking out arbitrary functions/addresses within another image is a hazardous task. Remember also that 16-bit THUMB code has ODD addresses, and the M3/M4 cannot run 32-bit ARM code.
2014-04-04 12:17 AM
My next function is going in hardfault handler, why?
void FLASH_Bootloader(void) { __disable_irq(); JumpAddress = (uint32_t) (void *)0x08000004; Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) 0x08000000); __enable_irq(); Jump_To_Application(); }2014-04-04 12:30 AM
Is it possible to fix the main() at a specific address? then it will be easy and sure to jump to it in the two binary.
2014-04-04 01:00 AM
Hi
Why enable Interrupts before doing the jump? I suspect this may be causing the Hardfault - the stack has just been changed and now any IRQ can trigger, which may try to do a context switch on an empty stack2014-04-04 01:01 AM
Hi
''Is it possible to fix the main() at a specific address? then it will be easy and sure to jump to it in the two binary.'' Yes BUT it is still not the recommended way! Stick to the method that clive1 suggested. The code that you posted last does look OK apart from the enable_irq() Try it without the enable_irq()2014-04-04 01:06 AM
By ODD address, do you mean
JumpAddress = (uint32_t) (void *)0x08000004+1; ? It still not working.2014-04-04 01:17 AM
Hi
''By ODD address, do you mean JumpAddress = (uint32_t) (void *)0x08000004+1;'' I have never really understood clive1's comments about jumping to an odd address. What you are trying to do is to emulate the boot up process. The boot process has a pre-determined address to go to (this may be fixed or may be configurable, lets just say it is fixed for now). Lets call this the 'boot vector' The boot up process takes the first address at the 'boot vector' as the address for the stack. The next address along at the 'boot vector' is the address of the code to run. When you compile and link some code on the ARM, usually the linker script will place the vector table first. The first 2 entries in the vector table are : the address for the stack and then the address for the code to run. So your code should look like this : void FLASH_Bootloader(void) { __disable_irq(); JumpAddress = (uint32_t) (void *) <address of new binary + 4>; Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) <address of new binary>; Jump_To_Application(); } where <address of new binary> should be 0x08031000 (Check if this address is valid for placing the vector table - see the reference manual for NVIC)2014-04-04 01:37 AM
Thank you for replu sung,
this is exaclty what i mean too. But it still not not working. May be my scatter file mapping is not good. ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00060000 { ; load region size_region ER_IROM1 0x08000000 0x0002F000 { ; load address = execution address *.o (RESET,+First) ; others *(InRoot$$Sections) .ANY (+RO) } ER_IROM2 0x0802F000 0x00001000 { ; load address = execution address flash_bootloader.o (+RO) } RW_IRAM1 0x20000000 0x0000F000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x2000F000 0x00001000 { ; RW data flash_handle.o (+RO) stm32f10x_flash.o (+RO) } }2014-04-04 02:15 AM
Hi
''May be my scatter file mapping is not good.'' No - do not try to mix your application and bootloader. Treat the bootloader as one project and the program as another project. The bootloader can then just treat the program as a binary and not know anything about it.