Skip to main content
Associate
September 7, 2026
Solved

STM32G431RBT3 enters HardFault during standalone power-on but works correctly with ST-LINK

  • September 7, 2026
  • 13 replies
  • 158 views

Hello ST Community,

I am using an STM32G431RBT3 on a custom-designed PCB. The STM32 is used to control a DRV8334 3-phase motor driver for a blower motor application.

I am facing a critical issue where the controller works correctly when using ST-LINK debugging, but it does not run correctly when the PCB is powered on standalone.

Hardware

  • MCU: STM32G431RBT3
  • Package: LQFP64
  • Motor driver: DRV8334
  • PCB: Custom-designed PCB
  • IDE: STM32CubeIDE
  • Programmer/debugger: ST-LINK
  • MCU supply: 3.3 V

Problem

When I power the PCB directly without ST-LINK, the following happens:

  1. The STM32 starts executing the firmware.
  2. A GPIO that I set HIGH in main() becomes HIGH.
  3. The GPIO that I toggle inside the while(1) loop does not toggle.
  4. I added a GPIO HIGH operation inside HardFault_Handler().
  5. That HardFault GPIO becomes HIGH.

Therefore, it appears that the MCU reaches main() but subsequently enters HardFault before the normal while(1)  execution continues.

When ST-LINK is connected

If I connect ST-LINK and program/debug/run the same firmware through STM32CubeIDE:

  • The GPIO in the  while(1) toggles normally.
  • The application runs normally.
  • Timers work.
  • Other peripherals work.
  • The DRV8334 control works normally.

So the behavior is:

Standalone power ON
↓
main() starts
↓
GPIO in main = HIGH
↓
while(1) GPIO does NOT toggle
↓
HardFault_Handler()
↓
HardFault GPIO = HIGH
 

But:

ST-LINK connected
↓
Program / Debug / Run
↓
main()
↓
while(1) executes normally
↓
GPIO toggles
↓
Application works
 

Minimal firmware test

To eliminate the DRV8334 and other peripherals, I reduced the firmware to a very simple program:

int main(void)
{
HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);

while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_10);
}
}

There is no TIM1, TIM4, ADC, SPI, UART, DRV8334 or motor-control initialization in this test.

Even with this minimal firmware, the problem occurs during standalone power-on.

HardFault test

I have also modified the HardFault handler:

void HardFault_Handler(void)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);

while (1)
{
}
}

During standalone power-on, this GPIO becomes HIGH, confirming that the MCU is entering HardFault_Handler().

Best answer by Ejack1979

‘0x1FFFxxxx’ related issues are largely related to boot status of the Cortex core.

  1. Check your hardware design, especially whether BOOT pin(s) are properly pulled. 
  2. Always start your debugging with a tiny, limited project. Disconnect some chips if necessary.

13 replies

Ozone
Principal
September 7, 2026

One option is to try to “attach” to the target with the debugger at runtime, once it hardfaulted.
Most toolchains / IDEs / debuggers have this option.
Here a screenshot of mine, Segger Embedded Studio
 

Then, stop the core, it should be in the while(1) loop of the hardfault handler.
Read out the SCB registers, to determine the cause of the hardfault.

Another option would be to implement instrumemtation code to the hardfault handler to output diagnostics that could point you to the cause.

 

Andrew Neil
Super User
September 7, 2026

One option is to try to “attach” to the target with the debugger at runtime, once it hardfaulted.
Most toolchains / IDEs / debuggers have this option.

 

Indeed.

​@NANJAM BHULAKSHMI for instructions to do this with CubeIDE (and other tips), see:

 

Another option would be to implement instrumemtation code to the hardfault handler to output diagnostics that could point you to the cause.

Indeed.

​@NANJAM BHULAKSHMI - also provide instrumentation in the rest of your code, so that you can see what’s happening without the debugger attached.

 

​@NANJAM BHULAKSHMI 

