IoTHubデバイス開発を極める - Azure IoT C SDKsとAzure SDK for Embedded Cの違い

先回はIoT Hub Device SDKのラインナップを紹介しました。MPUで使えるfor .NET, Python, Node.js, Javaと、MCUMPUで使えるAzure IoT C SDKs, Azure SDK for Embedded Cがありました。Azure SDK for Embedded Cは第二世代のSDKで、フラッシュメモリやRAM少ないMCU向けのものでした。
今回は第一世代のAzure IoT C SDKsと、第二世代のAzure SDK for Embedded Cの違いを紹介します。

Azure IoT C SDKs - 第一世代

C99以降、C++向けのAzure IoT SDKです。このSDKにはIoT Hub Device SDKやIoT Hub Service SDK, Provisioning Device SDKが含まれています。(SDKsと複数形になっているのはそのためです。)

github.com

Azure IoT Hubの進化とともに機能追加、改善されてきた経緯によるものか分かりませんが、ディレクトリ構成は分かりやすいとは言い難いです。IoT Hub Device SDKは、/iothub_clientディレクトリ配下なので、まずはここをじっくりと見るのが良いでしょう。(docsに解説があります。)

...
いきなりソースコードを見るのはしんどいので、、、
先ずは、移植の手引き(How to Port the Azure IoT C SDK to Other Platforms)にあるOverviewの図でSDKを理解しましょう。

How to Port the Azure IoT C SDK to Other Platformsから引用:

SDKの最も大事な部分であるネットワーク通信は、TLSIOSocketIOを使用します。たとえば、TLSIOにMbedTLS、SocketIOにBerkeley Socket APIを使うとか。通信の際、時刻を把握したり待ちを加えるといったことが発生するので、TimerSleepも呼び出しています。また、SDK内部でスレッドを起動してバックグラウンド処理を実行するため、ThreadingLockといった機能も呼び出しています。

スレッド起動に関して、docsに少し書かれています。
「IoTHubClient_CreateFromConnectionString を呼び出すと、基になるライブラリでは、バックグラウンドで実行される新しいスレッドを作成します。 このスレッドは、IoT Hub にイベントを送信し、IoT Hub ハブからメッセージを受信します。 」「バックグラウンド スレッドが作成されるのは、開発者にとって便利です。 IoT Hub とのイベントの送信とメッセージの受信を明示的に実行することについて心配する必要はありません。自動的にバックグラウンドで実行されます。」

Azure SDK for Embedded C - 第二世代

その後、Azure IoT SDKの第二世代、Azure SDK for Embedded Cがリリースされました(docs)。

とにかくメモリリソースの消費を最小限にするよう、さまざまな情報をポインタ参照で実装されています。また、SDK内部ではメモリの動的確保が完全に排除されています。
そのため、Azure IoT C SDKsのIoT Hub Device SDKとはAPIは別物です。関数名、引数はおろか、関数ラインナップも全く違います。

Azure IoT Embedded C SDKアーキテクチャdocs)から引用:

また、SDKからネットワーク通信APIを呼び出していない点も特徴です。SDKMQTTに渡すデータへの変換MQTTから受け取ったデータを変換する役割で、APIを呼んでもそれだけでは通信されません。SDKからの戻り値を使って、アプリケーションで通信のAPIを呼び出す必要があります。

Azure IoT C SDKとAzure SDK for Embedded Cの比較

Azure IoT C SDKとAzure SDK for Embedded Cを、API呼び出しの流れと提供者の観点で比較した図がこちらです。

Azure IoT C SDKは、アプリケーションからSDK APIを呼び出すと、あとは勝手に通信してくれます。通信お任せなので扱いが楽ですね。そのかわり、デバイス毎の通信部分をAzure IoT C SDKから呼び出せるよう用意しなければならず、ここに少し手間がかかりますが、メジャーなOS/Platform向けには3rd party(やMicrosoft)がパッケージの形態で提供しています。

Azure SDK for Embedded Cは、アプリケーションからSDK APIを呼び出し、さらに、通信APIを適時呼び出さなければいけません。正直、面倒です。じゃあ何が良いのか?というと、メモリリソース消費が抑えられる点と、通信APISDK(正しくはパッケージ)に内包していない点です。特に後者が重要で、例えばLTE通信モジュールが内蔵しているMQTT/TLSを活用しようとしたとき、Azure IoT C SDKではパッケージを作らないといけない(つらい)のですが、Azure SDK for Embedded Cは容易に実装ができます。

まとめ

  • Azure IoT C SDKs(第一世代)
    • 通信を内包。扱いが楽。
    • スレッドを作成してくれて便利。(な用法もある)
    • OS/Platformが合致しないと、つらい。
  • Azure SDK for Embedded C(第二世代)
    • 通信含まず。めんどい。
    • メモリリソース消費が少ない。
    • OS/Platformが提供する高度な通信を活用しやすい。

次回は、Azure SDK for Embedded Cでの注意点を書こうと思います。