How to prevent system hang before watchdog timer task kicks in

Professional embedded systems are designed like this:

  • Pick a MCU with power-on-reset interrupt and on-chip watchdog. This is standard on all modern MCUs.
  • Implement the below steps from inside the reset interrupt vector.
  • If the MCU memory is simple to setup, such as just setting the stack pointer, then do so the first thing you do out of reset. This enables C programming. You can usually write the reset ISR in C as long as you don’t declare any variables – disassemble to make sure that it doesn’t touch any RAM memory addresses until those are available.
  • If the memory setup is complex – there is a MMU setup or similar – C code will have to wait and you’ll have to stick to assembler to prevent accidental stacking caused by C code.
  • Setup the most fundamental registers, such as mode/peripheral routing registers, watchdog and system clock.
  • Setup the low-voltage detect hardware, if applicable. Hopefully the out-of-reset state for LVD on the MCU is a sound one.
  • Application-specific, critical registers such as GPIO direction and internal pull resistor registers should be set from here. Many MCU have pins as inputs by default, making them vulnerable. If they are not meant to be inputs in the application, the time they are kept as such out of reset should be minimized, to avoid problems with noise, transients and ESD.
  • Setup the MMU, if applicable.
  • Everything else “CRT”, such as initialization of .data and .bss.
  • Call main().

Please note that pre-made startup code for your MCU is not necessarily made by professionals! It is fairly common that there’s an amateur-level “CRT” delivered with your toolchain, which fails to setup the watchdog and clock early on. This is of course unacceptable since:

  1. This makes any program running on that platform a notable safety/poor quality hazard, in case the “CRT” will crash/hang for whatever reason.
  2. This makes the initialization of .data and .bss needlessly, painfully slow, as it is then typically executed with the clock running on the default on-chip RC oscillator or similar.

Please note that even industry de facto startup code such as ARM CMSIS fails to do some of the MCU-specific hardware setups mentioned above. This may or may not be a problem.

Leave a Comment