Observed since 21 Oct, 10:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Aidge export for ARM CortexM systems
This plugin allow Aidge to create exports for ARM CortexM systems.
It generates standalone C/C++ code intended to run on STM32 targets.
pip install aidge_export_arm_cortexm
If you want to generate exports and/or better understand how it works in Aidge, you may take a look at the following resources :
Additional targets can be added upon request.
Normally, any recent STM32 board should be compatible with the generated code. You must ensure that the corresponding pack is installed in pyOCD (e.g., stm32h743zitx for NUCLEO-H743ZI), that the deployment target declares the proper pyOCD/UART defaults, and that the respective hardware configuration (RAM/Flash size, etc.) and template project exist for the board.
This export provides two backends:
arm_cortexm:
Provides specific optimizations for Convolution and Fully Connected (FC) layers, and is largely based on the aidge_export_cpp backend.
CMSIS-NN:
Relies on the optimized kernels provided by CMSIS-NN.
| Layer | Supported |
|---|---|
| Convolution | ✔️ |
| Depthwise Convolution | ✔️ |
| Convolution Transpose | ✔️ |
| Fully Connected | ✔️ |
| Layer | Supported |
|---|---|
| Add | ✔️ |
| Mul | ❌ |
| Convolution | ✔️ |
| Depthwise Convolution | ✔️ |
| Fully Connected | ✔️ |
| Average Pooling | ✔️ |
| Max Pooling | ✔️ |
| Global Average Pooling | ✔️ |
| Concat | ❌ |
| Reshape | ❌ |
| Softmax | ❌ |
[!NOTE]:
- If your model contains unsupported operators, the export will still work. In that case, the implementation from the
aidge_export_cppmodule will be used.- The CMSIS-NN backend only supports quantized models (int8).
Several example scripts are available in aidge/examples.
| Model | arm_cortexm | CMSIS-NN | Notes |
|---|---|---|---|
| LeNet | ✔️ | ✔️ | |
| Deep Autoencoder | ✔️ | 🔶 | Generation works, but slight output differences are observed on the last FC layer |
| DS-CNN | ✔️ | ✔️ | |
| MobileNetV1 VWW | ✔️ | ✔️ | |
| ResNet8 | ✔️ | 🔶 | Generation works, but slight output differences are observed on the third convolution |
Navigate to the root of the repository and run the following command to execute the LeNet example. The required Drivers/HAL files are downloaded automatically during the build; no manual target setup is required.
cd aidge/examples/benchmark
Run the Python script:
python benchmark_model.py --profiling --target stm32h743 --model-path lenet_mnist
Run python <model>.py --help to see all available options.
The script will generate the export, compile it, flash it on the board, and capture the UART output to measure inference time and perform some benchmarking. Some chats will be generated with the results of the benchmark, and the raw output will be stored in export_folder/uart_output.txt.
By default, the compilation will be done using a docker container, but you can also choose to compile it locally by installing the required toolchain (e.g., arm-none-eabi-gcc for STM32 targets) and running the command with the --no_docker flag.
This module also provides a template for running the tinyMLPerf benchmark. The benchmark can be executed for the following models:
| Model | Dataset | Notes |
|---|---|---|
| Deep AutoEncoder | ToyADMOS | |
| DS-CNN | Speech Commands | |
| MobileNetV1 VWW | Visual Wake Words | |
| ResNet8 | Cifar10 |
Each dataset can be evaluated in terms of accuracy and inference time. For the moment, the evaluation of power consumption is not supported, since it relies on external hardware to do the measurement. In order to run the benchmark, you can use the following command :
python benchmark_model.py --target stm32h743 --model-path resnet8_cifar10 --tinymlbenchmark
This will create a different main file that communicates with the tinyML framework to perform the evaluation. Once you have flashed the board, you need to cancel the execution of the script (CTRL+C), and follow the instructions provided by tinyML to run the benchmark.
git clone https://github.com/mlcommons/tiny.git
cd tiny
# Install dependencies into virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows, use `.venv\Scripts\activate`
pip install -r benchmark/training/streaming_wakeword/requirements.txt pyusb libusb
To execute the benchmark itself, you'll first need to generate the dataset samples. Each folder inside tiny/benchmark/training/ contains the instructions to download and generate the samples for each model. For example, for the MobileNetV1 VWW model, you can run:
cd benchmark/training/visual_wake_words
./download_and_train_vww.sh
python generate_y_labels.py
Note: This procedure may change in the future, so please refer to the official tinyML repository for the most up-to-date instructions on dataset generation and benchmark execution.
Once you have generated the dataset samples (and placed them in the correct directory, which is tiny/evaluation/datasets/), you can run the benchmark using the command provided above.
cd benchmark/runner
python main.py --dataset_path=../evaluation/datasets/ --test_script=tests_accuracy.yaml --device_list=devices_kws_ic_vww.yaml --mode=a # for accuracy evaluation
python main.py --dataset_path=../evaluation/datasets/ --test_script=tests_performance.yaml --device_list=devices_kws_ic_vww.yaml --mode=p # for performance evaluation
This will generate a report with the results of the benchmark in tiny/runner/sessions/.
It is also possible to use the flashing and UART capture functionalities of this module through an API. Basically, instead flashing the board locally, the export will generate a .elf file that will then be flashed by the API using pyOCD. The API is available in the (repository)[https://gitlab.eclipse.org/antoniopereira/api_board_farms], along will all the necessary instructions. Once everything is set up, you can run the same example script as before, but with the --backend api flag:
cd aidge/examples/benchmark
python benchmark_model.py \
--target stm32h743 \
--backend api \
--api-url http://127.0.0.1:8000 \
--api-username admin \
--api-password changeme \
--api-board-name stm32h7_lab_01
--model-path lenet_mnist
You can also compare your model's performance against the ST Edge AI Developer Cloud using the stzooapi backend. This backend uploads your model to ST's cloud services and benchmarks it on their remote board farms.
To use this feature, you must install the stm32ai-dc Python package:
pip install pycurl seaborn numpy matplotlib ipywidgets gitdir shutils marshmallow tqdm
gitdir https://github.com/STMicroelectronics/stm32ai-modelzoo-services/tree/main/common/stm32ai_dc
You can use the benchmark_interface.py script (found in examples/) to compare onnxruntime, aidge_backend_cpu, and aidge_export_arm_cortexm with the ST Cloud results:
python examples/benchmark_interface.py \
--stmai-username your_email@st.com \
--stmai-password your_password \
--stmai-board B-U585I-IOT02A
Note: You need an active account on ST Edge AI Developer Cloud. You can also check the boards available on their website.
Prerequisite:
pyocd >= 0.35.0pyserial >= 3.5pip install aidge_export_arm_cortexm
Prerequisite (in addition to previous one):
| Environment | Python Development |
|---|---|
| Windows | .\setup.ps1 -Modules backend_cpu -Tests |
| Unix | ./setup.sh -m backend_cpu --tests |
[!TIP] Use
Get-Help setup.ps1(Win) or./setup.sh -h(Unix) for full documentation.
Run these commands from the aidge_export_arm_cortexm/ directory:
#fStandard install
pip install . -v
# Install with testing dependencies
pip install .[test] -v && pytest
STM32 HAL/Drivers files are not stored in the repository. They are downloaded automatically for the selected target during the build, so users do not need to run the target's setup.sh script manually before the first compilation.
By default, pyOCD does not include all STM32 packs. The pack corresponding to NUCLEO-H743ZI (stm32h743zitx) must be installed manually:
pyocd pack install stm32h743zitx
This operation can take several minutes.
If you are on Windows, make sure you installed the ST-LINK USB Driver that you can find on ST website.
Then connect your board via USB and run:
pyocd list
Expected output example:
# Probe/Board Unique ID Target
------------------------------------------------------------------
0 STM32 STLink 066DFF343339415043185830 ✔︎ stm32h743zitx
NUCLEO-H743ZI
If you see a green check ✔︎, the board is properly detected.
If you see a red cross x, manually install the pack as described above.
If running the following command results in an error:
pyocd list
No available debug probes are connected
but your STM32 device is visible via lsusb, this may be due to missing USB permissions.
Search in https://github.com/pyocd/pyOCD/tree/main/udev for the file that corresponds to your debugger. For example, for the NUCLEO-H743ZI board, the file is 49-stlinkv2.rules. For newer boards, such as the STM32N657, the file is 49-stlinkv3.rules. You can use the following command to find the file:
Create a new udev rule:
sudo nano /etc/udev/rules.d/50-st-link.rules
Paste the content of the file you found in the previous step into this new file and save it.:
Reload udev and trigger:
sudo udevadm control --reload-rules
sudo udevadm trigger
Unplug and replug your STM32 device.
Try again:
pyocd list
You should now see your board listed.
If you see an error like this when trying to flash :
Error connecting to serial port: [Errno 13] could not open port /dev/ttyACM0: [Errno 13] Permission denied: '/dev/ttyACM0'
This usually means your user doesn't have the right permissions for serial access.
For fix that you have to add your user to the dialout group :
sudo usermod -a -G dialout $USER
Then Restart your terminal for the change to take effect
DeployConfig.uart_capture_duration accordingly (e.g., from 30s to 60 or more),The flashing process now includes a retry mechanism:
if the UART output file is missing or empty, the firmware is reflashed up to 5 times by default (this can be changed via the MAX_RETRIES constant in the code).
This improves robustness against rare flashing issues caused by the pyOCD library, where firmware may not start correctly despite successful flashing.
A special end keyword (default: "DEMO END") is now expected in the UART output to determine when inference is complete and to stop UART capture.
The file uart_output.txt is automatically generated during execution and placed in the export_folder.
An export_log.log file is generated at compilation to store the build logs.
When testing dimensions like [16], set DeployConfig.uart_capture_duration to at least 60 or more.
[32, 32, 32, 32] (e.g., for ReLU), compilation errors or RAM/Flash overflows may occur.16, such as [1,1,1,1], [4,4,4,4], or [16,16,16,16].uart_capture_duration when working with large output tensors.Aidge has a Eclipse Public License 2.0, as found in the LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.10.1 | 17 Sept 2026 | 8 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 10:28 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:7003a750ef41aa5989598eb226ff73d3ca2d8738d09364394fc2c66305728351