If I connect ST-LINK and program/debug/run the same firmware through STM32CubeIDE

What happens if you the do a reset & restart the code still within CubeIDE ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Associate
September 8, 2026

I performed the suggested reset/restart test in STM32CubeIDE.

While connected to ST-LINK, I clicked Reset and then Run/Resume. The application did not continue normally. The debugger stopped again at an address in the 0x1FFFxxxx region.

I observed:

  • 0x1FFF44D2
  • 0x1FFF4518

The CubeIDE disassembly window also shows code executing from this 0x1FFFxxxx region.

My application is located at 0x08000000, and SCB->VTOR reads 0x08000000.

According to the STM32G431 documentation, system memory is located starting at 0x1FFF0000.

Could this indicate that the MCU is entering/executing the system-memory bootloader during reset/restart? If so, what should I check regarding BOOT0, option bytes, or the reset behavior?

Andrew Neil
Super User
September 7, 2026

to eliminate the DRV8334 and other peripherals, I reduced the firmware to a very simple program

…

Even with this minimal firmware, the problem occurs during standalone power-on.

Can you reproduce this on an ST board ?

Have you used a scope to see what’s happening at power-on ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Ozone
Principal
September 8, 2026

> Can you reproduce this on an ST board ?
> Have you used a scope to see what’s happening at power-on ?

Power supply and startup-related issues are plausible, but only the OP can determine that on the actual hardware.
And a second board or / and an equivalent ST board would serve as reference, to see if it is software-related or not.

MM..1
Super User
September 7, 2026

Hope you remove HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET); from main for hardfault test , because together ?...

Associate
September 8, 2026

Based on everything I’ve tested so far, I would report it like this:

1. Power supply: The 3.3 V rail was checked during power-up and no abnormal voltage dip was observed.\

2. NRST: NRST was checked during power-up and the reset signal appears normal, with a clean release from reset.

3. Clock/HSE: HSE is disabled in the CubeMX configuration and the MCU is configured to use HSI. I also removed SystemClock_Config() as a test, but the standalone HardFault problem remained. Therefore, the issue does not appear to be caused by the external HSE clock configuration.

4. BOOT0/SWD: BOOT0 is not being externally driven by another circuit. The application reaches main() during standalone power-up, confirmed by the GPIO set in main(). Therefore, the MCU is entering the application normally. No external circuitry is intentionally driving the SWD pins.

5. Linker/vector table: The linker script shows FLASH starting at 0x08000000 and RAM starting at 0x20000000. SCB->VTOR was checked during debugging and its value is 0x08000000, which corresponds to the application Flash start address. No obvious issue was found with the linker memory configuration or vector-table location.

6. As a test, SystemClock_Config() was removed completely, but the same standalone problem occurred. The MCU still reaches main(), but the while(1) GPIO does not toggle and the HardFault GPIO becomes HIGH. Therefore, removing the system clock configuration did not resolve the issue.

Additional HardFault investigation

Following the initial investigation, I performed the additional steps recommended for identifying where the HardFault occurs.

I first tested the board with ST-LINK connected and programmed the firmware normally. The application ran correctly, the while(1) GPIO toggled, and the GPIO inside HardFault_Handler() remained LOW.

I then powered OFF the board, disconnected ST-LINK, and powered the board ON standalone. In this condition:

  • The GPIO set in main() becomes HIGH.
  • The GPIO toggled inside while(1) does not toggle.
  • The GPIO set inside HardFault_Handler() becomes HIGH.

This confirms the standalone-power failure condition.

To investigate the HardFault without downloading the firmware again and potentially changing the MCU state, I then connected ST-LINK while the board was still powered and changed the STM32CubeIDE debug configuration so that Download/Program was intentionally set to Fail/disabled. I then selected Debug, but did not Run, in order to inspect the existing MCU state.

The debugger stopped at:

0x1FFF44D6

STM32CubeIDE displayed:

"Break at address '0x1fff44d6' with no debug information available, or outside of program code."

