Amazon Web Services ブログ

FreeRTOSでセカンダリプロセッサのOTAアップデートを実行する方法

多くの組み込みアーキテクチャでは、コネクティビティプロセッサが ビジネスロジックを実行する1 つ以上のセカンダリプロセッサに接続されています。セカンダリプロセッサの無線 (OTA) アップデートを実行する機能は、コネクティビティプロセッサの更新と同じくらい重要です。 これは、バグやセキュリティの脆弱性に対する低コストのパッチ適用と、デバイスへの新機能の提供が可能なためです。

プライマリ接続プロセッサを AWS IoT に接続し、複数のセカンダリプロセッサをシリアルインターフェイス経由で接続した例を示す画像

FreeRTOSは、マイクロコントローラ用のオープンソースのリアルタイムオペレーティングシステムで、小型で低消費電力のエッジデバイスのプログラミング、デプロイ、セキュリティ、接続、管理を容易にします。 AWS IoT Device Managementにより、IoT デバイスを大規模に安全に登録、整理、監視、リモート管理することが容易になります。 AWS IoT Device Managementは、OTA 更新マネージャサービスを提供し、デバイス群全体でアップデートを安全に作成および管理します。 このサービスは FreeRTOS OTA エージェントライブラリと連携して、ファームウェアにデジタル署名し、ストリーミング API を使用してファイルを MQTT ストリームに変換し、AWS IoT ジョブを使用してファームウェアをデバイスに配信します。 OTA エージェントライブラリを使用すると、TLS経由でのMQTT接続を再利用することで、コネクティビティプロセッサのメモリ消費を減らすことができます。

この記事では、fileId パラメーターを使用して、セカンダリプロセッサに更新を配信する方法について説明します。 この投稿は、特定のハードウェアに固有のものではなく、FreeRTOS 201908.00 以降を実行しているすべてのシステムに適用することができます。 FreeRTOS および AWS IoT デバイス管理を使用して OTA を設定する方法の詳細については、FreeRTOS OTA チュートリアルを参照してください。

リファレンス・アーキテクチャの概要

次のアーキテクチャ図は、コネクティビティプロセッサを介した AWS IoT からのセカンダリプロセッサ更新の流れを示しています。 このデバイスは、コネクティビティプロセッサ上でFreeRTOSを実行し、セカンダリプロセッサに接続されたSPIなどのシリアルインターフェイスを備えています。許可されたオペレータは、ファームウェアを Amazon S3 バケットに安全にアップロードし、OTA アップデートを開始します。 ファームウェアファイルはデジタル証明書を使用して署名され、ストリームが作成されます。 次に、ファームウェアアップデートをデバイスに送信するための AWS IoT ジョブが作成されます。 デバイスのコネクティビティプロセッサは、ファームウェアのアップデートがセカンダリプロセッサ宛であることを識別し、シリアルインターフェイス経由でアップデートを送信します。

AWS IoT から接続プロセッサーを介したセカンダリプロセッサーの更新フローの一般的なアーキテクチャーを示す画像

ファームウェアの変更

FreeRTOS には、OTA アップデートを実行する方法を示すコードが含まれています。 デモの仕組みの詳細については、OTAアップデートのデモアプリケーションのドキュメントをご覧ください。 また、このコードリンクからOTAデモへの変更をダウンロードし、パッチを適用した後に実行することもできます。

プロセッサのOTAは通常、OTAポーティングガイドに記載されているガイドラインを使用して、マイクロコントローラユニット (MCU) ベンダーによって処理されます。 MCU ベンダーは、アップデートを実行するプラットフォームアブストラクションレイヤ (PAL) の機能を実装します。 このパッチにより、コネクティビティプロセッサプロセッサのファームウェア更新処理を上書きし、コネクティビティプロセッサのファームウェア更新を行わずに、セカンダリプロセッサの更新を行います。 先ほどのパッチファイルを使用すると、次のことを実行できます。

  1. PAL レイヤーへの関数のオーバーライドを提供します。 ファームウェアがコネクティビティプロセッサ用のものである場合は、ベンダーが提供する PAL 関数が呼び出されます。 それ以外の場合は、オーバーライドを使用して更新をセカンダリプロセッサに送信できます。 これらの関数は空のままにされているため、プラットフォームの必要に応じてハードウェア固有の転送を実行できます。
  2. PALレイヤーをオーバーライドして、内部OTAエージェント初期化関数を使用して関数オーバーライドを呼び出します。
OTA_AgentInit_internal(xConnection.xMqttConnection, (const uint8_t *)(clientcredentialIOT_THING_NAME), &otaCallbacks, (TickType_t)~0);

