Zephyr OS on HiFive1

A guide on how to cross compile Zephyr OS for RISC-V on MacOS running OSX Mojave. You will be using precompiled tools and a custom Zephyr OS toolchain.

GCC Toolchain & OpenOCD

Download the prebuilt RISC‑V GCC Toolchain and OpenOCD from the SiFive home page:

$ wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.1.0-2018.12.0-x86_64-apple-darwin.tar.gz
$ wget https://static.dev.sifive.com/dev-tools/riscv-openocd-0.10.0-2018.12.0-x86_64-apple-darwin.tar.gz

and extract both archives:

$ tar -xvf riscv64-unknown-elf-gcc-8.1.0-2018.12.0-x86_64-apple-darwin.tar.gz
$ tar -xvf riscv-openocd-0.10.0-2018.12.0-x86_64-apple-darwin.tar.gz

Zephyr OS

Zephyr RTOS is developed on GitHub. You can get the sources easily by cloning the official repo:

$ git clone https://github.com/zephyrproject-rtos/zephyr.git
$ cd zephyr

Install the required dependencies using Homebrew:

$ brew install cmake ninja gperf ccache dfu-util qemu dtc python3

and the Python dependencies:

$ pip3 install -r zephyr/scripts/requirements.txt

Custom CMake toolchain

The Hifive1 uses the SiFive Freedom E310 Microcontroller which supports the RV32I Base Integer Instruction Set (Version 2.0) including 3 extensions:

  • M - Standard Extension for Integer Multiplication and Division, Version 2.0
  • A - Standard Extension for Atomic Instructions, Version 2.0
  • C - Standard Extension for Compressed Instructions, Version 1.9

The toolchain is build with multilib support so we can use the 64bit version to compile 32bit application. We use CMake to configure the compiler and linker by adding parameters to TOOLCHAIN_C_FLAGS and TOOLCHAIN_LD_FLAGS.

Create a directory for for the custom toolchain in the cmake directory:

$ cd cmake/toolchain
$ mkdir riscv32

Create 2 files in this directory with the following content:

  • generic.cmake (replace TOOLCHAIN_PATH with the path where you extracted the toolchain)
set(CROSS_COMPILE "<TOOLCHAIN_PATH>/bin/riscv64-unknown-elf-")

set(COMPILER gcc)

list(APPEND TOOLCHAIN_C_FLAGS
  -march=rv32imac
  -mabi=ilp32
)
list(APPEND TOOLCHAIN_LD_FLAGS
  -march=rv32imac
  -mabi=ilp32
)
  • target.cmake
# This file intentionally left blank.

Building the samples

Set up your build environment:

$ source zephyr-env.sh

Set the Zepyr OS toolchain:

$ export ZEPHYR_TOOLCHAIN_VARIANT=riscv32

Navigate to the Hello World sample directory:

$ cd samples/hello_world

Create a build directory

$ mkdir build
$ cd build

Run CMake to configure a Ninja-based build system:

$ cmake -GNinja -DBOARD=hifive1 ..

Run Ninja to build:

$ ninja

Runnin on the SiFive HiFive1

Get the OpenOCD configuration:

$ wget https://raw.githubusercontent.com/sifive/freedom-e-sdk/master/bsp/env/freedom-e300-hifive1/openocd.cfg

Plug in the HiFive1 and run:

$ openocd -f openocd.cfg

In a second terminal navigate to samples/hello_world/build/zephyr/ and run this command to load the program onto the HiFive1:

$ riscv64-unknown-elf-gdb zephyr.elf --batch -ex 'set remotetimeout 240' -ex 'target extended-remote localhost:3333' -ex 'monitor reset halt' -ex 'monitor flash protect 0 64 last off' -ex 'load' -ex 'monitor resume' -ex 'monitor shutdown' -ex 'quit'

Now run screen and connect to the serial port:

$ screen /dev/cu.usbserial-14101 115200

If you press the reset button on the HiFive1 you should see:

***** Booting Zephyr OS zephyr-v1.13.0-2883-g56d144cd70 *****
Hello World! hifive1

Previous Post