Skip to main content

The alp CLI

alp is the Alp SDK's single command-line front door. One verb set scaffolds a project, builds it (multi-core aware), runs it on the simulator or in Renode, checks its footprint against the SoM memory budget, flashes it, bundles it for OTA, cleans it, inspects the generated configuration, validates board.yaml, compiles AI models, sanity-checks the host environment, opens a serial console, and scaffolds the metadata for porting a new SoM.

It is the headless companion to the VS Code extension: both front doors sit on the same shared core as the west alp-* extension commands, so a validate in CI matches what the editor sees, and a CLI-driven build behaves identically to a west one.

Install

The bootstrap scripts install alp automatically as an editable install into the workspace venv — scripts/bootstrap.sh on Linux / macOS / WSL2, scripts/bootstrap.ps1 on native Windows (see Installation). Because the install is editable, a git pull in the alp-sdk checkout updates the CLI in place.

Without an install it also runs straight from a checkout:

# From the alp-sdk repo root (or with <sdk>/scripts on PYTHONPATH):
PYTHONPATH=scripts python3 -m alp_cli --help

Every verb is a thin wrapper — the actual logic lives in the same scripts and packages the west alp-* commands drive (scripts/alp_orchestrate/, scripts/alp_project.py, scripts/validate_board_yaml.py, scripts/flash_backends/). The CLI adds discoverability and sane defaults; it never forks the behaviour.

alp vs west alp-* — which do I use?

Both front doors drive the same underlying pipeline; pick by ergonomics, not capability:

You are…Use
In an app directory, want the shortest commandalp build / alp run / alp flash — they find board.yaml by walking up from the cwd
Scripting CI or a west-centric workflowwest alp-build <app> / west alp-flash <app> — explicit app path, no cwd magic
Outside any west workspace (validate, emit, doctor, model, monitor)alp … — these verbs don't need a workspace
Building Zephyr for one named board target directlyeither alp build --board <target> or plain west build -b <target>

Rules of thumb:

  • alp build == west alp-build, alp flash == west alp-flash, and alp size / alp clean / alp image / alp renode == their west alp-* twins — same implementation, same flags; the alp form finds the app by walking up from the cwd, the west form takes the app path explicitly.
  • alp emit is a superset of west alp-emit: every artefact either front door can generate is reachable from alp emit (one catalog, below). west alp-emit exposes the orchestrator's ADR-0014 subset for west-centric scripting. The same emitter runs underneath either way — the two can never produce different output for the same mode.

Verb reference

alp init — scaffold a new project

alp init my-app --som E1M-AEN701 --preset e1m-evk --peripherals uart,gpio
alp init my-app # interactive: pick SoM / preset / peripherals

Copies the hello-world template, rewrites board.yaml for the chosen SoM SKU + board preset, and seeds the optional starter peripherals: list. Omit any flag to be prompted.

OptionMeaning
NAME (argument)New project directory (must not exist)
--somSoM SKU, e.g. E1M-AEN701
--presetBoard preset from metadata/boards/, e.g. e1m-evk
--peripheralsComma-separated starter peripherals (uart,gpio,i2c,spi,pwm)

alp new-som — scaffold metadata for a new SoM port

alp new-som --sku E1M-NX9555 --soc-ref nxp:imx9:imx95 --family nxp-imx9
alp new-som # interactive: prompts for every field

The vendor-N+1 porting kit. Generates the two metadata skeletons a new SoM port needs — metadata/e1m_modules/<SKU>.yaml (the SoM preset) and, when the target SoC has no spec yet, metadata/socs/<vendor>/<family>/<part>.json — with every schema-required hardware-fact field present as an explicit TBD placeholder. Values are never invented; the JSON carries its TODOs in the schema-sanctioned _pending_reason + notes fields. Both skeletons are schema-valid on arrival, and the command finishes by printing a numbered porting checklist (fill the TBDs, extend the schema sku pattern for a brand-new family, register the silicon ref, validate, regenerate, run the conformance suite).

The scaffold is committable as-is: every input is validated before anything is written (a rejected invocation never leaves half-written files). Use --dry-run to see the planned files — and run the full validation — without writing anything. In a pipe or CI, missing required flags fail fast with an explicit list instead of dropping into the prompts. The full walkthrough lives in the SDK's docs/porting-new-som.md.

