STM32L4 Discovery Kit IoT Node に Amazon FreeRTOS を導入する

· Read in about 12 min · (5985 words) ·

Amazon FreeRTOS は 2017/11/29 に Amazon のイベント re:Invent 2017 にて発表されたマイクロコントローラー向けリアルタイム OS のディストリビューションです。 今回、とりあえず触ってみようと対応ボードを買ってきてセットアップしてみたので、その手順をご紹介。

FreeRTOS 自体は 2003 年 Richard Barry 氏により開発されたリアルタイム OS です[参考文献1]。これまでは彼の会社である Real Time Engineers Ltd. によりメンテされていましたが、re:Invent 2017 で発表があったように今後は AWS によりメンテされることになります。また、ライセンスも例外付き GPL から MIT License に変更され、より商業利用に適したライセンスになりました。更に、ソースコードも GitHub でホスティングされるようになりました[参考文献2]

Amazon FreeRTOS はこの FreeRTOS (kernel) と Amazon FreeRTOS Libraries の組み合わせで構成されており、Amazon FreeRTOS Libraries には以下の3つの役割が含まれています[参考文献3]:

  • MQTT と Device Shadow を用いたデバイスと AWS IoT Cloud のセキュアな接続
  • AWS Greengrass コアのディスカバリと接続
  • Wi-Fi 接続の管理

・・・なんだか Mbed OS のコンセプトと近いものを感じますね。

FreeRTOS 自体は非常に多くのマイクロコントローラーに対応しているようなのですが、Amazon FreeRTOS として現在対応が謳われているボードは以下の 3 種類になります[参考文献2]

(Microchip Technology Incorporated の Curiosity PIC32MZ EF Development Board はカミングスーン!)

加えて、Windows 用のシミュレーターも提供されています。

今回チョイスしたのは ST のボードです (冒頭の写真)。STM32L4 Discovery kit IoT node と呼ばれていますが、正式名称は B-L475E-IOT01A で、もっと正確には B-L475E-IOT01A2 となっています。Mouser Electronics で ¥6,440 で購入しました。私の注文は UPS でアメリカから発送されました。

基盤たった1枚を、ダラス・フォートワース空港、ルイビル空港、アンカレッジ空港、成田空港と4空港も経由して運んできてくれるなんてなんだか胸が熱くなりますね。 ちなみに、UPS がダイレクトに自宅に届けにきたときは不在だったのですが、電話が掛かってきて明日にしてと言ったらヤマト運輸に振替となりました。さすが世界の UPS!

この基盤の素晴らしいところは、いろんな IO やセンサーがごった煮になっているところです。載っているものを調べて図示してみました。

STM32L4 Discovery kit IoT node オモテ

めちゃめちゃたくさん載っていますね!ある意味スマホよりすごいかも!全く、こんなに載ってたらハックしがいがあるってもんです。

それでは本題のセットアップをスタートしたいと想います (前置きが長い)。

事前準備

用意するものは以下の 2 つです:

  • AWS アカウント (AmazonFreeRTOSFullAccess ポリシーがアタッチされた IAM, または root account)
  • 対応ボード
  • シリアルポートターミナルアプリ (screen, Cool Term, Tera Term 等)
  • Wi-Fi (Open/WEP/WPA/WPA2) 接続環境

なお、ドキュメントには AWSFreeRTOSFullAccess とありますが[参考文献5]、実際にはそんなポリシーはなく AmazonFreeRTOSFullAccess の間違いと思われます。

AWS IoT の設定

このセクションは FreeRTOS は全く関係ナシで、ひたすら AWS IoT の仕込みです。 まず、AWS IoT コンソールを開き「モノ」(Thing) の定義を行います。

AWS IoT

https://console.aws.amazon.com/iot

左側のメニューから [管理 -> モノ] を選び [モノの登録]、既に何かある場合は [作成] を選びます。

一番上の [単一のモノを作成する] を選びます。

モノにキュートな名前を付けてあげましょう。終わったら一番下までスクロールして [次へ] を選びます。

一番上の [証明書の作成] を選びます。

証明書が発行されたら、一通りダウンロードしておきましょう。そして [有効化] を押すのを忘れずに!

本当に有効化しましたか? (しつこい) ボタンが [無効化] に変わっていれば大丈夫です。[ポリシーのアタッチ] に進みましょう。

おや、何もありませんね。大丈夫、あとで作ります。というわけでそのまま [モノの登録] に進みます。

モノができました。これぞニッポンが誇るモノづくりです。

・・・失礼。さっき飛ばしたポリシーを作りましょう。左側のメニューから [安全性] -> [ポリシー] を選びます。[ポリシーの作成]、既に何かある場合は [作成] に進んでください。

なにやら難しそうな画面がでてきました。ここでやることは大きく 2 つあります。

  1. 名前の入力
  2. 以下の通りステートメントを 4 つ追加:
