EV3RT用mrubyサンプルコードの使い方

この記事はETロボコン関係者(参加者含む)向けに、Ruby(mruby)をお試しいただくために作成しました。
そのため、ETロボコンの公式サイトで解説している部分は省略しています。
ESEC 2015のデモはこのコード(旧タイヤ版)を利用していました。

(2018/04/19追記)
2018年度からの新しいタイヤ版用に修正しました
~~(2018/05/05追記)
EV3RT β7-1でもたぶん大丈夫と思いますが、私の方で動作確認はまだできていません~~
(2018/06/23追記)
EV3RT β7-1は[(toppers-etrobo 112) Bluetooth PANで転送後，アプリの起動が失敗する](http://www.toppers.jp/ETROBO-ML/2018-May/000112.html)が未解決のため動作確認をしていません。~~EV3RT β7を使用してください。~~
(2019/05/03追記） 上記現象に対応したものがβ7-2になります。よってETロボコン2019ではβ7-2を推奨します

# 必要なもの
 * Ruby(mrubyじゃないいわゆるCRuby。mrubyのビルドに必要)
 * [mruby](https://github.com/mruby/mruby)
 * [mruby-ev3rt (EV3RT用の拡張ライブラリ)](https://github.com/yamanekko/mruby-ev3rt)
 * [EV3RT(ETロボコン用(C/C++用とか)にインストール済のものがあればそれでよい)](http://dev.toppers.jp/trac_user/ev3pf/wiki/Download#%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)
 環境構築方法は[Mac](https://qiita.com/yamanekko/items/3cee3991ea9472a1f6b6) , [Windows, Linux](http://dev.toppers.jp/trac_user/ev3pf/wiki/DevEnv#%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB) を参照してセットアップしておいてください。
 * mruby用のサンプルプログラム([2018,2019年度プライマリー向け](https://github.com/yamanekko/mrb_way_2018))
  
**2019年度も2018年度way(mrb_way_2018)を使用してください** （名前付けに失敗しました…）

# mrubyのビルド

## mrubyの取得


GitHubのmrubyリポジトリは日々更新されています。
最近の更新状況を考慮して[^1]、2019年度の技術教育は（今後致命的なバグを見つけない限り）リリース版2.0.1を推奨にしようと思っています。
なので、個人的には今年は2.0.1がおすすめかな…

[^1]: ビルドが通らないです！とか問題に突き当たったときに問題の切り分けが大変なので…

https://github.com/mruby/mruby/releases/tag/2.0.1
こちらから[Source code(zip)](https://github.com/mruby/mruby/archive/2.0.1.zip)または[Source code(tar.gz)](https://github.com/mruby/mruby/archive/2.0.1.tar.gz)をダウンロードして使いましょう。

もちろん、GitHubのmrubyリポジトリからmrubyを取得して使うこともできます。

```
$ git clone -b 2.0.1 https://github.com/mruby/mruby.git
```


## EV3RT用のmrbgemsの取得

こちらはGitHubからgit cloneしてください。
(要望により機能追加する場合があります。その際、git pullで更新できると便利です)
mrubyと同じ階層に置く前提です。
ex. `/Users/xxx/git/mruby` なら `/Users/xxx/git/mruby-ev3rt` 

```
$ git clone https://github.com/yamanekko/mruby-ev3rt.git
```

## mrubyのMakefileをEV3RT用に変更

`/mruby/makefile` の `RAKE=`をEV3RT用のbuild config 用に変更します。


~~RAKE = MRUBY_CONFIG=../mruby-ev3rt/build_config_ev3rt.rb ruby ./minirake~~

```
RAKE=MRUBY_CONFIG=../mruby-ev3rt/build_config_ev3rt.rb ruby ./minirake
```

もともとは ```RAKE = MRUBY_CONFIG（略）``` と=の前後にスペースを入れてましたが、紛らわしいかなと思って削除しました。お好みの方でどうぞ

※ minirake を使えばRakeがインストールされてなくてもOKです


## build_config_ev3rt.rb の設定内容を環境に合わせる

* EV3RT_PATH = hrp2のパス
* GNU_TOOL_PREFX = arm-none-eabi-gcc のパス

GCC ARMにパスが通っている場合は
```GNU_TOOL_PREFX = arm-none-eabi-```
でよい。パスが通っているかは、以下のコマンドで確認できます。
```arm-none-eabi-gcc -v```


## ~~バランサーのコードの追加 (wayのみ必要)~~
2017/3/27追記
最近はETロボコンのバランサーライブラリは公開されているようなので、他のサンプルに倣って同梱しました。 

## mrubyをmakeする

```
cd (mrubyのディレクトリ) 
make
```

# mruby用サンプルプログラムのビルド

(以下バイトコードを利用するバージョンのサンプルコードの使用方法です。Rubyのファイルを読み込んで実行するバージョンについては[EV3RT用mrubyサンプルコード(*.rbファイル読み込み版)](http://qiita.com/yamanekko/items/b48d4a716e9032c796f3)を参照してください。)

Rubyのコードは、mrubyをビルドすると生成される`mrbc`コマンドを使ってmruby独自の"バイトコード"と呼ばれているものに変換します。
C/C++との違いは、makeする前にこのバイトコードを生成するところのみです。
※ バイトコードはRubyのコードを変更した場合のみ再作成すればよいです。

## サンプルコードの取得
* 2018年度way用

```
$ cd (ev3rtのパス)/hrp2/workspace/
$ git clone https://github.com/yamanekko/mrb_way_2018.git
```

* 旧way用

```
$ cd (ev3rtのパス)/hrp2/workspace/
$ git clone https://github.com/yamanekko/mrb_way.git
```

* trike用

```
$ cd (ev3rtのパス)/hrp2/workspace/
$ git clone https://github.com/yamanekko/mrb_trike.git
```

※ wayの方には、以下のバイトコードの作成からEV3RTのビルドまでを実行するシェル(build_mod.sh)が入っています。利用する際にはご自身の環境に合わせてパスを変更してください。(こちらを使用する場合にも次の「Makefile.incの修正」は必要です)
詳しくはbuild_mod.shの中のコメントを参照してください

```
$ cd (ev3rtのパス)/hrp2/workspace/mrb_way_2018
$ ./build_mod.sh
```

## Makefile.inc の修正 

修正箇所はwayもtrikeも同じです。

```
APPL_LIBS += (mrubyをインストールしたパス)/mruby/build/EV3RT/lib/libmruby.a -lm
INCLUDES += -I(mrubyをインストールしたパス)/mruby/include
※先頭の-Iを消さないようにね
```

## ev3rt.h の修正

ちょっと強引かもしれないですが、デフォルトのスタックサイズを増やしてしまう方法です。
ev3rt.hの７９行目あたりの ```#define STACK_SIZE  4096``` を```4096``` から```80960``` に変更します。

```
/*
 *  タスクのスタックサイズ
 */
#ifndef STACK_SIZE
#define STACK_SIZE  80960
#endif
```

この修正をすると、どのアプリもSTACK_SIZEが増えることになります。

app.hにも

```
#ifndef STACK_SIZE
#define STACK_SIZE      4096
#endif /* STACK_SIZE */
```

という記述がありますが、こちらを変更しても、先にev3rt.hが読み込まれているため、STACK_SIZEは既に定義済みとなり、反映されないので注意しましょう。
アプリ個別で変更したい場合は、app.cfgのタスクの定義のスタックサイズ（以下のコード例のSTACK_SIZEのところ）に適当な大きさの数字を入れましょう。（各タスクごとに個別に設定なので注意しましょう）

```Ex.
CRE_TSK(MAIN_TASK, { TA_ACT , 0, main_task, TMIN_APP_TPRI + 1, STACK_SIZE, NULL });
```


## バイトコードの作成

mrbcコマンドを実行します。(2018年度mrb_wayの例)

```
$ cd mrb_way
$ (mrubyをインストールしたパス)/mruby/bin/mrbc -g -Bbcode -oapp_ruby.h app_ruby2.rb
$ (mrubyをインストールしたパス)/mruby/bin/mrbc -g -Bcyccode -obalance_ruby.h balance2.rb
$ (mrubyをインストールしたパス)mruby/bin/mrbc -g -Bwatchcode -owatch_ruby.h watch.rb
```

### コマンドの説明
```
-g : デバッグ情報を生成
-B : 直後の文字列がバイトコードの変数名(この名前でmrubyのコードから呼び出します)
-o : バイトコードを出力するファイル名
最後がバイトコードに変換したいRubyのファイル名
```
## バイトコードの修正
mrubyの修正でバイトコードに
```extern const uint8_t```
が出力されるようになっており、ビルドエラーになります。
生成した*.hから上記1行を消してください。
``` ruby delete_extern.rb ```
を実行しても消去できます。
(mrubyのバージョンによって上記出力されないバージョンもあります。出力されていないバージョンのバイトコードにdelete_extern.rb を実行しても特に問題はありません。)


## EV3RTのビルド
C/C++と同様に mod=xxx または app=xxx を使用してmakeしてください。

```
$ cd (ev3rtのパス)/hrp2/workspace/
$ make app=mrb_way_2018
```