Skip to main content
Use XMOS XTC Tools with an xTAG to debug an xcore board. You can load the application’s .xe and stop at main, attach to a program that is already running, inspect tiles, threads, registers, memory, and stacks, and program persistent boot flash. To debug without a board, see XMOS xsim.

Prepare

  1. Install XMOS XTC Tools on the machine connected to the board. Embedder uses xrun, xgdbserver, and xgdb for debugging, and xflash for boot flash.
  2. Connect the xTAG to the board and to USB, then power the board.
  3. Build the application’s .xe with debug information. Note its path relative to the project root.
  4. Make sure the project targets your XMOS board, or that it has a .embedder/xmos.json (see Select the application and target). Embedder lists xTAGs only for XMOS projects.
  5. Switch to Debug mode with /debug. Ask Embedder to check XTC Tools and list the attached xTAGs.
Each xTAG is reported with its adapter ID and a state. Only a ready adapter can be used. Fix an adapter reported as in_use, invalid_firmware, none, or unknown before you connect (see Troubleshoot). You can also list adapters yourself with xrun -l.

Where Embedder finds XTC Tools

Embedder uses the first XTC installation it finds, in this order: If the first of sources 1 to 3 that’s set points at a folder that doesn’t exist, Embedder reports XTC Tools as not found. It doesn’t fall back to the later sources. If the installation it picks is missing a tool Embedder needs, the error names the missing tools. Point EMBEDDER_XTC_PATH at a complete installation. Set environment variables before you start Embedder. In VS Code, run Embedder: Restart CLI Server after you change the tool path.

Select the application and target

Put the application and target in .embedder/xmos.json at the project root:
.embedder/xmos.json
Replace bin/app.xe with your artifact path and YOUR_XTAG_ID with the ID of the adapter you want. Choosing an app in the Monitor’s App (.xe) list saves the same xe setting. XMOS lists every field in this file. Embedder resolves the target the same way for every XMOS request: When xe isn’t set, or the file it names doesn’t exist, Embedder uses the newest .xe in the project without warning. Set xe whenever the project builds more than one application, and correct it when you move the build output. XMOS settings in EMBEDDER.md, such as xmos_xe or xmos_adapter_id, are no longer read. Embedder shows a notice naming any it finds; move them to .embedder/xmos.json.

Load and inspect

Ask Embedder to start a debug run:
A normal hardware connection resets the target, loads the .xe, and runs to main. If main isn’t reached within about five seconds, Embedder halts the target where it is. The first connection to an xTAG can take up to a minute while the adapter loads its firmware. Starting a debug session takes the xTAG over from any other xgdbserver started from the same XTC Tools installation. If the xTAG still reports that it’s in use, Embedder retries once after two seconds. Loading for debugging replaces the running program but doesn’t change boot flash. To change what the board boots, see Program persistent boot flash. You can then ask for tile selection, breakpoints, stepping, threads, registers, memory, and stack frames. Name the tile when you investigate code that runs across tiles. A stop on one tile doesn’t describe what the others were doing.

Live and real-time applications

xgdb is all-stop. Connecting, an interrupt, a breakpoint hit, and a run-control timeout each halt every logical core on every tile until the next resume. While the chip is halted, USB stops answering the host and the host drops the device. I²S, TDM, and other port-driven streams also stop, so an external codec loses sync. Treat any value or host-side result captured across a stop as coming from a restarted stream.
xgdb can’t set breakpoints or read registers, memory, or expressions while the target runs. Every read needs a stop. On hardware that serves USB or audio, choose the method by what must keep running: Don’t loop on breakpoints in a sample loop, a USB endpoint task, or an audio callback to collect values. On the xsim simulator, a stop is harmless because no host or codec is waiting.

Use a hardware script

For repeatable checks, connect from a hardware script with gdb.xmos_connect(...): A debugger connection opened in a script is disconnected when the script finishes.

Program persistent boot flash

  1. Build the .xe for the exact board and its boot-flash layout.
  2. Confirm "target": "hardware" and the intended adapterId in .embedder/xmos.json.
  3. If the project’s flashing procedure needs a board-specific .xn target file or a boot partition size, set them under flash in .embedder/xmos.json as targetFile and bootPartitionSize, or give them in your request. Don’t guess a partition size.
  4. Ask Embedder to program the image. Name the .xe in the request; Embedder doesn’t take the flash image from .embedder/xmos.json.
  5. After programming succeeds, power-cycle the board according to its instructions. Check a boot indicator or an independent output such as UART, and confirm the firmware’s expected startup behavior before you start another debug or xSCOPE run.
Programming replaces the board’s flash contents without a confirmation prompt from xflash. Embedder first closes the Monitor’s xSCOPE connections and any debugger session holding the xTAG.
Programming times out after ten minutes by default. A successful result means xflash exited successfully. It doesn’t show that the board booted the new image. If you ask for output right after flashing, Embedder runs the .xe again from RAM to capture xSCOPE output. That output confirms the RAM run, not a boot from flash. Later, if you ask for output without naming an .xe, Embedder runs the image it flashed rather than the xe in .embedder/xmos.json. With "target": "simulator", the same request reloads the simulator and doesn’t program a board. See Flashing firmware for other targets.

Attach to an existing run

Ask for an attach-only connection to keep the program that is running. Attaching skips the load and the reset. In a script, use attach=True and run_to_main=False with the .xe that matches the running program. Attaching still halts every tile, so it interrupts live USB and audio streams. See Live and real-time applications. no_halt=True resumes the target right after connecting. It doesn’t mean the target was never stopped, and it can resume a target that had already halted on a fault. State whether the target must stay halted or may continue, and follow the attachment precautions.

Read output and finish

Use the xSCOPE Monitor for application output. A Monitor connection that matches an active hardware debug session can reuse that session’s console instead of launching the application again; the Monitor then shows Attached to xgdbserver console. Check which application and target the Monitor is following before you treat output as evidence. When you’re done, ask Embedder to disconnect and state whether execution should continue.

Troubleshoot

  • XTC Tools not found: check the installation and the sources in Where Embedder finds XTC Tools, including any path variable that points at a missing folder, then restart Embedder.
  • No xTAG found: check the USB cable, board power, and USB access, then list adapters with xrun -l.
  • xTAG in use: another process holds the adapter, such as xrun, an xSCOPE Monitor connection, or a debugger from another XTC Tools installation. Stop it and retry.
  • Invalid firmware: unplug and replug the xTAG so XTC Tools reload its firmware, or update XTC Tools.
  • xTAG listed with no devices (none): the adapter is attached but sees no target. Check board power and the xTAG-to-board connection.
  • Several xTAGs found: set adapterId to the intended adapter’s ID.
  • xTAG not found by ID: the adapterId doesn’t match an attached, ready adapter. Compare it with the IDs from xrun -l, and check that nothing else is using it.
  • Connection timed out: the first connection can be slow while the xTAG loads its firmware. Retry once, then check board power and the USB link.
  • No .xe found, wrong symbols, or an unexpected application runs: build the application and correct the xe path in .embedder/xmos.json.
  • Breakpoint or variable unavailable: check the selected tile, symbol information, and compiler optimization.
  • xgdbserver reports Xcore N is not enabled: the debugger’s own reset doesn’t clear this state. Power-cycle the board, then retry the connection.
  • A simulated run was selected by mistake: set target to hardware and verify the adapter before restarting.
Last modified on October 13, 2026