CLI
Documentation

Version Latest

Firmware and hardware environments

The CLI's optional embedded and hdl environments add firmware and HDL tools. This page covers switching them on, their settings, each tool, flashing safety and maturity.

The CLI has two optional developer environments, the same ones the Editor has:

EnvironmentLabelForTools
embeddedfirmwareCortex-M firmware built with CMake presets (Arm GCC, Arm Compiler 6, IAR)fw_toolchain, fw_build, fw_size, fw_test, fw_flash, fw_serial, fw_fault, fw_debug, fw_import
hdlhardwareFPGA and ASIC designs in Verilog, SystemVerilog and VHDL described by hdl.jsonhdl_project, hdl_lint, hdl_sim
noneEverything else (the default)None

Selecting an environment adds its tools and a short section of the system prompt that tells the agent how to use them; none removes both. The welcome screen shows an Environment cell, and the status bar shows firmware or hardware while one is active.

Maturity

The CLI's firmware and HDL tools reuse the Editor's embedded and HDL modules (tool definitions, CMake presets reader, size report, fault decoder, CTest and Unity parsing, project importer, OpenOCD arguments, GDB/MI layer). Those modules' own records state:

  • Embedded: nothing has been run on a board yet. Flashing through J-Link, ST-LINK (STM32CubeProgrammer) or OpenOCD, and debugging, have integration tests written but not yet run. IAR and Keil projects are not yet run against IAR or Keil.
  • HDL: the open tools are verified on Linux. No vendor path is verified, nothing is verified on Windows, and no board was programmed in the repository's tests.

The CLI's own documentation records no runs against hardware. Do not rely on flashing, debugging or serial tools for production work until they are verified for your probe, target, tools and operating system. See Domain modules for the Editor's state.

Switch an environment on

An environment is a project setting, chosen by hand:

/environment                 # picker in the interactive interface
/environment embedded        # or: firmware, hdl, hardware, none
neuralinverse env            # show the current environment
neuralinverse env set hdl    # set it from a shell (writes .neuralinverse/settings.json)

Or edit .neuralinverse/settings.json:

{ "environment": "embedded" }

Rules:

  • It is never switched on automatically. A folder full of CMake presets, Keil projects or hdl.json still starts with none.
  • It is never stored in user-level settings. ~/.neuralinverse/settings.json cannot set it, and /environment --user and neuralinverse env set --user refuse. Managed policy does not set it either.
  • It applies only in a project folder: a repository, a folder with a build manifest (CMakeLists.txt, Makefile, package.json and similar), or a folder with hdl.json. Not your home folder. Outside a project the setting is ignored and /environment says why.
  • The Editor's switches count. When the CLI setting is absent, neuralInverse.embedded.enabled or neuralInverse.hdl.enabled (or neuralInverse.environment) in the project's .vscode/settings.json select the environment, so a project set up in the Editor works unchanged. An explicit "environment": "none" in .neuralinverse/settings.json turns them off for the CLI.

Settings

The tool settings use the Editor's names: embedded.X.Y in .neuralinverse/settings.json is neuralInverse.embedded.X.Y in .vscode/settings.json, and hdl.X.Y is neuralInverse.hdl.X.Y. Both files are read; the CLI's values win.

SettingMeaning
embedded.paths.<tool>Path to a tool or its folder: armGcc, cmake, ninja, openocd, gdb, armCompiler6, iarArm, jlinkCommander, jlinkGdbServer, stm32Programmer, stlinkGdbServer; CLI only: qemu, stFlash
embedded.cmake.sourceDirectoryFolder with CMakePresets.json (default: the project root)
embedded.cmake.configurePreset, buildPreset, testPresetCLI only: presets used when a call names none
embedded.elfFile, embedded.linkerScriptImage to measure, flash or debug, and the script with the MEMORY regions
embedded.probeServeropenocd (default), jlink or stlink
embedded.openocd.board, interface, target, adapterSerial, adapterSpeed, argumentsOpenOCD scripts; board defaults to board/stm32f4discovery.cfg
embedded.jlink.device, interface, speed, serialSEGGER J-Link
embedded.stlink.serial, frequency, connectUnderResetST-LINK through STM32CubeProgrammer
embedded.debug.gdbPortGDB server port (3333 OpenOCD, 2331 J-Link, 1234 QEMU)
embedded.serial.port (CLI only), embedded.serial.baudRateSerial console
embedded.qemu.machine, cpuCLI only: QEMU machine for fw_debug without hardware
hdl.projectFileHDL project file (default hdl.json)
hdl.paths.<tool>verilator, iverilog, vvp, ghdl
hdl.lint.verilatorArguments, ghdlArgumentsExtra lint arguments; the CLI adds -Wall for Verilator when unset
hdl.simulation.icarusArguments, verilatorArguments, ghdlArguments, ghdlWaveformSimulation arguments; GHDL writes a VCD by default
hdl.simulation.failPatterns, passPatternsCLI only: extra regular expressions that fail or mark a run