OptionMeaning
--skuNew SoM SKU, e.g. E1M-NX9555
--soc-refSilicon triple-colon ref, e.g. nxp:imx9:imx95
--familyHuman-readable family slug, e.g. nxp-imx9
--vendorVendor display name for the SoC JSON (default: soc-ref vendor segment)
--display-namePreset display name (default derived from the SKU)
--inference-backendethos_u / drpai / deepx_dxm1 / tbd (default tbd)
--ethos-u-variantu55 / u65 / u85; required with --inference-backend ethos_u
--coresComma-separated canonical core ids (default: a tbd_core0 placeholder)
--default-boardStock carrier board (default E1M-EVK)
--default-hw-revDefault hardware revision (default r1)
--output-rootRoot to generate metadata/ under (default: the SDK checkout)
--dry-runValidate and print the planned files; write nothing
--forceOverwrite an existing preset for this SKU

alp build — build the project (multi-core aware)

alp build # nearest board.yaml upward from the cwd
alp build path/to/app # explicit app directory
alp build --core m33_sm # iterate on one slice only
alp build --board native_sim # single-image fallback: plain `west build`

Default path: validate board.yaml, then fan out every non-off core via the orchestrator — exactly what west alp-build does. Outputs land under <app>/build/: per-slice build directories plus system-manifest.yaml, the single source of truth that alp flash, alp image, and OTA consume.

--board <zephyr-board> skips the orchestrator and performs a plain single-image west build -b <board> into build/<board>/ — the right tool for a one-core Zephyr app when you want to name the board target directly.

OptionMeaning
APP_PATH (argument, optional)App directory (default: walk up from cwd)
--coreLimit the fan-out to one core ID
--no-parallelForce sequential slice dispatch
--no-validateSkip the board.yaml pre-flight validation
--build-rootOverride the build root (default: <app>/build)
--boardSingle-image fallback: west build -b <board>

alp run — build + run on the simulator

alp run # build for native_sim and execute it
alp run --board <target> # real-hardware build instead
alp run --board <target> --flash # …then west flash

Builds through the same single-image path as alp build --board, then executes the produced zephyr.exe (native_sim). For heterogeneous multi-core projects use alp build + alp flash instead — native_sim is a single-image target.

alp flash — program the built project

alp build && alp flash # the whole system, one-liner
alp flash --core m33_sm # one slice only
alp flash --helper gd32_bridge # one helper MCU only
alp flash --dry-run # print commands, touch nothing

Walks build/system-manifest.yaml (produced by alp build / west alp-build) and programs every slice + helper MCU via the registered flash backends, in boot_order:. Identical to west alp-flash.

OptionMeaning
APP_PATH (argument, optional)App directory (default: walk up from cwd)
--coreFlash only the slice with this core ID
--helperFlash only the helper MCU with this name
--dry-runPrint the flash commands but don't run them
--build-rootOverride the build root
--skip-missing-toolsWarn + skip slices whose flash tool is missing

alp size — footprint vs the SoM memory budget

alp build && alp size # does each image fit the silicon?
alp size --fail-over-budget # CI gate: non-zero exit when over
alp size --json # machine-readable (VS Code extension)

Walks build/system-manifest.yaml, measures every Zephyr slice's zephyr.elf, and compares FLASH and RAM usage against the budget resolved from the SoM's SoC metadata — before you flash. Slices that aren't built report not built, Yocto/baremetal slices n/a, and an unresolvable budget unknown (never a guessed number). Identical to west alp-size.

alp image — assemble a flashable bundle

alp build && alp image # produces build/image-bundle/

Reads build/system-manifest.yaml and assembles a single flashable bundle under build/image-bundle/: per-slice tar.gz archives, helper-MCU firmware, and a bundle-manifest.json with per-artefact SHA-256s. Identical to west alp-image.

alp clean — remove build outputs

alp clean # remove <app>/build + orchestrator cache
alp clean --dry-run # list what would go, delete nothing

Removes the per-project build directory and the orchestrator's .alp-build-state.json. Identical to west alp-clean.

alp renode — boot the build in Renode (no hardware)

alp build && alp renode # headless smoke boot
alp renode --expect "[hello] done" # exit 0 when seen, 1 if not
alp renode --log out.log --timeout 60

Boots the built system manifest's Zephyr slice in the Renode emulator, headless, with a wall-clock timeout — a no-hardware smoke test. The SoM family maps to a platform descriptor under metadata/renode/. Requires the renode binary on PATH; exits non-zero with install guidance when absent, never a silent pass. Identical to west alp-renode.

OptionMeaning
--logTee the console output to this file (default build/renode.log)
--timeoutWall-clock cap in seconds (default 120)
--expectStop early (exit 0) when this substring appears; exit 1 if it never does

alp emit — print one generated artefact (no build)

alp emit zephyr-conf # the per-core Zephyr fragment
alp emit system-manifest # the full-system manifest
alp emit carrier-netlist --output nets.json # Studio carrier handoff
alp emit hw-info-h --output hw_info.h # write instead of stdout

