WSL上でEV3RT（ev3rt-1.0以降、hrp3）を使う

## EV3RTのアプリをWSLの上で開発したい

この記事は、EV3RTのアプリ（最近噂の「箱庭」じゃなく実機の方ね）を開発したいWindowsユーザー向けの記事です。
せっかく WSL（Windows Subsystem for Linux） を入れたんだから、CygwinやMSYS2を入れずにWSLを使いたいって思ったら、この記事が役に立つかもしれません（MSYS2を使う場合でも、EV3RT関連の情報は共通の部分が多いです）。

> 2023/9/26追記
EV3RTのコンフィギュレータ（cfg）の`pass1.rb` がRuby 3.0以降ではエラーを発生する件とその対応策に関して説明を追加しました。


> 【注意】 もし、あなたが ETロボコン2020にチャレンジするなど、ETロボコンシミュレータを使う環境をご所望でしたら、この記事ではなく、[etrobo all-in-one installer/builder/launcher environment](https://github.com/ETrobocon/etrobo) を参照しましょう。
ETロボコンの参加や技術教育に必要なシミュレータ上の環境と実機を動かす環境の両方が手に入ります。

WSLとUbuntuさえインストールしてしまえば、あとは基本的に EV3RTのWebサイトにかいてある手順と同じです。

* [開発環境構築のマニュアル](https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnv)
* [Linuxでの環境構築方法（Ubuntu Linux）](https://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnvLinux) 

この記事では、以降、上記のWebサイトに書いてある手順を参照して説明しています。

> 【注意】 ev3rt-beta7-x（hrp2）が使いたい場合
> いきなりごめんなさい。
> WSL上ではhrp2用のコンフィギュレータのビルドがうまくいかず、WSL上でhrp2を使うのは難しそうです（cfgコマンドが手に入ればイケます、たぶん）。
> この事情から、この記事ではhrp3のインストールを紹介しています。
> ev3rt-beta7-3-releaseなどhrp2系を使いたい場合には、cygwinかMSYS2を使いましょう。

## インストール手順

### WSL+Ubuntuをインストールする

> いきなりごめんなさい、その2。
> この記事では、WSLのインストール手順は扱いません（ほかのひとの記事のほうがきっとわかりよいはず…）。

私は、次の記事を参考に WSL1とUbuntu 18.04をインストールしました。
いまは、もっと簡単な方法（Storeからインストールするなど）があるので、調べてみたほうがよいでしょう。

* [Windows Subsystem for Linux (WSL1) をインストールしてみよう！](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)

> WSL2でもこの記事の手順が使えたというコメントをいただきました（2021年2月8日）

> Ubuntu 20.04 も利用できています。
> ただし、ターミナルに日本語を表示する際に問題が生じている人がいるようです。
> ディレクトリ名やファイル名に日本語は使わないようにするか、使っていなパスにEV3RTをインストールしておくとよいでしょう。

インストールが終わったら、一度Windowsを再起動しておきましょう。

### ターミナルを起動する

以降の手順では、WSLのターミナルを使います。
すでにWindowsターミナルを使っている人は、WSLのターミナルの代わりにWindowsターミナルを使ってもかまいません。

### 開発に使うパッケージを追加する

EV3RTの開発では gcc-core、make、diffutils、ruby を使います。
これらを apt コマンドで追加します。

``` shell
$ sudo apt install wget ←たぶん予め入っていますが、なかったら追加します
$ sudo apt install build-essential
$ sudo apt install make
$ sudo apt install diffutils
$ sudo apt install ruby
```

### ruby のgem を追加する

EV3RT-1.1のカーネルであるhrp3が使っているコンフィギュレータ（cfg）はrubyスクリプトです。
このスクリプトが使っている shell というライブラリが、ruby 2.7から標準添付ライブラリではなくなりました。
そのため、別途 gemコマンドを使って追加します。

``` shell
sudo gem install shell
```

### クロスコンパイラをインストールする

EV3のCPU（ARM9）用のクロスコンパイラをインストールします。
EV3RTを使うためのクロスコンパイラは、できるだけ下記のスクリプトを使って、TOPPERSプロジェクトの利用実績のあるものを導入しましょう。

> 最近のもの（バージョン10.xなど）だと、コンパイル時に `ld` コマンドがエラーを発生させることがあるようです。

EV3RTのGitHubリポジトリから、Ubuntu用のクロスコンパイラインストール用スクリプトを取得します。
取得や実行の場所は指定されていません。
私は、自分のホームディレクトリでやりました。

``` shell
$ cd  ←ホームディレクトリに移動する
$ wget http://ev3rt-git.github.io/public/ev3rt-prepare-ubuntu.sh
```
取得したシェルスクリプトを実行します。

``` shell
$ sudo bash ev3rt-prepare-ubuntu.sh
（略）
Done. Please reboot or logout.
```

最後のメッセージに従い、WSLのターミナルを再起動します（Windowsの再起動じゃなくてね）。

このスクリプトは、最後に環境変数PATHにクロスコンパイラの場所を追加しています。
ターミナルを再起動しないまま次へ進むと、環境変数が更新されないので、ビルドのときに「gcc-arm-none-xxxx（クロスコンパイラのコマンド名）が見つからない」というエラーが発生します。

### EV3RTのインストール先はCドライブにする

EV3RTの開発中は、しょっちゅうPCからEV3へプログラムを転送します。USBケーブルで互いを接続したり、Bluetoothによる転送を使います。これらの操作は、Windowsから使うほうが、使い勝手もよく、安定しています。

もちろん、WindowsからWSLのドライブにアクセスするには、たとえばWSLで使っているのが Ubuntu-20.04 なら、 `\\wsl$\Ubuntu-20.04` のようなパス名でアクセスできます。このような、Windowsから使える場所なら、転送などで困ることはありません。

しかし、ここでは、EV3RTや開発するプログラムをWindows側のドライブに置いて開発する方法を紹介します。そのほうが、他のPCともファイルを容易に共有できて便利だからです。

そこで、EV3RTをインストールする場所をCドライブにします。他のドライブでもかまわないのですが、WSLは、Cドライブを予めアクセスできるようマウントしてくれていますので、Windows側のドライブをWSL側でマウントする手間を省けます。確認してみましょう。

``` shell
$ mount
rootfs on / type lxfs (rw,noatime)
（略）
C:\ on /mnt/c type drvfs (rw,noatime,uid=1000,gid=1000,umask=22,fmask=11,metadata,case=off)
```
`/mnt/c/` がマウントされているのがわかります。これがWindows側のCドライブを指しています。

この説明では、インストールする場所をのCドライブのルート（ `C:\` ）を使うことにします。違う場所（たとえば自分のホームディレクトリ `C:\Users\kuboaki` など）でもよいでしょう。その場合には説明を読み替えて作業してください。

まず、カレントディレクトリを `/mnt/c/` に移動しておきます。

``` shell
cd /mnt/c
```

Cドライブのルートディレクトリではなく、自分のホームディレクトリにインストールしたいなら、Windowsの自分のホームディレクトリに移動しておきます。
わたし（ `kuboaki` ）の場合、次のようになるでしょう。

``` shell
cd /mnt/c/Users/kuboaki
```

### EV3RTのアーカイブをダウンロードする

EV3RTのWebサイトから、EV3RTのアーカイブをダウンロードします。

* [EV3RTのダウンロードページ](https://dev.toppers.jp/trac_user/ev3pf/wiki/Download)
 
ここでは `ev3rt-1.1-release.zip`  をダウンロードしたものとして説明します。より新しいものを選んだ場合は読み替えてください（たとえばev3rt-1.2とか）。
逆に、EV3RT-1.0よりも古いものは、多くの点で異なっていますので、そのバージョンについて説明している記事に従ってインストールしましょう。

``` shell
$ pwd ←カレントディレクトリを表示して確認した
/mnt/c
$ wget -c http://www.toppers.jp/download.cgi/ev3rt-1.1-release.zip
```

### EV3RTのアーカイブを展開する

ダウンロードしたzipファイルを展開します。
あ、基本的にWSLにインストールしたUbuntuのターミナルを使って作業してくださいね。
面倒がってWindows用のツールを使おうとすると、うまく展開できなかったり、フォルダを作ってその中に展開されるといったことが起きます（みなさんがそういったことをわかって使う分にはかまいません）。

``` shell
$ unzip ev3rt-1.1-release.zip 
$ ls -1  ←「エル」じゃなく「イチ」です
（略）
ev3rt-1.1-release ←展開してできたディレクトリ
ev3rt-1.1-release.zip
（略）
```
`ev3rt-1.1-release` が展開されてできたディレクトリです。
中身を確認しましょう。

``` shell
$ ls ev3rt-1.1-release
Changelog.txt
EV3RT_CPP_API_Reference
EV3RT_C_API_Reference
hrp3.tar.xz
sdcard
tgki_spec-340.pdf
```

### EV3RTのディレクトリ名を短くする（お好みで）

このままではディレクトリ名が少し長いので、変更しましょう。
いくつかのバージョンのEV3RTを併存したいなら、そのままにしておいてもよいでしょう。

``` shell
$ mv ev3rt-1.1-release ev3rt
```

これで `/mnt/c/ev3rt` がEV3RTをインストールしたディレクトリとなりました。

### EV3RTの本体を展開する

実はまだ展開は終わっていません。
展開したファイルの中に、さらに展開すべきアーカイブが含まれています。
`hrp3.tar.xz` がそれです。これを展開します。

``` shell
$ cd ev3rt
$ tar xvf hrp3.tar.xz
$ ls hrp3
E_PACKAGE       arch          doc        library  syssvc       utils
MANIFEST        cfg           extension  modules  target
MANIFEST.early  cfg_test      include    sample   tecs_kernel
README.txt      configure.rb  kernel     sdk      test
```
展開したら、 ev3rtの下に hrp3 ディレクトリができて、その中にsdkディレクトリなどができました。

### EV3RTのコンフィギュレータのコードを修正する（2023/9/28追加）

コンフィギュレータ（cfg）の中の、CSVファイルをオープンするコードには、引数の誤りが含まれています。Ruby 2.7では動作していましたが、Ruby 3.0になって誤りが検出されるようになり、次のようなエラーを報告するようになりました。

``` shell
  CFG[1]  module_cfg.h
/usr/lib/ruby/3.2.0/csv.rb:1593:in `initialize': no implicit conversion of Hash into String (TypeError)

        f = File.open(filename, mode, **file_opts)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        from /usr/lib/ruby/3.2.0/csv.rb:1593:in `open'
        from /usr/lib/ruby/3.2.0/csv.rb:1593:in `open'
        from /ev3rt/hrp3/cfg/pass1.rb:178:in `block in ReadSymvalTable'
        from /ev3rt/hrp3/cfg/pass1.rb:172:in `each'
        from /ev3rt/hrp3/cfg/pass1.rb:172:in `ReadSymvalTable'
        from /ev3rt/hrp3/cfg/pass1.rb:902:in `Pass1'
        from ../../cfg/cfg.rb:705:in `<main>'
```

そこで、コードの誤りを修正します。

`(ev3rtのインストールディレクトリ）/hrp3/cfg/pass1.rb` の178-179行目（実際のコードは折り返されて2行になっています）：
``` ruby
# 元のコード
symvalCsv = CSV.open(symvalTableFileName, { skip_blanks: true, skip_lines: /^#/ })
# 修正後のコード
symvalCsv = CSV.open(symvalTableFileName, skip_blanks: true, skip_lines: /^#/ )
```

この件については、`chihayafuru` さんの下記の記事の情報を使わせていただきました。

https://www.chihayafuru.jp/tech/index.php/archives/5460

### サンプルをビルドしてみる

`ev3rt/hrp3/sdk/workspce` がみなさんがプログラムの開発に使うワークスペースです（ `sdk` の下には別のワークスペースも作れます）。
このワークスペースの中にサンプルが含まれているので、ビルドできるか確認してみましょう。

``` shell
$ cd hrp3/sdk/workspace
$ ls
Makefile  gyroboy   hrp            test-cpp  test-spp-master  uImage
app       helloev3  periodic-task  test-cyc  trike
$ make app=helloev3
（略）
  LD      app
make[1]: Leaving directory '/mnt/c/ev3rt/hrp3/sdk/OBJ'
``` 

`app` というファイルが、直近の日付と時刻で作成できていればオーケーです（ちゃんと日時が更新されていることを確かめること）。


``` shell
$ ls -l app  ←こんどは「イチ」じゃなく「エル」です
-rwxr-xr-x 1 kuboaki kuboaki 100884 Sep 13 13:36 app
```

クロスコンパイラの導入を忘れてる場合、導入に失敗している場合、パスの設定に失敗している場合には、ビルドのときにエラーになります。
メッセージの中に次のような箇所が見つかったら、クロスコンパイラの導入手順に戻ってやりなおしましょう。

``` shell
（略）
make[1]: arm-none-eabi-gcc: Command not found
（略）
```

これで、WSL上のUbuntuを使って、EV3RTのアプリケーションを開発できるようになりました。

## あとは作って動かすだけです、が…

### アプリケーションの作成手順

EV3RTのアプリケーションの作成やプログラムの転送方法は、EV3RTのWebサイトを参照してください。
SDカードのフォーマットやsdcardフォルダのデータのコピーを忘れている場合があるので、気をつけましょう。

* [サンプルアプリケーションのビルドと実行](https://dev.toppers.jp/trac_user/ev3pf/wiki/SampleProgram)

### hrp2時代のコードを流用するには

カーネルがhrp2からhrp3に変わったことで、アプリケーションのコードにも影響が出てきます。
周期ハンドラのAPIが変わっているといった大きな変更があるので、hrp2のときのコードがそのままではビルドできない場合が多いでしょう。
また、仮にビルドできても、期待通り動作しない場合もあります。

hrp2とhrp3の違いについては、EV3RTのWebサイトのFAQに載っています（下記項目は、それぞれFAQページの半ばにあります）

* [EV3RT β7-3とv1.1で，カーネルがHRP2からHRP3に変わったようなのですが，どのような違いがありますか？](https://dev.toppers.jp/trac_user/ev3pf/wiki/FAQ)
* [周期的な処理を追加するためには、どうすれば良いでしょうか？](https://dev.toppers.jp/trac_user/ev3pf/wiki/FAQ)

hrp2時代の既存のコードは、たいていこれらのFAQを参照して修正する必要があります。
ビルドする前に一度参照しておくことをお勧めします。

### VS Code を使いたい

Visual Studio Code（VS Code）を使っているなら、VS Code内でWSLのターミナルを開いて使えます。
MiscrosftのWebページを紹介しておくので参考にしてみてください。
（Qiitaなどで日本語の解説記事もたくさん見つかるでしょう）

* [Developing in WSL](https://code.visualstudio.com/docs/remote/wsl#_getting-started)

## まとめ

WSLを導入済みであれば、ev3rt-1.0（hrp3）以降（この記事のev3rt-1.1など）の開発環境を、かなり容易に手に入れられるのではないかと思います。

* Windowsに、WSLをインストールし、そこにUbuntuをインストールした
* EV3RTに使うパッケージとgemパッケージを追加した
* クロスコンパイラをインストールした
* EV3RTをインストールした
* EV3RTのコンフィギュレータのコードを修正した
* サンプルがビルドできることを確認した
* hrp2時代のコードは修正が必要