RISC-V上でZephyrが動作する環境ができてきました。
公式のチュートリアルに沿って実行すれば良いのですが、そのままでは幾つかハマった点があったのでメモ。
#環境
OS: Windows10 VMware Player15上のUbuntu 18.04
Zephyr: v1.14.0-rc3 (https://github.com/zephyrproject-rtos/zephyr)
Board: SiFive HiFive1 (https://www.sifive.com/boards/hifive1)
#参照ページ
Zephyr Project "RISC-V - Getting Started Guide" https://risc-v-getting-started-guide.readthedocs.io/en/latest/
#Setup
Ubuntuではチュートリアルに従って足りないパッケージがあれば追加しました。
$ sudo apt install --no-install-recommends git cmake ninja-build gperf
ccache dfu-util device-tree-compiler wget
python3-pip python3-setuptools python3-wheel xz-utils file make gcc
gcc-multilib
###cmakeバージョン
Ubuntu18.04では3.10が入ってますがZephyrが3.13.1以上を要求してきました。
cmakeのdebパッケージに対応したものが無かったため、こちら (https://cmake.org/download/) からcmake-3.14.1-Linux-x86_64.tar.gzをダウンロードしました。
$ tar zxvf cmake-3.14.1-Linux-x86_64.tar.gz
$ export PATH=cmake-3.14.1-Linux-x86_64/bin:$PATH
###dtcバージョン
device tree compilerもUbuntu18.04のものはバージョンが古いと言われました。
こちら (https://packages.ubuntu.com/cosmic/amd64/device-tree-compiler/download) から1.4.7-1をダウンロードしました。
$ sudo apt install ./device-tree-compiler_1.4.7-1_amd64.deb
#環境変数の設定
後で良いですが、Zephyrインストールと動作の過程で幾つか設定が必要になりました。
$ export ZEPHYR_BASE=/home/work/zephyr #zephyrをgit cloneするディレクトリ
$ export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
$ export ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk #Zephyr SDKのインストールディレクトリ
#Zephyrのダウンロードと設定
$ git clone https://github.com/zephyrproject-rtos/zephyr
$ cd zephyr # (← $ZEPHYR_BASE)
$ pip3 install --user -r scripts/requirements.txt
$ export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
$ . ./zephyr-env.sh
#Zephyr SDKのダウンロード
公式ページには0.9.5で記載されているのですが、インストールの過程で古いと怒られました。
まだNG版なのか分からないですが、動作確認のため取り急ぎ0.10.0にしておきます。
$ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.10.0/zephyr-sdk-0.10.0-setup.run
$ chmod 755 zephyr-sdk-0.10.0-setup.run
$ sudo ./zephyr-sdk-0.10.0-setup.run
Verifying archive integrity... All good.
Uncompressing SDK for Zephyr 100%
Enter target directory for SDK (default: /opt/zephyr-sdk/): #デフォルトは/opt下
Installing SDK to /opt/zephyr-sdk
Creating directory /opt/zephyr-sdk
Success
[*] Installing x86 tools...
[*] Installing arm tools...
[*] Installing arc tools...
[*] Installing iamcu tools...
[*] Installing nios2 tools...
[*] Installing xtensa tools...
[*] Installing riscv32 tools...
[*] Installing additional host tools...
Success installing SDK. SDK is ready to be used.
#HiFive1で動作させるアプリケーションのビルド
hello_worldの中身をいじって動作させてみます。printkを2行追加。
元々がWindRiverのRocketだったことが分かります。
$ vi $ZEPHYR_BASE/samples/hello_world/src/main.c
$ mkdir build-example
$ cd build-example
$ cmake -DBOARD=hifive1 $ZEPHYR_BASE/samples/hello_world
Zephyr version: 1.14.0
-- Selected BOARD hifive1
-- Loading /home/work/boards/riscv32/hifive1/hifive1.dts as base
-- Overlaying /home/work/dts/common/common.dts
Parsing Kconfig tree in /home/work/zephyr/Kconfig
Loading /home/work/zephyr/build-example/zephyr/.config as base
Configuration written to '/home/work/zephyr/build-example/zephyr/.config'
-- Cache files will be written to: /home/.cache/zephyr
-- Configuring done
-- Generating done
-- Build files have been written to: /home/work/zephyr/build-example
$ make -j $(nproc)
[ 1%] Built target kobj_types_h_target
[ 2%] Built target syscall_macros_h_target
[ 3%] Built target driver_validation_h_target
[ 4%] Generating misc/generated/syscalls.json
[ 7%] Built target syscall_list_h_target
Scanning dependencies of target offsets
[ 8%] Building C object zephyr/CMakeFiles/offsets.dir/arch/riscv32/core/offsets/offsets.c.obj
[ 8%] Built target offsets
[ 9%] Built target offsets_h
Scanning dependencies of target linker_script_target
Scanning dependencies of target app
[ 10%] Generating linker.cmd
Scanning dependencies of target zephyr
Scanning dependencies of target kernel
[ 11%] Building C object CMakeFiles/app.dir/src/main.c.obj
[ 11%] Built target linker_script_target
[ 12%] Linking C static library app/libapp.a
Scanning dependencies of target lib__libc__minimal
[ 12%] Built target app
[ 13%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdlib/malloc.c.obj
Scanning dependencies of target boards__riscv32__hifive1
[ 14%] Building C object zephyr/lib/libc/minimal/CMakeFiles/lib__libc__minimal.dir/source/stdout/stdout_console.c.obj
[ 15%] Linking C static library liblib__libc__minimal.a
[ 16%] Building C object zephyr/boards/riscv32/hifive1/CMakeFiles/boards__riscv32__hifive1.dir/pinmux.c.obj
[ 17%] Building C object zephyr/boards/riscv32/hifive1/CMakeFiles/boards__riscv32__hifive1.dir/clock.c.obj
[ 27%] Built target lib__libc__minimal
[ 28%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/common/isr_tables.c.obj
[ 29%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/device.c.obj
Scanning dependencies of target drivers__gpio
[ 30%] Linking C static library libboards__riscv32__hifive1.a
[ 31%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/common/sw_isr_common.c.obj
[ 32%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/errno.c.obj
[ 33%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/cpu_idle.c.obj
[ 34%] Building C object zephyr/drivers/gpio/CMakeFiles/drivers__gpio.dir/gpio_sifive.c.obj
[ 35%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/fatal.c.obj
[ 36%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/idle.c.obj
[ 36%] Built target boards__riscv32__hifive1
[ 37%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/irq_manage.c.obj
[ 38%] Linking C static library libdrivers__gpio.a
[ 39%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/init.c.obj
[ 40%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/irq_offload.c.obj
Scanning dependencies of target drivers__spi
[ 41%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mailbox.c.obj
[ 42%] Building ASM object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/isr.S.obj
[ 42%] Built target drivers__gpio
[ 43%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/prep_c.c.obj
Scanning dependencies of target drivers__serial
[ 44%] Building C object zephyr/drivers/spi/CMakeFiles/drivers__spi.dir/spi_sifive.c.obj
[ 45%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mem_slab.c.obj
[ 46%] Building ASM object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/reset.S.obj
[ 47%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mempool.c.obj
[ 48%] Linking C static library libdrivers__spi.a
[ 50%] Building ASM object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/swap.S.obj
[ 51%] Building C object zephyr/drivers/serial/CMakeFiles/drivers__serial.dir/uart_sifive.c.obj
[ 52%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/msg_q.c.obj
[ 53%] Building C object zephyr/CMakeFiles/zephyr.dir/arch/riscv32/core/thread.c.obj
[ 54%] Linking C static library libdrivers__serial.a
[ 55%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/mutex.c.obj
[ 55%] Built target drivers__spi
[ 56%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/pipes.c.obj
[ 57%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/fdtable.c.obj
[ 58%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/mempool.c.obj
[ 59%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/queue.c.obj
[ 59%] Built target drivers__serial
[ 61%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sem.c.obj
[ 61%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/sched.c.obj
[ 62%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/rb.c.obj
[ 63%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/stack.c.obj
[ 64%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/system_work_q.c.obj
[ 65%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/thread_entry.c.obj
[ 66%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/work_q.c.obj
[ 67%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/thread.c.obj
[ 68%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/printk.c.obj
[ 69%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/thread_abort.c.obj
[ 70%] Building C object zephyr/CMakeFiles/zephyr.dir/soc/riscv32/riscv-privilege/common/idle.c.obj
[ 71%] Building ASM object zephyr/CMakeFiles/zephyr.dir/soc/riscv32/riscv-privilege/common/soc_irq.S.obj
[ 72%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/work_q.c.obj
[ 73%] Building C object zephyr/CMakeFiles/zephyr.dir/soc/riscv32/riscv-privilege/common/soc_common_irq.c.obj
[ 75%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/interrupt_controller/plic.c.obj
[ 76%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/console/uart_console.c.obj
[ 77%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/smp.c.obj
[ 78%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/pinmux/pinmux_sifive.c.obj
[ 79%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/timer/sys_clock_init.c.obj
[ 81%] Building C object zephyr/CMakeFiles/zephyr.dir/drivers/timer/riscv_machine_timer.c.obj
[ 81%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timeout.c.obj
[ 82%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/timer.c.obj
[ 83%] Building C object zephyr/kernel/CMakeFiles/kernel.dir/atomic_c.c.obj
[ 84%] Linking C static library libzephyr.a
[ 85%] Linking C static library libkernel.a
[ 91%] Built target zephyr
[ 92%] Built target kernel
[ 93%] Linking C executable zephyr_prebuilt.elf
Memory region Used Size Region Size %age Used
ROM: 18176 B 12 MB 0.14%
RAM: 4272 B 16 KB 26.07%
IDT_LIST: 553 B 2 KB 27.00%
[ 94%] Built target zephyr_prebuilt
Scanning dependencies of target linker_pass_final_script_target
[ 95%] Generating linker_pass_final.cmd
[ 95%] Built target linker_pass_final_script_target
[ 96%] Generating isr_tables.c
Scanning dependencies of target kernel_elf
[ 97%] Building C object zephyr/CMakeFiles/kernel_elf.dir/isr_tables.c.obj
[ 98%] Linking C executable zephyr.elf
Generating files from zephyr.elf for board: hifive1
[100%] Built target kernel_elf
#HiFive1のFlashへの書き込み
$ cd $ZEPHYR_BASE/build-example/zephyr
makeによるbuildの結果、ここに zephyr.elfができています。
OpenOCDで接続してGDBで書き込みです。
openocdが必要なのですが、SiFiveのfreedom-e-sdkを用意しておきます。
チュートリアルに記載されているPATHも少し古いようです。
また、openocdコマンドに&をつけてバックグラウンド実行しないとうまくいきませんでした。
$ git clone https://github.com/sifive/freedom-e-sdk
$ sudo openocd -f freedom-e-sdk/bsp/sifive-hifive1/openocd.cfg &
Open On-Chip Debugger 0.10.0+dev-00198-g35eed36f (2018-12-16-20:53)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 10000 kHz
Info : auto-selecting first available session transport "jtag". To override use 'transport select '.
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 10000 kHz
Info : JTAG tap: riscv.cpu tap/device found: 0x10e31913 (mfg: 0x489 (SiFive, Inc.), part: 0x0e31, ver: 0x1)
Info : Examined RISCV core; XLEN=32, misa=0x40001105
Info : Listening on port 3333 for gdb connections
Info : [0] Found 2 triggers
halted at 0x20400904 due to debug interrupt
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
GDBからFlashのプロテクトを解除してelfをUSB経由で書き込みます。
$ riscv32-unknown-elf-gdb
(gdb)set remotetimeout 240
(gdb)target extended-remote localhost:3333
(gdb)monitor reset halt
(gdb)monitor flash protect 0 64 last off
(gdb)load zephyr.elf #buildで生成されたelfファイル
(gdb)monitor resume
#HiFive1での動作確認
シリアル通信ができるターミナルから、ttyUSBxに115200 baudで接続し、HiFive1ボードのリセットボタンを押します。
$ sudo gtkterm
Zephyr OS上で表示をタスクとして実行できました。
オープンCPUとオープンRTOSの組み合わせで色々できそうです。
##QEMU
ちなみにQEMU版であれば、アプリケーションビルドのあとに make run だけで実行できるようになっています。
$ make run
[ 1%] Built target kobj_types_h_target
[ 2%] Built target syscall_macros_h_target
[ 3%] Generating misc/generated/syscalls.json
[ 6%] Built target syscall_list_h_target
[ 7%] Built target driver_validation_h_target
[ 8%] Built target offsets
[ 9%] Built target offsets_h
[ 34%] Built target kernel
[ 36%] Built target app
[ 37%] Built target linker_script_target
[ 70%] Built target zephyr
[ 82%] Built target lib__libc__minimal
[ 85%] Built target boards__riscv32__hifive1
[ 87%] Built target drivers__gpio
[ 89%] Built target drivers__spi
[ 91%] Built target drivers__serial
[ 93%] Built target zephyr_prebuilt
[ 94%] Built target linker_pass_final_script_target
[ 98%] Built target kernel_elf
Scanning dependencies of target run
[100%]
To exit from QEMU enter: 'CTRL+a, x'
[QEMU] CPU: riscv32
***** Booting Zephyr OS v1.14.0-rc3-137-g6c6217e8b330 *****
Hello World! hifive1
From Heisei to Reiwa in Japan! hifive1
2019/04/07 hifive1
QEMU: Terminated
[100%] Built target run