Read-only: shows exactly what a consuming tool (CMake, Yocto, the IDE, Alp Studio) would see. This is the one catalog of every generated artefact — alp emit reaches everything scripts/alp_project.py --emit and west alp-emit can produce, delegating each mode to the single implementation that owns it:

ModeArtefactEmitted by
zephyr-confPer-core Zephyr alp.conf Kconfig fragmentalp_project.py
cmake-argsPer-core -D CMake argument listalp_project.py
yocto-confPer-core local.conf fragmentalp_project.py
dts-overlayBoard DTS overlay (bus aliases + pin array)alp_project.py
hw-info-hBuild-time hw_info.h macro headeralp_project.py
west-librarieswest.yml fragment for libraries: depsalp_project.py
system-manifestFull-system manifest (slices, boot order)orchestrator
dts-reservationsDTS reserved-memory overlay (cross-core carve-outs)orchestrator
ipc-contract-hCross-core IPC contract headerorchestrator
os-topologyPer-core natural-vs-effective OS factsorchestrator
composed-route-tableJSON route-table dump (demonstrator)alp_project.py
carrier-netlistStudio-facing carrier nets + BOM JSON handoffalp_project.py
dts-partitionsDTS fixed-partitions overlay (storage: entries)orchestrator
storage-mounts-cStatic C storage mount tableorchestrator
tfm-sysbuild-confTF-M sysbuild child-image overlay (security.psa:)orchestrator
build-planPer-slice build plan, JSON (IDE / CI consumers)orchestrator
OptionMeaning
--inputPath to board.yaml (default: nearest one upward)
--outputWrite to this path instead of stdout
--coreScope per-core modes to one core ID
--build-rootBuild root used for build-plan slice paths

See carrier-netlist in the board.yaml reference for what the Studio handoff contains — and, just as importantly, what it deliberately excludes.

alp validate — check a board.yaml

alp validate # ./board.yaml
alp validate path/to/board.yaml

Runs the rich diagnostic validator (JSON-Schema pass, SoM/preset cross-references, peripheral-vs-SoC capability check) and renders every finding as a Rust-style diagnostic block with an ALP-Bxxx code — decode any code with alp explain ALP-B001. Exit 0 when clean, 1 on errors. The schema pass is the same shared implementation scripts/validate_board_yaml.py (the west alp-build pre-flight) and the orchestrator's loader use, so all front doors report identical violations.

alp model — compile + package AI models

alp model build # compile board.yaml `models:` entries
alp model build --board path/to/board.yaml --out build/models

Compiles every models: entry declared in board.yaml into a .alpmodel package via the SoM-appropriate backend (Vela for Ethos-U, DRP-AI for RZ/V2N, …). See Inference for the end-to-end flow.

alp doctor — host environment preflight

alp doctor # human-readable PASS/WARN/FAIL report
alp doctor --json # machine-readable
alp doctor --strict # WARNs also fail the exit code

Strictly hardware-free: checks Python / west / CMake / Ninja / dtc / gperf / imgtool / host compiler / J-Link presence, the Zephyr pin (read live from west.yml), the workspace venv, ZEPHYR_BASE, the Zephyr SDK, plus Windows-specific traps (git core.autocrlf, long-path support). Exit 0 = ready to build; every FAIL/WARN comes with a remediation hint. Run it first whenever a build machine misbehaves.

alp monitor — serial console

alp monitor --port COM7 # Windows
alp monitor --port /dev/ttyUSB0 # Linux
alp monitor # lists available ports if none given

Opens pyserial's miniterm (Ctrl+] to quit). Baud defaults to 115200 (--baud to override). When no port is given, or the requested one doesn't exist, it lists every serial port on the host and exits non-zero instead of hanging on a wrong device.

alp explain / alp faultdecode — diagnostics

alp explain ALP-B001 # cause + fix + doc link for a validator code
alp faultdecode fault.txt # decode an ARMv8-M (M33/M55) fault dump

alp explain prints the cause, fix, and doc link for any ALP-Bxxx validator diagnostic. alp faultdecode decodes a Cortex-M fault-register dump into a human-readable cause chain.

Environment

VariableEffect
ALP_SDK_ROOTExplicit path to the alp-sdk checkout; otherwise the CLI locates the repo it was installed (editable) from
ZEPHYR_BASEThe Zephyr tree used by single-image builds + checked by alp doctor

The delegating verbs (build, flash, emit, size, image, clean, renode) export ALP_SDK_ROOT, append the SDK to EXTRA_ZEPHYR_MODULES, and put <sdk>/scripts on PYTHONPATH for their sub-processes — the same wiring the west alp-* wrappers use.

See also

Questions about this page? Discuss in Community Forum