Files
HaloKeymind/s3_memory_soak_validation/index.html
T
2026-09-16 22:09:44 +00:00

3312 lines
57 KiB
HTML

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Documentation for the open source MeshCore firmware">
<link rel="canonical" href="https://mikecarper.github.io/MeshCore/s3_memory_soak_validation/">
<link rel="prev" href="../role_feature_switches/">
<link rel="next" href="../separated_radio_modulation_cache_validation/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
<title>ESP32-S3 OTA memory experiment - MeshCore Docs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../_stylesheets/extra.css">
<link rel="stylesheet" href="../_stylesheets/firmware_picker.css">
<link rel="stylesheet" href="../_stylesheets/telemetry_decoder.css">
<link rel="stylesheet" href="../_stylesheets/filter_tool.css">
<link rel="stylesheet" href="../_stylesheets/preset_test.css">
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#esp32-s3-ota-memory-experiment" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="MeshCore Docs" class="md-header__button md-logo" aria-label="MeshCore Docs" data-md-component="logo">
<img src="../_assets/meshcore.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
MeshCore Docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
ESP32-S3 OTA memory experiment
</span>
</div>
</div>
</div>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/mikecarper/MeshCore/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
mikecarper/MeshCore
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="MeshCore Docs" class="md-nav__button md-logo" aria-label="MeshCore Docs" data-md-component="logo">
<img src="../_assets/meshcore.svg" alt="logo">
</a>
MeshCore Docs
</label>
<div class="md-nav__source">
<a href="https://github.com/mikecarper/MeshCore/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
mikecarper/MeshCore
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../WiFi/" class="md-nav__link">
<span class="md-ellipsis">
WiFi and MQTT by Firmware Type
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cad_scan_validation/" class="md-nav__link">
<span class="md-ellipsis">
SX1262 channel-scanning hardware results
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../carrier_wave/" class="md-nav__link">
<span class="md-ellipsis">
Carrier-wave RF checks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../carrier_wave_validation/" class="md-nav__link">
<span class="md-ellipsis">
CW and CW2 validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli_build_matrix/" class="md-nav__link">
<span class="md-ellipsis">
CLI Availability by Firmware Build
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli_command_availability/" class="md-nav__link">
<span class="md-ellipsis">
CLI Command Availability Matrix
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli_commands/" class="md-nav__link">
<span class="md-ellipsis">
CLI Commands
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cli_settings_audit/" class="md-nav__link">
<span class="md-ellipsis">
CLI setting dispatch audit
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_contact_cache/" class="md-nav__link">
<span class="md-ellipsis">
Full Companion contact caches
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_contact_cache_results/" class="md-nav__link">
<span class="md-ellipsis">
Contact-cache and NimBLE RAM qualification
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_offline_queue/" class="md-nav__link">
<span class="md-ellipsis">
Companion Offline Message Queue
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_protocol/" class="md-nav__link">
<span class="md-ellipsis">
Companion Protocol
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_radio_full/" class="md-nav__link">
<span class="md-ellipsis">
Full Companion
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_usb_ascii_validation/" class="md-nav__link">
<span class="md-ellipsis">
USB Companion ASCII default validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../companion_usb_client_validation/" class="md-nav__link">
<span class="md-ellipsis">
USB Companion client compatibility
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../docs/" class="md-nav__link">
<span class="md-ellipsis">
Local Documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../double_frequency_v4_validation/" class="md-nav__link">
<span class="md-ellipsis">
Double center-frequency write: V4 transmitter / XIAO receiver
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../esp32_memory_budget/" class="md-nav__link">
<span class="md-ellipsis">
Classic ESP32 image memory budget
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../espnow_bridge_setup/" class="md-nav__link">
<span class="md-ellipsis">
ESP-NOW bridge: simple setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/" class="md-nav__link">
<span class="md-ellipsis">
Frequently Asked Questions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../filter_tool/" class="md-nav__link">
<span class="md-ellipsis">
Filter policy playground
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../firmware_memory_budget/" class="md-nav__link">
<span class="md-ellipsis">
Firmware memory checks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../firmware_picker/" class="md-nav__link">
<span class="md-ellipsis">
Firmware picker
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../flood_filtering/" class="md-nav__link">
<span class="md-ellipsis">
Flood Filtering and Moderation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../four_fixed_tx_dwell_validation/" class="md-nav__link">
<span class="md-ellipsis">
Four fixed transmitters: longer dwell repeats
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../four_fixed_tx_single_pass_validation/" class="md-nav__link">
<span class="md-ellipsis">
Four fixed transmitters / fast single-pass receiver
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../full_companion_features/" class="md-nav__link">
<span class="md-ellipsis">
Full Companion: turn features on and off
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../full_companion_usb_switcher/" class="md-nav__link">
<span class="md-ellipsis">
Companion USB CLI and binary switcher
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../full_usb_logging_validation/" class="md-nav__link">
<span class="md-ellipsis">
Full USB logging repair — 1.17.1.6
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../gps_tracking/" class="md-nav__link">
<span class="md-ellipsis">
GPS Tracking
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../halo_keymind_settings/" class="md-nav__link">
<span class="md-ellipsis">
Halo and Keymind Branch Settings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hardware_validation_bluetooth_stealth_2026-09-07/" class="md-nav__link">
<span class="md-ellipsis">
XIAO Bluetooth stealth hardware validation - 2026-09-07
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hardware_validation_checklist/" class="md-nav__link">
<span class="md-ellipsis">
Hardware validation checklist
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../home_text_spacing/" class="md-nav__link">
<span class="md-ellipsis">
Home-screen text spacing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../host_cli_service/" class="md-nav__link">
<span class="md-ellipsis">
LoRa CLI Host Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../kiss_modem_protocol/" class="md-nav__link">
<span class="md-ellipsis">
MeshCore KISS Modem Protocol
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../lora_ota_automation/" class="md-nav__link">
<span class="md-ellipsis">
Scripted LoRa OTA from start to finish
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mbedtls-tls-footprint/" class="md-nav__link">
<span class="md-ellipsis">
Shrinking the per-connection TLS footprint on non-PSRAM observers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mixed_scan_validation/" class="md-nav__link">
<span class="md-ellipsis">
Mixed-bandwidth two-channel reception test
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../mixed_sf_bw_validation/" class="md-nav__link">
<span class="md-ellipsis">
Equal-symbol-time mixed SF/BW, four-channel test
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nimble_companion_trial/" class="md-nav__link">
<span class="md-ellipsis">
ESP32-S3 NimBLE Full Companion trial
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nimble_companion_trial_results/" class="md-nav__link">
<span class="md-ellipsis">
ESP32-S3 NimBLE trial results, 2026-09-08
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nrf52-usb-ready-fix/" class="md-nav__link">
<span class="md-ellipsis">
nRF52 USB READY hang
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nrf52_companion_storage_recovery/" class="md-nav__link">
<span class="md-ellipsis">
nRF52 Companion automatic ExtraFS recovery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nrf52_power_management/" class="md-nav__link">
<span class="md-ellipsis">
nRF52 Power Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../number_allocations/" class="md-nav__link">
<span class="md-ellipsis">
Number Allocations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_easy/" class="md-nav__link">
<span class="md-ellipsis">
Easy firmware updates over LoRa
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_meshtower_v2_sdcard/" class="md-nav__link">
<span class="md-ellipsis">
MeshTower V2 microSD LoRa OTA
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_nrf52_bootloader_update/" class="md-nav__link">
<span class="md-ellipsis">
nRF52 bootloader updates over LoRa
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_nrf52_qspi/" class="md-nav__link">
<span class="md-ellipsis">
nRF52 repeater LoRa OTA with external QSPI
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_protocol/" class="md-nav__link">
<span class="md-ellipsis">
MeshCore OTA - .mota container &amp; LoRa protocol
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ota_user_guide/" class="md-nav__link">
<span class="md-ellipsis">
Updating your node over the air (OTA) - user guide
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../packet_format/" class="md-nav__link">
<span class="md-ellipsis">
Packet Format
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pair_4p6_300us_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF7/62.5 + SF8/500: 4.6 slow chirps, 0.3 ms reserve
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pair_preamble32_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF7/62.5 + SF8/500, fast switching and preamble 32
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../payloads/" class="md-nav__link">
<span class="md-ellipsis">
Payload Format
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pr7_review_validation/" class="md-nav__link">
<span class="md-ellipsis">
PR #7 review and validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../preamble_detection_investigation/" class="md-nav__link">
<span class="md-ellipsis">
Off-channel preamble investigation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../preset_test/" class="md-nav__link">
<span class="md-ellipsis">
Temporary radio test command generator
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../qr_codes/" class="md-nav__link">
<span class="md-ellipsis">
QR Codes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_chirp_math_validation/" class="md-nav__link">
<span class="md-ellipsis">
Shared radio/radio2 chirp timing and preamble warnings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_dwell_policy_validation/" class="md-nav__link">
<span class="md-ellipsis">
Automatic dwell policy: 4.6 chirps on both profiles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_profile_switch_validation/" class="md-nav__link">
<span class="md-ellipsis">
SX1262 profile-switch validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_profiles/" class="md-nav__link">
<span class="md-ellipsis">
Two LoRa profiles on one radio
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_profiles_validation/" class="md-nav__link">
<span class="md-ellipsis">
Dual-profile receive validation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../radio_receive_calibration/" class="md-nav__link">
<span class="md-ellipsis">
Radio receive calibration and recovery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../rak3401_mota_chain/" class="md-nav__link">
<span class="md-ellipsis">
RAK3401 1W repeater compact LoRa update chain
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../role_feature_switches/" class="md-nav__link">
<span class="md-ellipsis">
Feature switches by role — 1.17.1.5 USA Cascade
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
ESP32-S3 OTA memory experiment
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
ESP32-S3 OTA memory experiment
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#hardware-and-scope" class="md-nav__link">
<span class="md-ellipsis">
Hardware and scope
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reproducible-builds" class="md-nav__link">
<span class="md-ellipsis">
Reproducible builds
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#instrumentation" class="md-nav__link">
<span class="md-ellipsis">
Instrumentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#results-and-continuing-soak" class="md-nav__link">
<span class="md-ellipsis">
Results and continuing soak
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#physical-display-checks" class="md-nav__link">
<span class="md-ellipsis">
Physical display checks
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../separated_radio_modulation_cache_validation/" class="md-nav__link">
<span class="md-ellipsis">
Separated radios, normal XIAO RX gain, and unchanged-modulation timing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf10_10_vs_100hz_full_sample_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF10/125 full samples: 10 Hz versus 100 Hz first-pass detour
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf10_10hz_cr_detour_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF10/125: tiny first-pass frequency offset and coding-rate detour
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf10_full_retune_twice_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF10/125: apply the full radio settings twice per hop
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf10_nrf52_double_write_settling_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF10 / 125 kHz, XIAO nRF52 TX, double write, 1 ms delay grid
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf10_rollback_failure_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF10/125 rollback and wider-spacing failure isolation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf125_settling_limits_validation/" class="md-nav__link">
<span class="md-ellipsis">
Descending SF10..SF5 / 125 kHz settling limits
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf5_250_dwell_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF5 / 250 kHz: four-channel dwell sweep
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf6_125_settling_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF6/125 four-channel post-switch settling sweep
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf6_5p1_trace_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF6 / 125 kHz: four channels at 5.1 chirps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf6_channel_scan_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF6 / 125 kHz channel-count test
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sf8_5p1_trace_validation/" class="md-nav__link">
<span class="md-ellipsis">
SF8 / 125 kHz: four-channel comparison at 5.1 chirps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../spiffs_regular_file_reads/" class="md-nav__link">
<span class="md-ellipsis">
SPIFFS regular-file reads and login replay state
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../stats_binary_frames/" class="md-nav__link">
<span class="md-ellipsis">
Stats Binary Frame Structures
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../telemetry_decoder/" class="md-nav__link">
<span class="md-ellipsis">
Telemetry decoder
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../terminal_chat_cli/" class="md-nav__link">
<span class="md-ellipsis">
Terminal Chat CLI
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../usb_serial_backpressure/" class="md-nav__link">
<span class="md-ellipsis">
Native USB backpressure and radio liveness
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../v4_pixel5_font_trial/" class="md-nav__link">
<span class="md-ellipsis">
Small-screen message fonts
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_89" >
<label class="md-nav__link" for="__nav_89" id="__nav_89_label" tabindex="0">
<span class="md-ellipsis">
Releases
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_89_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_89">
<span class="md-nav__icon md-icon"></span>
Releases
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../releases/1.17.1.5-doc-audit/" class="md-nav__link">
<span class="md-ellipsis">
Markdown audit — 1.17.1.5 USA Cascade
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../releases/1.17.1.5/" class="md-nav__link">
<span class="md-ellipsis">
MeshCore 1.17.1.5 Dev - USA Cascade
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../releases/1.17.1.6/" class="md-nav__link">
<span class="md-ellipsis">
MeshCore 1.17.1.6 Dev - USA Cascade
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#hardware-and-scope" class="md-nav__link">
<span class="md-ellipsis">
Hardware and scope
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reproducible-builds" class="md-nav__link">
<span class="md-ellipsis">
Reproducible builds
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#instrumentation" class="md-nav__link">
<span class="md-ellipsis">
Instrumentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#results-and-continuing-soak" class="md-nav__link">
<span class="md-ellipsis">
Results and continuing soak
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#physical-display-checks" class="md-nav__link">
<span class="md-ellipsis">
Physical display checks
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/mikecarper/MeshCore/edit/keymindCascade/docs/s3_memory_soak_validation.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<h1 id="esp32-s3-ota-memory-experiment">ESP32-S3 OTA memory experiment</h1>
<p>This experiment compares the current static S3 OTA workspace (A) with
<code>OTA_HEAP_CONTEXT=1</code> (B), with WiFi and a real TLS MQTT connection enabled.
It is isolated on <code>experiment/s3-ota-memory-soak</code>; published recipes retain
their existing defaults. A short stress test cannot establish months of uptime.</p>
<h2 id="hardware-and-scope">Hardware and scope</h2>
<table>
<thead>
<tr>
<th>Board</th>
<th>Role</th>
<th style="text-align: right;">Flash</th>
<th style="text-align: right;">PSRAM</th>
<th>Lab identity</th>
</tr>
</thead>
<tbody>
<tr>
<td>Heltec V4.3 OLED, standard V4</td>
<td>Observer/MQTT repeater</td>
<td style="text-align: right;">16 MiB</td>
<td style="text-align: right;">2 MiB QSPI</td>
<td>USB MAC <code>44:1B:F6:69:CF:98</code></td>
</tr>
<tr>
<td>Original SenseCAP Indicator LoRa</td>
<td>Full companion plus experimental MQTT</td>
<td style="text-align: right;">8 MiB</td>
<td style="text-align: right;">8 MiB octal</td>
<td>WiFi MAC <code>D8:3B:DA:75:23:AC</code></td>
</tr>
<tr>
<td>Seeed XIAO ESP32-S3 with WIO LoRa</td>
<td>Observer/MQTT repeater</td>
<td style="text-align: right;">8 MiB</td>
<td style="text-align: right;">8 MiB octal</td>
<td>MAC <code>28:84:85:B4:09:80</code>, Windows COM31</td>
</tr>
</tbody>
</table>
<p>This is not an R8 test. Both Indicator variants use the same 320x320 canvas;
the native 480x480 Full-plus-MQTT configuration is not qualified by this run.
One custom TLS MQTT slot per board publishes only to the isolated Pi broker.
These results do not qualify five concurrent slots, JWT renewal, heavy RF
traffic, every OTA receive/apply path, or months of operation.</p>
<h2 id="reproducible-builds">Reproducible builds</h2>
<p>Base commit: <code>bc0fb2c335938c97220de51098cea6162f2f0fe0</code>, following PR #7's merge.
Copy <code>tools/hil/s3_memory_soak.ini</code> to ignored <code>platformio.local.ini</code> and build
the six named environments sequentially, with <code>MESHCORE_ESP32_FULL_BUILD=1</code>.
Never run multiple PlatformIO processes in this checkout. Archive each image,
ELF, map, partitions, bootloader, and memory report before the next build.</p>
<p>The private broker's public CA must be in <code>ssl_certs</code> while generating these
experimental images. Remove it and <code>platformio.local.ini</code> afterward. Private
keys stay on the Pi. WiFi credentials and the Windows logger token are in
private local files; do not commit them or the generated certificate bundle.
Broker certificate verification remains enabled.</p>
<p>The V4 and XIAO lab recipes also enable <code>MESH_SOAK_WIFI_KEY_OVERRIDE</code> and
require the ignored local header <code>tools/hil/S3SoakWiFiKey.h</code>. To reproduce
diagnostics using ordinary WiFi credentials, remove that define from the lab
recipe; the private header is then unnecessary. Published recipes do not
enable either lab flag.</p>
<table>
<thead>
<tr>
<th>Image</th>
<th style="text-align: right;">Application bytes</th>
<th style="text-align: right;">Link-time available internal bytes</th>
<th>SHA-256</th>
</tr>
</thead>
<tbody>
<tr>
<td>V4 A</td>
<td style="text-align: right;">1,910,392</td>
<td style="text-align: right;">237,360</td>
<td><code>68c2749e0ea40db91d953f6355010bc602f85424526ca6acbe1cad7fd11c8630</code></td>
</tr>
<tr>
<td>V4 B</td>
<td style="text-align: right;">1,911,256</td>
<td style="text-align: right;">252,760</td>
<td><code>6847ad4ad6bac2e558b8aed67de37417a497972391f13a71e0a42b5c9704dcff</code></td>
</tr>
<tr>
<td>Indicator A</td>
<td style="text-align: right;">2,313,256</td>
<td style="text-align: right;">244,248</td>
<td><code>3d0ac27f95ddc54a32b59a3892d157713dcded285dbeb98d1bdfdb1ce0b951ab</code></td>
</tr>
<tr>
<td>Indicator B</td>
<td style="text-align: right;">2,314,136</td>
<td style="text-align: right;">255,496</td>
<td><code>83045d7ec48befc43f3460c08c68b71da037a5476e14dd59def5706fc5a1b07e</code></td>
</tr>
<tr>
<td>XIAO A</td>
<td style="text-align: right;">1,845,000</td>
<td style="text-align: right;">238,448</td>
<td><code>6fcc657c5ccbc5dd3d53a0cf1ceebde54479d59d329f8625e7cb7141a27d9ed8</code></td>
</tr>
<tr>
<td>XIAO B</td>
<td style="text-align: right;">1,845,912</td>
<td style="text-align: right;">253,864</td>
<td><code>2b233e42e0c515b152ce83ca8fe38b1f35780970bb6350dbadf2591b6a2699a1</code></td>
</tr>
</tbody>
</table>
<p>All six firmware builds passed their RAM/flash gates. The linked internal
capacity gain is 15,400 bytes on V4, 11,248 bytes on Indicator, and 15,416 bytes
on XIAO. This is
capacity returned while idle, not a reduction in peak OTA allocation needs.
Both A/B variants keep the existing MQTT client reuse policy and internal
MQTT task stack; this experiment does not move that stack into PSRAM.</p>
<h2 id="instrumentation">Instrumentation</h2>
<p><code>MESH_SOAK_DIAGNOSTICS</code> exposes local-only <code>get soak</code>, <code>soak ota-cycle</code>, and
<code>soak wifi-drop</code> commands. They report free/largest/minimum internal heap,
free PSRAM, OTA context size/presence, WiFi state, and uptime. No published
recipe enables these controls.</p>
<p>The lab network has a valid 64-digit raw WiFi key. Production MQTT preferences
currently accept only 63 characters. The V4 experiment uses a separate,
test-only NVS key through <code>MESH_SOAK_WIFI_KEY_OVERRIDE</code>, without changing the
production binary preference layout. This does not fix released raw-key input.
The network's original nine-character passphrase was subsequently recovered
from the connected Windows profile; XIAO uses it through ordinary settings.
The override is compiled into both XIAO images but no override key is stored.</p>
<p>The Pi logger owns one persistent V4 USB handle: opening this particular USB
device resets it, even with DTR/RTS disabled. Firmware installations and logger
restarts therefore begin new uptime runs. Indicator telemetry uses TCP 5002.
The logger distinguishes the 49.7-day <code>millis()</code> rollover from a reboot.</p>
<p>Passive samples omit <code>get mqtt.stats</code>: its outbox query can block behind the
MQTT client lock during a TLS handshake and stall the CLI. The logger reads
<code>get mqtt.status</code> and separately counts messages received through a verified
TLS subscription. It stores topic counts, not MQTT payloads or credentials.</p>
<p>Two exploratory rapid-flap runs used an overly short 90-second recovery cutoff.
The first also used the blocking outbox probe. Preserve those pilot results;
do not count them as successful tests. Production MQTT backoff deliberately
grows to five minutes and clears after two stable connected minutes, so rapid
flapping is not equivalent to repeated independent connection tests.</p>
<h2 id="results-and-continuing-soak">Results and continuing soak</h2>
<p>V4 and Indicator both passed the matched A/B workload: 200 explicit OTA context
acquire/release attempts, four MQTT bridge restarts, one WiFi reconnection and
one five-second private-broker outage per image. An initial bridge restart
preconditions each run. No unexpected uptime resets occurred in these runs.
A was paused after its four bridge restarts to investigate the display report,
then resumed for the network faults; its elapsed duration includes that pause.</p>
<p>After the workload, with WiFi and one TLS MQTT slot connected:</p>
<table>
<thead>
<tr>
<th>Board</th>
<th style="text-align: right;">A free internal bytes</th>
<th style="text-align: right;">B free internal bytes</th>
<th style="text-align: right;">Gain</th>
<th style="text-align: right;">A largest block</th>
<th style="text-align: right;">B largest block</th>
</tr>
</thead>
<tbody>
<tr>
<td>Standard V4</td>
<td style="text-align: right;">95,396</td>
<td style="text-align: right;">111,040</td>
<td style="text-align: right;">15,644 (15.28 KiB)</td>
<td style="text-align: right;">81,908</td>
<td style="text-align: right;">98,292</td>
</tr>
<tr>
<td>Indicator</td>
<td style="text-align: right;">107,168</td>
<td style="text-align: right;">118,520</td>
<td style="text-align: right;">11,352 (11.09 KiB)</td>
<td style="text-align: right;">94,196</td>
<td style="text-align: right;">106,484</td>
</tr>
<tr>
<td>XIAO (same saved settings, cold boot)</td>
<td style="text-align: right;">151,028</td>
<td style="text-align: right;">166,444</td>
<td style="text-align: right;">15,416 (15.05 KiB)</td>
<td style="text-align: right;">139,252</td>
<td style="text-align: right;">147,444</td>
</tr>
</tbody>
</table>
<p>Free heap varies with network activity; link-time capacity is the cleaner
measurement of storage moved out of static RAM. PSRAM remained about 2.01 MB
on V4 and 6.33 MB on Indicator. In each B run the OTA context returned to absent
after the allocation workload. Neither board's largest block shrank through
those 200 allocation cycles or the reconnect workload. WiFi/MQTT recovery took
about 4.3 seconds on A and 3.8 seconds on B; broker recovery took about 19.5 and
21.8 seconds respectively. These are single observed recovery times.</p>
<p>Workspace recreation has an observed latency cost. The 200 command cycles
took approximately 189 seconds on V4 B and 379 seconds on Indicator B, versus
32 and 15 seconds on A. This includes command transport, OTA initialization,
and ordinary firmware service, so it is not an allocator microbenchmark.
The static comparator already owns an initialized workspace; the dynamic
variant recreates it. This experiment does not claim faster OTA startup, and
this cost should be checked against real session use before a default change.
Code inspection shows that <code>OtaContext::begin()</code> calls <code>ota_self_firmware()</code>,
which scans the running ESP32 application for its EndF identity on each call.
All six experimental images contain valid EndF trailers. Caching immutable
boot identity is a candidate for a separate change, not part of these results.</p>
<p>The real WiFi mOTA folder endpoint was tested separately on Indicator: 20
empty-folder sessions on A and 40 on B. All completed and B released its context.
During B's first batch, free internal RAM went from 118,552 to 116,316 bytes,
and its largest block from 106,484 to 102,388. A second batch ended at 116,308
bytes with the same 102,388-byte largest block. This retained allocation/layout
change is not explained by the now-absent OTA context; record it separately and
watch it during the soak. It did not keep growing in the second batch.</p>
<p>The original A folder script also tried V4, whose observer recipe has no TCP
5001 folder source. Its overall result therefore says <code>passed: false</code>, despite
Indicator completing all 20 sessions. That endpoint mismatch is preserved in
the evidence; it is not an OTA failure on V4. The corrected script targets only
the Indicator. These empty-folder checks do not qualify a full firmware transfer.</p>
<p>XIAO passed 200 context cycles, four bridge restarts and one WiFi reconnect
per image, with no unexpected reset. Its largest block stayed unchanged within
each workload. WiFi/TLS recovered in about six seconds for both. This local
test did not inject a separate broker outage or exercise a TCP folder endpoint.
Verified subscriptions on the Pi confirmed actual TLS publications for both.</p>
<p>The first XIAO A run followed initial device configuration and finished with
126,140 internal bytes free, which would have overstated the OTA saving. It is
preserved as <code>xiao-live/A-configuration-stress.json</code>. Reflashing A without an
erase, retaining exactly the saved settings used by B, and rerunning the whole
workload produced the 151,028-byte baseline above. Its resulting gain exactly
matches the 15,416-byte linked-capacity change. The earlier larger gap is not
credited to OTA storage; the precise retained allocation was not isolated.</p>
<p>The Pi stores evidence under <code>/home/mikec/hwtest/runs/s3-memory-soak</code>:</p>
<ul>
<li><code>telemetry.jsonl</code>: append-only memory, WiFi/MQTT state, uptime, transport errors.</li>
<li><code>latest.json</code>: latest samples plus broker-side received-message counts.</li>
<li><code>A-stress.json</code> / <code>B-stress.json</code>: matched stress results and phase boundaries.</li>
<li><code>A-folder.json</code> / <code>B-folder.json</code>: real WiFi mOTA empty-folder session checks.</li>
<li><code>B-repeat-folder.json</code>: the extra batch checking the initial allocation change.</li>
</ul>
<p><code>meshcore-memory-soak.service</code> holds the USB connection and samples each minute.
<code>meshcore-soak-broker.service</code> supplies the private TLS broker. Both are enabled
on the Pi. The logger never reboots a board to hide a firmware failure, but
reopening the V4 USB transport can itself reset it; inspect transport counts,
service restarts, and uptime together when diagnosing any interruption.
The final passive phase started at <code>2026-09-11T07:18:07Z</code>. Installing the final
logger revision (which serializes concurrent samples) deliberately restarted
the service and therefore reset V4 once. That begins its long-soak uptime run;
Indicator retained its uptime. Both then reported WiFi/TLS connected, absent
OTA contexts, and actual broker-side publications.</p>
<p>The local XIAO logger owns COM31 and writes under
<code>C:\git\MeshCore\out\s3-memory-soak\xiao-live</code>. Its control endpoint is
loopback-only with a private token. It runs while this Windows session remains
alive; it is not a Pi service and will not survive a computer shutdown. A
separate verified TLS subscription on the Pi confirmed XIAO publications for
both images. The Pi logger's per-device counts cover V4 and Indicator only.
The final XIAO B passive phase was verified at <code>2026-09-11T07:21:21Z</code>, with
166,508 free internal bytes, a 155,636-byte largest block, WiFi/TLS connected,
and no active OTA context. The largest block differs from the post-stress
sample because this is a fresh boot, which illustrates why comparisons must
use the same workload history. A Pi subscription received its publication two
seconds later.</p>
<p>Read-only checks on the Pi:</p>
<pre><code class="language-sh">systemctl is-active meshcore-memory-soak meshcore-soak-broker
cat /home/mikec/hwtest/runs/s3-memory-soak/latest.json
</code></pre>
<p>On Windows, read <code>out/s3-memory-soak/xiao-live/latest.json</code>. Keep the computer
awake for continuous local samples. Neither logger automatically reboots a
radio in response to a failed sample.</p>
<p>The public lab CA was removed from <code>ssl_certs</code>, and the temporary local PIO
configuration and generated test trust bundle were removed after building.
Archived experimental firmware and public evidence remain in ignored
<code>out/s3-memory-soak</code>; no test CA enters the published build configuration.</p>
<p>No published default has changed. Leave the experimental B images running to
collect longer evidence before deciding whether to expand S3 heap allocation.
More idle internal RAM gives WiFi/TLS useful headroom; it does not itself prove
stability or eliminate the need to allocate the OTA workspace during use.</p>
<h2 id="physical-display-checks">Physical display checks</h2>
<p>The user reported unresponsive screens during MQTT restart testing. The V4
lit after temporarily choosing <code>on</code>; after restoring battery and USB profiles
to <code>button</code>, 15 seconds, the user confirmed that pressing the button wakes it.
The synchronous reconnect/diagnostic work may have delayed UI service, but the
exact cause of the original visual report was not established.</p>
<p>The T096 is a separate nRF52840 board, USB identity <code>651F8E496197F882</code>. It was
reflashed with current Full firmware and briefly instrumented. The trace showed
the radio, sensor and UI loop advancing; the display had initialized but was
marked off. Its functional CDC0 was in Binary mode after a host-session close.
Sending a newline-delimited <code>+++MESHCORE-TERM-START</code> restored ASCII control.
With display mode set to <code>on</code>, the user confirmed the normal screen appeared.
Temporary tracing was removed by reinstalling the non-instrumented image, and
battery/USB profiles were restored to <code>button-pairing</code>, 15 seconds. The user
then confirmed that its button wakes the normal screen after timeout.</p>
<p>T096 recovery firmware: <code>v1.17.1-t096-check</code>, Full/shared OTA queue, <code>-Os</code> size
profile, available linked internal RAM 99,892 bytes (73,728 required). ZIP SHA-256
<code>f5cfcb001efda559ae9b4e7b105ac9766a604808f5fd708b7c533f8a11c64578</code>.
No device-wide filesystem erase was needed for this recovery. T096 does not
count as an S3 A/B test.</p>
<p>Host validation: <code>python -m unittest discover -s tools/hil -p test_s3_memory_soak.py</code>.
The five checks cover diagnostic filtering, missing data, resets, and counter
rollover. They are not substitutes for the hardware evidence.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
<script src="../_javascript/firmware_picker.js"></script>
<script src="../_javascript/telemetry_decoder.js"></script>
<script src="../_javascript/filter_tool.js"></script>
<script src="../_javascript/preset_test.js?v=20260916-2"></script>
</body>
</html>