Skip only @response-file flags under IDF_TOOLCHAIN_BUILD_DIR using
quote-aware parse and cmake_path(IS_PREFIX). Cache the toolchain build
dir as REALPATH so prefix checks compare against a stable path spelling.
Include esp_hal_cache so the G1-restricted build still pulls in the
cache HAL after it was extracted from the generic HAL.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove the EXAMPLE_LCD_IMAGE_SOURCE Kconfig option (embedded binary vs
file system) and always load images from LittleFS.
- Convert the PNG images into LZ4-compressed LVGL binary images (.bin)
at
build time using LVGLImage.py, and flash them to a LittleFS partition.
- Upgrade lvgl to 9.6.0 and add the espressif/lz4 component; link the
external LZ4 library into lvgl.
- Split the example: main.c focuses on the esp_lcd i80 API, while the
LVGL
porting (lvgl_port.c) and the UI (lvgl_demo_ui.c) live in separate
files.
- Rework the demo animation to use the LVGL animation engine (lv_anim)
with
easing paths instead of a manual software timer for smoother
rendering.
- Remove the embedded C image arrays (esp_logo.c, esp_text.c) and the
obsolete sdkconfig.ci.image_in_{bin,fs} variants.
Relative CI_PROJECT_DIR after cd nested --work-dir under tools/test_build_system
and blew MAX_PATH. Save failed-command output next to artifacts instead of
streaming a 12 KB record that still hangs shard 3/6.
Co-authored-by: Cursor <cursoragent@cursor.com>
git worktree add leaves every submodule as an empty directory, and the
copy loop skipped any submodule it could not read from the source repo.
The placeholder then stayed in the copy and the build failed much later
in an unrelated component, as a missing mbedtls/include or tlsf.c
Check each submodule in the destination after copying it. If one is
still a placeholder, drop the worktree and create the copy with
shutil.copytree, which does not depend on the submodule state of the source checkout
Migrate the MCP server extension to the shared esp-pylib library:
- replace raw stderr prints with esp_pylib.logger.log (note/err)
- route informational logs to stderr via set_info_stream so stdout
stays reserved for the MCP JSON-RPC transport
- enumerate connected devices via esp_pylib.serial_ports.get_port_names
- stub the new imports in the mcp_ext unit tests
Co-authored-by: Cursor <cursoragent@cursor.com>
Add a `monitor_device` MCP tool that lets an AI agent run a scripted,
non-interactive `esp-idf-monitor` session against a flashed device and
get back a short status plus a log file path, instead of raw serial
output inline.
Under the hood:
- The agent supplies a plain-text command body (expect/send/sleep/reset/
exit/comments). `assemble_monitor_script_from_agent_commands()` frames
it into a script the monitor's non-interactive command mode can
consume via stdin: it appends `exit` if the agent didn't already end
with one, and rewrites every bare `expect <regex>` into `expect
--timeout <timeout_sec> <regex>` via `_monitor_normalize_expect_line()`
(an already-bounded `expect --timeout ...` line is left untouched so
the monitor itself reports a bad value). A leading `reset` is not
prepended - the monitor already resets the chip when it opens the
port - and any `reset` the agent wrote is left in place.
`_monitor_parse_sleep_duration()` extracts each `sleep <n>` duration.
The effective timeout is the sum of every bounded expect duration
plus every sleep duration. Scripts whose sum exceeds
`MONITOR_MAX_SCRIPT_SEC` are rejected. If the script has neither
expect nor sleep (for example only `send`), `timeout_sec` is used so
the process still has a kill bound.
- `monitor_device()` runs `python -m esp_idf_monitor` via
`subprocess.run(..., input=script, timeout=2 * effective_timeout)`.
`no_reset` is forwarded as `--no-reset` so the connection reset can be
skipped; an explicit `-p` is forwarded when a port is given. Extra
arguments match `idf.py monitor` where a build exists: baud (`baud`
tool arg, else `monitor_baud` from `project_description.json`),
toolchain prefix, `--target`/`--revision`, coredump/panic decode, and
ELF files with the app ELF first. The 2x hard timeout is a safety net
independent of the script's own `expect --timeout`/`exit` logic; on
`TimeoutExpired` the process is killed but any output already captured
is preserved and logged. `decode_stream()` normalizes that captured
output, which can be `bytes` on the timeout path even though the
process otherwise runs in text mode.
- The monitor's exit code drives the reported status via
`_monitor_status()`, using `EXIT_EXPECT_TIMEOUT` and
`EXIT_SCRIPT_ERROR` from `esp_idf_monitor.base.constants`: 0 is
success, 110 means an `expect` pattern never showed up before its
`--timeout` elapsed, 2 means the monitor rejected the script (bad
syntax/timeout/regex), anything else is reported generically.
- Serial output and the monitor's own messages share one pipe
(`stderr=STDOUT`) so decoded panic backtraces stay next to the lines
that triggered them. `_save_monitor_output()` writes the full merge to
`<tempdir>/esp_idf_mcp_log/action_monitor/monitor_<timestamp>.log` and
reports a dedicated `Log file:` line. On non-zero exit or process
kill, a short tail of that same merge is also returned inline so the
agent has some failure context without a second file read. If the log
file can't be written, it falls back to inlining a truncated tail.
Closes https://github.com/espressif/esp-idf/issues/18757
Closes https://github.com/espressif/esp-idf/pull/18385
Co-authored-by: Cursor <cursoragent@cursor.com>
change: the light-sleep test so an internal-RAM helper task enters light sleep while the PSRAM-stacked Unity task is blocked.Verifies that light sleep succeeds and that the PSRAM-stacked task resumes correctly afterward.Removes the unreliable sleep-callback counter check.
The DRAM and RTC_FAST execute cases race the CPU exception against the PMS or
cache interrupt on ESP32-S3 too, so the panic reason is not deterministic.
__generate_gdbinit wrote into a single shared directory and derived the
application ELF from a global property, so a project building multiple
executables had their gdbinit files overwrite each other. Take the ELF
path and output directory as arguments, and derive them per executable in
idf_build_generate_metadata.
change(build): drop BUILD_COMPONENTS support and migrate test_apps to not use it for buildv2
Closes IDF-15859
See merge request espressif/esp-idf!51695
Auto-detect used to pick the first Espressif device, even when it did
not match IDF_TARGET. With several boards attached, flash/monitor could
talk to the wrong chip.
Pass the project target into esptool so unmatched ports are skipped.
Resolve the port after ensure_build_directory() so the target is known.
For monitor on an unconfigured project, probe the connected chip and
pass it directly to idf_monitor without configuring the project.