2021-09-03 09:53 AM
We are in the process of upgrading one of our MCUs from the STM32F072RBT6 to the STM32F303RBT6 and we are experiencing problems with the F303. I am testing out all the firmware using a NUCLEO-F303RE (the 512kB version of the MCU). To further test this issue, I have also made a very simple application that simply blinks the NUCLEO LED once per second. If I pull the BOOT0 pin low, I can communicate with the bootloader over USART1. So I am able to flash the MCU binary with the bootloader and then pull BOOT0 high, reset the MCU, and then the LED blink program runs without any issue. What I am not able to do is issue the Go command to the bootloader and start the user application from the bootloader. With this, I see the LED flash very quickly once (not the duration it should) and then the MCU is back in the bootloader. I can then endlessly issue the Go command, without physically resetting the MCU (NRST), and see this very short single flash. If I change the firmware to not blink the LED, I see no quick flash. This indicates that the user application is actually starting, but it then just returns to the bootloader.
I've included the stm_bootloader.h header that I've written for bootloader USART communication. We've been using this for quite a while with the F072 and never had an issue. The commands I call from there in order are:
stm_boot.Init(ui_->dev_name->text().toStdString());
stm_boot.BootloaderVersionSupportedCommands();
stm_boot.FlashBinary(FIRMWARE_BIN_PATH);
The FlashBinary funciton primarily just performs a global erase, writes the firmware binary, and then calls the Go command. The NUCLEO boards also allow flashing a HEX file from the onboard STLINK via mass storage. If I flash the MCU in this way, it still has the same issue with starting the user application from bootloader Go command. (Enabling/disabling RDP did not have an effect).
Solved! Go to Solution.
2021-09-03 11:28 AM
If you disable processor interrupts, make sure you enable them.
If the ROM loader is running a watchdog (IWDG), you'd better keep kicking it.
A reset with BOOT0=High will reenter the ROM on reset.
The ROM will also be mapped at Zero Address.
The GO expects the base of the vector table, describing Initial SP,PC values.
Make sure you set SCB->VTOR appropriately.
Failing this add simple code in startup.s at the ResetHandler to output state via a UART or GPIO. Start simple, and build out code to report conditions on the ground, and check-point arrival at code deeper into the application.
2021-09-03 11:28 AM
If you disable processor interrupts, make sure you enable them.
If the ROM loader is running a watchdog (IWDG), you'd better keep kicking it.
A reset with BOOT0=High will reenter the ROM on reset.
The ROM will also be mapped at Zero Address.
The GO expects the base of the vector table, describing Initial SP,PC values.
Make sure you set SCB->VTOR appropriately.
Failing this add simple code in startup.s at the ResetHandler to output state via a UART or GPIO. Start simple, and build out code to report conditions on the ground, and check-point arrival at code deeper into the application.
2021-09-10 09:36 PM
Thanks for the reply. I found that SCB-VTOR was not being set anywhere. The following is in system_stm32f3xx.c
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
and later on
void SystemInit(void)
{
/* FPU settings --------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
}
So by uncommenting
/* #define USER_VECT_TAB_ADDRESS */
This allowed SCB->VTOR to be set at FLASH_BASE, which is defined in stm32f303xe.h with the value 0x08000000UL. I am now able to start the user application.
This raises a lot questions on my end that just seem like inconsistencies:
If you have a moment to elaborate on some of these things, it would be much appreciated, otherwise thanks for pointing me in the right direction.