In this section, you duplicate the existing Blinky example to create a new CMSIS project called mv2_runner, configured to include ExecuTorch libraries, the compiled model, and SEGGER RTT for debug output.
Start by copying the working Blinky project as a template:
cd ~/alif/alif_vscode-template
cp -R blinky/ mv2_runner
Rename the project file inside the new directory:
mv mv2_runner/blinky.cproject.yml mv2_runner/mv2_runner.cproject.yml
Replace all internal references from blinky to mv2_runner:
perl -pi -e 's/\bblinky\b/mv2_runner/g' $(grep -RIl "blinky" mv2_runner)
ExecuTorch is a C++ library, so the source file needs a .cpp extension:
mv mv2_runner/main.c mv2_runner/main.cpp
Create an assets directory and copy the model header into the project:
mkdir -p mv2_runner/assets
cp ~/alif/models/mv2_ethosu85_256_pte.h mv2_runner/assets/
RTT (Real-Time Transfer) works through the J-Link debug probe, reading and writing a memory buffer through the debug interface. It’s faster than UART and doesn’t require extra wiring. Create the configuration file mv2_runner/SEGGER_RTT_Conf.h:
#ifndef SEGGER_RTT_CONF_H
#define SEGGER_RTT_CONF_H
#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (1)
#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (1)
#define SEGGER_RTT_BUFFER_SIZE_UP (1024)
#define SEGGER_RTT_BUFFER_SIZE_DOWN (16)
#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP
#define SEGGER_RTT_PRINTF_BUFFER_SIZE (256)
#endif
The project depends on two CMSIS packs that aren’t installed by default. Install them from the terminal:
cpackget add ARM::CMSIS-Compiler@2.1.0
cpackget add Keil::MDK-Middleware@8.2.0
Open alif.csolution.yml and make the following changes.
Update the created-for field to match your CMSIS Toolbox version:
created-for: CMSIS-Toolbox@2.12.0
Add the required packs under the packs: section:
packs:
- pack: AlifSemiconductor::Ensemble@2.0.4
- pack: ARM::CMSIS@6.0.0
- pack: ARM::CMSIS-Compiler@2.1.0
- pack: Keil::MDK-Middleware@8.2.0
- pack: ARM::ethos-u-core-driver
Add a target-set block to the E8-HP target type so the Security Toolkit knows which binary to flash. Find the type: E8-HP section and add:
- type: E8-HP
device: Alif Semiconductor::AE822FA0E5597LS0:M55_HP
board: Alif Semiconductor::DevKit-E8
define:
- "CORE_M55_HP"
target-set:
- set:
images:
- project-context: mv2_runner.debug
For all other target types (E7-HE, E7-HP, E1C-HE, E8-HE), add a target-set pointing to blinky.debug instead.
Add mv2_runner to the projects list:
projects:
- project: blinky/blinky.cproject.yml
- project: hello/hello.cproject.yml
- project: hello_rtt/hello_rtt.cproject.yml
- project: mv2_runner/mv2_runner.cproject.yml
Replace the contents of mv2_runner/mv2_runner.cproject.yml with the following configuration:
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/tools/projmgr/2.6.0/tools/projmgr/schemas/cproject.schema.json
project:
groups:
- group: App
files:
- file: main.cpp
- file: SEGGER_RTT_Conf.h
- file: assets/input_image.h
- group: SEGGER_RTT
files:
- file: ../libs/SEGGER_RTT_V796h/RTT/SEGGER_RTT.c
- file: ../libs/SEGGER_RTT_V796h/RTT/SEGGER_RTT_printf.c
- file: ../libs/SEGGER_RTT_V796h/Syscalls/SEGGER_RTT_Syscalls_GCC.c
output:
base-name: $Project$
type:
- elf
- bin
layers:
- layer: ../device/ensemble/alif-ensemble.clayer.yml
packs:
- pack: AlifSemiconductor::Ensemble
- pack: ARM::ethos-u-core-driver
components:
- component: ARM::Machine Learning:NPU Support:Ethos-U Driver&Generic U85
define:
- C10_USING_CUSTOM_GENERATED_MACROS
- ETHOSU85
add-path:
- .
- ../libs/SEGGER_RTT_V796h/RTT
- ../third_party/executorch/et_bundle/include
- ../third_party/executorch/et_bundle/include/executorch/runtime/core/portable_type/c10
misc:
- for-compiler: GCC
Link:
- -L/absolute/path/to/alif/third_party/executorch/lib
- -Wl,--whole-archive
- -lexecutorch
- -lexecutorch_core
- -lexecutorch_delegate_ethos_u
- -lcortex_m_ops_lib
- -Wl,--no-whole-archive
- -Wl,--start-group
- -lextension_runner_util
- -lcortex_m_kernels
- -lportable_ops_lib
- -lportable_kernels
- -lquantized_ops_lib
- -lquantized_kernels
- -lkernels_util_all_deps
- -lcmsis-nn
- -lflatccrt
- -Wl,--end-group
You must update the -L path to match the absolute path to your third_party/executorch/lib directory. For example: -L/Users/username/alif/third_party/executorch/lib.
There are several important details in this configuration:
--whole-archive is required for libexecutorch, libexecutorch_core, libexecutorch_delegate_ethos_u, and libcortex_m_ops_lib. These libraries contain static registration constructors (for operator registration and PAL symbols) that the linker would otherwise discard as unused.portable_ops_lib or quantized_ops_lib to --whole-archive. They are large and will overflow the microcontroller’s ITCM/MRAM.--start-group/--end-group resolves circular dependencies among the remaining libraries.C10_USING_CUSTOM_GENERATED_MACROS tells ExecuTorch to skip looking for a cmake_macros.h header that doesn’t exist in the bare-metal build.The project structure is ready. The next sections cover the application code, memory configuration, and image preparation before you build and flash.
You’ve created the mv2_runner firmware project, configured CMSIS packs, and set up the linker to include ExecuTorch libraries with the correct archive flags.
Next, you’ll add the application code that loads the model and runs inference on the Ethos-U85 NPU.