Build and Flashing
Overview
This guide walks you through the following steps:
Set up a Zephyr command-line development environment on Ubuntu or Windows (this guide supports Ubuntu 24.04 LTS and later versions; for other Linux distributions, refer to Install Linux Host Dependencies)
Obtain the source code
Build, flash, and run a sample application
Select and Update the Operating System
Click the operating system you are using.
Update system packages:
sudo apt update
sudo apt upgrade
Ensure your Windows system has the latest updates installed.
Install Dependencies
Next, use the package manager to install the host dependencies.
The minimum version requirements for the main dependencies are as follows:
Tool |
Minimum Version |
|---|---|
CMake |
3.28.0 |
Python |
3.12 |
Device Tree Compiler |
1.4.6 |
Install the required dependencies using
apt:sudo apt install --no-install-recommends git cmake ninja-build gperf \ ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \ xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1
Note
On AArch64 (ARM64) systems,
gcc-multilibandg++-multilibmay not be available and should be removed from the installation list.Verify the installed versions of the main dependencies:
cmake --version python3 --version dtc --version
Compare the output versions against the requirements in the table above. To manually update dependencies, refer to the Install Linux Host Dependencies page.
Use winget to install the required dependencies:
winget install Kitware.CMake Ninja-build.Ninja oss-winget.gperf Python.Python.3.12 Git.Git oss-winget.dtc wget 7zip.7zip
For more details, see the Install dependencies section of the Zephyr Getting Started Guide.
Verify the installed versions:
cmake --version
python --version
dtc --version
Get Zephyr and Install Python Dependencies
Next, download Zephyr and its modules into a new west workspace. You will also install Zephyr’s Python dependencies in a Python virtual environment so they stay separate from your system Python installation.
The commands below use ~/nuwa as an example workspace path. You can choose any name and location — just replace it with your own path.
Create a new virtual environment:
python3 -m venv ~/nuwa/.venvActivate the virtual environment:
source ~/nuwa/.venv/bin/activateAfter activation, the shell prompt will display a
(.venv)prefix. You can exit the virtual environment at any time by runningdeactivate.Note
Remember to activate the virtual environment each time you start working.
Install west:
pip install westGet the nuwa Zephyr source code:
cd ~/nuwa west init -m https://github.com/Ameba-AIoT/nuwa.git west update
Export the Zephyr CMake package. This allows CMake to automatically load the boilerplate code needed to build Zephyr applications:
west zephyr-exportCreate a shortcut to
nuwa.py. This Python script wraps west commands. When usingnuwa.pyto build, it automatically installs the Python dependencies and the Toolchain:ln -sf tools/meta_tools/nuwa.py nuwa.pyInstall Python dependencies using
west(automatically installed when usingnuwa.py):west packages pip --install
Install Toolchain
The Zephyr toolchain contains the compilers, assemblers, linkers, and other programs required to build Zephyr applications for each architecture supported by Zephyr.
Currently, the Ameba platform supports only the gnuarmemb toolchain provided by Ameba; the official Zephyr SDK toolchain released by the Zephyr project is not supported.
Use the following command to install the toolchain provided by Ameba (automatically installed when using nuwa.py):
cd ~/nuwa
west realtek ameba install
Command options let you specify where the SDK is installed and which architecture toolchains to install; run west realtek ameba install -h for details.
When building with nuwa.py, the ZEPHYR_TOOLCHAIN_VARIANT and GNUARMEMB_TOOLCHAIN_PATH environment variables are automatically set to point to the Toolchain installed here, with no manual configuration needed. If you skip nuwa.py and use raw west or native zephyr commands instead, configure these two toolchain environment variables manually:
export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
export GNUARMEMB_TOOLCHAIN_PATH=~/rtk-toolchain/asdk-12.3.1-4600/linux/newlib
Use the setx command to configure user environment variables (reopen the terminal window for them to take effect):
setx ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb
setx GNUARMEMB_TOOLCHAIN_PATH C:\rtk-toolchain\asdk-12.3.1-4600\mingw32\newlib
For more details, see the Zephyr official documentation on GNU Arm Embedded.
Creating an Application
SDK uses CMake as its build system. This build system is application-centric, combining application code with the Zephyr kernel source into a single unified binary. It primarily consists of two parts:
Zephyr base directory: contains Zephyr’s own source code, kernel configuration options, and build definitions.
Application directory: contains all files specific to the application, such as configuration options and source code.
A typical application directory structure is as follows:
<app>
├── CMakeLists.txt Entry build script that integrates with the Zephyr build system
├── app.overlay Device Tree overlay file (optional)
├── prj.conf Application-specific Kconfig configuration file
├── VERSION Version identifier file (optional)
└── src
└── main.c Main application source file
Building the Application
The Zephyr build system compiles and links all components of the application into a single firmware image, which can run on either simulated or real hardware.
As with any CMake-based system, the build process occurs in two phases:
Configuration Phase: The CMake command-line tool generates build files when a generator is specified. In Zephyr, this phase also includes:
Generating
build/zephyr/zephyr.dtsandbuild/zephyr/include/generated/devicetree_generated.hbased on DTS content and YAML bindings.Collecting all Kconfig files, loading default configurations, and combining them with DTS output to determine the final set of configuration options and dependencies, resulting in
build/zephyr/.configandbuild/zephyr/include/generated/autoconf.h.Generating build system files, including
CMakeCache.txtandbuild.ninja.
Build Phase: The native build tool (e.g., Ninja) executes the actual compilation and linking to produce the firmware binary. For more information on these concepts, refer to the CMake documentation: Introduction to CMake.
Build Command
The following command is used to build an application:
./nuwa.py build -b <BOARD> [-d <BUILD_DIR>] [-i <IMAGE_DIR>] [-p] [--sysbuild] <SOURCE_DIR>
Parameter descriptions:
build: executes the build subcommand.-b <BOARD>: [Required] specifies the target board name (e.g.,rtl872xda_evb). The build toolchain automatically loads the board configuration files underzephyr/boards/realtek/rtl872xda_evb.<SOURCE_DIR>: [Required] positional argument specifying the path to the application project (relative to the SDK root directory).-d <BUILD_DIR>: [Optional] specifies the output directory for build artifacts. All intermediate and result files generated during the build are stored here; the directory name can be freely chosen. Defaults to thebuilddirectory if not specified.-i <IMAGE_DIR>: [Optional] specifies the output directory for the ImageTool firmware images. Defaults toSDK/imagesif not specified.-p: [Optional] pristine rebuild. Without this flag, the build defaults to incremental (only regenerating when the configuration changes); with it, the entire build directory is cleaned and regenerated before building, equivalent to runningwest build -t pristineand then building.--sysbuild: [Optional] creates a multi-domain (sysbuild) build system for building multiple images together (e.g., the application and MCUboot). See the Zephyr Sysbuild documentation for details.
Example: Building the Hello World Sample
./nuwa.py build -b rtl872xda_evb zephyr/samples/hello_world
Note
For the build phase, it’s best to use ./nuwa.py build (a wrapper around west build), which is more convenient than using west build manually. For environment setup, see Install Toolchain.
Partial Clean
Removes files generated during the Build Phase (e.g., .obj, .elf, .hex), but retains configuration files from the Configuration Phase (e.g., .config):
west build -t clean
Full Clean (Pristine)
Removes all files generated in both the Build Phase and Configuration Phase:
west build -t pristine
Opening the Menuconfig Interface
Menuconfig is part of the build process and depends on intermediate files generated during the Configuration Phase. If the build directory is empty, menuconfig cannot be launched, as the build system has no knowledge of the specific application directory at that point:
west build -t menuconfig
Contents of the Build Directory
The build directory is used by CMake and Ninja, and contains the build system files, intermediate files, and the final images. Its main structure is as follows:
SDK/build/
├── amebaxxx_gcc_project/ Intermediate files needed to merge multiple MCU images
├── build.ninja Ninja build file
├── CMakeCache.txt CMake configuration cache
├── CMakeFiles/ CMake internal files
├── rules.ninja Ninja build rules
└── zephyr/ Zephyr's generated files and build artifacts
After configuration and build complete, the following files are typically generated:
.config: the final effective Kconfig configuration..o,.a: compiled object files and static libraries.zephyr.elf: the final ELF image containing the application and the Zephyr kernel.zephyr.bin,zephyr.hex: other image formats converted from the ELF.
Images Directory and Firmware Flashing
After the build completes, the firmware can be flashed to the development board in either of the following two ways:
west flash: flashes the firmware directly using the
westcommand-line tool, with no additional tools required. See west flash Usage for details.ImageTool: after building with
./nuwa.py, the firmware for ImageTool is placed in theSDK/imagesdirectory by default; the ImageTool utility is located underSDK/tools/ameba/ImageTool. Refer to the Image Tool user guide for flashing instructions.
West Build and Flash Methods
west build Usage
Before building, set the toolchain environment variables. These are configured automatically when using ./nuwa.py, so no manual action is needed; if you use raw west commands directly, see Install Toolchain to configure them manually.
Common commands:
# Build the application for a specific board
west build -b <BOARD> <SOURCE_DIR>
# Clean the default build directory
west build -t pristine
west flash Usage
A Windows PC is connected to the development board via a serial cable, and the Linux server performs remote flashing.
Download and launch AmebaRemoteService on the Windows PC;
Connect the Windows PC to the development board using a serial cable, and press the button to enter download mode;
Execute the following command on the Linux server,
<PORT>is the serial port of the development board on the Windows PC, and<WINDOWS_IP>is the IP address of that PC.west flash --port <PORT> --remote-server <WINDOWS_IP>
The Windows PC is directly connected to the development board via a serial cable for flashing.
Connect the Windows PC to the development board using a serial cable, and press the button to enter download mode;
Use the following command to specify the port and start downloading,
<PORT>is the serial port of the development board on this PC.west flash --port <PORT>
Note
If the firmware currently running on the development board has
CONFIG_SHELLenabled, runningwest flashcauses the flashing tool to send a command over the serial port before flashing, automatically putting the board into download mode without needing to press the button.