Measurement units: bytes (STM32F446 is 32-bit; configSTACK_DEPTH_TYPE
word count Γ 4).
Instrument: uxTaskGetStackHighWaterMark() read at 10 s cadence.
Soak duration: 48 h nominal flight-mode.
Reporting: stack minimum free bytes per task, downlinked with
housekeeping telemetry APID 0x010.
Each taskβs init path writes a known sentinel pattern through the
entire stack (FreeRTOS default on configCHECK_FOR_STACK_OVERFLOW
= 1). A periodic probe walks the stack looking for the first word
that still holds the sentinel β the watermark. A deep-recursion
event trims the watermark downward permanently; no βhealingβ is
possible once a push overwrote the sentinel, so the watermark is
a true worst-case witness across the whole soak.
| Task | Allocated (B) | HWM observed (B) | Margin (%) | Status |
|---|---|---|---|---|
| SensorTask | 2048 | TBD | TBD | β³ |
| TelemetryTask | 2048 | TBD | TBD | β³ |
| CommTask | 4096 | TBD | TBD | β³ |
| ADCSTask | 4096 | TBD | TBD | β³ |
| WatchdogTask | 1024 | TBD | TBD | β³ |
| PayloadTask | 2048 | TBD | TBD | β³ |
| IDLE (FreeRTOS) | 256 | TBD | TBD | β³ |
| Timer (FreeRTOS) | 512 | TBD | TBD | β³ |
Margin: (allocated β HWM) / allocated * 100.
Status legend: β
β₯ 30 % free / β 15β30 % / β < 15 % (bump stack) / β³ not yet measured.
Sizes from firmware/stm32/Core/Inc/main.h:
| Define | Value (words) | Bytes |
|---|---|---|
SENSOR_TASK_STACK_SIZE |
512 | 2048 |
TELEMETRY_TASK_STACK_SIZE |
512 | 2048 |
COMM_TASK_STACK_SIZE |
1024 | 4096 |
ADCS_TASK_STACK_SIZE |
1024 | 4096 |
WATCHDOG_TASK_STACK_SIZE |
256 | 1024 |
PAYLOAD_TASK_STACK_SIZE |
512 | 2048 |
configTOTAL_HEAP_SIZE (heap_4) is sized to accommodate the sum
of task control blocks + queue storage; tracked separately in
heap_usage.md.
FreeRTOSConfig.h: configCHECK_FOR_STACK_OVERFLOW = 2
(method-2 pattern check) and INCLUDE_uxTaskGetStackHighWaterMark = 1.vApplicationStackOverflowHook() implemented in
firmware/stm32/Core/Src/error_handler.c to raise
FAULT_STACK_OVERFLOW on hook entry (primary action REBOOT per
docs/reliability/fdir.md).