アクション リソース ARN 効果
iot:Connect arn:aws:iot:ap-northeast-1:580599857604:client/MQTTEcho ☑許可
iot:Publish arn:aws:iot:ap-northeast-1:580599857604:topic/freertos/demos/echo ☑許可
iot:Subscribe arn:aws:iot:ap-northeast-1:580599857604:topicfilter/freertos/demos/echo ☑許可
iot:Receive arn:aws:iot:ap-northeast-1:580599857604:topic/freertos/demos/echo ☑許可

リソース ARN 欄は自動で入力されますが、あくまでテンプレでサフィックス (replaceWithXXX 部分) の修正が重要です。表の通り修正してください。全て追加し終わったら [作成] を選びます。

作成し終わったら左側メニューから [安全性] -> [証明書] を選びます。いつのまにか (モノの定義をしたときに) 出来ている証明書を選び、アクションメニューから [ポリシーのアタッチ] を選びます。

さっき作ったポリシーの名前は覚えていますか?忘れた?そんなあなたのために画面には既に先程作ったポリシーが現れています。チェックを入れて [アタッチ] を選びます。

これで一通り仕込みは済んだはず。それでは次のステップへ行きましょう。

Amazon FreeRTOS の開発環境構築

FreeRTOS をダウンロードしましょう。以下のリンクか、または IoT コンソールの左下の [ソフトウェア] -> [Amazon FreeRTOS デバイスソフトウェア] ペインの [ダウンロードの設定] からも行くことができます。

AWS IoT

https://console.aws.amazon.com/freertos

今回のお目当ては「Connect to AWS IoT - ST」です。ダウンロードします。高々 2.38 MB しかありません。ダウンロードしたら、ZIP を展開しておきましょう。

展開すると AmazonFreeRTOS ディレクトリが入っているかと思います。この中のデモを開発環境で読み込んで、設定をちょちょいといじって配備するわけですが、か、開発環境?どこにあるの?なんか .project とかあるけど?Eclipse か!? (※AmazonFreeRTOS/demos/st/stm32l475_discovery/ac6)

Eclipse は半分正解で、半分間違いです。System Workbench for STM32 という Eclipse ベースの開発環境を使います。以下のサイトからダウンロードします:

OpenSTM32 Community Site | HomePage

http://www.openstm32.org/

開くとこんな感じのウェブサイトが (ブラウザの「安全ではありません」警告と共に) 現れるはずです。

悲しいことに、開発環境をダウンロードするにはログインしないといけないのです (実はファイル名がわかっていればココからダウンロードもできますが、一応案内上ログインしないといけないことにさせてください😇)。

しかも、https ではないサイトで入力フォームに必要事項を全て記入しないといけません。しかもしかも、MS メールだと弾かれるらしいです。

登録が済んだら、次の URL からようやくダウンロードの案内にありつけます。

OpenSTM32 Community Site | Downloading the System Workbench for STM32 installer

http://www.openstm32.org/Downloading+the+System+Workbench+for+STM32+installer

Windows 10 64bit な私は「Windows 7」の 64bit 版をダウンロードしました。433MB もあり、しかもダウンロードサーバーは激しく遅いです。ダウンロードをはじめたら、お風呂にでも入りに行きましょう (私は4時間ぐらいかかりました。90年代か!不安な場合は wget などレジューム可能なツールを使ったほうが良いかもしれません)。

ダウンロードが終わったら、実行です。基本全部デフォルトで進めたほうが無難でしょう。もしエラーに遭遇したら FAQ が助けになるかもしれません。

途中、インストール終盤では、ドライバをインストールする画面が別途出現します (Windows の場合)。

全てうまくいくと、こんな感じ。[Done] で閉じます。

スタートメニューやデスクトップショートカットやら作る設定 (デフォルト) なら、出来ているはずなのでそこから起動します。

起動スプラッシュはなかなか。起動途中に現れる Eclipse 同様のワークスペース選択設定は適当に。

起動後も初回インストール処理のようなものが走ります。Eclipse IDE for C/C++ Developers がベースになっていることがわかります。

メニューから [File] -> [Import] を選び、Import 画面にて [General] -> [Existing Project into Workspace] を選んで [Next >] を選びます。

このセクションの冒頭でダウンロードした ZIP の中にある AmazonFreeRTOS/demos/st/stm32l475_discovery/ac6 ディレクトリを指定し、aws_demos プロジェクトが選択されていることを確認します。最後に [Finish]!

Welcome タブを閉じてプロジェクトファイルを眺めたあと、メニューから [Project] -> [Build All] を選びます。

👉エラーよし、👉ウォーニングよし、👉モチベーションよし!次に進みましょう。

IoT Node の構成

