cancel
Showing results for 
Search instead for 
Did you mean: 

Cortex M0 Vector Table Reallocation Problem

Morpheuss01
Associate III

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.

1 ACCEPTED SOLUTION

Accepted Solutions
gbm
Principal

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).

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

View solution in original post

23 REPLIES 23
TDK
Super User

> 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.

If you feel a post has answered your question, please click "Accept as Solution".
Morpheuss01
Associate III

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.
Ekran görüntüsü 2025-12-03 143504.pngEkran görüntüsü 2025-12-03 143544.png

TDK
Super User

Are you jumping from within an interrupt?

If you feel a post has answered your question, please click "Accept as Solution".

No, I disabled all peripherals after I posted this post. However, it didn't work.

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.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
TDK
Super User

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

If you feel a post has answered your question, please click "Accept as Solution".

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
}

 

Morpheuss01
Associate III

Sorry my bad, I didn't pay close attention. I'll try that. Thank you :grinning_face_with_sweat:

It doesn't working.