Debugging STM32L0 Firmware with Sleep Mode with OpenOCD

This tutorial shows how to configure VisualGDB and OpenOCD to debug STM32L0 firmware that puts the microcontroller in the sleep mode.

We will create a basic project for the NUCLEO-L031K6  board, show why the default configuration does not work when the CPU enters the sleep mode and how to work around it by using a special reset mode in debug settings.

  1. Start Visual Studio and open the VisualGDB Embedded Project Wizard:01-prjname
  2. Select “Create a new project -> Embedded binary” and click “next”:02-prjtype
  3. Select the ARM toolchain and your device from the list. The NUCLEO-L031K6 board shown in this tutorial has the STM32L031K6 microcontroller:03-device
  4. Proceed with the default “LEDBlink” sample:04-sample
  5. On the last page select “OpenOCD”, connect your board via USB and click “Detect” to automatically detect debugging settings:05-debug
  6. Press “Finish” to generate your project. Replace the contents of the main() function with the following:
    int main(void)
    {
        HAL_Init();
        
        __GPIOB_CLK_ENABLE();
        GPIO_InitTypeDef GPIO_InitStructure;
     
        GPIO_InitStructure.Pin = GPIO_PIN_3;
     
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
        GPIO_InitStructure.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
        
        for (;;)
        {
            HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
        }
        
    }

    This will put the device in the sleep mode until a SysTick interrupt occurs.06-build

  7. Press F5 to start debugging. The debugging should start normally and you should be able to step through the code:07-debug
  8. Press Shift-F5 to stop debugging and try starting it again. Debugging will now fail with the following error shown by OpenOCD:
    Error: timed out while waiting for target halted

    08-problemThe error happens because while the device is in the sleep mode, OpenOCD cannot properly connect to it over JTAG.

  9. Now we will show how to fix this by editing the OpenOCD configuration. Open the Debug Settings page of VisualGDB Project Properties and switch to the Manual setup mode:09-debugsetting
  10. Click the “Open” button in the “Target” field, make a copy of the original file (e.g. to stm32l0_reset.cfg) and open it in an editor:11-reset
  11. Locate the line starting with reset_config and replace it with the following one:
    reset_config trst_and_srst srst_nogate connect_assert_srst

    12-resetThe connect_assert_rst flag will force OpenOCD to reset the CPU during the initial connection, forcing it out of the sleep mode and ensuring that the debug communication succeeds.

  12. Save the new script and ensure that it is selected in the VisualGDB Project Properties:13-newcfg
  13. Press F5 to start debugging. The debugging should now work normally despite the firmware entering the sleep mode:14-debug