2015年12月18日金曜日

ESP8266の開発環境セットアップ手順

ESP8266の開発元であるEspressifが公開している*ESP8266 IoT SDK*を使った開発をできるようにする方法です。

  • ESP8266_RTOS_SDKにあるソースを使って、freertosを使った開発ができるようになる
  • Macだけ(仮想環境とか使わずに)で開発できるようになる

というのも、始めはVirtualBox上のDebianで作業していたのです。が、Macに繋げたFTDIのUSB-シリアルコンバータをVirtualBoxから見えるようにすると、ゲストOSをシャットダウンするときにホストOSを巻き込んで落ちるのですよ。。。El Capitan 。。。で、ESP8266用バイナリのビルドまでを仮想OS(Debian)でやって、バイナリをMacに持ってきて実機に転送ってやってたんですけど、手間多いし、仮想OSムダーと思い始めて、全てをMacでやることにしたわけです。

環境の構築

esp-open-sdkを使ってしまうので、ほとんど待機の時間になりますw

クロスコンパイルに必要なものを揃える

brewでワッっと入れてしまいます。

$ brew tap homebrew/dupes
$ brew install binutils coreutils automake wget gawk libtool gperf gnu-sed grep --with-default-names

--with-default-namesすることでコマンドのプリフィックスの’g’が付かなくなります。

クロスコンパイラを入れるディスクを作る

クロスコンパイラの都合で大文字小文字を区別するファイルシステムが必要なので、以下のコマンドでイメージを作ってマウントします。

$ hdiutil create -type SPARSEBUNDLE -nospotlight -volname xtensa-crosstools -size 10g -fs "Case-sensitive HFS+" -verbose ./xtensa-crosstools.sparsebundle
$ hdiutil mount xtensa-crosstools.sparsebundle

esp-open-sdkにあるように-typeを指定しないとUDIFイメージになってしまい、、、さらに-size 10gとなっているので、べっとりと10ギガバイトのイメージを作ることになっています。ここに書いたように-type SPARSEBUNDLEしてイメージ内で使った分だけイメージの大きさが拡張されるようにしておきます。(実際、10GBも使いませんでした)

クロスコンパイラをビルド

まずは、esp-open-sdkのソースコード一式を手に入れます。ひとつ前の手順でイメージをマウントできていると/Volumes/xtensa-crosstoolsにイメージがマウントされていますので、そこにクローンします。

$ cd /Volumes/xtensa-crosstools
$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git

esp-open-sdkのリポジトリはサブモジュールが含まれるので--recursiveを付けていますね。

さっそくビルドしてみます。

$ cd esp-open-sdk
$ export PATH=/usr/local/opt/gnu-sed/bin:$PATH
$ make STANDALONE=n

sedのパスがesp-open-sdkのREADMEと違っていました。さてこれでビルドが始まりますが、エラーになります。はい。なりました。一部切り出すとこんな感じです。

