Skip to main content
Marek Frydrysiak_2
Associate
February 18, 2018
Question

Vector table relocation works only in debug mode

  • February 18, 2018
  • 7 replies
  • 2315 views
Posted on February 18, 2018 at 19:23

Hi,

I'm facing a problem with relocation of the vector table to the internal SRAM. I work with the STM32F030CCT6 (using the Ac6 System Workbench and CubeMX, with the HAL libraries 1.9.0) and I want to design a simple bootloader.

This is a part of my linker script:

/* Specify the memory areas */

MEMORY

{

RAM (xrw)      : ORIGIN = 0x200000C0, LENGTH = 32K-0xC0

VTRAM (xrw)    : ORIGIN = 0x20000000, LENGTH = 0xC0

FLASH (rx)     : ORIGIN = 0x08000800, LENGTH = 256K-0x800

}

....RAMVectorTable(NOLOAD): {*(.RAMVectorTable)} >VTRAM

This is a vector table relocation in the main() of the bootloader:

__IO uint32_t VectorTable[48] __attribute__((section('.RAMVectorTable')));

/* USER CODE END 0 */

/**

  * @brief  The application entry point.

  *

  * @retval None

  */

int main(void)

{

  /* USER CODE BEGIN 1 */

  uint32_t i = 0;

  for(i = 0; i < 48; i++)

    VectorTable[i] = *(__IO uint32_t*)((uint32_t)0x08000800 + (i<<2));

  /* Enable the SYSCFG peripheral clock*/

  __HAL_RCC_SYSCFG_CLK_ENABLE();

  /* Remap SRAM at 0x00000000 */

  __HAL_SYSCFG_REMAPMEMORY_SRAM();

...

Later on I send some test messages over the UART interface. I do not know why, but the above code works perfectly in the debug mode - I just need to run 'debug' and then 'resume' the program execution (with or without breakpoints later, does not matter).

Nevertheless, if I program the target (right click on the project -> 'Target' -> 'Program chip...', or just power-reset what I uploaded during the debug session), there is no response from the board. I am pretty sure that finally there is the same program on flash since I use the same .elf file both for the debugging session and regular programming... However, I've checked that if I do not relocate the vector table and I program the flash from the beginning (flash starts at 0x08000000), everything works just fine.

Just to clarify - I want to program the bootloader with some offset (0x0800) in memory because I need some space for the bootloader sensitive data (bootheader).

BR,

Marek

    This topic has been closed for replies.

    7 replies

    Tesla DeLorean
    Guru
    February 18, 2018
    Posted on February 19, 2018 at 00:55

    Well absent a debug connection you're probably going to want to push telemetry out a serial port.

    Things would want to dump out would be the FLASH based vector table, the one in SRAM, the address of the table as linked, and the SYSCFG registers, etc.

    I might order things like this to avoid any potential clock enable hazards.

      /* USER CODE BEGIN 1 */

      /* Enable the SYSCFG peripheral clock*/

      __HAL_RCC_SYSCFG_CLK_ENABLE();

      uint32_t i = 0;

      for(i = 0; i < 48; i++)

        VectorTable[i] = *(__IO uint32_t*)((uint32_t)0x08000800 + (i<<2));

      /* Remap SRAM at 0x00000000 */

      __HAL_SYSCFG_REMAPMEMORY_SRAM();

    Also make sure BOOT0 is pulled low externally.

    Don't transfer control from an IRQ Handler

    Watch for name mangling issue with C++ syntax

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Marek Frydrysiak_2
    Associate
    February 19, 2018
    Posted on February 19, 2018 at 21:31

    Hi, thank you for your attention! Unfortunately, none of this has helped: what I did:

    1. I checked whether the vector table is correctly copied to SRAM; furthermore, I disassembled the .elf and I checked that the vector table content from SRAM (after copying) contains proper addresses of the IRQ handlers,
    2. I checked the content of all flash regions,
    3. I checked the content of the SYSCFG register,
    4. BOOT0 pin is externally pulled low (through and without pull-down resistor, checked both options),
    5. In the debug mode I put a breakpoint in the very first instruction (assembler code, loading the end of stack address to the r0 register (ldr r0, _estack); this is the very first instruction below the Reset_Handler label marked in the linker script as the ENTRY point), then I just run the program without any more breakpoints in the debug mode and it worked like a charm...
    6. Moreover, I do not transfer control from an IRQ Handler; I tried to disable interrupts at all but it does not help neither

    Any suggestions would be appreciated

    BR,

    Marek

    Tesla DeLorean
    Guru
    February 19, 2018
    Posted on February 19, 2018 at 22:27

    Disabling interrupt can be problematic if you never re-enable them again.

    And the code runs without the debugger? ie if you set up a GPIO in the loader, and first code in application main() can toggle.

    Without some output to look at and review it is probably not something I can debug through a keyhole.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..