cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt vector table relocation on cortex M0

jparera
Associate II
Posted on April 18, 2016 at 18:42

I read that the M-0 cant relocate the vector table ''M0 CPU does not support the vector table relocation. For application code which is located in a different address than 0x0800 0000, some additional code must be added in order to be able to serve the application interrupts''. I am trying to make a bootloader and I can jump from one main to another and back but I cant use interrupts because that limitation, is there any example on how to do it? The only reference I found is the AN4065 and it doesn't do this. I am using STL peripheral library.

thank you very much.

#stm32-mo-bootloader-relocation
7 REPLIES 7
Posted on April 18, 2016 at 18:58

It is demonstrated in the IAP examples, and has been gone over numerous times on the forum.

You make space in the front of RAM. You copy your new vectors there. You map the RAM at 0x00000000 instead of the FLASH. Now the processor pulls its interrupt vectors from your new table Adapted from STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\binary_template\src\main.c

...
int main(void)
{
uint32_t i = 0;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f0xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f0xx.c file
*/
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
/* Copy the vector table from the Flash (mapped at the base of the application
load address 0x08003000) to the base address of the SRAM at 0x20000000. */
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Not Reset, Clock
/* Remap SRAM at 0x00000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
...

To have the boot loader work again you'd need to Remap back to FLASH

/* Remap SRAM at 0x08000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_FLASH);

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jparera
Associate II
Posted on April 21, 2016 at 18:32

Thanks for the help I didn't notice that main.c the AN has 3 projects inside. Sry for asking something trivial. ( I navigated like 20 pages of forum search results... and haven't found it )

I did that then the second main had interrupts working but if I jumt to first main again( 0x800...00)  interrupts after inits() don't work. I did the trick of moving the interrupts to RAM in first main(FW1) too, then I solved jumping from FW 1 to FW 2 to FW1 and having interrupts working.  I am not sure its necessary.

Posted on April 21, 2016 at 18:47

I navigated like 20 pages of forum search results... and haven't found it 

Search here is useless, I use Google with strategic search terms.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jparera
Associate II
Posted on May 25, 2016 at 11:45

I thought it worked... now that I solved getting and writing the binary when I jump to 0x8004000 the app works except interrupts the first thing I do is remap table, I verified that the interrupts vector is in its place in RAM. the  EXTI0_1_IRQHandler or SysTick_Handler never gets called even if I init them the same way I do in the main residing at 0x8000000.

#define APPLICATION_ADDRESS     (uint32_t)0x08004000

void Remap_Table(void)

{

    uint32_t i = 0;

    /*!< At this stage the microcontroller clock setting is already configured,

    this is done through SystemInit() function which is called from startup

    file (startup_stm32f0xx.s) before to branch to application main.

    To reconfigure the default setting of SystemInit() function, refer to

    system_stm32f0xx.c file

    */

    /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/  

    /* Copy the vector table from the Flash (mapped at the base of the application

    load address 0x08003000) to the base address of the SRAM at 0x20000000. */

    for(i = 0; i < 48; i++)0690X00000605OCQAY.png

    {

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

    }

        

                

    

  // @brief  Forces or releases High Speed APB (APB2) peripheral reset.

  // @param  RCC_APB2Periph: specifies the APB2 peripheral to reset.

  //          This parameter can be any combination of the following values:

  //             @arg RCC_APB2Periph_SYSCFG: SYSCFG clock

  //             @arg RCC_APB2Periph_USART6: USART6 clock  

  //             @arg RCC_APB2Periph_USART7: USART7 clock

  //             @arg RCC_APB2Periph_USART8: USART8 clock   

  //             @arg RCC_APB2Periph_ADC1:   ADC1 clock

  //             @arg RCC_APB2Periph_TIM1:   TIM1 clock

  //             @arg RCC_APB2Periph_SPI1:   SPI1 clock

  //             @arg RCC_APB2Periph_USART1: USART1 clock

  //             @arg RCC_APB2Periph_TIM15:  TIM15 clock

  //             @arg RCC_APB2Periph_TIM16:  TIM16 clock

  //             @arg RCC_APB2Periph_TIM17:  TIM17 clock

  //             @arg RCC_APB2Periph_DBGMCU: DBGMCU clock

  // @param  NewState: new state of the specified peripheral reset.

  //          This parameter can be: ENABLE or DISABLE.

  // @retval None

        

        

        

    // Enable the SYSCFG peripheral clock

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);         

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1, ENABLE);

    /*

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_DBGMCU, ENABLE);

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);

        */

    

    

    /* Remap SRAM at 0x00000000 */

    //SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);

    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SystemMemory);

            

  // @brief  Configures the memory mapping at address 0x00000000.

  // @param  SYSCFG_MemoryRemap: selects the memory remapping.

  //         This parameter can be one of the following values:

  //            @arg SYSCFG_MemoryRemap_Flash: Main Flash memory mapped at 0x00000000  

  //            @arg SYSCFG_MemoryRemap_SystemMemory: System Flash memory mapped at 0x00000000

  //            @arg SYSCFG_MemoryRemap_SRAM: Embedded SRAM mapped at 0x00000000

  // @retval None

 

}

jparera
Associate II
Posted on May 25, 2016 at 13:16

I did one more test, from the AN4065 I loaded the project App2 on to 8003000 and Ap1

onto 8000000, I modified App1 to jump to App2 on push button, I modified App2 to flash my discovery-board Leds not the eval-board ones, if I jump to App2 from the modified App1 then App2 systick timer works and delays keeps flashing leds. If I Jump from my App1 (my IAP ) using the same jump to function , the leds on App2 work but not the systick so I get stuck on Delay. So the App2 is not independent from the App1 because if I jump from my App1 interrupts don't work but the same App2 has working interrupt if I jump from another App1 ? Again I did another test, if I call the jump to App2 from Button interrupt routine then at App2 interrupts don't work, but if I call it from main polling button or Polling a variable modified by the button interrupt they work even from my Evil App1 code. why I can't jump from inside a Interrupt ?
Posted on May 25, 2016 at 16:45

RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);         !!NOT RESET!!

You want to enable the Clock

  //SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);

    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SystemMemory);  !!NOT ROM!!

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
jparera
Associate II
Posted on May 25, 2016 at 17:28

well I tried that too, sometimes I enter in monkey mode just compile with other options and see if it works...  I can jump from App1 to App2 and if I do rellocate vector table interrupts works in App2, if I jump from App2 to App1 (located at 0x08000000) then interrupts don't work at App1 I can do  a SW reset to jump to App1 then interrupts work fine.  Thanks for your patience.