アプリケーションのパッチで修正する必要がある項目は次のとおりです。

  • OTA エージェントを初期化する前に、セカンダリプロセッサとの通信を初期化します。
  • コード内のファイル ID を確認して、どのプロセッサが更新されているかを特定します。 このファイル ID は、次のセクションで説明するスクリプトで送信される ID と一致する必要があります。 OTA アップデートがコンソールから作成されると、送信されるファイル ID は 0 になります。 セカンダリプロセッサの更新に 0 を使用しないでください。
  • 各コールバックが適切なエラーを返すようにしてください。 たとえば、prvPAL_CreateFileForRx_customer コールバックでは、セカンダリプロセッサを既知の状態にして、アップデートの受信を開始することができます。 状態変更が失敗した場合、コールバックはエラーを返します。
  • 起動時に現在のプラットフォームイメージの状態として eOTA_PAL_ImageState_Valid を返し、OTA エージェントステートマシンによってプラットフォームの状態が eOTA_ImageState_Testing に設定されている場合は、eOTA_PAL_ImageState_PendingCommit を返してください。
  • セルフテストルーチンでバージョン番号を確認して、セカンダリプロセッサが更新されていることを確認します。 OTAステートマシンによるセカンダリプロセッサの更新を確認するための明示的なチェックはありません。

デモを正しく実行するには、次の変更を行ってください。

  1. ストレージとコード署名証明書を設定して、AWS 環境を設定します。 Perform OTA Updates on Espressif ESP32 using FreeRTOS Bluetooth Low Energy のStep 1 と 2 に従うことで設定できます。
  2. 使用しているプラットフォームの aws_demo_config.h を見つけます。 たとえば、ESP32 の場合、このファイルはvendors/espressif/boards/esp32/aws_demos/config_files/ にあります。
    • CONFIG_OTA_UPDATE_DEMO_ENABLED を定義し、他のデモ定義をコメントアウトします。
  3. demos/include/aws_clientcredential.h を変更します。
    • clientcredentialMQTT_BROKER_ENDPOINT[] でエンドポイント URL を設定します
    • clientcredentialIOT_THING_NAMEでモノの名前を設定します。
  4. demos/include/aws_clientcredential_keys.h を変更します。
    • デバイス証明書を CLIENT_CERTIFICATE_PEM 定義に追加します。
    • デバイスプライベートキーをキーCLIENT_PRIVATE_KEY_PEM 定義に追加します。
  5. demos/include/aws_ota_codesigner_certificate.h を変更します。
    • ファームウェアバイナリファイルの署名に使用する証明書を使用して、signingcredentialSIGNING_CERTIFICATE_PEM を設定します。 証明書の作成方法の詳細が必要な場合は、最初のステップの指示に従ってください。

ファームウェアがプログラムされると、OTA エージェントはコネクティビティプロセッサに対して正常に機能し続けます。 同時に、セカンダリプロセッサにOTAアップデートを提供することもできます。 コネクティビティプロセッサのデバッグコンソールに次の出力が表示されます。

12 309 [iot_thread] OTA demo version 0.9.2
13 309 [iot_thread] Creating MQTT Client...
----
21 823 [iot_thread] Connected to broker.
22 824 [iot_thread] [OTA_AgentInit_internal] OTA Task is Ready.
23 825 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [Ready] Event [Start] New state [RequestingJob]
----
56 924 [iot_thread] State: Ready  Received: 1   Queued: 0   Processed: 0   Dropped: 0
57 1024 [iot_thread] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
58 1124 [iot_thread] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0

この時点で、お使いのデバイスは OTA アップデートを受信する準備ができています。

OTA 更新スクリプトを設定する

