STM32H7 watchdog reset scope / ES0445 2.3.1 feedback request
Hi all,
I would like feedback from the ArduPilot team on an STM32H7 watchdog-reset-scope erratum and a proposed mitigation in the ChibiOS HAL watchdog path.
Context
While reviewing CubeOrangePlus / STM32H757 errata applicability, I found the following STM32H7 erratum:
ES0445 2.3.1 — AXI domain locked when watchdog reset limited to CPU1 or CPU2
The AXI domain may get locked when the watchdog reset is limited to CPU1 or CPU2, i.e. when
WW1RSCorWW2RSCis cleared inRCC_GCR, and a watchdog reset is generated.ST’s workaround is to configure watchdog reset scope to reset the full system by setting
RCC_GCR.WW1RSCand/orRCC_GCR.WW2RSC.
For CubeOrangePlus, the firmware target is STM32H757-based (MCU STM32H7xx STM32H757xx). The ArduPilot watchdog implementation directly enables the independent watchdog in:
libraries/AP_HAL_ChibiOS/hwdef/common/watchdog.c
stm32_watchdog_init()
Runtime J-Link inspection on the current target showed:
RCC_GCR = 0x00000000
WW1RSC = 0
WW2RSC = 0
This means an IWDG1 reset is scoped to CPU1 rather than the full system, matching the erratum trigger condition.
Why I think this matters
The question is not whether ArduPilot wants a “larger reset” in normal operation. The issue is that the silicon erratum says a CPU-local watchdog reset can leave the AXI/shared domain locked. In that case, limiting the reset to CPU1 may be less safe than a full-system reset, because the watchdog may not recover the full SoC cleanly.
For an autopilot, my assumption is that if the independent watchdog fires, the safer behavior is full SoC recovery rather than a CPU1-only recovery that may leave shared infrastructure in an undefined or locked state.
Proposed mitigation
Set the STM32H7 watchdog reset-scope bits before enabling IWDG:
#if defined(STM32H7)
#define RCC_GCR_REG (*(__IO uint32_t *)(RCC_BASE + 0x10))
#define RCC_GCR_WW1RSC (1U<<0)
#define RCC_GCR_WW2RSC (1U<<1)
#endif
#if defined(STM32H7)
static void stm32_watchdog_configure_reset_scope(void)
{
RCC_GCR_REG |= RCC_GCR_WW1RSC | RCC_GCR_WW2RSC;
}
#endif
void stm32_watchdog_init(void)
{
#if defined(STM32H7)
stm32_watchdog_configure_reset_scope();
#endif
IWDGD.KR = 0x5555;
IWDGD.PR = 3;
IWDGD.RLR = STM32_WDG_TIMEOUT_MS - 1;
IWDGD.KR = 0xCCCC;
watchdog_enabled = true;
}
WW1RSC is required for the CPU1/IWDG1 reset-scope case. I also set WW2RSC defensively for dual-core H7 coverage, even if ArduPilot is only running on CPU1 for the reviewed target.
Questions for maintainers
- Does the team agree that on STM32H7 targets, an ArduPilot independent watchdog reset should reset the full system rather than only CPU1/CPU2?
- Are there any H7 boards or bootloader/application flows where setting
WW1RSC | WW2RSCbefore enabling IWDG would be undesirable? - Should this be applied globally for all
STM32H7ChibiOS builds, or should it be board-gated for affected dual-core parts such as STM32H747/H757? - Is there a preferred CMSIS/ChibiOS register definition already available for
RCC_GCRand these bits, instead of defining the register offset locally inwatchdog.c? - Would maintainers prefer the reset-scope bits to be set earlier in board startup rather than in
stm32_watchdog_init()?
Evidence checked so far
- CubeOrangePlus hwdef selects STM32H757.
- ArduPilot watchdog code directly programs and starts IWDG in
watchdog.c. - A repo search found no existing
RCC_GCR,WW1RSC, orWW2RSCconfiguration. - Runtime J-Link inspection showed
RCC_GCR = 0x00000000before this change.
Requested feedback
Please sanity-check the interpretation of ES0445 2.3.1 and whether the proposed mitigation is appropriate for ArduPilot H7 targets. In particular, feedback from maintainers familiar with ChibiOS startup, STM32H7 dual-core behavior, CubeOrangePlus, and watchdog/reboot semantics would be very helpful.
Thanks in advance,
Theo