Beyond the Getting Started Guide
The Getting Started Guide gives a straight-forward path to set up your Linux, macOS, or Windows environment for Zephyr development. In this document, we delve deeper into Zephyr development setup issues and alternatives.
Python and pip
Python 3 and its package manager, pip1, are used extensively by Zephyr to install and run scripts required to compile and run Zephyr applications, set up and maintain the Zephyr development environment, and build project documentation.
Depending on your operating system, you may need to provide the
--user
flag to the pip3
command when installing new packages. This is
documented throughout the instructions.
See Installing Packages in the Python Packaging User Guide for more
information about pip1, including information on -\-user.
On Linux, make sure
~/.local/bin
is at the front of yourPATH
environment variable, or programs installed with--user
won’t be found. Installing with--user
avoids conflicts between pip and the system package manager, and is the default on Debian-based distributions.On macOS, Homebrew disables -\-user.
On Windows, see the Installing Packages information on
--user
if you require using this option.
On all operating systems, pip’s -U
flag installs or updates the package if the
package is already installed locally but a more recent version is available. It
is good practice to use this flag if the latest version of a package is
required. (Check the scripts/requirements.txt file to
see if a specific Python package version is expected.)
Advanced Setup and tool chain alternatives
Here are some alternative instructions for more advanced platform setup configurations for supported development platforms:
Set Up a Toolchain
Zephyr binaries are compiled and linked by a toolchain comprised of a cross-compiler and related tools which are different than the compiler and tools used for developing software that runs natively on your operating system.
On Linux systems, you can install the Zephyr SDK to get toolchains for all supported architectures. Otherwise, you can install other toolchains in the usual way for your operating system: with installer programs or system package managers, by downloading and extracting a zip archive, etc.
You configure the Zephyr build system to use a specific toolchain by
setting environment variables such as
ZEPHYR_TOOLCHAIN_VARIANT
to a supported value, along with
additional variable(s) specific to the toolchain variant.
While the Zephyr SDK includes standard tool chains for all supported architectures, there are also customized alternatives as described in these documents. (If you’re not sure which to use, check your specific board-level documentation. If you’re targeting an Arm Cortex-M board, for example, GNU Arm Embedded is a safe bet.)
Cloning the Zephyr Repositories
The Zephyr project source is maintained in the GitHub zephyr repo. External modules used by Zephyr are found in the parent GitHub Zephyr project. Because of these dependencies, it’s convenient to use the Zephyr-created west tool to fetch and manage the Zephyr and external module source code. See Basics for more details.
Once your development tools are installed, use West (Zephyr’s meta-tool) to create,
initialize, and download sources from the zephyr and external module
repos. We’ll use the name zephyrproject
, but you can choose any
name that does not contain a space anywhere in the path.
west init zephyrproject
cd zephyrproject
west update
The west update
command fetches and keeps Modules (External projects) in the
zephyrproject
folder in sync with the code in the local zephyr
repo.
Warning
You must run west update
any time the zephyr/west.yml
changes, caused, for example, when you pull the zephyr
repository, switch branches in it, or perform a git bisect
inside of
it.
Keeping Zephyr updated
To update the Zephyr project source code, you need to get the latest
changes via git
. Afterwards, run west update
as mentioned in
the previous paragraph.
# replace zephyrproject with the path you gave west init
cd zephyrproject/zephyr
git pull
west update
Export Zephyr CMake package
The Zephyr CMake Package can be exported to CMake’s user package registry if it has not already been done as part of Getting Started Guide.
Board Aliases
Developers who work with multiple boards may find explicit board names cumbersome and want to use aliases for common targets. This is supported by a CMake file with content like this:
# Variable foo_BOARD_ALIAS=bar replaces BOARD=foo with BOARD=bar and
# sets BOARD_ALIAS=foo in the CMake cache.
set(pca10028_BOARD_ALIAS nrf51dk_nrf51422)
set(pca10056_BOARD_ALIAS nrf52840dk_nrf52840)
set(k64f_BOARD_ALIAS frdm_k64f)
set(sltb004a_BOARD_ALIAS efr32mg_sltb004a)
and specifying its location in ZEPHYR_BOARD_ALIASES
. This
enables use of aliases pca10028
in contexts like
cmake -DBOARD=pca10028
and west -b pca10028
.
Build and Run an Application
You can build, flash, and run Zephyr applications on real hardware using a supported host system. Depending on your operating system, you can also run it in emulation with QEMU, or as a native POSIX application. Additional information about building applications can be found in the Building an Application section.
Build Blinky
Let’s build the Blinky sample application.
Zephyr applications are built to run on specific hardware, called a
“board”2. We’ll use the Phytec reel_board here, but you can change the reel_board
build target
to another value if you have a different board. See Supported Boards or run
west boards
from anywhere inside the zephyrproject
directory for
a list of supported boards.
Go to the zephyr repository:
cd zephyrproject/zephyr
Build the blinky sample for the
reel_board
:west build -b reel_board samples/basic/blinky
The main build products will be in build/zephyr
;
build/zephyr/zephyr.elf
is the blinky application binary in ELF
format. Other binary formats, disassembly, and map files may be present
depending on your board.
The other sample applications in the samples folder are documented in Samples and Demos.
Note
If you want to re-use an
existing build directory for another board or application, you need to
add the parameter -p=auto
to west build
to clean out settings
and artifacts from the previous build.
Run the Application by Flashing to a Board
Most hardware boards supported by Zephyr can be flashed by running
west flash
. This may require board-specific tool installation and
configuration to work properly.
See Run an Application and your specific board’s documentation in Supported Boards for additional details.
Setting udev rules
Flashing a board requires permission to directly access the board
hardware, usually managed by installation of the flashing tools. On
Linux systems, if the west flash
command fails, you likely need to
define udev rules to grant the needed access permission.
Udev is a device manager for the Linux kernel and the udev daemon handles all user space events raised when a hardware device is added (or removed) from the system. We can add a rules file to grant access permission by non-root users to certain USB-connected devices.
The OpenOCD (On-Chip Debugger) project conveniently provides a rules file that defined board-specific rules for most Zephyr-supported arm-based boards, so we recommend installing this rules file by downloading it from their sourceforge repo, or if you’ve installed the Zephyr SDK there is a copy of this rules file in the SDK folder:
Either download the OpenOCD rules file and copy it to the right location:
wget -O 60-openocd.rules https://sf.net/p/openocd/code/ci/master/tree/contrib/60-openocd.rules?format=raw sudo cp 60-openocd.rules /etc/udev/rules.d
or copy the rules file from the Zephyr SDK folder:
sudo cp ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d
Then, in either case, ask the udev daemon to reload these rules:
sudo udevadm control --reload
Unplug and plug in the USB connection to your board, and you should have permission to access the board hardware for flashing. Check your board-specific documentation (Supported Boards) for further information if needed.
Run the Application in QEMU
On Linux and macOS, you can run Zephyr applications via emulation on your host system using QEMU when targeting either the x86 or ARM Cortex-M3 architectures. (QEMU is included with the Zephyr SDK installation.)
For example, you can build and run the Hello World sample using
the x86 emulation board configuration (qemu_x86
), with:
# From the root of the zephyr repository
west build -b qemu_x86 samples/hello_world
west build -t run
To exit QEMU, type Ctrl-a, then x.
Use qemu_cortex_m3
to target an emulated Arm Cortex-M3 sample.
Run a Sample Application natively (POSIX OS)
You can compile some samples to run as host processes on a POSIX OS. This is currently only tested on Linux hosts. See Native POSIX execution (native_posix) for more information. On 64-bit host operating systems, you need to install a 32-bit C library; see Host system dependencies for details.
First, build Hello World for native_posix
.
# From the root of the zephyr repository
west build -b native_posix samples/hello_world
Next, run the application.
west build -t run
# or just run zephyr.exe directly:
./build/zephyr/zephyr.exe
Press Ctrl-C to exit.
You can run ./build/zephyr/zephyr.exe --help
to get a list of available
options.
This executable can be instrumented using standard tools, such as gdb or valgrind.
Footnotes
- 1(1,2)
pip is Python’s package installer. Its
install
command first tries to re-use packages and package dependencies already installed on your computer. If that is not possible,pip install
downloads them from the Python Package Index (PyPI) on the Internet.The package versions requested by Zephyr’s
requirements.txt
may conflict with other requirements on your system, in which case you may want to set up a virtualenv for Zephyr development.- 2
This has become something of a misnomer over time. While the target can be, and often is, a microprocessor running on its own dedicated hardware board, Zephyr also supports using QEMU to run targets built for other architectures in emulation, targets which produce native host system binaries that implement Zephyr’s driver interfaces with POSIX APIs, and even running different Zephyr-based binaries on CPU cores of differing architectures on the same physical chip. Each of these hardware configurations is called a “board,” even though that doesn’t always make perfect sense in context.