General debug tips

Here are the typical points of attention to check in case an issue is encountered. This is whether it is from flashing the device to running the example code.

If further investigation is needed, this page also introduces:

  • A debug build profile.

  • A “debug toolbox” application note.

Flashing issues

  1. Try flashing using STM32CubeProgrammer.

  2. Check the device configuration against the description in the AN2606 STM32 microcontroller system memory boot mode application note.

Startup issues

  1. Read the FLASH or RAM content using STM32CubeProgrammer to make sure that the expected code is loaded in the device.

  2. Check the boot options of the device in the reference manual. This can be boot pins and so on.

  3. Try connecting to the board and use a debugger to spot any hard faults in the code. Refer to the Fault exceptions page.

Issues to connect to the board

  1. Ensure that the low-power mode is not enabled as the communication with ST-LINK is disabled in this mode.

  2. Check if the target is secured or debug-disabled. If this is the case, the target does not respond to an external debugger.

HAL timing issues

  1. Care must be taken when using HAL_Delay(). This function provides an accurate delay (in milliseconds) based on a variable incremented in the SysTick ISR. This implies that if HAL_Delay() is called from a peripheral ISR [1] process, then the SysTick interrupt must have higher priority (numerically lower) than the peripheral interrupt. Otherwise, the caller ISR process is blocked. To change the SysTick interrupt priority, use the HAL_NVIC_SetPriority() function.

  2. The example needs to ensure that the SysTick time base is always set to 1 millisecond to have correct HAL operation.

Debug build profile

The STM32Cube Software Examples are provided with the debug symbols enabled, and the toolchain optimizations are enabled by default too. Observability and debugging can be improved by updating these default settings.

Important

Do not use the settings provided in this section to estimate the performances of the system. This is only for observing and debugging the system, not for measuring its performances.

Observability

Some examples offer an application log to follow the execution flow of the code. This is disabled by default, and is enabled by setting the USE_TRACE compiler switch to 1. These logs are not made to offer a full debug experience. Their primary purpose is to illustrate the execution flow of the example code. It allows the user to observe any execution flow deviations. Compare the application logs with the nominal example logs in the README file.

The pins of the STM32 can also be used to observe the signals on the board. See Using the pinout connections.

Step by step debugging

When the toolchain optimizations are enabled, the step by step debugging can be impeded, and some variables may not be available in the debugger.

To improve the step by step debugging experience, use a “ debug build” profile if needed. In most examples, this build profile is not provided by default. Create a debug profile using the following steps:

  1. Open the project with the IDE.

  2. Create a new build profile named debug.

  3. Set the compiler optimizations as indicated below:

    • For the GCC toolchain, set the optimization level to -O0. Set the -g3 flag to enable the maximum debug level.

    • For the IAR toolchain, set the optimization level to Low or None.

    • For the Arm toolchain, set the optimization level to -O1 or -O0.

  4. Build the project with this new profile.

  5. Flash the device with the new binary.

  6. Use the debugger to set breakpoints, inspect variables, and step through the code.

Warning

By disabling the compiler optimization, the binary may significantly differ from the optimized version.

Performances : the most demanding examples might not work with the debug build profile.

Code size : some examples might also not fit in the device memory, leading to a linker error. The stack size and heap size required by the example code can also increase. This can lead to a stack overflow or heap overflow unless the appropriate settings in the linker script are increased.

Memory layout : the placement of the code in memory changes. Updating some linker script sections and symbols might be required to ensure that the code operates correctly.

Some examples include a debug build profile when manual setup is complex.

Debug toolbox

Refer to the AN4989 STM32 microcontroller debug toolbox application note for further information on how to troubleshoot the problem.