Proof of Concept for Hardware-Level JTAG Debugging on the ESP32.
Required: ESP32 DevKit V1 + ESP-Prog JTAG Adapter.
| Signal | ESP-Prog | ESP32 |
|---|---|---|
| TDI | TDI | GPIO 12 |
| TCK | TCK | GPIO 13 |
| TMS | TMS | GPIO 14 |
| TDO | TDO | GPIO 15 |
| GND | GND | GND |
-
Flash Firmware (PlatformIO/VS Code):
Cmd + Shift + P->PlatformIO: Upload
-
Start Debugging:
- Select "PIO Debug" (or ESP32 JTAG) in Run & Debug.
- Press F5.
-
The Hack:
- Pause execution.
- Debug Console:
set var g_false_positive_detected = 1 - Continue.
- Result:
[TRAP] False Positive Detected!
If OpenOCD fails with libusb_open() failed, macOS might be blocking the connection.
- Go to System Settings > Privacy & Security.
- Look for "Allow accessories to connect".
- Set to "Always" or "Ask for New Accessories".
- If prompted when plugging in ESP-PROG, click Allow.
- Open this folder in VS Code with PlatformIO installed.
- Build the "Debug" Firmware:
pio run -e esp32doit-devkit-v1
- Upload Firmware (via JTAG):
Note: Ensure ESP-PROG is connected. If upload fails, check wiring.
pio run -t upload
We will now catch the code execution in the act of a False Positive.
- In VS Code, go to the Run & Debug Activity Bar (Side Panel).
- Select "PIO Debug" configuration at the top.
- Press Green Play Button (Start Debugging).
- The status bar will turn orange. OpenOCD will launch.
- The code will HALT automatically at
setup()(as defined inplatformio.ini).
- Set the Trap:
- Open
src/main.cpp. - Scroll to the line inside
if (g_false_positive_detected)around line 92 (Serial.println("[TRAP]...")). - Click to the left of the line number to Set Breakpoint (Red Dot).
- Open
- Resume Execution:
- Press the Continue (Play) button in the floating debug toolbar.
- The code is now running at 50Hz.
- Trigger the Trap:
- Quickly TAP the GPIO 4 pin (Touch 0) with your finger. Do NOT hold it.
- A quick tap creates a spike (Raw Signal) but usually fails to pull the Moving Average up fast enough.
- RESULT: The debugger should PAUSE execution at your breakpoint.
- Inspect:
- Look at the VARIABLES pane on the left.
- Expand
Global. - Observe
g_signal_strength(likely > 40) vsg_filtered_signal(likely < 40). - You have strictly proven a noise artifact occurred.
New Feature: You can intentionally break the code at any time using the hardware.
- Ensure the debugger is running (Play button).
- Press the BOOT button on the ESP32 DevKit.
- The code will immediately HALT inside the
loop()function. - The Serial Monitor will print:
[DEBUG] Manual Interrupt Triggered via BOOT Button. - This confirms your interrupt service routines (ISRs) and JTAG control are working perfectly in tandem.
Open simulation.html in any browser to visualize the algorithm logic without hardware strings attached.