12

I have a ChibiOS 3.x program on a STM32F4 microcontroller where I use the IWDG watchdog to reset the MCU on errors like this:

int main() {
    iwdgInit();
    iwdgStart(&IWDGD, &wd_cfg);
    while(true) {
        // ... do stuff
    }
}

If I now attach my debugger and, at any point, stop the program (manually or via a breakpoint), the microcontroller will reset after the timeout defined by the watchdog configuration (and therefore cause issues in my debugging process)

How can I disable this behaviour, i.e. how can I disable the IWDG while the core is stopped due to the debugger?

I have tried disabling it entirely, however, I need to leave it running to catch unwanted IWDG resets.

Uli Köhler
  • 13,012
  • 16
  • 70
  • 120

3 Answers3

14

The STM32 MCUs contain a feature called debug freeze. You can stop several peripherals, including I2C timeouts, the RTC and, of course, the watchdog.

In the STM32 reference manual, refer to section 38.16.4ff "MCU debug component (DBGMCU)".

The IWDG is running on the APB1 bus. Therefore you need to modify DBGMCU_APB1_FZ, most specifically assert the bit DBG_IWDG_STOP in that register.

The POR value (= default value) for this register is 0x0, i.e. if you not actively disable it, the IWDG will still be running.

int main() {
    // Disable IWDG if core is halted
    DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_IWDG_STOP;
    // Now we can enable the IWDG
    iwdgInit();
    iwdgStart(&IWDGD, &wd_cfg);
    // [...]
}

Note that when not enabling the watchdog in software, it might still be enabled in hardware if the WDG_SW bit is reset in the flash option bytes.

If you are using the ST HAL (not included in ChibiOS, see STM32CubeF4), you can also use this macro:

 __HAL_DBGMCU_FREEZE_IWDG();

(which basically does exactly the same as we did above)

Besides, you need enable the DBGMCU clock on APB2 before calling __HAL_DBGMCU_FREEZE_IWDG().

 __HAL_RCC_DBGMCU_CLK_ENABLE();
chrisemb
  • 79
  • 5
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
9

When using the ST HAL, the right macro to use is:

__HAL_DBGMCU_FREEZE_IWDG()
  • Good point, thanks for adding this. Most of the time I don't use the HAL at least for simple stuff, however I suppose most people generally use the ST HAL so this might be very helpful for them. – Uli Köhler Jul 27 '16 at 13:47
  • Does this work also to disable IWDG before Stop mode ? – Colateral Nov 16 '18 at 09:33
  • @Colateral If you have problem disabling IWDG before stop mode, anytime you wanted to go to stop mode, software restart the micro. Then before initializing IWDG, check if it was a software reset or what. (You can simply check restart reason). If it's a software restart, go to stop mode BEFORE calling `HAL_IWDG_Init(....)` function. (You also need to save all your data before restarting). – Mohammad Kholghi Sep 07 '22 at 03:40
4

According to the reference manual, the DBGMCU_CR register "can be written by the debugger under system reset", so, if the debugger supports it, there is no need for changes in the software.

For instance, in STM32CubeIDE (as of now Version 1.6.0) just set Project > Properties > Run/Debug Settings > Launch configurations for [project name]: > [project name] Debug > Edit > Debugger > Device Settings > Suspend watchdog counters while halted:

to Enable.

chrisemb
  • 79
  • 5