2026-01-04 1:54 AM - edited 2026-01-04 2:10 AM
Hi I have a question that blocked me for several days, Hopefully someone can help, thanks a lot.
1:MCU:STM32G0B0CET6,Develop tool:STM32CubeIDE
2:I wanna have a test for OTA ,so i create a bootloader project and app project
3:Flash segmentation:
1)Bootloader(32KB),0x08000000~0x08007FFF
APP(240K):0x08008000~0x08047FFF
APP BAK(236K):0x08048000~0x08079FFF
INFO(8K):0x0807A000~x0807FFFF
4:In Bootloader ,try to jump to APP(0x08008000):
5:Attached the source code (bootloader and app) and hex file(in debug directory)
6:Modifed "ld" file in bootloader project and app project, and I confirm the stack address in 0x08008000 and reset_handler in 0x08008004 is correct.
And have set vector in main entry(first line in main()):SCB->VTOR = FLASH_BASE | 0x8000;
7:If i use stm32CubeProgrammmer and STM32CubeIDE to start ,app will be run ,But app can not run via bootloader software jump.
bootloader jump slide:
void RunUserCode( void )
{
uint32_t* ucaddr;
// if( ( ( *( uint32_t* )ROM_APP_VECT_START_ADDR ) & 0x2FFC0000 ) == 0x20000000 )
if( ( *( uint32_t* )APP1ADDR ) == 0x20023FF8)
{
HAL_DeInit();//DeInit The Peripherals Used By The Bootloader
//Rocky report fault shield first __set_FAULTMASK( 1 );
__disable_irq();
__set_MSP( *( __IO uint32_t* )APP1ADDR ); // Get top of stack address and initialize SP
__set_PSP( *( __IO uint32_t* )APP1ADDR );
__set_CONTROL( 0 );
ucaddr = ( uint32_t* )( ROM_APP_VECT_RESET_ADDR ); // Get APP Reset Handler address
( *( ( void( * )( void ) )( *ucaddr ) ) )(); // Let's Jump!
}
}app vector set:
int main(void)
{
/* USER CODE BEGIN 1 */
/* 第一步:强制设置向量表偏移,优先级最高 */
//SCB->VTOR = 0x08008000; // 必须放在最前面!
SCB->VTOR = FLASH_BASE | 0x8000;
setMainState(BOOT,3);
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();bootloader ld slice: :
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
APP ld Slice:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20023FF8;/*8 bytes alignment*/
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 144K
FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 240K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASHflash readback screen shot for boot and app:
2026-01-04 12:29 PM
1. The interrupts are disabled while jumping to the app. They must be enabled.
2. No need to set PSP.
3. The code may not work if compiled with the default -O0. Use -O1 or above.
4.The routine jumping to the app should be invoked in the bootloader right after reset, before initializing peripherals. It should NOT be called from ISR. See some other threads on bootloaders and app starting.
5. See the content of the file, esp. the comments:
https://github.com/gbm-ii/STM32_Inc/blob/main/cm_boot.h