MacにESP32向けのmruby開発環境を構築する

# 概要

MacにESP32向けmruby開発環境を構築します。

## 前提条件

parallesでmacOSの仮想マシンを新規で作成し、クリーンインストールした状態から試しました。
使用したマシンとOSのバージョンです。

- MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
- macOS Mojave 10.14.4
- ターゲットデバイス : [M5Stack](https://www.switch-science.com/catalog/3647/)

ターゲットとしてNodeMCU-32Sも試したのですが、うまくいきませんでした。成功したら追記します。

# 手順

## Xcodeをインストール

執筆時点(2019/12/5)で最新のXcode 11.2.1をインストールします。

## Homebrewをインストール

下のコマンドでHomebrewをインストールします。

```
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

```~/bash_profile``` に以下を追加してPATHを通します。

```
export PATH=$PATH:/usr/local/bin
```

## コマンド類のインストール

### pipインストール

ESP-IDFのセットアップでpipが必要になるため下のコマンドでインストールします。

```
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ sudo python get-pip.py
```

### gcc、cmake インストール

```
$ brew install gcc
$ brew install cmake
```


## ESP-IDF開発環境構築

ESP32でmrubyを使うためにはESP-IDFという開発環境を使います。
今までArduino IDEだけ使用していたので、ESP-IDFという開発環境については全く知識を持ってなくて、どこから始めればいいの？ということになりますが、こちらに公式ドキュメントがありました。

[Get Started — ESP-IDF Programming Guide v4.1-dev-1066-g93a8603c5 documentation](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html)

### ESP-IDFのソースコード 一式Clone

ドキュメントに従ってespディレクトリ内にgithubからCloneします。

```
$ mkdir ~/esp
$ cd ~/esp
$ git clone --recursive https://github.com/espressif/esp-idf.git
```

### ESP-IDFのセットアップ

```install.sh``` を実行してセットアップします。

```
$ cd ~/esp/esp-idf
$ ./install.sh
```

```~/.bash_profile``` に以下の行を追加します。

```
. $HOME/esp/esp-idf/export.sh
```

ターミナルを立ち上げ直すか、```source ~/.bash_profile```を実行して反映させます。



### hello worldサンプルプロジェクトのコピー

esp-idfで用意されているhello worldのサンプルをコピーします。

```
$ cd ~/esp
$ cp -r $IDF_PATH/examples/get-started/hello_world .
```

### Configuration

ビルドに先立ってmenuconfigを起動します。

```
$ cd ~/esp/hello_world
$ idf.py menuconfig
```

正常に起動すると下の様な画面がでます。
この画面がでればここまでの作業が問題なくできています。

![Image from Gyazo](https://i.gyazo.com/0dee1b0f572eb5a5eb07f17d747cc520.png)

### ビルド

下のコマンドでhello world プロジェクトがビルドされます。

```
$ idf.py build
```

しかし、Too many open filesエラーがでて失敗しました。
(その後にライブラリーも見つからないなどでてました。)

```
/Users/kito/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find esp-idf/tcp_transport/libtcp_transport.a: Too many open files
```

一度に開けるファイルの数を増やす必要がある様です。

　```/Library/LaunchDaemons/limit.maxfiles.plist``` を作成して以下の内容を書き込みます。
(viなどのコマンドで作成するにはsudoが必要になります)

```
<?xml version="1.0" encoding="UTF-8"?>  
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"  
          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">  
    <dict>
      <key>Label</key>
      <string>limit.maxfiles</string>
      <key>ProgramArguments</key>
      <array>
        <string>launchctl</string>
        <string>limit</string>
        <string>maxfiles</string>
        <string>64000</string>
        <string>524288</string>
      </array>
      <key>RunAtLoad</key>
      <true/>
      <key>ServiceIPC</key>
      <false/>
    </dict>
  </plist> 
```

オーナーを変更してロードさせます。

```
$ sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
$ sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
```

macOSを再起動してからもう一度 ```build``` を試してみるとうまくいきました。

```
$ idf.py build
```

### 通信ドライバーインストール

Silicon Labsからシリアル通信用ドライバーをダウンロードします。
下のページのDownload for Macintosh OSX のパッケージをダウンロードします。
執筆時点のバージョンはv5.2.2でした。

[USB to UART Bridge VCP Drivers - Silicon Labs](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)

展開してインストーラーでインストールします。

### デバイス確認

M5StackをUSBケーブルでつないで ```ls``` で確認します。

```
$ ls /dev/tty.*U*
/dev/tty.SLAB_USBtoUART
```

```/dev/tty.SLAB_USBtoUART``` がM5Stackとの通信ポートになります。

### プログラムのアップロード

プログラムをアップロードするには下のコマンドを実行します。

```
$ idf.py -p /dev/tty.SLAB_USBtoUART flash
```

### プログラムの動作確認

monitorでプログラムの出力を確認できます。

```
idf.py -p /dev/tty.SLAB_USBtoUART monitor
```

Hello world!とチップの情報が出力されているのが確認できます。

```
Hello world!
This is ESP32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, 2MB external flash
Restarting in 10 seconds...
```

これでESP-IDFでプロジェクトビルトから実行まで確認できました。


## mruby構築

### ソースコードをClone

[GitHub の mruby-esp32](https://github.com/mruby-esp32/mruby-esp32) のドキュメントに従ってソースコードをCloneします

```
$ cd ~/
$ git clone --recursive https://github.com/mruby-esp32/mruby-esp32.git
$ cd mruby-esp32
```

### ビルド

ドキュメントにあるようにmakeでビルドします。
MRUBY_EXAMPLE=simplest_mrb.rb はいくつかあるサンプルから使用するmrubyファイルを指定する様です。

```
$ make MRUBY_EXAMPLE=simplest_mrb.rb
```

しかし、-Wオプションのチェックでエラーがでました。

```
error: '%d' directive writing between 1 and 3 bytes into a region of size between 1 and 7 [-Werror=format-overflow=]
 #define IPSTR "%d.%d.%d.%d"
               ^~~~~~~~~~~~~
```

CFLAGSにチェックを無効にする設定をしてからmakeすると成功しました。

```
$ export CFLAGS="-Wno-error=format-overflow="
$ make MRUBY_EXAMPLE=simplest_mrb.rb
```

### 通信ポートの設定

```menuconfig``` で通信に使用するポートを設定します。

```
$ make menuconfig
```

```menuconfig``` が起動したら次の様に設定します。

1. __Serial flasher config --->__ を選択
2. __(/dev/ttyUSB0) Default serail port)__ を選択
3. 使用するポートとして __/dev/tty.SLAB_USBtoUART__ を設定
4. __ESC__ を2回押し、ダイアログで __Y__ を押して保存します。

![Image from Gyazo](https://i.gyazo.com/73bff694f289fdd0913568e063430e2c.png)

### プログラムの書き込みと動作確認

[simplest_mrb.rb](https://github.com/mruby-esp32/mruby-esp32/blob/master/main/examples/simplest_mrb.rb)ファイルを確認してみると、下の様に1234と4321の2行出力する様になっています。

```
puts "1234"
puts "4321"
```

プログラムの書き込みと動作確認するにはflashとmonitorタスクを実行します。

```
$ make MRUBY_EXAMPLE=simplest_mrb.rb flash monitor
```

出力を確認すると正常に動作している様です。

```
I (542) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (370) mruby_task: Loading binary...
1234
4321
I (390) mruby_task: Success
```

という事で無事mrubyプログラムが実行されました。
やったー!!!


# 関連

Linux版も書きました。

- [ESP32向けのmruby開発環境を構築する(Linux編) - Qiita](https://qiita.com/katsuyoshi/private/ed96b0e5044cfe590d04)

# 参照

以下のサイトを参考にさせていただきました。(ほぼまとめサイトの様になっておりますが…)
ありがとうございました。


- [macOSのデフォルトPythonでpipを使う - Qiita](https://qiita.com/tom-u/items/134e2b8d4e11feea8e12)
- [macos - Open files limit does not work as before in OSX Yosemite - Super User](https://superuser.com/questions/827984/open-files-limit-does-not-work-as-before-in-osx-yosemite/1171026#1171026)
- [mruby-esp32 を使って ESP-WROOM-32（ESP32）上で、Ruby言語のコードから作ったアプリケーションを動かす - Qiita](https://qiita.com/GORO_Neko/items/12967d5c8f84975db221)
- [GitHub - mruby-esp32/mruby-esp32: mruby application template for ESP32](https://github.com/mruby-esp32/mruby-esp32)