diff --git a/src/main/drivers/system_stm32f4xx.c b/src/main/drivers/system_stm32f4xx.c index 3b7b38ef79..cab9560a91 100644 --- a/src/main/drivers/system_stm32f4xx.c +++ b/src/main/drivers/system_stm32f4xx.c @@ -187,9 +187,12 @@ void systemInit(void) // cache RCC->CSR value to use it in isMPUSoftReset() and others cachedRccCsrValue = RCC->CSR; - /* Accounts for OP Bootloader, set the Vector Table base address as specified in .ld file */ - extern void *isr_vector_table_base; + // Although VTOR is already loaded with a possible vector table in RAM, + // removing the call to NVIC_SetVectorTable causes USB not to become active, + + extern uint8_t isr_vector_table_base; NVIC_SetVectorTable((uint32_t)&isr_vector_table_base, 0x0); + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, DISABLE); RCC_ClearFlag(); diff --git a/src/main/target/link/stm32_flash_f405.ld b/src/main/target/link/stm32_flash_f405.ld index 91c709d8f3..429262f7f4 100644 --- a/src/main/target/link/stm32_flash_f405.ld +++ b/src/main/target/link/stm32_flash_f405.ld @@ -36,5 +36,6 @@ MEMORY REGION_ALIAS("STACKRAM", CCM) REGION_ALIAS("FASTRAM", CCM) +REGION_ALIAS("VECTAB", RAM) INCLUDE "stm32_flash_split.ld" diff --git a/src/main/target/link/stm32_flash_split.ld b/src/main/target/link/stm32_flash_split.ld index 19a48e3df6..4659c3232c 100644 --- a/src/main/target/link/stm32_flash_split.ld +++ b/src/main/target/link/stm32_flash_split.ld @@ -26,14 +26,25 @@ _Min_Stack_Size = 0x800; /* required amount of stack */ /* Define output sections */ SECTIONS { - /* The startup code goes first into FLASH */ + /* + * The ISR vector table is loaded at the beginning of the FLASH, + * But it is linked (space reserved) at the beginning of the VECTAB region, + * which is aliased either to FLASH or RAM. + * When linked to RAM, the table can optionally be copied from FLASH to RAM + * for table relocation. + */ + + _isr_vector_table_flash_base = LOADADDR(.isr_vector); + PROVIDE (isr_vector_table_flash_base = _isr_vector_table_flash_base); + .isr_vector : { . = ALIGN(4); PROVIDE (isr_vector_table_base = .); KEEP(*(.isr_vector)) /* Startup code */ . = ALIGN(4); - } >FLASH + PROVIDE (isr_vector_table_end = .); + } >VECTAB AT> FLASH /* System memory (read-only bootloader) interrupt vector */ .system_isr_vector (NOLOAD) : diff --git a/src/main/target/system_stm32f4xx.c b/src/main/target/system_stm32f4xx.c index eb40659f1b..ed251b2fe6 100644 --- a/src/main/target/system_stm32f4xx.c +++ b/src/main/target/system_stm32f4xx.c @@ -314,6 +314,7 @@ * @{ */ +#include #include "stm32f4xx.h" #include "system_stm32f4xx.h" #include "platform.h" @@ -349,9 +350,7 @@ /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ -/* #define VECT_TAB_SRAM */ -#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. - This value must be a multiple of 0x200. */ +#define VECT_TAB_SRAM /******************************************************************************/ /** @@ -539,10 +538,20 @@ void SystemInit(void) //SetSysClock(); /* Configure the Vector Table location add offset address ------------------*/ + #ifdef VECT_TAB_SRAM - SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ + // Copy vector table from isr_vector_table_flash_base to isr_vector_table_base. + // If these two regions are the same, the copy will have no effect + // (Happens when linker script aliases VECTAB to FLASH). + + extern uint8_t isr_vector_table_flash_base; + extern uint8_t isr_vector_table_base; + extern uint8_t isr_vector_table_end; + + memcpy(&isr_vector_table_base, &isr_vector_table_flash_base, &isr_vector_table_end - &isr_vector_table_base); + SCB->VTOR = (uint32_t)&isr_vector_table_base; #else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ + SCB->VTOR = (uint32_t)&isr_vector_table_flash_base; #endif SystemCoreClockUpdate();