1028 lines
37 KiB
HTML
1028 lines
37 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>ESP32-C5 GDB Debugging Guide - WiFi Monitor Mode Edition</title>
|
||
<style>
|
||
:root {
|
||
--primary-color: #0e7490;
|
||
--secondary-color: #357edd;
|
||
--bg-color: #f9f9f9;
|
||
--code-bg: #f0f0f0;
|
||
--border-color: #e0e0e0;
|
||
--text-color: #1a1a1a;
|
||
--success-color: #19a974;
|
||
--warning-color: #ff6300;
|
||
}
|
||
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||
line-height: 1.6;
|
||
color: var(--text-color);
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
background: var(--bg-color);
|
||
}
|
||
|
||
header {
|
||
background: linear-gradient(135deg, #0891b2, var(--secondary-color));
|
||
color: white;
|
||
padding: 40px 30px;
|
||
border-radius: 8px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
header h1 {
|
||
margin: 0 0 10px 0;
|
||
font-size: 2.5em;
|
||
}
|
||
|
||
header p {
|
||
margin: 5px 0;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
.git-branch {
|
||
background: rgba(255,255,255,0.2);
|
||
padding: 10px 15px;
|
||
border-radius: 5px;
|
||
margin-top: 15px;
|
||
font-family: 'Courier New', monospace;
|
||
}
|
||
|
||
nav {
|
||
background: white;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
margin-bottom: 30px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
nav h2 {
|
||
margin-top: 0;
|
||
color: var(--secondary-color);
|
||
}
|
||
|
||
nav ul {
|
||
list-style: none;
|
||
padding: 0;
|
||
column-count: 2;
|
||
column-gap: 30px;
|
||
}
|
||
|
||
nav li {
|
||
margin: 8px 0;
|
||
}
|
||
|
||
nav a {
|
||
color: var(--secondary-color);
|
||
text-decoration: none;
|
||
transition: color 0.2s;
|
||
}
|
||
|
||
nav a:hover {
|
||
color: #0e7490;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
main {
|
||
background: white;
|
||
padding: 40px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
h2 {
|
||
color: var(--primary-color);
|
||
border-bottom: 2px solid var(--border-color);
|
||
padding-bottom: 10px;
|
||
margin-top: 40px;
|
||
}
|
||
|
||
h3 {
|
||
color: var(--secondary-color);
|
||
margin-top: 25px;
|
||
}
|
||
|
||
h4 {
|
||
color: #333;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
code {
|
||
background: var(--code-bg);
|
||
padding: 2px 6px;
|
||
border-radius: 3px;
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
pre {
|
||
background: var(--code-bg);
|
||
padding: 20px;
|
||
border-radius: 5px;
|
||
overflow-x: auto;
|
||
border-left: 4px solid var(--primary-color);
|
||
}
|
||
|
||
pre code {
|
||
background: none;
|
||
padding: 0;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 20px 0;
|
||
}
|
||
|
||
th, td {
|
||
padding: 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid var(--border-color);
|
||
}
|
||
|
||
th {
|
||
background: var(--primary-color);
|
||
color: white;
|
||
font-weight: 600;
|
||
}
|
||
|
||
tr:hover {
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.alert {
|
||
padding: 15px 20px;
|
||
border-radius: 5px;
|
||
margin: 20px 0;
|
||
border-left: 4px solid;
|
||
}
|
||
|
||
.alert-success {
|
||
background: #e6f7ed;
|
||
border-color: var(--success-color);
|
||
}
|
||
|
||
.alert-warning {
|
||
background: #fff3e0;
|
||
border-color: var(--warning-color);
|
||
}
|
||
|
||
.alert-info {
|
||
background: #e3f2fd;
|
||
border-color: var(--secondary-color);
|
||
}
|
||
|
||
ul.checkmark li::before {
|
||
content: "✓ ";
|
||
color: var(--success-color);
|
||
font-weight: bold;
|
||
margin-right: 5px;
|
||
}
|
||
|
||
ul.checkmark {
|
||
list-style: none;
|
||
padding-left: 0;
|
||
}
|
||
|
||
.button {
|
||
display: inline-block;
|
||
background: var(--secondary-color);
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border-radius: 5px;
|
||
text-decoration: none;
|
||
margin: 5px;
|
||
transition: background 0.2s;
|
||
}
|
||
|
||
.button:hover {
|
||
background: #0e7490;
|
||
}
|
||
|
||
.feature-box {
|
||
background: #f8f9fa;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
margin: 20px 0;
|
||
border-left: 4px solid var(--primary-color);
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
body {
|
||
padding: 10px;
|
||
}
|
||
|
||
header {
|
||
padding: 30px 20px;
|
||
}
|
||
|
||
header h1 {
|
||
font-size: 2em;
|
||
}
|
||
|
||
main {
|
||
padding: 20px;
|
||
}
|
||
|
||
nav ul {
|
||
column-count: 1;
|
||
}
|
||
|
||
table {
|
||
font-size: 0.9em;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<h1>ESP32-C5 GDB Debugging Guide</h1>
|
||
<p><strong>WiFi Monitor Mode Edition</strong> - Real-Time WiFi Frame Analysis & Threshold Tuning</p>
|
||
<p><strong>Author:</strong> Bob McMahon</p>
|
||
<p><strong>Hardware:</strong> ESP32-C5 DevKit (RISC-V, Dual-Band WiFi 6)</p>
|
||
<p><strong>ESP-IDF:</strong> v6.0 or later</p>
|
||
<p><strong>Tools:</strong> GDB 16.3_20250913, OpenOCD v0.12.0-esp32-20250707</p>
|
||
<p><strong>Last Updated:</strong> December 2025</p>
|
||
<div class="git-branch">
|
||
<strong>📦 Git Branch:</strong> feature/wifi-monitor-mode<br>
|
||
<strong>🔗 Repository:</strong> https://github.com/yourusername/esp32-iperf
|
||
</div>
|
||
</header>
|
||
|
||
<nav>
|
||
<h2>Table of Contents</h2>
|
||
<ul>
|
||
<li><a href="#introduction">Introduction</a></li>
|
||
<li><a href="#why-gdb">Why GDB Debugging?</a></li>
|
||
<li><a href="#capabilities">ESP32-C5 Debug Capabilities</a></li>
|
||
<li><a href="#prerequisites">Prerequisites</a></li>
|
||
<li><a href="#building">Building with Debug Symbols</a></li>
|
||
<li><a href="#starting">Starting a Debug Session</a></li>
|
||
<li><a href="#commands">Essential GDB Commands</a></li>
|
||
<li><a href="#wifi-monitor">WiFi Monitor Mode Debugging</a></li>
|
||
<li><a href="#frame-analysis">802.11 Frame Analysis</a></li>
|
||
<li><a href="#threshold-tuning">Runtime Threshold Tuning</a></li>
|
||
<li><a href="#duration-analysis">Duration Analysis</a></li>
|
||
<li><a href="#strategies">Debugging Strategies</a></li>
|
||
<li><a href="#examples">Real-World Examples</a></li>
|
||
<li><a href="#troubleshooting">Troubleshooting</a></li>
|
||
<li><a href="#advanced">Advanced Techniques</a></li>
|
||
<li><a href="#resources">Resources</a></li>
|
||
</ul>
|
||
</nav>
|
||
|
||
<main>
|
||
<section id="introduction">
|
||
<h2>Introduction</h2>
|
||
<p>The ESP32-C5 is Espressif's first RISC-V microcontroller with dual-band WiFi 6 (802.11ax) support. This guide demonstrates advanced GDB debugging techniques for WiFi monitor mode, including real-time 802.11 frame analysis, runtime threshold tuning, and WiFi collapse detection.</p>
|
||
|
||
<div class="feature-box">
|
||
<h3>New in This Edition: WiFi Monitor Mode</h3>
|
||
<ul class="checkmark">
|
||
<li><strong>802.11 Frame Capture</strong>: Debug WiFi at the packet level</li>
|
||
<li><strong>Runtime Threshold Tuning</strong>: Adjust detection parameters without rebuilding</li>
|
||
<li><strong>Duration Analysis</strong>: Analyze PHY rates, NAV, and expected vs actual duration</li>
|
||
<li><strong>WiFi Collapse Detection</strong>: Real-time network degradation analysis</li>
|
||
<li><strong>GDB Integration</strong>: Combine C code performance with GDB flexibility</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="wifi-monitor">
|
||
<h2>WiFi Monitor Mode Debugging</h2>
|
||
|
||
<p>The WiFi monitor mode implementation in the <code>feature/wifi-monitor-mode</code> branch provides real-time 802.11 frame capture and analysis capabilities. This section shows how to debug WiFi at the packet level using GDB.</p>
|
||
|
||
<h3>Branch Setup</h3>
|
||
<pre><code>cd ~/Code/esp32/esp32-iperf
|
||
git checkout feature/wifi-monitor-mode
|
||
git pull
|
||
|
||
# Build and flash
|
||
idf.py build
|
||
idf.py -p /dev/ttyACM0 flash</code></pre>
|
||
|
||
<h3>Component Architecture</h3>
|
||
<p>The WiFi monitor is implemented as a reusable ESP-IDF component:</p>
|
||
<pre><code>esp32-iperf/
|
||
├── components/
|
||
│ └── wifi_monitor/
|
||
│ ├── wifi_monitor.c # Frame capture & analysis
|
||
│ ├── wifi_monitor.h # API definitions
|
||
│ └── CMakeLists.txt
|
||
└── main/
|
||
└── main.c # Monitor mode integration</code></pre>
|
||
|
||
<h3>Starting a WiFi Monitor Debug Session</h3>
|
||
<pre><code># Terminal 1: Start OpenOCD
|
||
cd ~/Code/esp32/esp32-iperf
|
||
idf.py openocd
|
||
|
||
# Terminal 2: Start GDB
|
||
idf.py gdb</code></pre>
|
||
|
||
<div class="alert alert-info">
|
||
<strong>Auto-Loading .gdbinit:</strong> The project includes a <code>.gdbinit</code> file with WiFi debugging commands. Enable it once:
|
||
<pre><code>mkdir -p ~/.config/gdb
|
||
echo "set auto-load safe-path /" >> ~/.config/gdb/gdbinit</code></pre>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="frame-analysis">
|
||
<h2>802.11 Frame Analysis</h2>
|
||
|
||
<p>GDB can inspect captured WiFi frames in real-time, showing detailed 802.11 MAC header information.</p>
|
||
|
||
<h3>Frame Callback Breakpoint</h3>
|
||
<pre><code>(gdb) break monitor_frame_callback
|
||
Breakpoint 1 at 0x4200e926
|
||
|
||
(gdb) continue
|
||
|
||
# When frame is captured:
|
||
Thread 6 "main" hit Breakpoint 1, monitor_frame_callback (
|
||
frame=0x4082a6e4,
|
||
payload=0x40833c34,
|
||
len=1268
|
||
) at main.c:212</code></pre>
|
||
|
||
<h3>Displaying Frame Information</h3>
|
||
<p>Use the <code>show_frame_full</code> command (auto-loaded from .gdbinit):</p>
|
||
<pre><code>(gdb) show_frame_full
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
Frame: DATA
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
RSSI: -45 dBm
|
||
Channel: 36
|
||
Retry: no
|
||
|
||
PHY Rate: 433500 Kbps (433.5 Mbps)
|
||
Mode: MCS 8, BW 80MHz, SGI Yes
|
||
|
||
Byte Count: 1500 bytes
|
||
Expected Duration: 71 us (27 tx + 44 overhead)
|
||
Actual Duration (NAV): 68 us
|
||
Difference: -3 us shorter
|
||
|
||
Dest: ff:ff:ff:ff:ff:ff
|
||
Source: e0:46:ee:07:df:01
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</code></pre>
|
||
|
||
<h3>Frame Structure Breakdown</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Field</th>
|
||
<th>GDB Access</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Frame Type</strong></td>
|
||
<td><code>frame->type</code></td>
|
||
<td>0=Management, 1=Control, 2=Data</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Subtype</strong></td>
|
||
<td><code>frame->subtype</code></td>
|
||
<td>Specific frame subtype (e.g., BEACON, ACK, DATA)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>NAV</strong></td>
|
||
<td><code>frame->duration_id</code></td>
|
||
<td>Network Allocation Vector (microseconds)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Retry Bit</strong></td>
|
||
<td><code>frame->retry</code></td>
|
||
<td>true if frame is a retransmission</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>RSSI</strong></td>
|
||
<td><code>frame->rssi</code></td>
|
||
<td>Received Signal Strength (dBm)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>PHY Rate</strong></td>
|
||
<td><code>frame->phy_rate_kbps</code></td>
|
||
<td>Physical layer rate (Kbps)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>MAC Addresses</strong></td>
|
||
<td><code>frame->addr1/2/3</code></td>
|
||
<td>Destination, Source, BSSID</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>Conditional Breakpoints for WiFi Analysis</h3>
|
||
|
||
<h4>Break on High NAV (Potential Collapse)</h4>
|
||
<pre><code>(gdb) break monitor_frame_callback if frame->duration_id > 10000
|
||
Breakpoint 2 at 0x4200e926
|
||
|
||
(gdb) commands 2
|
||
>printf "⚠ HIGH NAV: %u us\n", frame->duration_id
|
||
>show_duration
|
||
>continue
|
||
>end
|
||
|
||
(gdb) continue</code></pre>
|
||
|
||
<h4>Break on Retry Frames (Collisions)</h4>
|
||
<pre><code>(gdb) break monitor_frame_callback if frame->retry == 1
|
||
Breakpoint 3 at 0x4200e926
|
||
|
||
(gdb) continue</code></pre>
|
||
|
||
<h4>Break on Collision Indicators</h4>
|
||
<pre><code># Retry + High NAV = Strong collision indicator
|
||
(gdb) break monitor_frame_callback if frame->retry && frame->duration_id > 5000
|
||
Breakpoint 4 at 0x4200e926
|
||
|
||
(gdb) commands 4
|
||
>printf "🚨 COLLISION DETECTED!\n"
|
||
>show_frame_full
|
||
>end
|
||
|
||
(gdb) continue</code></pre>
|
||
</section>
|
||
|
||
<section id="threshold-tuning">
|
||
<h2>Runtime Threshold Tuning</h2>
|
||
|
||
<p>One of the most powerful features is the ability to adjust WiFi detection thresholds <strong>at runtime via GDB</strong> without rebuilding firmware.</p>
|
||
|
||
<h3>Tunable Thresholds</h3>
|
||
<p>The WiFi monitor exposes 9 threshold variables that control detection sensitivity:</p>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Variable</th>
|
||
<th>Default</th>
|
||
<th>Purpose</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>threshold_high_nav_us</code></td>
|
||
<td>5000</td>
|
||
<td>NAV above this = "high"</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_duration_mismatch_us</code></td>
|
||
<td>10000</td>
|
||
<td>Log mismatches when NAV exceeds this</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_phy_rate_fallback_mbps</code></td>
|
||
<td>100</td>
|
||
<td>PHY rate below this = fallback</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_duration_multiplier</code></td>
|
||
<td>2</td>
|
||
<td>NAV > expected × this = mismatch</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_retry_rate_percent</code></td>
|
||
<td>20.0</td>
|
||
<td>Retry % for collapse detection</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_avg_nav_collapse_us</code></td>
|
||
<td>10000</td>
|
||
<td>Average NAV threshold for collapse</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_collision_percent</code></td>
|
||
<td>10.0</td>
|
||
<td>Collision % for collapse</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>threshold_mismatch_percent</code></td>
|
||
<td>5.0</td>
|
||
<td>Duration mismatch % for collapse</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>log_every_n_mismatches</code></td>
|
||
<td>1</td>
|
||
<td>Log every Nth mismatch (1=all)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>GDB Commands for Threshold Control</h3>
|
||
|
||
<h4>View Current Thresholds</h4>
|
||
<pre><code>(gdb) show_thresholds
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
WiFi Monitor Thresholds (GDB-tunable)
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
High NAV threshold: 5000 us
|
||
Duration mismatch log: 10000 us
|
||
PHY rate fallback: 100 Mbps
|
||
Duration multiplier: 2x expected
|
||
|
||
Collapse Detection:
|
||
Retry rate threshold: 20.0%
|
||
Avg NAV collapse: 10000 us
|
||
Collision percentage: 10.0%
|
||
Mismatch percentage: 5.0%
|
||
|
||
Logging Control:
|
||
Log every N mismatches: 1 (1=all, 10=every 10th)
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</code></pre>
|
||
|
||
<h4>Preset Profiles</h4>
|
||
<p>Three pre-configured profiles for different scenarios:</p>
|
||
|
||
<pre><code># Sensitive - Catch more issues (stricter thresholds)
|
||
(gdb) tune_sensitive
|
||
Thresholds set to SENSITIVE (catch more issues)
|
||
|
||
# Normal - Default balanced settings
|
||
(gdb) tune_normal
|
||
Thresholds set to NORMAL (default)
|
||
|
||
# Relaxed - Fewer false positives (lenient thresholds)
|
||
(gdb) tune_relaxed
|
||
Thresholds set to RELAXED (fewer false positives)</code></pre>
|
||
|
||
<h4>Adjust Individual Thresholds</h4>
|
||
<pre><code># Set high NAV threshold to 8000 us (8ms)
|
||
(gdb) set_high_nav 8000
|
||
High NAV threshold set to 8000 us
|
||
|
||
# Set mismatch logging threshold to 15000 us
|
||
(gdb) set_mismatch_log 15000
|
||
Duration mismatch logging threshold set to 15000 us
|
||
|
||
# Set rate fallback to 50 Mbps
|
||
(gdb) set_rate_fallback 50
|
||
PHY rate fallback threshold set to 50 Mbps
|
||
|
||
# Set duration multiplier (NAV > 3x expected = mismatch)
|
||
(gdb) set_multiplier 3
|
||
Duration multiplier set to 3x expected
|
||
|
||
# Log every 10th mismatch (reduce verbosity)
|
||
(gdb) set_log_rate 10
|
||
Logging every 10 mismatch(es)</code></pre>
|
||
|
||
<h4>Direct Variable Modification</h4>
|
||
<p>You can also modify threshold variables directly:</p>
|
||
<pre><code>(gdb) set threshold_high_nav_us = 7500
|
||
(gdb) set threshold_phy_rate_fallback_mbps = 75
|
||
(gdb) set log_every_n_mismatches = 5
|
||
|
||
(gdb) continue
|
||
# Changes take effect immediately!</code></pre>
|
||
|
||
<h3>Real-World Tuning Examples</h3>
|
||
|
||
<h4>Example 1: Noisy 2.4GHz Environment</h4>
|
||
<p><strong>Problem:</strong> Too many false positives on 2.4GHz</p>
|
||
<pre><code>(gdb) tune_relaxed
|
||
(gdb) set_rate_fallback 24 # 2.4GHz rates lower
|
||
(gdb) set_log_rate 10 # Reduce log spam
|
||
(gdb) continue</code></pre>
|
||
|
||
<h4>Example 2: Clean 5GHz Network</h4>
|
||
<p><strong>Problem:</strong> Want to catch subtle issues early</p>
|
||
<pre><code>(gdb) tune_sensitive
|
||
(gdb) set_rate_fallback 200 # Expect >200 Mbps
|
||
(gdb) set_multiplier 1.5 # Catch 1.5x mismatches
|
||
(gdb) continue</code></pre>
|
||
|
||
<h4>Example 3: Production Monitoring</h4>
|
||
<p><strong>Problem:</strong> Need to reduce log spam while maintaining detection</p>
|
||
<pre><code>(gdb) tune_normal
|
||
(gdb) set_log_rate 100 # Log every 100th mismatch
|
||
(gdb) set_mismatch_log 20000 # Only log severe (>20ms)
|
||
(gdb) continue</code></pre>
|
||
|
||
<div class="alert alert-success">
|
||
<strong>Key Benefit:</strong> No rebuild needed! Tune thresholds live while monitoring WiFi traffic, see effects immediately, then document optimal settings for your network.
|
||
</div>
|
||
</section>
|
||
|
||
<section id="duration-analysis">
|
||
<h2>Duration Analysis</h2>
|
||
|
||
<p>The WiFi monitor calculates expected frame duration based on PHY rate and compares it with the actual NAV (Network Allocation Vector). Large mismatches indicate WiFi problems.</p>
|
||
|
||
<h3>Duration Calculation</h3>
|
||
<p>For each captured frame:</p>
|
||
<pre><code>TX Time = (Frame Bytes × 8000) / PHY Rate (Kbps)
|
||
Overhead = Preamble + PLCP + SIFS + ACK ≈ 44 us
|
||
Expected Duration = TX Time + Overhead
|
||
|
||
Mismatch = Actual NAV - Expected Duration</code></pre>
|
||
|
||
<h3>GDB Commands for Duration Analysis</h3>
|
||
|
||
<h4>Quick Duration Check</h4>
|
||
<pre><code>(gdb) break monitor_frame_callback
|
||
(gdb) continue
|
||
|
||
(gdb) show_duration
|
||
DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)</code></pre>
|
||
|
||
<h4>Watch DATA Frames</h4>
|
||
<pre><code>(gdb) watch_data
|
||
Watching DATA frames
|
||
Continuing.
|
||
|
||
# Output streams:
|
||
DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)
|
||
DATA: 1200 bytes @ 433.5 Mbps → Expected 66 us, NAV 64 us (-2)
|
||
DATA: 800 bytes @ 54.0 Mbps → Expected 162 us, NAV 158 us (-4)</code></pre>
|
||
|
||
<h4>Find Duration Mismatches</h4>
|
||
<pre><code>(gdb) find_mismatch
|
||
Watching for NAV 2x+ expected duration
|
||
Continuing.
|
||
|
||
# Stops when mismatch detected:
|
||
DATA: 1200 bytes @ 54.0 Mbps → Expected 222 us, NAV 8500 us (+8278)
|
||
⚠ DURATION MISMATCH!</code></pre>
|
||
|
||
<h3>Interpreting Duration Differences</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Difference</th>
|
||
<th>Interpretation</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>-5 to +500 us</strong></td>
|
||
<td>✅ Normal overhead variation</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>+500 to +5000 us</strong></td>
|
||
<td>⚠️ Possible retransmission or fragmentation</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>+5000 to +20000 us</strong></td>
|
||
<td>⚠️⚠️ Likely collision or high contention</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>+20000+ us</strong></td>
|
||
<td>🚨 Severe WiFi collapse</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3>Example: Detecting WiFi Collapse</h3>
|
||
<pre><code># Normal WiFi
|
||
(gdb) show_duration
|
||
DATA: 1500 bytes @ 433.5 Mbps → Expected 71 us, NAV 68 us (-3)
|
||
✅ Healthy
|
||
|
||
# WiFi Collapse
|
||
(gdb) show_duration
|
||
DATA: 1200 bytes @ 54.0 Mbps → Expected 222 us, NAV 32000 us (+31778)
|
||
🚨 Severe collapse!
|
||
- PHY rate dropped: 433.5 → 54 Mbps
|
||
- NAV 144x expected duration
|
||
- Likely severe contention/collisions</code></pre>
|
||
|
||
<div class="alert alert-info">
|
||
<strong>Note:</strong> PHY rate calculation is approximate on ESP32-C5 (ESP-IDF v6.0 doesn't expose detailed MCS/bandwidth fields). However, large duration mismatches still accurately indicate WiFi problems.
|
||
</div>
|
||
</section>
|
||
|
||
<section id="strategies">
|
||
<h2>Debugging Strategies</h2>
|
||
|
||
<h3>WiFi Collapse Investigation Workflow</h3>
|
||
<ol>
|
||
<li><strong>Start with normal thresholds</strong>
|
||
<pre><code>(gdb) tune_normal
|
||
(gdb) continue</code></pre>
|
||
</li>
|
||
<li><strong>Run WiFi traffic test</strong>
|
||
<pre><code># From another machine
|
||
iperf -c 192.168.1.81 -t 60 -P 4</code></pre>
|
||
</li>
|
||
<li><strong>Monitor serial output</strong> for automatic detection</li>
|
||
<li><strong>If too noisy, adjust thresholds</strong>
|
||
<pre><code>(gdb) Ctrl-C
|
||
(gdb) set_log_rate 10
|
||
(gdb) continue</code></pre>
|
||
</li>
|
||
<li><strong>If not catching issues, increase sensitivity</strong>
|
||
<pre><code>(gdb) Ctrl-C
|
||
(gdb) tune_sensitive
|
||
(gdb) continue</code></pre>
|
||
</li>
|
||
<li><strong>Document optimal settings</strong> for your network</li>
|
||
</ol>
|
||
|
||
<h3>Best Practices</h3>
|
||
<div class="feature-box">
|
||
<h4>Threshold Tuning</h4>
|
||
<ul class="checkmark">
|
||
<li>Start conservative (tune_sensitive), then relax if needed</li>
|
||
<li>Use log_every_n_mismatches to control verbosity</li>
|
||
<li>Match thresholds to band (2.4GHz vs 5GHz)</li>
|
||
<li>Document final thresholds for each network/environment</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="feature-box">
|
||
<h4>Frame Analysis</h4>
|
||
<ul class="checkmark">
|
||
<li>Use conditional breakpoints to catch specific issues</li>
|
||
<li>Focus on DATA frames for throughput analysis</li>
|
||
<li>Watch for retry+high NAV combination (collision indicator)</li>
|
||
<li>Compare RSSI across frames to detect signal issues</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="feature-box">
|
||
<h4>Performance Monitoring</h4>
|
||
<ul class="checkmark">
|
||
<li>C code processes 10,000+ frames/sec</li>
|
||
<li>GDB adds minimal overhead for threshold tuning</li>
|
||
<li>Use GDB for deep inspection, C code for continuous monitoring</li>
|
||
<li>Combine automated detection (C) with interactive debugging (GDB)</li>
|
||
</ul>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="examples">
|
||
<h2>Real-World Examples</h2>
|
||
|
||
<h3>Example 1: Debugging Rate Fallback</h3>
|
||
<p><strong>Symptom:</strong> WiFi throughput suddenly drops</p>
|
||
<pre><code># Set breakpoint on low PHY rates
|
||
(gdb) break monitor_frame_callback if frame->phy_rate_kbps < 100000
|
||
Breakpoint 1 at 0x4200e926
|
||
|
||
(gdb) commands 1
|
||
>printf "Low PHY rate: %u Kbps, RSSI: %d dBm\n", frame->phy_rate_kbps, frame->rssi
|
||
>show_frame_full
|
||
>end
|
||
|
||
(gdb) continue
|
||
|
||
# Output reveals:
|
||
Low PHY rate: 54000 Kbps, RSSI: -82 dBm
|
||
# Root cause: Weak signal → rate adaptation → lower throughput</code></pre>
|
||
|
||
<h3>Example 2: Finding Collision Hotspots</h3>
|
||
<p><strong>Goal:</strong> Identify devices causing collisions</p>
|
||
<pre><code># Break on collision indicators
|
||
(gdb) break monitor_frame_callback if frame->retry && frame->duration_id > 5000
|
||
Breakpoint 1 at 0x4200e926
|
||
|
||
(gdb) commands 1
|
||
>printf "Collision from: %02x:%02x:%02x:%02x:%02x:%02x\n", \
|
||
frame->addr2[0], frame->addr2[1], frame->addr2[2], \
|
||
frame->addr2[3], frame->addr2[4], frame->addr2[5]
|
||
>continue
|
||
>end
|
||
|
||
(gdb) continue
|
||
|
||
# Track which MAC addresses retry most frequently</code></pre>
|
||
|
||
<h3>Example 3: Tuning for 2.4GHz vs 5GHz</h3>
|
||
<pre><code># 2.4GHz network (more interference, lower rates)
|
||
(gdb) set_high_nav 8000 # More lenient
|
||
(gdb) set_rate_fallback 24 # Expected lower rates
|
||
(gdb) set_log_rate 20 # Reduce noise
|
||
(gdb) continue
|
||
|
||
# Later, switch to 5GHz
|
||
(gdb) Ctrl-C
|
||
(gdb) set_high_nav 5000 # Stricter
|
||
(gdb) set_rate_fallback 100 # Expect higher rates
|
||
(gdb) set_log_rate 1 # Log all
|
||
(gdb) continue</code></pre>
|
||
</section>
|
||
|
||
<section id="troubleshooting">
|
||
<h2>Troubleshooting</h2>
|
||
|
||
<h3>GDB Commands Not Found</h3>
|
||
<p><strong>Symptom:</strong> <code>show_thresholds</code>, <code>tune_sensitive</code>, etc. not recognized</p>
|
||
<p><strong>Solution:</strong> Enable .gdbinit auto-loading</p>
|
||
<pre><code>mkdir -p ~/.config/gdb
|
||
echo "set auto-load safe-path /" >> ~/.config/gdb/gdbinit
|
||
|
||
# Restart GDB
|
||
quit
|
||
idf.py gdb</code></pre>
|
||
|
||
<h3>Compilation Errors</h3>
|
||
<p><strong>Symptom:</strong> Build fails with "has no member named 'mcs'" errors</p>
|
||
<p><strong>Solution:</strong> Make sure you have the latest code from feature/wifi-monitor-mode branch</p>
|
||
<pre><code>git checkout feature/wifi-monitor-mode
|
||
git pull
|
||
cp wifi_monitor.h components/wifi_monitor/
|
||
cp wifi_monitor.c components/wifi_monitor/
|
||
rm -rf build
|
||
idf.py build</code></pre>
|
||
|
||
<h3>No Frames Captured</h3>
|
||
<p><strong>Symptom:</strong> Breakpoint never hits, no frames captured</p>
|
||
<p><strong>Possible Causes:</strong></p>
|
||
<ul>
|
||
<li>WiFi not connected or monitor mode not started</li>
|
||
<li>Wrong channel</li>
|
||
<li>RSSI too low (out of range)</li>
|
||
</ul>
|
||
<p><strong>Solution:</strong> Check monitor mode status</p>
|
||
<pre><code>(gdb) print current_led_state
|
||
# Should be LED_STATE_MONITORING (4)
|
||
|
||
(gdb) print frame->channel
|
||
# Should match your AP's channel</code></pre>
|
||
|
||
<h3>Too Much Logging</h3>
|
||
<p><strong>Symptom:</strong> Serial output floods with mismatch logs</p>
|
||
<p><strong>Solution:</strong> Increase log rate or mismatch threshold</p>
|
||
<pre><code>(gdb) set_log_rate 50 # Log every 50th
|
||
(gdb) set_mismatch_log 20000 # Only log >20ms NAV
|
||
(gdb) continue</code></pre>
|
||
</section>
|
||
|
||
<section id="advanced">
|
||
<h2>Advanced Techniques</h2>
|
||
|
||
<h3>Creating Custom .gdbinit Profiles</h3>
|
||
<p>Add your own tuning profiles to .gdbinit:</p>
|
||
<pre><code>define tune_my_network
|
||
set threshold_high_nav_us = 6500
|
||
set threshold_phy_rate_fallback_mbps = 120
|
||
set log_every_n_mismatches = 5
|
||
printf "Custom profile loaded for my network\n"
|
||
end</code></pre>
|
||
|
||
<h3>Logging Frame Data to File</h3>
|
||
<pre><code>(gdb) set logging file wifi_frames.log
|
||
(gdb) set logging on
|
||
(gdb) watch_data
|
||
# All output goes to wifi_frames.log</code></pre>
|
||
|
||
<h3>Combining Multiple Conditions</h3>
|
||
<pre><code># Break on: High NAV + Retry + Low RSSI
|
||
(gdb) break monitor_frame_callback if \
|
||
frame->duration_id > 10000 && \
|
||
frame->retry == 1 && \
|
||
frame->rssi < -70
|
||
|
||
# Very specific debugging target</code></pre>
|
||
|
||
<h3>Performance: C Code vs GDB</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Method</th>
|
||
<th>Speed</th>
|
||
<th>Use Case</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>C Code (Running)</strong></td>
|
||
<td>10,000+ frames/sec</td>
|
||
<td>Continuous monitoring, production</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>GDB (Breakpoints)</strong></td>
|
||
<td>~10 frames/sec</td>
|
||
<td>Interactive inspection, debugging</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>GDB (Threshold Tuning)</strong></td>
|
||
<td>Full speed</td>
|
||
<td>Runtime configuration, no overhead</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div class="alert alert-success">
|
||
<strong>Best of Both Worlds:</strong> Use C code for real-time detection, GDB for threshold tuning and deep inspection. You get full performance with complete flexibility!
|
||
</div>
|
||
</section>
|
||
|
||
<section id="resources">
|
||
<h2>Resources</h2>
|
||
|
||
<h3>Git Repository</h3>
|
||
<pre><code># Clone repository
|
||
git clone https://github.com/yourusername/esp32-iperf.git
|
||
cd esp32-iperf
|
||
|
||
# Checkout WiFi monitor branch
|
||
git checkout feature/wifi-monitor-mode</code></pre>
|
||
|
||
<h3>Key Files</h3>
|
||
<ul>
|
||
<li><code>components/wifi_monitor/wifi_monitor.c</code> - Frame capture implementation</li>
|
||
<li><code>components/wifi_monitor/wifi_monitor.h</code> - API definitions</li>
|
||
<li><code>main/main.c</code> - Monitor mode integration</li>
|
||
<li><code>.gdbinit</code> - GDB commands for WiFi debugging</li>
|
||
</ul>
|
||
|
||
<h3>Documentation Files</h3>
|
||
<ul>
|
||
<li><code>GDB_THRESHOLD_TUNING_GUIDE.md</code> - Complete threshold tuning guide</li>
|
||
<li><code>DURATION_ANALYSIS_GUIDE.md</code> - Duration analysis details</li>
|
||
<li><code>C_DURATION_ANALYSIS_GUIDE.md</code> - C code implementation guide</li>
|
||
<li><code>COMPILATION_FIX_GUIDE.md</code> - Troubleshooting build issues</li>
|
||
<li><code>WIFI_MONITOR_MODE_GUIDE.md</code> - Full WiFi monitor documentation</li>
|
||
</ul>
|
||
|
||
<h3>External Resources</h3>
|
||
<ul>
|
||
<li><a href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32c5/api-guides/jtag-debugging/">ESP-IDF JTAG Debugging Guide</a></li>
|
||
<li><a href="https://sourceware.org/gdb/documentation/">GDB Documentation</a></li>
|
||
<li><a href="https://standards.ieee.org/ieee/802.11/7028/">IEEE 802.11 Standard</a></li>
|
||
</ul>
|
||
|
||
<h3>Quick Reference</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Command</th>
|
||
<th>Purpose</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>show_thresholds</code></td>
|
||
<td>Display current thresholds</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>tune_sensitive</code></td>
|
||
<td>Strict thresholds (catch more)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>tune_normal</code></td>
|
||
<td>Default balanced settings</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>tune_relaxed</code></td>
|
||
<td>Lenient thresholds (fewer alerts)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>set_high_nav <us></code></td>
|
||
<td>Set high NAV threshold</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>set_rate_fallback <mbps></code></td>
|
||
<td>Set rate fallback threshold</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>set_log_rate <n></code></td>
|
||
<td>Log every Nth mismatch</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>show_frame_full</code></td>
|
||
<td>Complete frame analysis</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>show_duration</code></td>
|
||
<td>Quick duration comparison</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>watch_data</code></td>
|
||
<td>Monitor DATA frames</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>find_mismatch</code></td>
|
||
<td>Auto-break on NAV mismatches</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<footer style="margin-top: 60px; padding-top: 30px; border-top: 2px solid var(--border-color); text-align: center; color: #666;">
|
||
<p><strong>ESP32-C5 GDB Debugging Guide - WiFi Monitor Mode Edition</strong></p>
|
||
<p>© 2025 Bob McMahon | Created for ESP32-C5 WiFi Analyzer Development</p>
|
||
<p>
|
||
<a href="https://github.com/yourusername/esp32-iperf" class="button">View on GitHub</a>
|
||
<a href="https://docs.espressif.com/" class="button">ESP-IDF Docs</a>
|
||
</p>
|
||
</footer>
|
||
</main>
|
||
</body>
|
||
</html>
|