Electronic – Bootloader and Vector Table on STM32F051

bootloaderstm32

I'm going through my company's code for a Bluetooth remote that uses a bootloader to download the main application over Bluetooth. The remote is pre-programmed with the bootloader application. Once the main application is loaded, the remote boots from the main application, unless there is a specific command to jump back to bootloader.

I'm new to bootloaders, so I've been trying to understand how it works. So far I'm quite confused. My main points of confusion are:

  1. Why is there a need to remap the vector table in the main application? I've seen a post on this, but I'm still not satisfied with the answer. How does the remap enable differentiation of the ISRs between that of the bootloader and main app? I include here a snippet of the remapping portion of the code:

    void remapMemToSRAM(void)
    {
        uint32_t vecIndex = 0;
        __disable_irq();
    
        for(vecIndex = 0; vecIndex < 48; vecIndex++)
        {
            VectorTable[vecIndex] = *(volatile uint32_t*)(APPLICATION_START_ADDRESS + (vecIndex << 2));
        }
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
        SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
    
        __enable_irq();
    }
    

    APPLICATION_START_ADDRESS is defined as 0x08004000. What does that for loop do? What kind of data is in those memory locations from 0x08004000, and how does it get put there?

    In the startup file, I see that reset handler branches to main after setting up the data in RAM etc. How does remapping the vector table enable the branching to go to different main()? I still don't see that.

  2. Do the bootloader and main application need separate linker files?

  3. Why must we remap the whole vector table? I understand the need for it for the reset vector, it needs an address to jump to upon power on or a reset. But for the other vectors shouldn't the stack be enough to tell if the caller is from the bootloader code or the main application?

I apologize if the questions are not clear, if they are let me know and I'll try my best to be clearer. I'm just very confused at this point.

Best Answer

1) The vector table is at the start of code normally and in your case there is the bootloader. The application code and it's vectors are later in code, so the interrupt controller needs to be told that when interrupt happens the vector is fetched from where the vectors for the main application are, otherwise it would jump to bootloader code. Bootloader uses bootloader vectors, application uses it's own vectors. But in your code it seems the application vectors are moved to SRAM, and they are used from there. Maybe they are used from there to enable changing the vectors during runtime.

2) If bootloader and application are two separate projects, then yes. Sometimes this is the easiest solution.

3) The hardware just has one register to tell at which address the vectors start, and all vectors are there.