セカンダリプロセッサの更新を許可するようにファームウェアを設定したら、これらの更新をデバイスに送信するようにクラウド側を設定する必要があります。 次の手順では、セカンダリプロセッサへの OTA アップデートを開始する方法について説明します。

  1. 前提条件のインストール:
    pip3 install boto3
    pip3 install pathlib
  2. このコードリンクからOTAスクリプトを取得します。
  3. 0より大きいfileIdでスクリプトを実行し、セカンダリプロセッサバイナリのファイルの場所を指定します。
  4. ヘルプは、以下のコマンドを発行することによって得ることができます。
    python3 start_ota_stream.py —h
    usage: start_ota_stream.py [-h] [--fileId FILEID] —profile PROFILE
    [--region REGION] [—account ACCOUNT]
    [--devicetype DEVICETYPE] --name NAME —role ROLE
    --s3bucket S3BUCKET —otasigningprofile
    OTASIGNINGPROFILE —signingcertificateid
    SIGNINGCERTIFICATEID [—codelocation CODELOCATION]
    [—filelocation FILELOCATION]
    
    Script to start OTA update
    
    optional arguments:
    -h, --help show this help message and exit
    --fileId FILEID ID of file being streamed to the device
    --profile PROFILE Profile name created using aws configure
    --region REGION Region
    --account ACCOUNT Account ID
    --devicetype DEVICETYPE
    thing|group
    --name NAME Name of thing/group
    --role ROLE Role for OTA updates
    --s3bucket S3BUCKET S3 bucket to store firmware updates
    --otasigningprofile OTASIGNINGPROFILE
    Signing profile to be created or used
    --signingcertificateid SIGNINGCERTIFICATEID
    certificate id (not arn) to be used
    --codelocation CODELOCATION
    base FreeRTOS folder location (can be relative) when
    fileId is 0
    --filelocation FILELOCATION
    OTA update file location when fileId is greater than 0
    
  5. 実行例:
    python3 start_ota_stream.py --profile otausercf --name mythingname --role ota_role --s3bucket ota-update-bucket --otasigningprofile signingprofile --signingcertificateid <certid> --fileId 1 --filelocation update.bin
    
    Certificate ARN: arn:aws:acm:us-east-1:123456789012:certificate/cert-uuid
    Using App Location: update.bin
    Build File Name: update.bin
    Searching for profile signingprofile
    Found Profile signingprofile in account
    Waiting for signing job to completeOTA Update Status: {'ResponseMetadata': {'RequestId': '2c910ef5-1df5-4df6-8fe9-ddc3c46c68d2', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Tue, 07 Jan 2020 19:53:48 GMT', 'content-type': 'application/json', 'content-length': '184', '
    connection': 'keep-alive', 'x-amzn-requestid': '2c910ef5-1df5-4df6-8fe9-ddc3c46c68d2', 'access-control-allow-origin': '*', 'x-amz-apigw-id': 'F8g4CFECoAMFz5g=', 'x-amzn-trace-id': 'Root=1-5e14e1cc-1fb61a4d9261e6b0602290c9'}, 'RetryAttem
    pts': 0}, 'otaUpdateId': 'device-8673-0-0-0', 'otaUpdateArn': 'arn:aws:iot:us-east-1:123456789012:otaupdate/device-8673-0-0-0', 'otaUpdateStatus': 'CREATE_PENDING'}
  6. コンソールにアップデートの開始が表示されるはずです。 以下はデバイスのデバッグコンソールの表示例です。
    75 2767 [OTA Agent Task] [prvParseJobDoc] Size of OTA_FileContext_t [64]
    76 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ jobId: AFR_OTA-device-58124-0-0-0 ]
    77 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ protocols: ["MQTT"] ]
    78 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ streamname: device-8673-0-0-0 ]
    79 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ filepath: update.bin ]
    80 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ filesize: 10446 ]
    81 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ fileid: 1 ]
    82 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ certfile: /cert.pem ]
    83 2767 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ sig-sha256-ecdsa: MEUCIQDNRumLRyXqUM3Z2wa71/LV4ufv... ]
    84 2767 [OTA Agent Task] [prvParseJobDoc] Job was accepted. Attempting to start transfer.
    85 2767 [OTA Agent Task] [prvPAL_GetPlatformImageState_customer] OTA Demo for secondary processor.
    86 2767 [OTA Agent Task] [prvPAL_CreateFileForRx_customer] OTA Demo for secondary processor.
    ----
    96 2781 [OTA Agent Task] [prvRequestFileBlock_Mqtt] OK: $aws/things/mythingname/streams/device-8673-0-0-0/get/cbor
    97 2781 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [RequestingFileBlock] Event [RequestFileBlock] New state [WaitingForFileBlock]
    98 2805 [OTA Agent Task] [prvIngestDataBlock] Received file block 0, size 4096
    99 2805 [OTA Agent Task] [prvPAL_WriteBlock_customer] OTA Demo for secondary processor.
    ----
    108 2816 [OTA Agent Task] [prvIngestDataBlock] Received final expected block of file.
    109 2816 [OTA Agent Task] [prvStopRequestTimer] Stopping request timer.
    110 2816 [OTA Agent Task] [prvPAL_CloseFile_customer] Received prvPAL_CloseFile_customer inside OTA Demo for secondary processor.
    111 2816 [OTA Agent Task] [prvIngestDataBlock] File receive complete and signature is valid.
    ----
    124 2833 [iot_thread] State: WaitingForJob  Received: 5   Queued: 0   Processed: 0   Dropped: 0
    125 2833 [OTA Agent Task] [prvPAL_ActivateNewImage_customer] OTA Demo for secondary processor.

OTAアップデートが完了すると、デバイスはOTAアップデートプロセスによって必要に応じて再起動し、更新されたファームウェアに接続しようとします。 接続が成功すると、更新されたファームウェアがアクティブとしてマークされ、更新されたバージョンがコンソールに表示されます。

58 866 [OTA Task] [prvUpdateJobStatus] Msg: {"status":"SUCCEEDED","statusDetails":{"reason":"accepted v0.9.2"}}

結論

このブログ記事では、AWS IoT Device Management と FreeRTOS を使用して、セカンダリプロセッサに対して OTA アップデートを実行する方法について説明しました。このメカニズムを拡張して、AWS IoT Core への既存の MQTT 接続を使用して、コネクティビティプロセッサに接続された任意の数のプロセッサをアップグレードできます。

この記事に記載されている手順をお使いのプラットフォームで使用できることを願っています。 FreeRTOSの詳細については、このリンクをご覧ください。

 

原文はこちら
翻訳はソリューションアーキテクト 三平が担当しました。