Cross-EVK Portability — <alp/board.h> and BOARD_* Aliases
One example, two EVKs. The <alp/board.h> facade plus the portable BOARD_* aliases let the same firmware source build unchanged for both official EVKs — the E1M EVK (35 × 35) and the E1M-X EVK (45 × 65) — for every interface the e1m-spec declares as a common role (STANDARD.md §7.2).
How it works
Three pieces, all generated from board.yaml:
-
ALP_BOARD_<SLUG>compile define — the build emitsALP_BOARD_E1M_EVKorALP_BOARD_E1M_X_EVKfrom theboard.yamlpreset. -
<alp/board.h>facade — selects the active board's generated routes header from that define:#include <alp/board.h> /* resolves to alp_e1m_evk_routes.h oralp_e1m_x_evk_routes.h at compile time */Building without any
ALP_BOARD_*define is a compile error with a pointed message — set the example'spreset:, or pass-DALP_BOARD_E1M_EVK/-DALP_BOARD_E1M_X_EVKby hand. -
BOARD_*aliases — each board's routes header defines the sameBOARD_*names, mapped to that board's own macros. The mapping comes from theboard_alias:field one1m_routes:entries in the board definition; parity across boards is CI-enforced, so an alias can never silently exist on one EVK only.
#include <alp/board.h>
alp_pwm_t *led = alp_pwm_open(BOARD_PWM_LED_RED, &cfg); /* builds on both EVKs */
Alias catalogue
| Alias | Role | E1M EVK | E1M-X EVK |
|---|---|---|---|
BOARD_UART_DEBUG | Console UART | EVK_UART_PORT_DEBUG | XEVK_UART_PORT_DEBUG |
BOARD_UART_ARDUINO | Arduino UNO UART | EVK_UART_PORT_ARDUINO | XEVK_UART_PORT_ARDUINO |
BOARD_I2C_SENSORS | Shared sensor + IO-expander bus | EVK_I2C_BUS_SENSORS | XEVK_I2C_BUS_SENSORS |
BOARD_SPI_ARDUINO | Arduino UNO SPI | EVK_SPI_BUS_ARDUINO | XEVK_SPI_BUS_ARDUINO |
BOARD_CAN0 | CAN-FD bus | EVK_CAN_VEHICLE_BUS | XEVK_CAN_BUS0 |
BOARD_DAC0 | Arduino DAC output | EVK_DAC_ARDUINO_DAC0 | XEVK_DAC0 |
BOARD_DAC1 | Audio line out | EVK_DAC_AUDIO_LINE_OUT | XEVK_DAC1 |
BOARD_I2S_AUDIO | Audio codec / amp bus | EVK_I2S_AUDIO_CODEC | XEVK_I2S_AUDIO |
BOARD_PWM_LED_RED / _GREEN / _BLUE | RGB status LED PWM | EVK_PWM_LED_* | XEVK_PWM_LED_* |
BOARD_PIN_LED_RED / _GREEN / _BLUE | RGB status LED GPIO | EVK_PIN_LED_* | XEVK_PIN_LED_* |
BOARD_PWM_ARD1..3 | Arduino PWM headers | EVK_ARD_PWM1..3 | XEVK_ARD_PWM1..3 |
BOARD_ENC_ROTARY | Rotary encoder (PEC12R) | EVK_ENC_ROTARY | XEVK_ENC_ROTARY |
BOARD_PIN_ENCODER_SW | Encoder push switch | EVK_PIN_ENCODER_SW | XEVK_PIN_ENCODER_SW |
BOARD_PIN_BMI323_INT1 | BMI323 data-ready | EVK_PIN_BMI323_INT1 | XEVK_PIN_BMI323_INT1 |
Declaring portability: supported_boards:
A portable example declares the presets it is verified to build for at the top level of its board.yaml:
supported_boards: [e1m-evk, e1m-x-evk]
CI builds one scenario per entry, so portability stays proven rather than claimed. When omitted, the list defaults to the single preset:. This is for examples — per ADR-0011 application firmware still targets one SoM family.
When NOT to use the facade
Form-factor-specific firmware (anything touching pads that exist on only one EVK) should include the specific routes header directly — alp_e1m_evk_routes.h / alp_e1m_x_evk_routes.h — and use the EVK_* / XEVK_* macros. The facade exists for the common-role subset, not as a universal indirection.
See also
board.yamlreference —board_alias:andsupported_boards:fields- Peripheral I/O — the
E1M_*portable pin layer underneath - EVK page — what each EVK populates