Settings that name programs or arguments to run (paths.*, openocd.arguments, the lint and simulation arguments) are "restricted": the Editor honours them only in a trusted workspace. In the CLI, when the project's own files set any of them, the otherwise read-only tools (fw_toolchain, fw_size, hdl_lint) ask before running, since a cloned repository could point them anywhere.

Firmware tools

Every tool runs programs from argument arrays, never through a shell, and answers with a short structured result and, on failure, the next step to take.

ToolWhat it does
fw_toolchainFinds Arm GCC, armclang, IAR iccarm, CMake, Ninja, OpenOCD, J-Link, ST-LINK (STM32CubeProgrammer, st-flash), GDB and QEMU: configured paths, then PATH, then the vendors' usual install folders. Reports versions, tools older than the minimums, and install hints. Read-only
fw_buildRuns cmake --preset <configure> and cmake --build --preset <build>. Compiler and linker output becomes file:line:col findings (GCC, armclang, IAR, GNU ld, armlink). After linking, reports Flash and RAM per MEMORY region and the largest symbols. Writes only into the preset's build folder and is treated like an edit
fw_sizeAnalyses an ELF the same way, or a GNU ld map file when the binutils are missing
fw_testRuns ctest --output-junit, parses the JUnit report and extracts Unity failure lines; can also parse a saved Unity log
fw_flashPrograms .elf or .hex (or .bin with an address) through OpenOCD (program <image> verify reset exit), J-Link Commander, or STM32CubeProgrammer (-w -v -rst; st-flash as a fallback). Always asks; see below
fw_serialReads a serial port for N seconds or until a regular expression matches, optionally sending a line first. Uses stty on macOS and Linux and PowerShell's System.IO.Ports on Windows. Opening a port asks for approval
fw_faultDecodes CFSR, HFSR, MMFAR, BFAR, EXC_RETURN and the stacked frame, explains the cause, and maps the stacked PC and LR to function and line with arm-none-eabi-addr2line when given the ELF. Read-only
fw_debugA short GDB/MI session against OpenOCD, the J-Link GDB Server, QEMU (started halted on the ELF) or a running server: registers, backtrace, memory at an address, or an expression. Connecting halts the target, so it asks for approval
fw_importReads Keil (.uvprojx), IAR (.ewp) and STM32CubeIDE (.cproject) projects and returns a proposed CMakeLists.txt, CMakePresets.json, toolchain file and, when needed, a GNU linker script. Nothing is written; the agent writes what you agree with through the normal edit tools

Flashing always asks

Flashing hardware always needs a person's approval:

  • in every permission mode, including full-auto;
  • even when an allow rule matches (fw_flash, fw_*) or a tool.before hook approves;
  • "always allow" answers are treated as "once", and no rule is saved.

Policy can still deny it ("deny": ["fw_flash"]), and read-only mode denies it. Non-interactive runs (-p, CI, schedules, helper agents without a person) cannot flash: the call is denied and the agent is told why.

The approval card shows the probe, the target, the image path, its size and its SHA-256. The image is hashed again just before programming; if it changed after you approved (for example, a rebuild in between), nothing is flashed.

Hardware tools

hdl.json is the Editor's project file:

{
  "name": "blinky",
  "sources": ["rtl/**/*.sv"],
  "includeDirs": ["rtl/include"],
  "defines": { "WIDTH": 8, "SIM": true },
  "top": "top",
  "vhdlStandard": "08",
  "buildDirectory": "build/hdl",
  "testbenches": [{ "name": "tb_top", "top": "tb_top", "sources": ["tb/tb_top.sv"], "simulator": "icarus", "timeout": 60 }],
  "targets": [{ "name": "icebreaker", "family": "ice40", "device": "up5k", "package": "sg48", "constraints": "icebreaker.pcf" }]
}

Comments and trailing commas are allowed; unknown keys are errors.

ToolWhat it does
hdl_projectValidates hdl.json, expands the source globs, lists the testbenches and targets, prints the design hierarchy, and reports which HDL tools are installed
hdl_lintRuns Verilator --lint-only -Wall on Verilog and SystemVerilog (Icarus -t null when Verilator is missing) and GHDL on VHDL, with the project's include folders, defines, top and VHDL standard. Findings come back as file:line:col: severity: message [CODE]
hdl_simBuilds and runs a testbench with Icarus Verilog (iverilog -g2012 and vvp -n), Verilator (--binary --timing --assert --trace) or GHDL (with a VCD), into <buildDirectory>/sim/<testbench>. A run passes when it exits 0 within its timeout and reports no $error or $fatal, failed assertion, or VHDL error or failure report, and matches no failPatterns. Waveform files the run wrote are listed

Troubleshooting

  • /environment (or neuralinverse env) prints where the current value came from and why an environment is off (not a project folder, or both Editor switches on).
  • fw_toolchain and hdl_project list every tool with its version or an install hint.
  • Probe problems: fw_flash names the probe software's error and suggests checking cables, USB permissions (udev rules on Linux) and power.

Last reviewed 17 October 2026View as Markdown

Firmware and hardware environments · Docs · Neural Inverse