I also added the following variables to Live Expressions:

hardfault_lr
hardfault_pc
hardfault_cfsr
hardfault_hfsr
hardfault_bfar
hardfault_mmfar

All of these were displayed as 0.

However, the GPIO inside HardFault_Handler() was already HIGH from the standalone-power failure.

Therefore, I would like to understand whether attaching the debugger after the fault and stopping without downloading/running can preserve the original fault state, and whether the address 0x1FFF44D6 provides any indication of what occurred.

Could you please advise us on the correct procedure to capture the actual faulting PC/LR and Cortex-M fault status registers at the moment of this standalone power-on HardFault?

Ozone
Principal
September 8, 2026

> Therefore, I would like to understand whether attaching the debugger after the fault and stopping without downloading/running can preserve the original fault state, and whether the address 0x1FFF44D6 provides any indication of what occurred.

This what the option “Attach debugger” means.

> Could you please advise us on the correct procedure to capture the actual faulting PC/LR and Cortex-M fault status registers at the moment of this standalone power-on HardFault?

The respective values will remain in the SCB registers until the next power cycle or core reset.

I’m not a CubeIDE user.
But I expect such basic debugging options to be well documented, both as written tutorials and as videos.

Andrew Neil
Super User
September 8, 2026

But I expect such basic debugging options to be well documented, both as written tutorials and as videos.

Indeed  they are.

 

​@NANJAM BHULAKSHMI - see Debugging Cortex-M Hard Faults

Also some general tips on How To Debug.

 

CubeIDE User Manuals are here:

https://www.st.com/en/development-tools/stm32cubeide.html#documentation

 

See also: https://wiki.st.com/stm32mcu/wiki/Category:STM32CubeIDE

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Ejack1979Best answer
Explorer II
September 8, 2026

‘0x1FFFxxxx’ related issues are largely related to boot status of the Cortex core.

  1. Check your hardware design, especially whether BOOT pin(s) are properly pulled. 
  2. Always start your debugging with a tiny, limited project. Disconnect some chips if necessary.
Associate
September 8, 2026

Issue is Finally Resolved. Thank You.

Since the code was breaking at an address related to the boot process, we suspected a BOOT/boot-mode related hardware issue. Based on the suggestion to check the BOOT pins and debug with a minimal project, we verified the following:


1.We created a minimal firmware with only basic GPIO functionality to rule out any application-level issue.
2.We checked PB8, which is the BOOT0 pin on the STM32G431RBT3 and is also being used as UART RX / CAN RX in our    design.
3.With the RS232 and CAN transceivers connected, PB8 was observed HIGH during startup.
4.We removed the RS232 and CAN transceivers from the board as an isolation test. After removing them, PB8 became LOW and the MCU booted the application correctly in standalone mode, without ST-LINK.
5.This confirmed that the external transceiver circuitry connected to PB8 was affecting the BOOT0 level during startup.
6.We then checked the STM32 option bytes. Initially, nSWBOOT0 = 1, meaning the physical PB8 pin was being used for BOOT0 selection.
7.Using STM32CubeProgrammer, we changed:
  nSWBOOT0 = 0
  nBOOT0 = 1
  nBOOT1 = 1
8.With this configuration, BOOT selection no longer depends on the physical PB8 level, and the MCU boots from Main Flash.
9.After restoring the RS232 and CAN transceivers, we tested the board both with and without ST-LINK, and the firmware now runs correctly in standalone operation.
 

So we identified the issue as a BOOT0/PB8 conflict with the external transceiver circuitry, and changing the BOOT option-byte configuration resolved the standalone boot problem.

LCE
Principal II
September 8, 2026

Another vote for: check the hardware, and the PCB layout.

Just guessing wildly:

Maybe you have some ground loop problem, so have a look at how power supplies, signals, and even more important grounds are connected.
Connecting the ST-Link might just short-circuit a GND loop - which connecting a scope might also do…