Build and Flashing

Overview

This guide walks you through the following steps:

  • Set up a Zephyr command-line development environment on Ubuntu or Windows (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.

This guide supports Ubuntu 22.04 LTS and later versions. For other Linux distributions, refer to Install Linux Host Dependencies.

Linux (Ubuntu):

Update system packages:

sudo apt update
sudo apt upgrade

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.20.5

Python

3.10

Device Tree Compiler

1.4.6

Linux (Ubuntu):
  1. 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-multilib and g++-multilib may not be available and should be removed from the installation list.

  2. 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.

Get Zephyr and Install Python Dependencies

Next, download Zephyr and its modules into a new west workspace. In the following instructions, the workspace is named nuwa, but you can choose any name and location. You will also install Zephyr’s additional Python dependencies in a Python virtual environment.

  1. Create a new virtual environment:

    python3 -m venv ~/nuwa/.venv
    
  2. Activate the virtual environment:

    source ~/nuwa/.venv/bin/activate
    

    After activation, the shell prompt will display a (.venv) prefix. You can exit the virtual environment at any time by running deactivate.

    Note

    Remember to activate the virtual environment each time you start working.

  3. Install west:

    pip install west
    
  4. Get the nuwa Zephyr source code:

    cd ~/nuwa
    west init -m https://github.com/Ameba-AIoT/nuwa.git
    west update
    
  5. Export the Zephyr CMake package. This allows CMake to automatically load the boilerplate code needed to build Zephyr applications:

    west zephyr-export
    
  6. Create a shortcut to nuwa.py. This Python script wraps west commands. When using nuwa.py to build, it automatically installs Python dependencies and the Toolchain:

    ln -sf tools/meta_tools/nuwa.py nuwa.py
    
  7. Install Python dependencies using west (automatically installed when using nuwa.py):

    west packages pip --install
    

    Note

    This operation may downgrade or upgrade west itself.

Install Toolchain

The Zephyr Software Development Kit (SDK) contains toolchains for each architecture supported by Zephyr, including compilers, assemblers, linkers, and other programs required to build Zephyr applications.

Use west sdk install to install the SDK provided by Ameba (automatically installed when using nuwa.py):

cd ~/nuwa
west realtek ameba install

Tip

Command options allow you to specify the SDK installation target directory and which architecture toolchains to install. For details, run west realtek ameba install -h.

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.dts and build/zephyr/include/generated/devicetree_generated.h based 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/.config and build/zephyr/include/generated/autoconf.h.

    • Generating build system files, including CMakeCache.txt and build.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 <device> -a <application> [-p]

Parameter descriptions:

  • build: executes the build subcommand.

  • -b <device>: specifies the target board (e.g., rtl872xda_evb). The build toolchain automatically searches for the required board configuration files under zephyr/boards/realtek/rtl872xda_evb.

  • -d BUILD_DIR: (optional) specifies the output directory for build artifacts. All files generated during the build are stored here; the directory name can be freely chosen.

  • -a <application>: specifies the path to the application (relative to the SDK root directory).

  • -p: forces a full rebuild. If build artifacts from a previous build exist in the build directory, omitting this flag results in an incremental build; including it triggers a clean rebuild.

Example: Building the Hello World Sample

./nuwa.py build -b rtl872xda_evb -a zephyr/samples/hello_world

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 or ./nuwa.py build -c

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 or ./nuwa.py config

Contents of the Build Directory

By default, the build directory has the following structure:

SDK/build
├── amebaxxx_gcc_project       Intermediate files for merging multiple MCU binaries
├── build.ninja                Ninja build script (auto-generated)
├── CMakeCache.txt             CMake cache configuration
├── CMakeFiles                 CMake intermediate files
├── cmake_install.cmake        Installation script (typically unused)
├── rules.ninja                Ninja rule definitions
└── zephyr                     Working directory for the Zephyr build system; most generated files are created and stored here

These build output files are written to the zephyr subdirectory within the build directory after running ninja:

  • .config: contains the configuration settings used to build the application.

  • Various object and archive files (.o and .a) containing compiled kernel and application code.

  • zephyr.elf: the final combined binary of the application and kernel. Other binary formats such as .hex and .bin are also supported.

Images Directory and Firmware Flashing

After a successful build using ./nuwa.py, the firmware intended for downloading via ImageTool is placed in the SDK/images directory. To flash the firmware, use ImageTool located in SDK/tools/ameba/ImageTool. Refer to the Image Tool user guide for flashing instructions.

West Build and Flash Methods

west build Usage

Two environment variables need to be set (check if they are already configured; if not, add them):

export ZEPHYR_TOOLCHAIN_VARIANT='gnuarmemb'
export GNUARMEMB_TOOLCHAIN_PATH=~/rtk-toolchain/asdk-12.3.1/linux/newlib

Common command examples:

west build -b <BOARD> path/to/build/directory // Build a specific application for a given board
west build -t pristine                        // Pristine build, removes all files in the build directory

west flash Usage

Linux:

A Windows PC is connected to the development board via a serial cable, and the Linux server performs remote flashing.

  1. Download and launch AmebaRemoteService on the Windows PC;

  2. Connect the Windows PC to the development board using a serial cable, and press the button to enter download mode;

  3. Execute the following command on the Linux server, where ip is the IP address of the Windows PC:

    west flash --port port --remote-server ip
    

Note

  • If the firmware on the development board was compiled with the CONFIG_SHELL configuration enabled, it can recognize the commands automatically sent to the board before flashing to enter download mode, eliminating the need to manually press the button.