Freedom E300 Arty DevKit でRISCVとZephyr OSを試す

Zephyrは Linux Foundationが開発する IoT向けのリアルタイムOSです。Zephyr OSがRISCVをサポートしたので、Freedom E300 Arty DevKit 上でマルチスレッドのサンプルアプリ、philosophersをARTYのRISCVで動かすまでの手順を紹介します。

## 作業環境

- Host PC (Ubuntu 16.04 64bit)
- Xilinx Vivado 2016.2
- Arduino 1.8.0
- SiFive 1.0.2
- Digilent Arty
- Olimex JTAG ARM-USB-TINY-H (https://strawberry-linux.com/catalog/items?code=15045)

ARTYにRISCV（Freedom E300 Arty DevKit）を書き込むまでは「[Freedom E300 Arty DevKit でRISCVを試す](http://qiita.com/mune10/items/98a19d49bbbe14473988)」を参考にしてください。以下はARTY上でRISCVが動いていてArduinoからアプリの実行が出来ている状態からの追加の作業になります。

## サンプルアプリのビルドとアップロードまで

ZephyrをGithubからCloneして、環境変数設定。

    $ git clone https://github.com/fractalclone/zephyr-riscv.git
    $ cd zephyr-riscv
    $ source zephyr-env.sh

RISCVのツールチェインを設定。ArduinoでSiFiveのパッケージをインストールしているのでそれを参照させます。ツールチェイン等は .arduino15/packages/sifive/tools/ 以下に展開されていいますが、ディレクトリ名にハッシュ値が使われているため、実際のパスは各自で確認してください。以下は設定例です。

    $ export RISCV32_TOOLCHAIN_PATH=~/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f
    $ export ZEPHYR_GCC_VARIANT=riscv32

あとはサンプリアプリのコンパイルです。

    $ cd samples/philosophers
    $ make BOARD=arty_fe310

問題なくコンパイル出来た場合は outdir/arty_fe310 に zephyr.bin、zephyr.elfが生成されます。次にOpenOCDを使ってArtyのSPI Flashにアップロードします。OpenOCDもArduinoのSiFiveパッケージでインストールしたものを使うようにPATHをセットします。

    $ export PATH=~/.arduino15/packages/sifive/tools/openocd/9bab0782d313679bb0bfb634e6e87c757b8d5503/bin:$PATH
    $ openocd --version
    Open On-Chip Debugger 0.10.0-dev-g9bab078 (2017-02-02-01:39)
    Licensed under GNU GPL v2
    For bug reports, read
      http://openocd.org/doc/doxygen/bugs.html

（パスが長いので）OpenOCD実行スクリプトと、コンフィグを手元にコピーしておきます。

    $ cp ~/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/tools/openocd_upload.sh .
    $ cp ~/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-arty/openocd.cfg .

アップロード

    $ ./openocd_upload.sh outdir/arty_fe310/zephyr.elf openocd.cfg
    + openocd -f openocd.cfg -c 'flash protect 0 64 last off; program outdir/arty_fe310/zephyr.elf verify; resume 0x20400000; exit'
    + tee openocd_upload.log
    Open On-Chip Debugger 0.10.0-dev-g193f630 (2017-01-19-14:49)
    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 <transport>'.
    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 (<unknown>), part: 0x0e31, ver: 0x1)
    Info : Examined RISCV core; XLEN=32, misa=0x40001105
    riscv.cpu: target state: halted
    halted at 0x20400104 due to debug interrupt
    Info : Found flash device 'micron n25q128' (ID 0x0018ba20)
    cleared protection for sectors 64 through 255 on flash bank 0
    Info : JTAG tap: riscv.cpu tap/device found: 0x10e31913 (mfg: 0x489 (<unknown>), part: 0x0e31, ver: 0x1)
    riscv.cpu: target state: halted
    halted at 0x404 due to software breakpoint
    ** Programming Started **
    auto erase enabled
    riscv.cpu: target state: halted
    halted at 0x80000004 due to software breakpoint
    riscv.cpu: target state: halted
    <SNIP>
    wrote 65536 bytes from file outdir/arty_fe310/zephyr.elf in 0.604254s (105.916 KiB/s)
    ** Programming Finished **
    ** Verify Started **
    Info : dtmcontrol_idle=5, dbus_busy_delay=0, interrupt_high_delay=1
    <SNIP>
    verified 17472 bytes in 0.147186s (115.925 KiB/s)
    ** Verified OK **
    halted at 0x20400004 due to step

以上でアップロードが終了し ARTYのRISCV上でphilosophersが動いてるはずです。

## 実行結果

ARTYのシリアルコンソールで動作を確認します。

    $ screen /dev /ttyUSB1 115200

下記のような画面が表示されれば成功です。

    Philosopher 0 [P: 3]        STARVING       
    Philosopher 1 [P: 2]    HOLDING ONE FORK   
    Philosopher 2 [P: 1]   EATING  [  400 ms ] 
    Philosopher 3 [P: 0]        STARVING       
    Philosopher 4 [C:-1]   EATING  [  525 ms ] 
    Philosopher 5 [C:-2]    HOLDING ONE FORK   
    
    
    Demo Description
    ----------------
    An implementation of a solution to the Dining Philosophers
    problem (a classic multi-thread synchronization problem).
    This particular implementation demonstrates the usage of multiple
    preemptible and cooperative threads of differing priorities, as
    well as dynamic mutexes and thread sleeping.


## 参照

- Zephyr
    - サイト https://www.zephyrproject.org/
    - コード https://github.com/fractalclone/zephyr-riscv
- RISC-V
    - サイト https://riscv.org/
- SiFive Freedom E300
    - サイト https://www.sifive.com/products/freedom/
    - コード https://github.com/sifive/freedom
- Digilent Arty
    - サイト http://store.digilentinc.com/arty-artix-7-fpga-development-board-for-makers-and-hobbyists/
    - 国内購入 http://akizukidenshi.com/catalog/g/gM-10034/
- Olimex JTAG ARM-USB-TINY-H 
    - サイト https://www.olimex.com/Products/ARM/JTAG/ARM-USB-TINY-H/
    - 国内購入 https://strawberry-linux.com/catalog/items?code=15045
- 食事する哲学者の問題(Dining Philosophers Problem)
    -  https://en.wikipedia.org/wiki/Dining_philosophers_problem