■うだうだと前書き
猫も杓子もIoTと皆さんが仰るので、その声が大きくなればなるほど自分は遠ざかる方向で生きていたのですが、そうすると完全に煙に巻かれたお爺さんのようになりまして、今は世の中が進んでおるんじゃのぉと言うだけの人です。気付いてみればガレスタさんのDIY日記は素晴らしい勢いで開発を進めており、こんな風に生きてみたいものだと思うようになってきた今日この頃。私も負けて・・・いら・・・れ・・・うぐぐぐぐ・・・パタ。←血を吐いて倒れました。
数か月前、とある都合からESP-WROOM-32(おっ!2017年8月4日にデータシートが更新されている!)を搭載した開発ボード(えぇ、あのねむいさんが激オコの電源に問題のあるですね...)を入手していたのですが、色々な別の開発で忙殺されており全く調査が進んでいませんでした。肝心の「とある都合」もほったらかしでマズイぞ。
さてさて、このESP-WROOM-32は、プロセッサ、フラッシュロム、クロック、アンテナ配線などが集約されたモジュールとして提供されています。加えてメーカーが提供するSDKを使えば、簡単にネットワーク通信可能な小型ソリューションが出来上がるという仕掛け。開発ボードを購入すれば手間をかけずに試すことが出来て、これは面白いですよねー。(棒読み)
ここいらで触っておかないと永遠に触らない事を悟ったので、ホストOSにUbuntu 16.04.3を配備した上で重い腰を上げました。
■事前準備
まずは設定やビルドなどで必要になるパッケージをインストールします。
sudo apt-get install git wget make libncurses-dev flex bison gperf python python-serial vim screen
■ツールチェインの準備
次にツールチェインをダウンロードして適当な場所に置いた上で、パスを通します。
私は/optの配下に配置することにしました。
cd ~/Downloads
wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz
tar xvfz xtensa-esp32-elf-linux64-1.22.0-61-gab8375a-5.2.0.tar.gz
mv xtensa-esp32-elf /opt/
vi ~/.bash_profile
.bash_profileには以下を追記しました。
export PATH=$PATH:/opt/xtensa-esp32-elf/bin
これで次回ログイン時からパスが通った状態の環境になります。当然ながら、即座に反映させたいときはsource ~/.bash_profileして下さい。
■ESP-IDFの準備
ESP-IDFとは、 Espressif IoT Development Frameworkの略のようです。このフレームワークは、ブートローダからデバイスのペリフェラルドライバまでを包括しており、更にサンプルが上位に加わって、文字通りフレームワークとして使えるように仕立てられています。なるほど。
後々MicroPythonと組み合わせるときに気付く事になるのですが、特定のリビジョンとの組み合わせを要求されますので、git cloneでリポジトリからコードを取り出すことにします。
後々MicroPythonと組み合わせるときに気付く事になるのですが、特定のリビジョンとの組み合わせを要求されますので、git cloneでリポジトリからコードを取り出すことにします。
cd /opt
git clone https://github.com/espressif/esp-idf.git
cd esp-idf
git submodule update --init
これで準備完了。
ESP-IDFは、外部モジュールに盛大に依存していますので、最後のgit submodule update --initをお忘れなく。
■MicroPython ESP32の準備
次にMicroPython ESP32をリポジトリから取り出します。
先のツールチェインとESP-IDFは/optに配置しましたが、こちらはホームの下に作ったProjectsディレクトリにcloneすることにしました。
mkdir ~/Projects
cd ~/Projects
git clone https://github.com/micropython/micropython-esp32.git
cd micropython-esp32/
git submodule update --init
MicroPythonも外部モジュールに依存しています。git submodule update --initをお忘れないようにね!これで一通りの準備が完了!
■フローズンモジュールをビルドする
さて、最初に行うのはフローズンモジュールのビルドです。
cd ~/Projects/micropython-esp32
make -C mpy-cross
以下のような出力が出れば完了です。
LINK mpy-cross
text data bss dec hex filename
133038 776 872 134686 20e1e mpy-cross
これで、MicroPythonのモジュールがビルドされた状態になります。
■本体をビルドする
はじめに、ビルド時に使用する変数を設定してMakefileを呼び出すためのメイクファイルmakefileを作ります。
cd micropython-esp32/esp32
vi makefile
エディタはお好きなものを御利用下さい。makefileは、5つの変数に必要なデータを格納した上でMakefileをインクルードするように記述します。
ESPIDF = /opt/esp-idf/
PORT = /dev/ttyUSB0
FLASH_MODE = dio
FLASH_SIZE = 16MB
CROSS_COMPILE = xtensa-esp32-elf-
include Makefile
最後に本体をビルドして完成です。
cd ~/Projects/micropython-esp32/esp32
make
これで、先ほど作ったmakefileが使われて環境変数が設定された後、Makefileがインクルードされて適切なビルドが行われます。ビルド時、最初のメッセージにご注目。もしも、ESP IDFがサポート外のバージョンだった場合、以下のようなメッセージが出力されているはずです。
** WARNING **
The git hash of ESP IDF does not match the supported version
The build may complete and the firmware may work but it is not guaranteed
ESP IDF path: /opt/esp-idf/
Current git hash: cd5cc9927bf494e759b8bb513de3f4a9312bc4af
Supported git hash: 4ec2abbf23084ac060679e4136fa222a2d0ab0e8
ここで、無理に未知のバージョンで頑張る積極的な理由はないと思いますので、ESP IDFのディレクトリに移動して、Supported git hashに書かれたバージョンをチェックアウトして下さい。
ガチャガチャとビルドが進行し、以下のような出力が出てきたら出来上がり。
LINK build/application.elf
text data bss dec hex filename
703087 194764 138472 1036323 fd023 build/application.elf
Create build/application.bin
esptool.py v2.1-beta1
Create build/firmware.bin
bootloader 13248
partitions 3072
application 897984
total 963520
次にこれを書き込みます。
■フラッシュの消去
フラッシュの消去は、先ほどのmakefileに書き込んだPORTに書かれたデバイスファイルを経由して実行されます。
sudo make erase
実行すると以下のようなメッセージが出力されます。Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
Erasing flash
esptool.py v2.1-beta1
Connecting........_
Chip is ESP32D0WDQ6 (revision 0)
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 3.3s
Hard resetting...
これでフラッシュが消去されました。次にファームウェアを書き込みます。■フラッシュの書き込み
フラッシュを消去したら、次にファームウェアを書き込みます。
sudo make deploy
実行すると以下のようなメッセージが出力されます。Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
Writing build/firmware.bin to the board
esptool.py v2.1-beta1
Connecting........__
Chip is ESP32D0WDQ6 (revision 0)
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0220
Compressed 959424 bytes to 598202...
Wrote 959424 bytes (598202 compressed) at 0x00001000 in 15.3 seconds (effective 502.5 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting...
あれ?Auto-detected Flash sizeが4MBとなっとる...
まぁ、とにかく書き込み出来ました。
■screenで接続してみる
screenコマンドを使ってシリアル接続してみましょう。
sudo screen /dev/ttyUSB0 115200
screenコマンドを終了させたい場合には、CTRL+Aを押してからKを押します。
試しにEnterキーを押してみてください。>>>が表示されていれば動作しています。
>>>
>>>
>>>
>>>
>>> import machine
>>> machine.
__name__ mem8 mem16 mem32
freq reset unique_id idle
disable_irq enable_irq time_pulse_us Timer
Pin Signal TouchPad ADC
DAC I2C PWM SPI
UART
更に「import machine」と打ってから「machine.」まで打ってTABを叩くと入力補間機能が使えます。あぁ、楽しいなぁ。
■物足りないよね?
こんな誰でもやるようなステップを踏んだ記事を読んでイライラしている方、居ますよね。居ます居ます。私もそう。
例えば、「ECO and Workarounds for Bugs in ESP32」を眺めて、Chip Revision 0に対するワークアラウンドがどのように実装されているのか見るのも楽しいでしょう。ESP32のRevision 0には、キャッシュ・メモリ・マネージメント・ユニットのバグによって、パワーアップ時/ディープ・スリープからのウェイク・アップ時に、間違ったウォッチドッグ・リセットが発生してしまいます。
さて、今回私が手にしたモジュールにはRevision 0のデバイスが搭載されていることが、フラッシュの消去と書き込み時の出力「Chip is ESP32D0WDQ6 (revision 0)」からわかっています。つまり、ワークアラウンドがなければ動作しない可能性があるわけです。このバグに対するワークアラウンドは、DPORT_PRO_CACHE_CTRL1_REGにあるPRO_CACHE_MMU_IA_CLRビットを1に設定し、次にそのビットを0にする事とあります。
では、これに対する実装はどこにあるのかというと、先ほどのESP-IDFで実装されているブートローダにあります。私の場合、ESP-IDFを/optの下に配置したので「/opt/esp-idf/components/bootloader/src/main」のディレクトリにあるbootloader_start.cにあります。
あぁ、楽しくなってきた。組み込みシステムのファームウェアというのは、こういう色々な事情を考慮した上で成り立っているんです。ちょっと実装して「あー動いた。終わり。」とか「あー動かないや。終わり。」という世界ではないんです。動いたら動いたで本当に意図した動作で動いているのか確かめる、動かないなら動かないでどこが意図しない動作で動いていないのか確かめる、どっちにしろ確かめるっていう姿勢が大事なんじゃないかと、ESP32にまつわる色々な記事を見ていて少し思いました。少しだけね。
■ここまでのまとめ
- Ubuntu 16.04.3の環境構築、ビルド、書き込み、動作確認までを一巡させた。
- 普通に動かす方法だけを書いても面白くないので、一部だけ掘り下げてみた。
0 件のコメント:
コメントを投稿