System Workbench の Project Explorer にて aws_clientcredential.h を開きます。application_code/common_demos/include にあります (ファイルシステム上のパスは AmazonFreeRTOS/demos/common/include です)。

以下の通り値を入れていきます (定義場所は執筆時点の最新版のものです):

設定値 定義場所 (行) デフォルト値 入力値
clientcredentialMQTT_BROKER_ENDPOINT L39 Paste AWS IoT Broker endpoint here. AWS IoT のエンドポイント
clientcredentialIOT_THING_NAME L44 Paste AWS IoT Thing name here. モノの名前 (この例では stm32-001)
clientcredentialWIFI_SSID L59 Paste WiFi SSID here. SSID
clientcredentialWIFI_PASSWORD L64 Paste WiFi password here. パスワード
clientcredentialWIFI_SECURITY L71 eWiFiSecurityWPA2 eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA, eWiFiSecurityWPA2

AWS IoT のエンドポイントは、IoT コンソールの左側メニューの下にある [設定] より確認できる値です。

次に、Project Explorer にて config/aws_wifi_config.h を開きます。これも先程と同様に、以下の箇所を修正します。ちなみにこれは公式ドキュメントにはない手順なのですが、設定しないと動きませんでした。

設定値 定義場所 (行) デフォルト値 入力値
wificonfigACCESS_POINT_SSID_PREFIX L68 ConfigureMe SSID
wificonfigACCESS_POINT_PASSKEY L73 awsiotdevice パスワード
wificonfigACCESS_POINT_SECURITY L90 eWiFiSecurityWPA2 eWiFiSecurityOpen, eWiFiSecurityWEP, eWiFiSecurityWPA, eWiFiSecurityWPA2

ファイルの編集が終わったら、次は証明書の設定です。

ファイルブラウザ (エクスプローラー) にて AmazonFreeRTOS/demos/common/devmode_key_provisioning/CertificateConfigurationTool にある CertificateConfigurator.html を開きます。

それぞれ指定するものは以前ダウンロードしておいた以下のファイルです:

  • Certificate PEM file: xxxxxxxxxx-certificate.pem.crt
  • Private Key PEM file: xxxxxxxxxx-private.pem.key

ファイルを指定したら、[Generate and save aws_clientcredential_keys.h] を選択します。

生成されたファイルは AmazonFreeRTOS/demos/common/include に配置 (上書き) します。

メニューから [Project] -> [Build All] を選び、コンパイルエラーがないかチェックします。

デモ!

AWS IoT の左側のメニューより [テスト] を選び、MQTT サブスクリプションの設定を行います。トピック名 freertos/demos/echo とし、[MQTT ペイロード表示] は [ペイロードを文字列として表示 (より正確)] を選びます。最後に [トピックへの…] に進みます (何!? 英語は Subscribe to topic なので「トピックへのサブスクライブ」かな)。

なお、このトピック名は application_code/common_demos/source/aws_hello_world.cechoTOPIC_NAME 定義にあるもので、かつアタッチしたポリシーで記載したものと一致している必要があります。

AWS IoT の準備が整ったら、次は基盤のほうをチェックです。パッケージのウラにも文書で書いてあるように、以下のようなコンフィギュレーションになっていることを確認します:

Jumper State
JP4 5V_ST_LINK
JP5 Closed
JP6 Closed
JP7 Closed
JP8 Open

STM32L4 Discovery kit IoT node ウラ

PC とボードを USB で接続します!繋ぐポートは USB ST-LINK (端っこの穴) です。向きに注意して優しくインサートしてください💕

System Workbench のメニューで [Run] -> [Run Configurations…] を選び、左側ペインで [Ac6 STM32 Debugging] -> [aws_demos Debug] を選びます。さらに [Debugger] タブを開き、中腹にある [Show generator options…] を押します。

[Connection Setup] の [Frequency] は [480MHz], [Mode Setup] の [Reset Mode] は [Software system reset] を選びます (または確認します)。設定を終えたら [Apply] ボタンで反映し、[Run] を押します。

こんな感じのログが流れるはずです。

Open On-Chip Debugger 0.10.0-dev-00005-g4030e1c-dirty (2017-10-24-08:00)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
none separate

(中略)

verified 306816 bytes in 9.605227s (31.194 KiB/s)
** Verified OK **
** Resetting Target **
Info : Stlink adapter speed set to 480 kHz
adapter speed: 480 kHz
shutdown command invoked

途中 ERROR とかも出てるけど大丈夫なんか・・・?😇 でも Verifyied OK とか言ってるし・・・?おそるおそる、シリアルポート端末アプリを開き (ここでは Cool Term)、Baudrate を 115200 にしてつなぎにいきます。

Cool Term は [OK] を押したあと、[Connect] を押す必要があります。繋がったら、ボードの リセットボタン (黒い物理ボタン) を押します。

