Skip to content

refactor OpenOCD Call CMD#416

Merged
Jason2866 merged 11 commits into
developfrom
refac_ocd_debug
Mar 6, 2026
Merged

refactor OpenOCD Call CMD#416
Jason2866 merged 11 commits into
developfrom
refac_ocd_debug

Conversation

@Jason2866
Copy link
Copy Markdown

@Jason2866 Jason2866 commented Mar 6, 2026

Description:

Checklist:

  • The pull request is done against the latest develop branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR, more changes are allowed when changing boards.json
  • I accept the CLA

Summary by CodeRabbit

  • Bug Fixes

    • More robust OpenOCD upload resolution and invocation to avoid failures and handle executable/path quoting.
  • Improvements

    • Broader detection of debug tooling, automatic SVD file discovery, safer app-offset handling with warnings when metadata is missing.
  • New Features

    • Added debug metadata (OpenOCD board identifiers) to many ESP32 board definitions to simplify hardware debug setup.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fc05fe60-a4c9-43c6-a1c9-09a72e8015fb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Recomputes OpenOCD executable/args for ESP32 upload, tightens uploader quoting, expands debug-tool detection and svd_path auto-fill, reads application_offset from build metadata with fallback, and adds/updates debug.openocd_board entries across many ESP32 board manifests.

Changes

