cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431: Application doesn't start after system bootloader finished

EThom.3
Senior II

This is one of those issues where I can hardly figure out what to seach for...

I have a board (with an STM32G431) where I can activate the BOOT pin with a switch, to start the system bootloader. This allows the customer to upload a new application version using STM32CubeProgrammer and the microcontroller's USB port.

However, on this board, the application doesn't run when the bootloader is done. On other boards with other micrcontroller types, the "Run after programming" feature works nicely, but not on the one with an STM32G431.

Even with an ST-LINK V3 connected to the board, I cannot see with certainty in what state the microcontroller ends up, or what the program counter says, as the ST-LINK loses its connection with the microcontroller. When I reconnect, STM32CubeProgrammer claims that the CPU is halted.

EThom3_0-1777418379790.png

 Why the CPU is halted, I have no idea. But it is quite annoying, as the board is a tiny thing in a very large industrial machine, where they should be able to upload new firmware without needing to cut the power.

If I try reading the PC, and compare with the .list file, the application is halted in Reset_Handler. But I'm not certain that I get the correct PC address, and in any case, I don't understand why it gets halted there. Or at all. If I press the Run button in ST-LINK connected CubeProgrammer (sometimes It need to use Hardware Reset first), the application starts as it is supposed to.

Another symptom: After programming is complete, the ST-LINK programmer loses its connection (as it should), and then a Windows notfication briefly appears with a message that Windows has found an unknown or incompatible device. Or at least it did, until I tried to capture it. Then it disappeared. And now I'm too tired to remember the text verbatim.

At least I can hear the "USB device disconnected" followed by the "USB device connected" chimes when firmware upload is complete. But the usual virtual serial port doesn't show up as usual, and CubeProgrammer (USB) cannot find it.

I hope that this made some kind of sense.

Do any of you have experience with an STM32G4 device being halted after uploading firmware through the USB port, and not starting its application afterwards? And might there be a solution?

 

P.S. My searches have just somewhat paid off. Apparently, this is a known issue:

https://gist.github.com/gonzabrusco/fd47e89e4c6fb302fc54b83637a3a101

However, I'll need a good night's sleep before I can begin to understand how this works. Also, a less cumbersome work-around would be preferred.

1 ACCEPTED SOLUTION

Accepted Solutions
EThom.3
Senior II

Problem seems to be solved!

It looks like the system bootloader leaves SCB->VTOR in a bad place when attempting to jump to the application. My solution was super-simple: Uncomment one line in the file system_stm32g4xx.c.

In the function SystemInit(), which I understand is the very first thing that is called at startup, SCB->VTOR is set if USER_VECT_TAB_ADDRESS is defined. Initially, it is not.

/* #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. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */

#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_OFFSET */

#endif /* USER_VECT_TAB_ADDRESS */

(...)

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 add offset address ------------------*/
#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 */
}

The default values for VECT_TAB_BASE_ADDRESS and VECT_TAB_OFFSET are FLASH_BASE and 0, respectively, which conveniently places SCB->VTOR at the start of my application. So my solution was to uncomment the line /* #if defined(USER_VECT_TAB_ADDRESS) */, which then allows SystemInit() to force SCB->VTOR to the correct value.

I could also have added the line SCB->VTOR = FLASH_BASE; to SystemInit(), but I thought the uncommenting was more sleek.

Some AI-thing claimed that I could set SCB->VTOR in the beginning of main(), but I imagine that this is too late. Haven't tried it though, so I'm not sure.

View solution in original post

2 REPLIES 2
EThom.3
Senior II

Now I noticed that the mentioned Windows notification had placed itself behind all the other open windows. It looks like this:

EThom3_0-1777421769339.png

But if the microcontroller is halted after having begun to set up its USB port, it makes sense to me that it malfunctions and Windows doesn't recognise it.

EThom.3
Senior II

Problem seems to be solved!

It looks like the system bootloader leaves SCB->VTOR in a bad place when attempting to jump to the application. My solution was super-simple: Uncomment one line in the file system_stm32g4xx.c.

In the function SystemInit(), which I understand is the very first thing that is called at startup, SCB->VTOR is set if USER_VECT_TAB_ADDRESS is defined. Initially, it is not.

/* #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. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */

#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_OFFSET */

#endif /* USER_VECT_TAB_ADDRESS */

(...)

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 add offset address ------------------*/
#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 */
}

The default values for VECT_TAB_BASE_ADDRESS and VECT_TAB_OFFSET are FLASH_BASE and 0, respectively, which conveniently places SCB->VTOR at the start of my application. So my solution was to uncomment the line /* #if defined(USER_VECT_TAB_ADDRESS) */, which then allows SystemInit() to force SCB->VTOR to the correct value.

I could also have added the line SCB->VTOR = FLASH_BASE; to SystemInit(), but I thought the uncommenting was more sleek.

Some AI-thing claimed that I could set SCB->VTOR in the beginning of main(), but I imagine that this is too late. Haven't tried it though, so I'm not sure.