Skip to main content

Quick Start

Build and run the gpio-button-led example end-to-end. By the end you'll have a working native_sim simulation and a path to real silicon.

What you need

  • The ALP SDK installed
  • A ZEPHYR_BASE environment variable pointing at the Zephyr checkout (set by bootstrap.sh)

Hardware is not required for native_sim. To target real silicon, jump to step 4.

Step 1 — Look at the example

Open alp-sdk/examples/gpio-button-led. Every example carries:

gpio-button-led/
├── board.yaml # declarative project config
├── prj.conf # empty (the loader generates alp.conf)
├── CMakeLists.txt # invokes alp_orchestrate.py at configure time
├── src/main.c # the application
└── boards/ # per-board overlay files

The minimum-viable board.yaml (schema v2):

schema_version: 2

som:
sku: E1M-AEN701 # your MPN — the SDK ships a preset
# at metadata/e1m_modules/<MPN>.yaml

carrier:
name: E1M-EVK # or your own custom carrier name

cores:
m55_hp:
os: zephyr # zephyr | yocto | baremetal | off
app: ./src
peripherals: [gpio]

diagnostics:
log_level: info

That's the whole config. The orchestrator resolves som.sku to the right silicon, picks up the carrier preset, and generates the per-slice native config (Zephyr Kconfig fragment, CMake -D flags, or Yocto local.conf) per core declared under cores:. Cores omitted inherit the SoM preset's topology: defaults — see the board.yaml reference for the full schema and the heterogeneous builds walkthrough for dual-OS projects.

See the board.yaml reference for the full schema.

Step 2 — Build under native_sim

cd alp-workspace
west alp-build -b native_sim/native/64 alp-sdk/examples/gpio-button-led
west build -d build -t run

Expected output:

*** Booting Zephyr OS build v4.4.0 ***
[gpio] init button=E1M_GPIO_IO0, led=E1M_GPIO_IO1
[gpio] led=0 status=0
[gpio] led=1 status=0
...
[gpio] is_pressed -> status=0 pressed=1
[gpio] done

status=0 means ALP_OK. pressed=1 is Zephyr's gpio_emul default "input is low" report.

What west alp-build did

west alp-build is one of five west alp-* commands the SDK ships (v0.6 split the old monolithic command into focused tools):

CommandWhat it does
west alp-buildValidates board.yaml, fans out into per-core slices, emits system-manifest.yaml.
west alp-imageConsumes the manifest, assembles a flashable bundle (build/image-bundle/).
west alp-flashWalks the manifest's boot_order: and programs each piece with the right backend.
west alp-cleanTears down per-slice build dirs idempotently.
west alp-renodeBoots the dual-OS image in Renode and drives the RPMsg handshake smoke test.

Under the hood west alp-build runs four steps:

  1. Validates the app's board.yaml (schema v2 + SoM SKU preset + carrier preset + hw_rev / SDK-version compatibility + per-slice peripherals: vs SoC caps + cores: keys against the SoM preset's topology:).
  2. Fans out into per-core slice build directories (build/<core>-zephyr/, build/<core>-yocto/, etc.) and emits per-slice Kconfig fragments + Yocto local.conf snippets.
  3. Emits cross-slice artefactsbuild/system-manifest.yaml, build/generated/alp/system_ipc.h, build/generated/dts-reservations.dtsi — byte-stable across rebuilds.
  4. Delegates to west build per slice. Any flags after the recognised ones pass through verbatim.

Step 3 — Read the source

Open examples/gpio-button-led/src/main.c. Every example is annotated as teaching material:

#include <alp/peripheral.h>
#include <alp/e1m_pinout.h>

int main(void) {
alp_gpio_t *led = alp_gpio_open(&(alp_gpio_config_t){
.pin_id = E1M_GPIO_IO1,
.direction = ALP_GPIO_DIR_OUTPUT,
});
if (led == NULL) {
printk("[gpio] led open failed: err=%d\n", (int)alp_last_error());
return -1;
}

alp_gpio_t *button = alp_gpio_open(&(alp_gpio_config_t){
.pin_id = E1M_GPIO_IO0,
.direction = ALP_GPIO_DIR_INPUT,
.pull = ALP_GPIO_PULL_UP,
});

for (int i = 0; i < 4; i++) {
alp_gpio_write(led, i & 1);
k_msleep(500);
}

bool pressed;
alp_gpio_read(button, &pressed);
printk("[gpio] is_pressed pressed=%d\n", pressed);

alp_gpio_close(led);
alp_gpio_close(button);
return 0;
}

Key points:

  • Handles (alp_gpio_t *) are opaque and obtained from alp_*_open().
  • Failures stamp alp_last_error() (thread-local) — check it whenever a handle is NULL.
  • Instance IDs (E1M_GPIO_IO1) are E1M-portable: this code works on every conformant SoM.
  • alp_*_close() releases the handle — observe it for clean shutdown.

See the <alp/peripheral.h> reference.

Step 4 — Target real silicon

For the E1M EVK populated with an AEN SoM (single-OS, Zephyr):

west alp-build -b alp_e1m_evk_aen alp-sdk/examples/gpio-button-led
west alp-flash

For the E1M-X EVK populated with a V2N SoM (heterogeneous, A55 Yocto + M33 Zephyr):

west alp-build alp-sdk/examples/rpmsg-v2n     # fans out per-core
west alp-image # assemble the bundle
west alp-flash # boot_order-aware programming

west alp-flash walks system-manifest.yaml's boot_order: and dispatches each artefact to the right backend — vendor flasher for the SoC, openocd-via-SWD for the GD32 helper MCU, USB-CDC bootloader for the CC3501E. No developer-side tool-selection.

Each example's boards/ directory carries an overlay that maps the application's alp,pin-array slots to specific EVK pins. The overlay applies automatically when you build for the matching board.

For SoMs without a published EVK board file yet, write your own board file under alplabai/alp-zephyr-modules or a private board layer. See docs/porting-new-som.md.

Step 5 — Explore more examples

Every wrapped peripheral has a corresponding minimal example:

for ex in pwm-led-fade adc-voltmeter i2c-scanner spi-loopback \
uart-echo uart-rx-ringbuf counter-alarm rtc-clock wdt-feed \
can-loopback i2s-tone qenc-readout; do
west build -b native_sim/native/64 alp-sdk/examples/$ex -d build/$ex
west build -d build/$ex -t run
done

On native_sim most peripherals don't have emul controllers (only I²C / SPI / GPIO / UART do). Examples that target unwrapped peripherals exit after printing the alp_last_error() diagnostic — that's expected and proves the wrapper plumbing compiles and links cleanly.

End-to-end reference apps:

Heterogeneous flagships (one board.yaml drives both halves):

Troubleshooting

SymptomCause / fix
west alp-build: command not foundWorkspace not bootstrapped; run west init -m https://github.com/alplabai/alp-sdk first.
validate_board_yaml.py exit 2som.sku doesn't match any preset under metadata/e1m_modules/. Check spelling.
validate_board_yaml.py exit 3hw_rev incompatible with this SDK version. Update SDK or pick a compatible rev.
Handle is NULL and alp_last_error() == ALP_ERR_NOSUPPORTPeripheral wrapper not implemented for this OS/SoM yet. Check the test plan.
Handle is NULL and alp_last_error() == ALP_ERR_OUT_OF_RANGERequested config exceeds the SoC's documented caps (e.g. 16-bit ADC on a 12-bit SoC).

Full troubleshooting index: docs/troubleshooting.md.

What next?

Questions about this page? Discuss in Community Forum