Cohort / File(s) Summary
Builder: OpenOCD & uploader
builder/main.py
Derive openocd_executable from tool-openocd-esp32 when present; substitute or strip $PACKAGE_DIR in openocd_args; fallback to "openocd" if package absent; set UPLOADER to computed path and quote UPLOADCMD ("\"$UPLOADER\" $UPLOADERFLAGS").
Platform: debug & metadata
platform.py
_needs_debug_tools() also checks debug_tool; _add_dynamic_options() auto-assigns debug.svd_path from misc/svd/<mcu>.svd if available; configure_debug_session() early-returns when load_cmds != ["load"], warns on missing flash_images, reads application_offset from build metadata with warning/fallback, and uses resolved app_offset in load commands.
Board manifests: add/modify debug.openocd_board
boards/*.json (e.g. boards/bpi-bit.json, boards/denky32.json, boards/esp32-*.json, boards/m5stack-*, boards/tinypico.json, ...)
Add top-level debug object with openocd_board (mostly "esp-wroom-32.cfg", some "esp32-wrover.cfg"); a few manifests update existing debug.openocd_board values. Review board-specific filenames for correctness.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I hopped the package paths at dawn,
Tweaked args where $PACKAGE_DIR had drawn,
I sniffed for SVDs and set offsets true,
Quoted uploaders, nudged configs through,
A tidy hop — debug boards now have a view. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'refactor OpenOCD Call CMD' is vague and lacks specificity about the actual changes made. While it references OpenOCD, it doesn't convey the full scope of improvements including argument handling, board debug configurations, or path resolution. Consider revising the title to be more descriptive, such as 'Improve OpenOCD executable and argument handling with package path resolution' or similar, to better reflect the substantive changes across multiple files.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refac_ocd_debug

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jason2866
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

✅ Actions performed

Full review triggered.

@Jason2866
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@builder/main.py`:
- Around line 1863-1874: The code builds openocd_executable from openocd_pkg_dir
which becomes "" when platform.get_package_dir("tool-openocd-esp32") is missing,
producing a relative "bin/openocd" and preventing PATH lookup; change the logic
around openocd_pkg_dir/openocd_executable so that if openocd_pkg_dir is falsy
(after _to_unix_slashes/get_package_dir) you set openocd_executable to the
literal "openocd" to allow PATH resolution, otherwise set it to
str(Path(openocd_pkg_dir) / "bin" / "openocd"); keep the UPLOADER/UPLOADERFLAGS
env.Replace usage but reference the updated openocd_executable and ensure any
$PACKAGE_DIR replacement in openocd_args still works when openocd_pkg_dir is
empty.

In `@platform.py`:
- Around line 835-839: The current code writes svd_path into an initially empty
debug dict (debug["svd_path"] = ...), which makes debug truthy and causes the
method to advertise debug capabilities and later produce invalid fallback args
in _get_debug_server_args(); change the assignment to only set svd_path when
debug already contains other data (e.g., if debug and not debug.get("svd_path"):
...), or otherwise check for meaningful debug keys (like
openocd_board/openocd_target) before mutating debug in the method that calls
get_dir()/svd lookup so empty debug blocks remain falsey.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff45581a-1e47-487d-814e-795b8cea0bdc

📥 Commits

Reviewing files that changed from the base of the PR and between f94b340 and 4d1aca6.

📒 Files selected for processing (2)
  • builder/main.py
  • platform.py

Comment thread builder/main.py
Comment thread platform.py
@Jason2866
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
platform.py (1)

929-939: ⚠️ Potential issue | 🟡 Minor

Avoid a misleading fallback warning for custom load flows.

Lines 935-939 warn on any early return, but one of those conditions is debug_config.load_cmds != ["load"]. Boards like arduino_nano_esp32 intentionally override load_cmds, so this now logs “flash_images metadata missing or incomplete” even when the metadata is fine. Split the custom-load case from the missing/incomplete-metadata cases and only warn for the latter.

💡 Suggested adjustment
-        ignore_conds = [
-            debug_config.load_cmds != ["load"],
-            not flash_images,
-            not all([Path(item["path"]).is_file() for item in flash_images]),
-        ]
-
-        if any(ignore_conds):
-            logger.warning(
-                "Falling back to default GDB load; "
-                "flash_images metadata missing or incomplete."
-            )
-            return
+        if debug_config.load_cmds != ["load"]:
+            return
+
+        if not flash_images or not all(
+            Path(item["path"]).is_file() for item in flash_images
+        ):
+            logger.warning(
+                "Falling back to default GDB load; "
+                "flash_images metadata missing or incomplete."
+            )
+            return
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platform.py` around lines 929 - 939, The warning is emitted whenever any
condition in ignore_conds is true, so boards that intentionally set a custom
load flow (debug_config.load_cmds != ["load"]) trigger a misleading
"flash_images metadata missing" warning; change the logic to treat the
custom-load case separately: first check if debug_config.load_cmds != ["load"]
and if so skip the warning/early-return for custom flows, otherwise evaluate the
metadata-related conditions (not flash_images or not
all(Path(item["path"]).is_file() for item in flash_images)) and only call
logger.warning when one of those metadata conditions is true. Keep references to
ignore_conds, debug_config.load_cmds, flash_images and the existing
logger.warning call so behavior and messages remain consistent.
♻️ Duplicate comments (1)
builder/main.py (1)

1863-1873: ⚠️ Potential issue | 🟠 Major

PATH fallback still leaves OpenOCD with a broken script search path.

Lines 1866-1868 still replace $PACKAGE_DIR even when platform.get_package_dir("tool-openocd-esp32") is missing. That turns "$PACKAGE_DIR/share/openocd/scripts" into /share/openocd/scripts, so the new "openocd" fallback at Lines 1870-1873 still cannot resolve the interface/board cfgs. Only substitute $PACKAGE_DIR when the package dir exists; otherwise drop that -s .../share/openocd/scripts pair and let the PATH-provided OpenOCD use its own default scripts directory.

🛠️ Suggested fix
-    openocd_args = [
-        f.replace("$PACKAGE_DIR", openocd_pkg_dir)
-        for f in openocd_args
-    ]
-    if openocd_pkg_dir:
-        openocd_executable = str(Path(openocd_pkg_dir) / "bin" / "openocd")
-    else:
-        openocd_executable = "openocd"
+    if openocd_pkg_dir:
+        openocd_args = [
+            f.replace("$PACKAGE_DIR", openocd_pkg_dir)
+            for f in openocd_args
+        ]
+        openocd_executable = str(Path(openocd_pkg_dir) / "bin" / "openocd")
+    else:
+        filtered_args = []
+        skip_next = False
+        for index, arg in enumerate(openocd_args):
+            if skip_next:
+                skip_next = False
+                continue
+            if (
+                arg == "-s"
+                and index + 1 < len(openocd_args)
+                and "$PACKAGE_DIR" in openocd_args[index + 1]
+            ):
+                skip_next = True
+                continue
+            filtered_args.append(arg)
+        openocd_args = filtered_args
+        openocd_executable = "openocd"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@builder/main.py` around lines 1863 - 1873, The current logic always replaces
"$PACKAGE_DIR" in openocd_args even when
platform.get_package_dir("tool-openocd-esp32") returns empty, producing paths
like "/share/openocd/scripts" that break the PATH fallback; change the handling
around openocd_pkg_dir/openocd_args so that you only perform the
f.replace("$PACKAGE_DIR", openocd_pkg_dir) when openocd_pkg_dir is truthy, and
when it is falsy filter out any argument entries that reference "$PACKAGE_DIR"
(or the "-s" + "$PACKAGE_DIR/.../scripts" pair) so the fallback
openocd_executable = "openocd" can use its own default script search paths;
update code locations referencing openocd_pkg_dir, openocd_args and
openocd_executable accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@platform.py`:
- Around line 929-939: The warning is emitted whenever any condition in
ignore_conds is true, so boards that intentionally set a custom load flow
(debug_config.load_cmds != ["load"]) trigger a misleading "flash_images metadata
missing" warning; change the logic to treat the custom-load case separately:
first check if debug_config.load_cmds != ["load"] and if so skip the
warning/early-return for custom flows, otherwise evaluate the metadata-related
conditions (not flash_images or not all(Path(item["path"]).is_file() for item in
flash_images)) and only call logger.warning when one of those metadata
conditions is true. Keep references to ignore_conds, debug_config.load_cmds,
flash_images and the existing logger.warning call so behavior and messages
remain consistent.

---

Duplicate comments:
In `@builder/main.py`:
- Around line 1863-1873: The current logic always replaces "$PACKAGE_DIR" in
openocd_args even when platform.get_package_dir("tool-openocd-esp32") returns
empty, producing paths like "/share/openocd/scripts" that break the PATH
fallback; change the handling around openocd_pkg_dir/openocd_args so that you
only perform the f.replace("$PACKAGE_DIR", openocd_pkg_dir) when openocd_pkg_dir
is truthy, and when it is falsy filter out any argument entries that reference
"$PACKAGE_DIR" (or the "-s" + "$PACKAGE_DIR/.../scripts" pair) so the fallback
openocd_executable = "openocd" can use its own default script search paths;
update code locations referencing openocd_pkg_dir, openocd_args and
openocd_executable accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 884daafa-b356-4f67-9f7d-10dd230045e8

📥 Commits

Reviewing files that changed from the base of the PR and between f94b340 and cc7b320.

📒 Files selected for processing (2)
  • builder/main.py
  • platform.py

@Jason2866
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@boards/m5stack-fire.json`:
- Around line 25-27: The debug.openocd_board value is wrong for this
PSRAM-equipped board: because the file contains BOARD_HAS_PSRAM and PSRAM cache
fix flags, update the "openocd_board" entry (the debug.openocd_board key in the
m5stack-fire.json diff) from "esp-wroom-32.cfg" to "esp32-wrover.cfg" to match
other PSRAM boards (e.g., m5stack_paper and m5stack-core2).

In `@builder/main.py`:
- Around line 1873-1886: The loop that filters openocd_args is currently
discarding every "-s <path>" pair; change it so only "-s" entries whose path
contains "$PACKAGE_DIR" (e.g. the generated
"$PACKAGE_DIR/share/openocd/scripts") are removed while preserving other "-s
<path>" pairs; specifically update the logic around the variables openocd_args,
filtered and skip_next to check the next token when encountering "-s" and only
set skip_next/continue when that next token contains "$PACKAGE_DIR" (otherwise
append both "-s" and its path to filtered), then assign openocd_args = filtered
and leave openocd_executable = "openocd" as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d32e48af-6908-4800-97fa-fd82c0bce47f

📥 Commits

Reviewing files that changed from the base of the PR and between f94b340 and 9977419.

📒 Files selected for processing (58)
  • boards/bpi-bit.json
  • boards/cnrs_aw2eth.json
  • boards/denky32.json
  • boards/denky_d4.json
  • boards/esp32-pico-devkitm-2.json
  • boards/esp32-poe-iso.json
  • boards/esp32-poe.json
  • boards/esp32-pro.json
  • boards/esp320.json
  • boards/espea32.json
  • boards/etboard.json
  • boards/healthypi4.json
  • boards/heltec_wifi_kit_32.json
  • boards/heltec_wifi_kit_32_v2.json
  • boards/heltec_wireless_stick_lite.json
  • boards/imbrios-logsens-v1p1.json
  • boards/inex_openkb.json
  • boards/intorobot.json
  • boards/kits-edu.json
  • boards/labplus_mpython.json
  • boards/lilygo-t-display.json
  • boards/m5stack-atom.json
  • boards/m5stack-core-esp32-16M.json
  • boards/m5stack-core-esp32.json
  • boards/m5stack-core2.json
  • boards/m5stack-coreink.json
  • boards/m5stack-fire.json
  • boards/m5stack-grey.json
  • boards/m5stack-station.json
  • boards/m5stack-timer-cam.json
  • boards/m5stack_paper.json
  • boards/m5stamp-pico.json
  • boards/m5stick-c.json
  • boards/magicbit.json
  • boards/mgbot-iotik32a.json
  • boards/mgbot-iotik32b.json
  • boards/microduino-core-esp32.json
  • boards/nano32.json
  • boards/nina_w10.json
  • boards/nscreen-32.json
  • boards/odroid_esp32.json
  • boards/onehorse32dev.json
  • boards/oroca_edubot.json
  • boards/piranha_esp32.json
  • boards/pycom_gpy.json
  • boards/qchip.json
  • boards/quantum.json
  • boards/roboheart_hercules.json
  • boards/s_odi_ultra.json
  • boards/sparkfun_esp32micromod.json
  • boards/tinypico.json
  • boards/ttgo-t-watch.json
  • boards/ttgo-t7-v13-mini32.json
  • boards/turta_iot_node.json
  • boards/widora-air.json
  • boards/wifiduino32.json
  • builder/main.py
  • platform.py

Comment thread boards/m5stack-fire.json
Comment thread builder/main.py
@Jason2866
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 6, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@platform.py`:
- Around line 626-627: The current logic calls an OpenOCD installer
unconditionally when _needs_debug_tools() is true; update it so
tool-openocd-esp32 is installed only when the configured debug tool actually
requires OpenOCD. Concretely, check variables.get("debug_tool") and/or
variables.get("upload_protocol") for values that map to OpenOCD (e.g., "openocd"
or whatever upload_protocol you treat as OpenOCD) before invoking the
installation of tool-openocd-esp32, while leaving _needs_debug_tools() as the
broader gate for any debug-tool-related setup.
- Around line 929-930: The guard currently compares debug_config.load_cmds to
the exact list ["load"] which fails when load_cmds is a string (e.g., "preload")
or other shapes; update the check in platform.py to normalize load_cmds (e.g.,
coerce to a list or treat string as single-item list) or test the semantic value
(e.g., check if "load" is in load_cmds when treated as an iterable) before
returning so the flash-image loading code runs when the effective load command
is "load" regardless of whether debug_config.load_cmds is a string or a list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4cc72320-ee8e-42f8-9113-0214bb183df6

📥 Commits

Reviewing files that changed from the base of the PR and between f94b340 and 850e56b.

📒 Files selected for processing (65)
  • boards/adafruit_feather_esp32_v2.json
  • boards/adafruit_itsybitsy_esp32.json
  • boards/adafruit_qtpy_esp32.json
  • boards/bpi-bit.json
  • boards/cnrs_aw2eth.json
  • boards/denky32.json
  • boards/denky_d4.json
  • boards/esp32-pico-devkitm-2.json
  • boards/esp32-poe-iso.json
  • boards/esp32-poe.json
  • boards/esp32-pro.json
  • boards/esp320.json
  • boards/esp32cam.json
  • boards/espea32.json
  • boards/etboard.json
  • boards/healthypi4.json
  • boards/heltec_wifi_kit_32.json
  • boards/heltec_wifi_kit_32_v2.json
  • boards/heltec_wireless_stick_lite.json
  • boards/imbrios-logsens-v1p1.json
  • boards/inex_openkb.json
  • boards/intorobot.json
  • boards/ioxesp32ps.json
  • boards/kb32-ft.json
  • boards/kits-edu.json
  • boards/labplus_mpython.json
  • boards/lilygo-t-display.json
  • boards/m5stack-atom.json
  • boards/m5stack-core-esp32-16M.json
  • boards/m5stack-core-esp32.json
  • boards/m5stack-core2.json
  • boards/m5stack-coreink.json
  • boards/m5stack-fire.json
  • boards/m5stack-grey.json
  • boards/m5stack-station.json
  • boards/m5stack-timer-cam.json
  • boards/m5stack_paper.json
  • boards/m5stamp-pico.json
  • boards/m5stick-c.json
  • boards/magicbit.json
  • boards/mgbot-iotik32a.json
  • boards/mgbot-iotik32b.json
  • boards/microduino-core-esp32.json
  • boards/nano32.json
  • boards/nina_w10.json
  • boards/nscreen-32.json
  • boards/odroid_esp32.json
  • boards/onehorse32dev.json
  • boards/oroca_edubot.json
  • boards/piranha_esp32.json
  • boards/pycom_gpy.json
  • boards/qchip.json
  • boards/quantum.json
  • boards/roboheart_hercules.json
  • boards/s_odi_ultra.json
  • boards/sparkfun_esp32micromod.json
  • boards/tinypico.json
  • boards/ttgo-t-beam.json
  • boards/ttgo-t-watch.json
  • boards/ttgo-t7-v13-mini32.json
  • boards/turta_iot_node.json
  • boards/widora-air.json
  • boards/wifiduino32.json
  • builder/main.py
  • platform.py

Comment thread platform.py Outdated
Comment thread platform.py
@Jason2866 Jason2866 merged commit 870b264 into develop Mar 6, 2026
1 check passed
@Jason2866 Jason2866 deleted the refac_ocd_debug branch March 7, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant