user icon

Mongoose OSをESP32で使ってみた

ESP32開発ボードを購入し、Mongoose OSを試してみました。
ESP32シリーズは、Wi-FiとBluetoothを内蔵する低コスト、低消費電力なSoCのマイクロコントローラです。
Mongoose OSは、低消費電力なマイクロコントローラ用のオープンソースのOSです。IoTするための機能が充実しています。

ESP32およびESP32開発ボードは、いくつかのベンダーが出していますが、購入したのは、「HiLetgo ESP32 ESP-32S NodeMCU開発ボード」という一番安かったもの。
中国から国際書留で送られてきましたが、到着するのに10日かかりました。
ちゃんと技術基準適合マークついてました。

Mongoose OSのインストール

以下を参考にしました。
https://mongoose-os.com/docs/quickstart/setup.html

開発環境はMacOSです。
開発環境にmosコマンドをインストールします。

$ curl -fsSL https://mongoose-os.com/downloads/mos/install.sh | /bin/bash
$ ~/.mos/bin/mos --help

USB-シリアルドライバをインストールします。
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

次にESP32のフラッシュに、Mongoose OSのdefaultのファームウェアを書き込みます。
ESP32開発ボードと端末をUSBで接続し、以下を実行するとブラウザでWEB UI IDEが起動します。

$ ~/.mos/bin/mos

ステップ1で「/dev/cu.SLAB_USBtoUART」を選択し「Select」ボタンを押します。もし、「/dev/cu.SLAB_USBtoUART」がない場合、USB-シリアルドライバがインストールされてません。
次に、「Select firmware, click Flash」で、「mos-esp32-1.17」を選択し「Flash」ボタンを押すわけですが、なぜかどうしてもフラッシュ書き込みが出来ませんでした。

よく分かりませんがコマンドラインだとフラッシュ書き込みが出来ます。

$ ~/.mos/bin/mos flash mos-esp32-1.17 --port /dev/cu.SLAB_USBtoUART

コマンドラインで書き込み後、再度WEB UI IDEを起動すると、「Mongoose OS is installed on this device:」と表示され次のステップへ進めます。


しかしここで、別の問題が発生しました。
今まで、Arduino IDE(arduino-esp32)やESP-IDFのesptool.pyでフラッシュ書き込みが出来てましたが、Mongoose OSのフラッシュ書き込み後、できなくなってしまいました。
なお、mos flashコマンドだとその後も、時々失敗しますが書き込みできます。


ステップ3でWIFIのSSIDとパスワードを登録します。

開発

WEB UI IDEまたはコマンドラインで開発できます。
コマンドラインの場合、以下のような感じです。

  • mos init –arch esp32   // スケルトンのプロジェクトファイルをダウンロード
    あるいは、ここから適当なものをgit clone
  • プログラミング
  • mos build –arch esp32 –local  // ビルド
  • mos flash           // フラッシュ書き込み
  • mos console          // ログ出力

ビルド

クラウド(http://mongoose.cloud/)またはローカルでできます。
デフォルトはクラウドです。ローカルの場合「–local」をつけてビルドします。
クラウドの方が速いです。ビルドするソースが全部、どこかに送られていると思うと嫌ですが。
ローカルのビルドではデバイスの環境依存吸収のためDockerが使用されています。

mjsについて

Mongoose OSは、Javascript(mjs)またはC/C++で開発できます。

ESP32はpartition tablesがあり、フラッシュ上にパーティションを配置でき、ファイルシステムのパーティション作成できます。
Mongoose OSは、フラッシュ上にファイルシステムを持っていて、
mjsの場合、ファイルシステム上に更新ファイルを置いて再起動するだけで、コンパイルもファームウェア更新しなくても、プログラムを更新できます。

AWS-IoTのテスト

以下を参考にしました。
https://mongoose-os.com/blog/secure-remote-device-management-with-mongoose-os-and-aws-iot-for-esp32-esp8266-ti-cc3200-stm32/

設定

事前にAWS CLIをインストールしIAM等の設定しておきます。

$ mos aws-iot-setup --aws-iot-policy=mos-default

これだけでカレントディレクトリに鍵を生成し、AWSにアクセスしてモノ(Thing)登録およびESP32のクライアント側のMQTT Settingsしてくれます。

検証

WEB UIの場合、自動生成されるdefaultアプリのinit.jsに、既にデバイスのボタンを押下したらMQTTのpubllishを行うロジックがあります。


// Publish to MQTT topic on a button press. Button is wired to GPIO pin 0
GPIO.set_button_handler(button, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function() {
let message = getInfo();
let ok = MQTT.pub(topic, message, 1);
print('Published:', ok, topic, '->', message);
}, null);

AWSコンソール画面でAWS IoTを開き、
「テスト」> 「トピックへサブスクライブする」で、トピックを入力し、「トピックへのサブスクライブ」ボタンを押します。。
入力例 /devices/esp32_21B54C/events  // ‘/devices/’ + Cfg.get(‘device.id’) + ‘/events’

ESP32開発ボードのIO0ボタンを押すと、AWSコンソール画面で以下の様なものが表示され、サブスクライブ出来たことが確認できます。

{
"free_ram": 105960,
"total_ram": 191920
}

AWS IoTでできること

AWS IoTを通じて(mqttで)、リモート越しにデバイスにアクセス・操作できます。

最初にエイリアスを作成

$ alias mos1="mos --cert-file $(mos config-get mqtt.ssl_cert) --key-file $(mos config-get mqtt.ssl_key) --port mqtts://$(mos config-get mqtt.server)/$(mos config-get device.id)"
$ mos1 ls -l       // ファイルシステム上のファイル一覧
$ mos1 call Sys.GetInfo // RPC呼び出し      システム情報表示  
$ mos1 call Sys.Reboot // RPC呼び出し 再起動

実はdefaultアプリだと、httpがenabledになっていて、AWS IoT以外にhttp、websocketでもデバイスにアクセス・操作できます。

$ mos --port http://192.168.17.142/rpc ls
$ mos --port http://192.168.17.142/rpc call Sys.GetInfo
$ mos --port ws://192.168.17.142/rpc call Sys.GetInfo

ライブラリおよび設定について

mos.ymlファイルで、ライブラリおよび設定を定義します。
defaultアプリで、httpがenabledになってるのは、defaultアプリはライブラリjs-demo-bundleを読み込んでいて、js-demo-bundleは、http-serverを読み込んでいます。
http-serverのmos.ymlに以下の記述があります。

config_schema:
- ["http.enable", "b", true, {title: "Enable HTTP Server"}]

RPC

Mongoose OSはRPC(remote procedure call)が強力です。

シェル上でmosコマンドで実行する場合以下のようにします。

$ mos1 call Sys.Reboot

OTA(Over The Air updates)で、リモートからファームウェア書き換えが出来ます。
またI2CやGPIOもRPCで操作できるので、デバイスにプログラムを置くのではなく、リモートにプログラムを置いて(たとえばAWS Lambda)、デバイス操作するすることが可能です。
バックドア的なことが簡単に実現可能な気がします。セキュリティ管理をちゃんとする必要があります。

デフォルトで用意されてるRPC一覧です。

$ mos call RPC.List
[
  "Wifi.Scan",
  "OTA.SetBootState",
  "OTA.GetBootState",
  "OTA.CreateSnapshot",
  "OTA.Revert",
  "OTA.Commit",
  "OTA.Update",
  "I2C.WriteRegW",
  "I2C.WriteRegB",
  "I2C.ReadRegW",
  "I2C.ReadRegB",
  "I2C.Write",
  "I2C.Read",
  "I2C.Scan",
  "GPIO.RemoveIntHandler",
  "GPIO.SetIntHandler",
  "GPIO.Toggle",
  "GPIO.Write",
  "GPIO.Read",
  "FS.Umount",
  "FS.Mount",
  "FS.Mkfs",
  "FS.Remove",
  "FS.Put",
  "FS.Get",
  "FS.ListExt",
  "FS.List",
  "Config.Save",
  "Config.Set",
  "Config.Get",
  "Sys.SetDebug",
  "Sys.GetInfo",
  "Sys.Reboot",
  "RPC.Ping",
  "RPC.Describe",
  "RPC.List"
]
Facebooktwitterlinkedintumblrmail

タグ: , , ,

名前
E-mail
URL
コメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)