2025-12-03 4:48 AM - last edited on 2025-12-03 5:06 AM by Andrew Neil
In my embedded software project, I need to write a bootloader. I wrote an application code for the bootloader and testing, and everything is fine so far, but the delay function in the application code is not working. I think the reason for this is the Vector Table. I wrote the vector table to the RAM address, but it didn't work at all. It jumps to the application code, turns on the LED, but does not toggle. I would really appreciate your help. (STM32f030c8t6 board)
#define APP_START_ADDRESS 0x08006000 // User application start address
#define APP_START_ADDR 0x08006000
#define SRAM_BASE_u 0x20000000
#define VECT_TABLE_SIZE 0xC0 // 48 vectors * 4 bytes
void JumpToApplication(void)
{
// 1. Dsiable all interrupts
__disable_irq();
// 2. Deinit HAL and RCC (optional if bootloader did init)
HAL_DeInit();
HAL_RCC_DeInit();
// 3. Copy vector table
memcpy((void*)SRAM_BASE_u, (void*)APP_START_ADDR, VECT_TABLE_SIZE);
// 4. Remap SRAM to 0x00000000
SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_MEM_MODE; //Clear MEM_MODE bits
SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_1; // SRAM -> 0x00000000
// 5. Load MSP and Reset Handler from RAM
uint32_t app_sp = *(volatile uint32_t*)SRAM_BASE_u;
uint32_t app_reset = *(volatile uint32_t*)(SRAM_BASE_u + 4);
// 6. Set MSP and jump
__set_MSP(app_sp);
pFunction app_entry = (pFunction)app_reset;
app_entry();
while(1); // Should never return
}Edited to apply source code formatting - please see How to insert source code for future reference.
Solved! Go to Solution.
2025-12-04 3:31 AM - edited 2025-12-04 4:05 AM
In the bootloader, you should start the app this way:
disable_unpend_all_ints();
vectable_setup(app_addr);
SYSCFG->CFGR1 = SYSCFG_CFGR1_MEM_RAM; // map RAM at 0
app_start(app_addr);Note that your app must also contain the ram_vectable definition in a source file and treat it properly in the linker script, exactly like the bootloader.
Next time you attach some code, please remove all the unnecessary stuff, like big comments and commented-out sections. Leave only the relevant parts.
Check the .map files of the bootloader and the app to make sure that locations of ram_vectable and the rest of data are correct.
Update: as I am currently working on my bootloader stuff, I made some more additions to the header file. with the current version, to start the application on STM32F0 it is enough to write just one line:
app_invoke(app_addr);
This is equivalent to the last 3 lines of code above (does not include interrupt deactivation).
2025-12-03 6:21 AM
> the delay function in the application code is not working
The code presented looks okay to me. Maybe the delay function is bad?
Debugging the code and stepping through should show the issue.
2025-12-03 6:38 AM
It cannot return from this while loop. I am thiking that because of vector table at the begining of flash memory. Because when I loaded the code to the begining of flash, it workes as should be. Delay funtion can't get the tick value.
2025-12-03 6:48 AM
Are you jumping from within an interrupt?
2025-12-03 7:10 AM
No, I disabled all peripherals after I posted this post. However, it didn't work.
2025-12-03 7:11 AM - edited 2025-12-03 7:15 AM
For this to work, you must guarantee that no other data is placed over RAM vectors. Some time ago that was discussed on the forum. You need to edit the linker script and declare the new .ram_isr_vector section before .data section, then define the vector table in this section:
__attribute__((section(".ram_isr_vector"))) struct cm0_vectable_ ram_vectable;
See this file for some details (vectable_setup() function):
https://github.com/gbm-ii/STM32_Inc/blob/main/cm_boot.h
Also, as discussed many times, you should jump to application right after reset, before any HAL calls. Please search the forum posts for "bootloader" keyword.
2025-12-03 7:21 AM
You also need interrupts enabled if you want SysTick to work. See generic working jump code here:
How to jump to system bootloader from application ... - STMicroelectronics Community
2025-12-03 7:22 AM
It's using Vector Table Offset Register but cortex M0 mcu doesn't have VTOR.
static inline void vectable_setup(uint32_t addr)
{
// at this point all interrupts must be disabled (NVIC, SysTick)
#ifdef __VTOR_PRESENT
SCB->VTOR = addr;
#else // Cortex-M0
// define with __attribute__((section(".ram_isr_vector")))
extern struct cm0_vectable_ ram_vectable;
ram_vectable = *(const struct cm0_vectable_ *)addr; // copy vectors to start of RAM
#endif
}
2025-12-03 7:26 AM
Sorry my bad, I didn't pay close attention. I'll try that. Thank you :grinning_face_with_sweat:
2025-12-03 7:54 AM
It doesn't working.