2015年12月31日木曜日

ESP-WROOM-02のRTOSをMacOS X El Capitaionで動かす


■大まかな手順■


  • esp-open-sdkをビルド
  • esp-open-rtosをダウンロード

…これだけのことなんですが、MacOS X El Capitain固有の問題やら私の環境固有の問題で大ハマリしました。また、最初ESP8266-RTOS-SDKを試してみたのですが、サンプルのビルドすら通らずに挫折してesp-open-rtosに逃げたら、あっという間にマルチスレッドなLチカまで通って拍子抜け、という経緯がありました。

ということで、ハマりどころも含めてご紹介します。

なお、esp-open-sdkは、大文字小文字を区別するファイル・システムでないと動作しません。なので、Volumeを作ってその中で作業をします。そしてesp-open-rtosはesp-open-sdkがないとダメです。なので、再起動などでunmoutされた後に再度esp-open-rtosを使う場合には以下の手順で再度esp-open-rtosの入っているdmgファイルをマウントしなおす必要があります。

$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
…「見つからない」というエラーが出ればすぐ気づくのですが、ビルドで別のエラーがでる、esptool.pyで書き込みしようとした時にうまくいかない…という直接関連なさそうなエラーが出るので、ちょっとハマりました。

あと、Homebrewが必要です。

■まずesp-open-sdkをビルド■


https://github.com/pfalcon/esp-open-sdk
このページの「Requirements and Dependencies / MacOS」を参考にesp-open-sdkが動く様にします。
$ brew tap homebrew/dupes
$ brew install binutils coreutils automake wget gawk libtool gperf gnu-sed --with-default-names grep
$ export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
$ sudo hdiutil create ~/Documents/case-sensitive.dmg -volname "case-sensitive" -size 10g -fs "Case-sensitive HFS+"
$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
$ cd /Volumes/case-sensitive
$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git$ make STANDALONE=y

Buildingでのgit cloneは当然問題ないのですが、その次のmakeでビルドが通りませんでした。なお、私はmake STANDALONE=yを選択しました。esp-open-rtosにはSTANDALONE=nを選べと書いてあるのですが(後で気付いた)、とりあえず問題なく使うことができました。

□ハマり1:じゃまな古いsed□

ビルド途中でエラーが出ました。sed -rオプションが使えない云々。調べるとmac標準のsedではなくgnu-sedを使えば解消できるとあるのですが、「Requirements and Dependencies / MacOS」でbrewと使って導入済み。かなり右往左往しましたが、結果として消し忘れていたMacPortsのsedが悪さをしていました。以下の手順に従ってMacPortsをアンインストールして、sed -rオプション云々のエラーは消えました。


□ハマり2:Xcode command line tools□

makeしているとこんなエラーがズラーっと出てとまります。
[INFO ]  Installing pass-2 core C compiler[ERROR]    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cstddef:46:9: error: no member named 'ptrdiff_t' in the global namespace
...
エラーメッセージの内容からXcodeのcommand line toolsが悪さをしているっぽい。対応策はここで見つけました。

私のところはXcode 6.3ではないですが、結果的には以下のスクリプトを実行することで解消できました。
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-blocking.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-clast-to-gimple.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-dependences.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-interchange.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-optimize-isl.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-poly.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-scop-detection.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-sese-to-poly.c
すぐに終わりますので、再度 make STANDALONE=y を実行します。私のところはこれで通りました。
Espressif ESP8266 SDK is installed, its libraries and headers are merged with the toolchain
このメッセージが出たら完了です。

なお、そのすぐ上にも書いてあるように、ツールを実行するためにパスを設定する必要があります。.bash_profileに追加しておきましょう。
export PATH=/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin:$PATH



■esp-open-rtosの設定とサンプルの実行■

https://github.com/SuperHouse/esp-open-rtos

RTOS-SDKの大騒ぎと比べるとあっけないほど簡単です。まず、適当な作業用ディレクトリを作り、そこにesp-open-rtosをダウンロードします。
cd
mkdir esp
cd esp
git clone --recursive https://github.com/Superhouse/esp-open-rtos.git
cd esp-open-rtos

…はい、これだけです。

次に、自分のアプリをビルドする際のssidとpasswordを設定しておきます。1つのESP8266/ESP-WROOM-02だけで遊ぶには良いんですが、複数あるときはちょっと面倒ですが・・・include/ssid_config.hを開き、
#define WIFI_SSID "mywifissid"
#define WIFI_PASS "my secret password"
を自分のSSID/passwordに変更し、すぐ上にある#warningも消します。やらないとは思いますが、ここでcloneしたsdkに変更をしてpushする際に、自分のSSID/passwordを一緒にプッシュしないように気をつけなさいよ、というwarningです。

続いて、サンプルのビルドと実行ですが、そのまえにESP-WROOM-02をシリアルポートにつなぎ、PROGを押したままRESETを押し離し、PROGを離します。さらに2組のLEDと220-1kΩの抵抗を直列にして、GPIO 12とGPIO 13に接続します。次に、examples/blink_times/blink_timers.cを開き、
const int gpio_frc2 = 14;
const int gpio_frc2 = 13;
に変更します(他のGPIOを使う場合にはそれに合わせて変更してください)。

あとは、

make flash -j4 -C examples/blink_timers ESPPORT=/dev/<usbシリアルのポート>
を実行すれば、ビルドの後、自動的にESPに書き込まれ、二個のLEDが1/5秒周期と2秒周期で点滅します。ソースを見ればわかりますが、2個のLEDはそれぞれ別々のスレッドとして動作しています。

お疲れ様でした。ソースをXcodeなどのエディタで開いてしまえば、ビルド&ダウンロードはコマンド一発(ターミナルでは上向き↓を押してENTERを押すだけ)なので、Arduino IDEで使う場合とそう変わりはありません。これで本格的なマルチスレッドが手に入るのだから、苦労も報われるというものです。



■余談:ESP8266-RTOS-SDKをビルドする際のハマり■

ビルドはできたものの、サンプル中の「GPIO_OUTPUTが見つからない」というエラーを解消できずに挫折というか諦めました。ただ、そこまで行くのにかなり苦労したので、一応記録を残しておきます。

ESP8266_RTOS_SDK

まず、esp-open-sdkをセットアップするのはesp-open-rtosと同じです。

次に適当なディレクトリを作ってそのなかに移動してから
$git clone https://github.com/espressif/ESP8266_RTOS_SDK.git
でSDKをダウンロードします。つぎに、gen_misc.shを開き、SDK_PATHは書いてあるとおりRTOSの場所、BIN_PATHはビルドしたバイナリを置く場所を指定します。

BIN_PATHに指定したディレクトリはビルド前に作っておかないとエラーになります。指定したディレクトリにバイナリが入るので、そこからesptool.pyなどを起動すると何かとラクですね。

さて、ビルドを始めると、
.out section `.irom0.text' will not fit in region `irom0_0_seg'
で止まってしまいます。

回避策はRTOS_SDK V1.3 do not fit my code any moreで見つけました。ESP8266_RTOS_SDK/ld/eagle.app.v6.ldってファイルを開き、MEMORYってブロックを記事の末尾にある
MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  iram1_0_seg :                         org = 0x40100000, len = 0x8000
  irom0_0_seg :                         org = 0x40210000, len = 0x7C000
}
で置き換えるとビルド通ります。お疲れ様でした。

0 件のコメント:

コメントを投稿