Files
ZephCore/zephcore/boards/common/hangdebug.conf
T
2026-08-14 08:36:36 +02:00

65 lines
3.5 KiB
Plaintext

# Hang / freeze diagnosis overlay.
#
# Build (stacks on top of debug.conf — order matters, this one must come last):
# west build -b meshtracker_x1 zephcore --pristine -- \
# -DEXTRA_CONF_FILE="boards/common/debug.conf;boards/common/hangdebug.conf"
#
# Exists to answer one question before any others: when the node goes silent,
# is the MCU dead, or is the radio wedged with the MCU still running? Those
# have completely different fixes and the ordinary debug build cannot tell them
# apart, because it produces no output either way.
# ========== Logging mode: deliberately left DEFERRED ==========
# CONFIG_LOG_MODE_IMMEDIATE was tried here and BRICKS THE BOOT on any board
# whose console is a USB CDC ACM (meshtracker_x1, promicro_lr2021, t1000_e...).
# Immediate logging writes synchronously from the calling context, and before
# the USB host has enumerated, uart_poll_out() on a CDC ACM with no host blocks
# forever — so the node hangs during early init and never comes up. This is the
# stall debug.conf's own backend comment has always warned about; it is harmless
# in deferred mode because the log thread absorbs it, and fatal in immediate
# mode because the booting thread does. Do not re-add it.
#
# It is also unnecessary for catching a crash: Zephyr's fatal handler calls
# LOG_PANIC(), which switches logging to synchronous and flushes whatever is
# queued. A genuine fault therefore prints its dump even in deferred mode —
# meaning a freeze that produces NO output is evidence of a hard hang or a
# supply collapse rather than of a lost message.
# ========== Claw back the RAM immediate mode would have saved ==========
# debug.conf sizes the deferred log buffer at 8 KB for heavy DBG output. This
# overlay is not trying to capture a firehose — it wants the thread table and a
# fault dump — so a quarter of that is plenty and returns 6 KB to a build that
# otherwise sits above 91 % on the X1. Headroom is the point: a production
# build survives what a debug build does not, so the debug build's own footprint
# is a suspect in its own right.
CONFIG_LOG_BUFFER_SIZE=2048
# ========== Proof of life + stack headroom ==========
# Periodic per-thread stack usage, printed from a thread of its own. Two jobs:
#
# 1. Proof of life. If these lines keep appearing after the radio goes quiet,
# the MCU is healthy and the radio is wedged — look at the driver. If they
# stop when the radio does, the hang is MCU-side (fault, deadlock, or a
# starved scheduler) and the radio is a red herring.
#
# 2. Stack headroom. The X1 debug build sits near 92% RAM, so a stack overflow
# is a live hypothesis rather than a formality. This rules it in or out by
# showing each thread's high-water mark.
CONFIG_THREAD_ANALYZER=y
CONFIG_THREAD_ANALYZER_AUTO=y
CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=10
CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
CONFIG_THREAD_NAME=y
# ========== Turn silent corruption into a loud fault ==========
# Without this an overflowing stack quietly scribbles on whatever is below it and
# the failure surfaces somewhere unrelated. With it, the MPU traps the overrun
# at the moment it happens and — thanks to IMMEDIATE logging above — the dump
# actually reaches the console.
CONFIG_HW_STACK_PROTECTION=y
# Keep the fatal handler halting rather than rebooting (debug.conf already sets
# this). With synchronous logging the dump is out before the halt, and halting
# preserves the state for a debugger if one is ever attached.
CONFIG_ZEPHCORE_RESET_ON_FATAL_ERROR=n