読者です 読者をやめる 読者になる 読者になる

hogehoge, world.

米国カリフォルニアから日本に一時帰国中のソフトウェアエンジニアがIT・自転車・音楽・天体写真・語学などについて書く予定。

ESP-WROOM-02(Arduino)によるWiFiネットワーキング (4) ~ OSなしのプログラミング

IT Arduino ESP-WROOM-02

前回Arduinoのソフトウェア開発はOSなしで実行されるC++プログラムを書くこと」と述べた。この「OSなし」が何を意味するのか、やったことのない人にはピンと来ないかもしれないので、簡単に説明してみたいと思う。

OSのある世界では、PCが起動するとブートローダーがまずOSを読み込んで実行し、次にOSがアプリケーションをファイルから読み込んで実行する。これがArduinoだとブートローダーが直接アプリケーションを読み込んで実行する。つまり普段空気のように当たり前に存在しているOSによるサポートを当てにせずにアプリケーションを書かねばならない。具体的には次のような違いが現れることになる。

単機能のシステムになる

OSがいればOSに対して「このアプリケーションを読み込んで実行せよ」と言えるが、それができない。あらかじめFlashに書き込まれたアプリケーションを実行するだけの単機能のシステムになる。

ファイルシステムがない

普段当たり前のように使っているファイルシステムだが、そんな高度なものはない。アプリケーションはFlashメモリの特定の領域にべたっと書き込まれているだけだし、電源を切っても覚えておきたいアプリケーションデータは、普通のArduinoであれば1KB程度のEEPROMを1バイト1バイト大切に使って覚えておくことになる。ESP-WROOM-02は若干恵まれていて、4MBの広大な(笑)Flashメモリのうち3MBをファイルシステムのように使えるライブラリ(SPIFFS)を使うことができる。ちなみにこのファイルシステム(もどき)はディレクトリの概念がない、つまりツリーではなくフラットな構造である。

並行実行機能(マルチプロセス・マルチスレッド)がない

Arduinoのコードを見ると、次のようなビジーループが平気で書いてあったりする。

while (digitalRead(PIN) == LOW) ; // PINにHIGH信号が入力されるまで待つ

これが普通のPCやスマフォ用のプログラムだったら、「こんなことしたらCPUが回りっぱなしになって電気を食うし、他のアプリやマウス・キーボードの反応が悪くなって困るよなあ。ちゃんとsleepを入れてCPUを解放するとか、イベント駆動型にするとかしなきゃ」などと思うのが近代のプログラマの常識である。

しかしこの考えは、「OSがバックグラウンドでいろいろ頑張っていて、CPUを使っていない間は省電力機能を働かせたり、他のプロセスにCPUを分け与えたり、マウスやキーボードのイベントを処理したりしている」という前提があって初めて成り立つ考えである。OSのサポートがなく、CPUにとってアプリケーションが実行すべき唯一のプログラムであれば、そんなことは関係ない。むしろ「delay() (一定時間待つArduinoAPI) を入れると信号を取りこぼすから使うな、できるだけ早くループを回せ」と言われたりするのである。

マルチスレッド機能もないので、複数の処理を同時に行ないたい場合には交互に処理を行うループを自分で書くことになる。例えばモーターの回転数を連続的に制御しながら外部からの入力を受け付けたければ、「片方を実行している間はもう片方の処理が止まる」ということを頭に入れて、両方を少しずつ交互に行うループを自分で書くのである。

なお割り込みを使えば本当の並列実行のようなことができるが*1、「割り込まれた側の変数が壊れるからちゃんとケアしてね(はぁと)」とマニュアルに書いてあったりするので、ちゃんと仕組みを理解して使う必要がある。

ところが、ESP-WROOM-02の場合には少しだけ事情が違う。ESP-WROOM-02ではWiFiを制御するための処理をバックグラウンドで走らせる必要があるので、長い間CPUを占有するような処理では時々yield()やdelay()を呼べ、その延長で必要な処理を行うから、ということになっている。一昔前の疑似スレッドと似たようなノリで、OSがアプリケーションからCPUを強制的に奪うことができないので、アプリケーションが自分でバックグラウンド処理を呼び出せということである。また、ESP-WROOM-02には省電力機能が実装されていて、CPUが不要な場合にはdelay()を呼ぶことで消費電力を抑えることができる。ここはアプリケーションがシステムを完全に占有している普通のArduinoとは異なるところである。

対話的なコマンドシェルがない

当然コマンドシェルもないので、「アプリケーションが落ちたので、トラブルシュートのためにシェルにログインしよう」なんていうことはできない。システムを対話的に操作したければ、アプリケーションにそういう機能を作りこまねばならない。それに第一アプリケーションが落ちたりしたら何もできないのでリセットするしかない。

デバッガによるリモートコントロール的なことはできるようだが、あまり追求していないのでここでは説明できない。

その他

  • メモリ保護がない。ただアプリケーションがシステム全体を占有しているのであまり困らない。
  • デバイスドライバがない。ただデバイスドライバというのはデバイスの細かい違いをユーザから隠すための仕組みであり、組み込み分野ではデバイスの詳細を意識せざるを得ないことがほとんどなので、あまり困らない。

*1:実際のOSのマルチスレッドやマルチプロセスも内部では割り込みを使用している。