[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
[ERROR]    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:413:13: error: unknown type name 'ptrdiff_t'
[ERROR]    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:440:56: error: unknown type name 'ptrdiff_t'

調べるとesp-open-sdkIssueに対応手順がありました。 ./crosstool-NG/.build/src/gmp-5.1.3/gmp-h.in#define __need_size_t#undef __need_size_tを削除しろと書いてありますので、以下のように修正します。

before:

#define __need_size_t  /* tell gcc stddef.h we only want size_t */
#if defined (__cplusplus)
#include <cstddef>     /* for size_t */
#else
#include <stddef.h>    /* for size_t */
#endif
#undef __need_size_t

after:

//#define __need_size_t  /* tell gcc stddef.h we only want size_t */
#if defined (__cplusplus)
#include <cstddef>     /* for size_t */
#else
#include <stddef.h>    /* for size_t */
#endif
//#undef __need_size_t

修正が終わったら、もう一度makeします。このときmake cleanなどは 絶対にやらない でくださいね。もう一度言いますよ。make cleanやらないでください。先ほど修正したファイルが元に戻っちゃいます。

私の環境(Macbook Air 13-inch, Mid 2011, OS X El Capitan, RAM 4GB)では、エラーになるまでが15分くらい、修正後のビルドで20分くらいかかりました。

STANDALONE=n とはなんなのか

生成されるコンパイラはxtensa-lx106-elf-gccとなりますが、このコマンドに-I-Lを付けずにSDKのヘッダファイルやライブラリを使うことができるのがSTANDALONE=y。 逆に-I-Lを使ってヘッダファイルやライブラリのパスを指定しないといけないのがSTANDALONE=n

コンパイラを使う

/Volumes/xtensa-crosstools/esp-open-sdk/xtensa-lx106-elf/bin/に以下のコマンドがあるので、このディレクトリをパスに通せば良いです。

esptool.py
xtensa-lx106-elf-addr2line
xtensa-lx106-elf-ar
xtensa-lx106-elf-as
xtensa-lx106-elf-c++
xtensa-lx106-elf-c++filt
xtensa-lx106-elf-cc
xtensa-lx106-elf-cpp
xtensa-lx106-elf-ct-ng.config
xtensa-lx106-elf-elfedit
xtensa-lx106-elf-g++
xtensa-lx106-elf-gcc
xtensa-lx106-elf-gcc-4.8.2
xtensa-lx106-elf-gcc-ar
xtensa-lx106-elf-gcc-nm
xtensa-lx106-elf-gcc-ranlib
xtensa-lx106-elf-gcov
xtensa-lx106-elf-gdb
xtensa-lx106-elf-gprof
xtensa-lx106-elf-ld
xtensa-lx106-elf-ld.bfd
xtensa-lx106-elf-nm
xtensa-lx106-elf-objcopy
xtensa-lx106-elf-objdump
xtensa-lx106-elf-ranlib
xtensa-lx106-elf-readelf
xtensa-lx106-elf-size
xtensa-lx106-elf-strings
xtensa-lx106-elf-strip

esptoolを使えるようにする

書き込みに使うesptoolがpythonで書かれているので必要なライブラリ(pySerial)を入れます。

$ easy_install --user pyserial
Searching for pyserial
Reading https://pypi.python.org/simple/pyserial/
Best match: pyserial 2.7
Downloading https://pypi.python.org/packages/source/p/pyserial/pyserial-2.7.tar.gz#md5=794506184df83ef2290de0d18803dd11
Processing pyserial-2.7.tar.gz
Writing /var/folders/5v/r31fkffd6x54jd54zqwnb4z80000gn/T/easy_install-NAdr8h/pyserial-2.7/setup.cfg
Running pyserial-2.7/setup.py -q bdist_egg --dist-dir /var/folders/5v/r31fkffd6x54jd54zqwnb4z80000gn/T/easy_install-NAdr8h/pyserial-2.7/egg-dist-tmp-mnhpcv
zip_safe flag not set; analyzing archive contents...
Adding pyserial 2.7 to easy-install.pth file
Installing miniterm.py script to /Users/jyun1/Library/Python/2.7/bin

Installed /Users/jyun1/Library/Python/2.7/lib/python/site-packages/pyserial-2.7-py2.7.egg
Processing dependencies for pyserial
Finished processing dependencies for pyserial

グローバルな環境を触るのが嫌なので--userを使っています。

まとめ

これでESP8266用のクロスコンパイラがビルドできます。今回の手順であれば、1時間もあれば作業は終わるでしょう。 スパースバンドルを使ったのでおおよそ2.5GBしか物理ディスクを占有していません。

$ du -hd 0 xtensa-crosstools.sparsebundle
2.5G    xtensa-crosstools.sparsebundle

$ df -h /Volumes/xtensa-crosstools
Filesystem     Size   Used  Avail Capacity iused   ifree %iused  Mounted on
/dev/disk2s2  9.7Gi  2.5Gi  7.2Gi    26%  654500 1882960   26%   /Volumes/xtensa-crosstools