こんな感じでログが流れていればたぶん成功しています (TONKOTSU は我が家の AP です🍜)。途中で止まったりしている場合はなにかがおかしいです。詳しくは後述のトラブルシューティングのセクションで解説します。

最初に開いておいた AWS IoT のトピック画面を見てみましょう!

ぞくぞくと届く Hello World たち!いいですね!🎉

だいぶ記事も長くなってきたので、本編はこれでおしまいにします。今後の活用もお楽しみに!

トラブルシューティング

さて、問題に直面したあなた (っていうかわたし) はより深い知見を得る絶好のチャンスです。切り分けの基本はまず事実を集めることです。というわけでログの確認から。例によって、AWS IoT は CloudWatch によるログ集計が可能です。が、デフォルトでオフになっています。有効にするには、左側メニューの下部にある [設定] から [ログ] ペインを確認します。

レベルは [デバッグ]、ロールは新規に作ります。名前はなんでも良いです。

設定できたら CloudWatch のコンソールに向かいます。

CloudWatch

https://console.aws.amazon.com/cloudwatch

[メトリクスの参照] を選択します。

お、[IoT] ができていますね。選択し、続けて [プロトコルメトリクス] を選択します。

MQTT や HTTP などいくつかのメトリクスが並んでいるので、まずは MQTT 系を全てチェックしグラフを眺めます。期待したものがなければ AWS IoT と疎通ができていないことが推測できますし、図のように Connect.AuthError が頻発しているときは、疎通はできているがポリシー違反などで弾かれていると推測できます。

疎通ができていない場合に関しては、どのレイヤーで止まっているかを切り分ける必要があります。幸い WiFi 接続に関してはシリアルポートに結果が出るので、問題があればすぐに特定できます。

WiFi は OK (AP や DHCP で振られた IP などが確認できる) が、その後で止まってしまった場合は解析が必要です。一番ありそうなのが、AWS IoT 通信で必須な TLS まわりでしょう。そこで、 aws_mqtt_agent.c の L1268 あたりに次のコードを挿入してみます。

configPRINTF( ( "DEBUG: prvManageConnections() lBytesReceived=%d\r\n", lBytesReceived) );

ログはこうなりました。

14 28165 [MQTT] DEBUG: prvManageConnections() lBytesReceived=-1004
15 32421 [MQTT] DEBUG: prvManageConnections() lBytesReceived=-1004
16 33425 [MQTT] DEBUG: prvManageConnections() lBytesReceived=-1
17 34428 [MQTT] DEBUG: prvManageConnections() lBytesReceived=-1
...

数値の値は定義済のものです。aws_secure_sockets.h では以下のように定義されているのが確認できます:

  • 0: 成功
  • -1: ソケットエラー
  • -11: 資源が一時的に利用できない
  • -12: メモリアロケーション失敗
  • -22:` 不正な引数
  • -109: 不正なオプション指定
  • -128: 提供されたソケットが既にクローズされている
  • -1001: TLS 初期化失敗
  • -1002: TLS ハンドシェイク失敗
  • -1003: 接続は確率したがサーバーを検証できない、ソケットのクローズがおすすめ
  • -1004: TLS 受信処理失敗
  • -1005: TLS 送信処理失敗
  • -1006: 通信機器がリセットされた

上のログでは、どうやらデータ受信に失敗していたようです。私の場合はこのあと直っちゃったのですが、TLS 実装部まで追う場合は aws_tls.c をデバッグしていくことになります。ちなみにこのコード、実は Mbed OS などで使われている mbed TLS なんです!んじゃ諦めて Mbed OS に乗りk・・・いやいや、もう少し頑張るんだ・・・😇 なお、先程用いたシリアルコンソール表示 configPRINTF はここでは #include "FreeRTOS.h" しないと使えません。

疎通はできていて、CloudWatch で Connect.AuthError が記録される場合は、使った証明書が (証明書としては正しいけれど) 別のものだったか、証明書に適切なポリシーがない、ないしは間違っている可能性があります。過去の手順を今一度確認してみてください。

Happy hacking!

参考文献

  1. RTOS - Free professionally developed and robust real time operating system for small embedded systems development
  2. aws/amazon-freertos: Cloud-native IoT operating system for microcontrollers.
  3. What Is Amazon FreeRTOS? - Amazon FreeRTOS
  4. アナウンス Amazon FreeRTOS – 何十億ものデバイスがクラウドから安全に利益を得ることを可能にする | Amazon Web Services ブログ
  5. Amazon FreeRTOS - Get Started - AWS
  6. B-L475E-IOT01A - STM32L4 Discovery kit IoT node, low-power wireless, BLE, NFC, SubGHz, Wi-Fi - STMicroelectronics
  7. Getting starting with STM32L4 Discovery kit IoT node - YouTube
  8. Amazon FreeRTOS Security - Amazon FreeRTOS