Run Zephyr RTOS on ESP32

3 minute read

IoT gains too much attention these years, there are various RTOS are claimed to IoT OS, Zephyr OS is one of them, it is originated from WindRiver and is a project of Linux Foundation, it supports many architectures including arm, risc-v, sparc, Tensilica Xtensa etc, today I am gonna give it a shot, trying to run it on popular ESP32 module.

Build Environment

Follow this guide to setup the required build environment for Zephyr.

Build Zephyr requires cmake to be more recent than the version in the Ubuntu’s apt repository, I am using Ubuntu 18.04, add kitware repository for new cmake, and install other required packages as follows:

$ wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
$ sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main'
$ sudo apt install --no-install-recommends git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget \
  python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
  make gcc gcc-multilib g++-multilib libsdl2-dev

Another way to install cmake is download the latest package and install it manually:

wget -c https://github.com/Kitware/CMake/releases/download/v3.18.6/cmake-3.18.6-Linux-x86_64.sh

west is the main tool for zephyr development, it manages the repositories (like repo in android), and build and more, so I install it first:

$ python3 -m pip install --user -U west

Next populate zephyr project with west:

$ mkdir zephyrproject && cd zephyrproject
$ west init
$ west update

# Install xtensa-esp32-elf to $HOME/.espressif
$ west espressif install

$ python3 -m pip install --user -r zephyr/scripts/requirements.txt

NOTE:
espressif subcommand only works under zephyr directory.

According to ESP32 Build Environment Setup following variables needs to be exported:

cat << EOF >> ~/.oh-my-zsh/custom/path.zsh

export ZEPHYR_TOOLCHAIN_VARIANT="espressif"
export ESPRESSIF_TOOLCHAIN_PATH="\${HOME}/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf"
export PATH=\$PATH:\$ESPRESSIF_TOOLCHAIN_PATH/bin
EOF

Build Hello World

As of this time, builtin WiFi and BLE is not supported yet, so this will be the last step of this post, Sylvio Alves is working on this, will update if there is any progress.

$ cd zephyr
$ west build -b esp32 samples/hello_world
$ west flash

-- west flash: rebuilding
[0/1] cd /opt/workdir/esplink/zephyrproject/zephyr/build/zephyr/cmake/flash && /usr/bin/cmake -E echo

-- west flash: using runner esp32
-- runners.esp32: Converting ELF to BIN
esptool.py v3.1-dev
Merged 2 ELF sections
-- runners.esp32: Flashing ESP32 on /dev/ttyUSB0 (921600bps)
esptool.py v3.1-dev
Serial port /dev/ttyUSB0
Connecting.....
Chip is ESP32-D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: ac:67:b2:30:47:80
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Wrote 32768 bytes at 0x00001000 in 0.5 seconds (535.1 kbit/s)...
Hash of data verified.
Wrote 16384 bytes at 0x00008000 in 0.2 seconds (577.6 kbit/s)...
Hash of data verified.
Wrote 81920 bytes at 0x00010000 in 1.1 seconds (611.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

The boot message can be viewed with kermit:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7312
load:0x40078000,len:13212
load:0x40080400,len:4568
entry 0x400806f4
I (26) boot: ESP-IDF 895d99ed0 2nd stage bootloader
I (27) boot: compile time 09:09:56
I (27) boot: chip revision: 1
I (30) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (37) boot.esp32: SPI Speed      : 40MHz
I (41) boot.esp32: SPI Mode       : DIO
I (46) boot.esp32: SPI Flash Size : 4MB
I (50) boot: Enabling RNG early entropy source...
I (56) boot: Partition Table:
I (59) boot: ## Label            Usage          Type ST Offset   Length
I (67) boot:  0 nvs              WiFi data        01 02 00002000 00006000
I (74) boot:  1 phy_init         RF data          01 01 00008000 00001000
I (82) boot:  2 factory          factory app      00 00 00010000 00100000
I (89) boot: End of partition table
I (93) boot_comm: chip revision: 1, min. application chip revision: 0
I (100) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x0031c (   796) map
I (110) esp_image: segment 1: paddr=0x00010344 vaddr=0x3ffb0000 size=0x001ec (   492) load
I (118) esp_image: segment 2: paddr=0x00010538 vaddr=0x3ffb01ec size=0x00148 (   328) load
I (127) esp_image: segment 3: paddr=0x00010688 vaddr=0x40080000 size=0x00400 (  1024) load
I (137) esp_image: segment 4: paddr=0x00010a90 vaddr=0x40080400 size=0x02600 (  9728) load
I (149) esp_image: segment 5: paddr=0x00013098 vaddr=0x00000000 size=0x0cf80 ( 53120)
I (174) esp_image: segment 6: paddr=0x00020020 vaddr=0x400d0020 size=0x01634 (  5684) map
I (178) boot: Loaded app from partition at offset 0x10000
��*** Booting Zephyr OS build v2.5.0-rc4-2-g769d91b922b7  ***
Hello World! esp32