はじめに
Amazon FreeRTOSのデバイス管理、次はOTAを試してみましょう。AWS S3に新しいファームウェアを置いてデバイスに配布することができます。
AWSのドキュメント Amazon FreeRTOS 無線による更新 の流れに沿って作業を行います。
前提条件
無線による更新(OTA)の前提条件として次のものがあります
1.更新を保存する Amazon S3 バケットを作成する.
新しいファームウェアを格納する場所を作成します。バージョニングを有効にする必要があります。
2.OTA 更新サービスロールの作成.
OTA 更新ジョブを実行する権限です。OTA 用のロールを作成して「AmazonFreeRTOSOTAUpdate」ポリシーをアタッチします。
「AWSIoTThingsRegistration 」のほうは一緒に割り当てられました。
3.OTA ユーザーポリシーの作成.
AWS IoTコンソールから配布する人の権限。(おすすめできませんが、ルートアカウントでテストする場合はスキップ可能)
4.コード署名証明書の作成.
ファームウェアへの署名用。
OpenSSL、AWS CLI がインストールされた環境で、Espressif ESP32 のコード署名証明書の作成 を実行します。
5.Code Signing for AWS IoT を使用している場合は、Code Signing for AWS IoT へのアクセスの許可.
AWS IoTコンソールから配布するファームに署名する人の権限(おすすめできませんが、ルートアカウントでテストする場合はスキップ可能)
6.OTA ライブラリで Amazon FreeRTOS をダウンロードする.
アプリケーション作成用。すでにサンプルアプリケーションを作成している場合は不要。
アプリケーション
前回 作成したファームウェアのバージョン、接続時刻をシャドウに送信するアプリケーションにOTAを追加します。
ネットワーク、MQTTに接続してOTA_AgentInitを呼び出します。
void vRunOTAUpdateDemo( IotMqttConnection_t mqttConnection,
const IotNetworkInterface_t * pNetworkInterface,
void * pNetworkCredentialInfo )
{
// IotMqttConnectInfo_t xConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;
OTA_State_t eState;
OTA_ConnectionContext_t xOTAConnectionCtx = { 0 };
configPRINTF( ( "OTA demo version %u.%u.%u\r\n",
xAppFirmwareVersion.u.x.ucMajor,
xAppFirmwareVersion.u.x.ucMinor,
xAppFirmwareVersion.u.x.usBuild ) );
configPRINTF( ( "Creating MQTT Client...\r\n" ) );
xOTAConnectionCtx.pvControlClient = mqttConnection;
xOTAConnectionCtx.pxNetworkInterface = ( void * ) pNetworkInterface;
xOTAConnectionCtx.pvNetworkCredentials = pNetworkCredentialInfo;
OTA_AgentInit( ( void * ) ( &xOTAConnectionCtx ), ( const uint8_t * ) ( clientcredentialIOT_THING_NAME ), App_OTACompleteCallback, ( TickType_t ) ~1 );
while( ( eState = OTA_GetAgentState() ) != eOTA_AgentState_Stopped )
{
/* Wait forever for OTA traffic but allow other tasks to run and output statistics only once per second. */
vTaskDelay( myappONE_SECOND_DELAY_IN_TICKS );
configPRINTF( ( "State: %s Received: %u Queued: %u Processed: %u Dropped: %u\r\n", pcStateStr[ eState ],
OTA_GetPacketsReceived(), OTA_GetPacketsQueued(), OTA_GetPacketsProcessed(), OTA_GetPacketsDropped() ) );
}
}
Espressif ESP32 にファームウェアの初期バージョンをインストールする の通り、無線による更新の前提条件 で生成した SHA-256/ECDSA PEM 形式のコード署名証明書(サンプル通りであれば、ecdsasigner.crt の内容)を demos/include/aws_ota_codesigner_certificate.h にコピーします。これは、次の方法でフォーマットする必要があります。
static const char signingcredentialSIGNING_CERTIFICATE_PEM[] = "-----BEGIN CERTIFICATE-----\n"
...base64 data...\n"
-----END CERTIFICATE-----\n";
ビルドできたら、フラッシュします。
Espressif ESP32 にファームウェアの初期バージョンをインストールする のように、ネットワークに接続し、shadowを更新した後に、OTA待ちになります。
アプリケーションのバージョンアップ
1.demos/include/aws_application_version.h を開き、APP_VERSION_BUILD トークン値を増やします。今回の例では0.9.2 → 0.9.3になります。
2.アプリケーションをビルドします。
3.ファームウェアをS3にアップロードします。サンプルであれば、build/freertos-ex.bin ファイルをアップロードします。
OTA 更新の作成 (AWS IoT コンソール)
AWS IoT コンソールから、対象デバイスの指定、更新するファイル(ファームウェア)の選択、署名を指定して、更新ジョブを作成します。
まだジョブがない場合はこんな画面。すでにジョブがある場合は右上にボタンが表示されます。
Amazon FreeRTOS 無線通信経由 (OTA) の更新ジョブの作成
更新するデバイスを選択
今回はプロトコルにMQTTを選択、新しいファームウェアイメージに署名します、を選択
コード署名プロファイルを作成します。作成済の証明書、鍵を指定します。テストでは、aws_ota_codesigner_certificate.h が使用されるため、デバイスのコード署名証明書のパス名は、指定した値は実行時に無視されます。
S3 のファームウェアイメージを選択します。デバイスのファームウェアイメージのパス名はupdatesとしました。(このパス名でダウンロードされる???)
ジョブを実行すると、次のようなログが表示されて更新が始まり、終了するとデバイスが再起動されます。
109 7334 [iot_thread] OTA demo version 0.9.2
110 7334 [iot_thread] Creating MQTT Client...
111 7335 [iot_thread] [OTA_AgentInit_internal] OTA Task is Ready.
112 7335 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [Ready] Event [Start] New state [RequestingJob]
113 7335 [OTA Agent Task] [INFO ][MQTT][73350] (MQTT connection 0x3ffe1edc) SUBSCRIBE operation scheduled.
114 7335 [OTA Agent Task] [INFO ][MQTT][73350] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3ffe895c) Waiting for operation completion.
115 7341 [OTA Agent Task] [INFO ][MQTT][73410] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3ffe895c) Wait complete with result SUCCESS.
116 7341 [OTA Agent Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/myfreertosthing2/jobs/$next/get/accepted
117 7341 [OTA Agent Task] [INFO ][MQTT][73410] (MQTT connection 0x3ffe1edc) SUBSCRIBE operation scheduled.
118 7341 [OTA Agent Task] [INFO ][MQTT][73410] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3ffe8c18) Waiting for operation completion.
119 7346 [OTA Agent Task] [INFO ][MQTT][73460] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3ffe8c18) Wait complete with result SUCCESS.
120 7346 [OTA Agent Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/myfreertosthing2/jobs/notify-next
121 7346 [OTA Agent Task] [prvRequestJob_Mqtt] Request #0
122 7348 [OTA Agent Task] [INFO ][MQTT][73460] (MQTT connection 0x3ffe1edc) MQTT PUBLISH operation queued.
123 7348 [OTA Agent Task] [INFO ][MQTT][73480] (MQTT connection 0x3ffe1edc, PUBLISH operation 0x3ffe895c) Waiting for operation completion.
124 7351 [OTA Agent Task] [INFO ][MQTT][73510] (MQTT connection 0x3ffe1edc, PUBLISH operation 0x3ffe895c) Wait complete with result SUCCESS.
125 7351 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [RequestingJob] Event [RequestJobDocument] New state [WaitingForJob]
126 7352 [OTA Agent Task] [prvParseJobDoc] Size of OTA_FileContext_t [64]
127 7353 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ clientToken: 0:myfreertosthing2 ]
128 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: execution
129 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: jobId
130 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: jobDocument
131 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: afr_ota
132 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: protocols
133 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: files
134 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: filepath
135 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: filesize
136 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: fileid
137 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: certfile
138 7353 [OTA Agent Task] [prvParseJSONbyModel] parameter not present: sig-sha256-ecdsa
139 7353 [OTA Agent Task] [prvDefaultCustomJobCallback] Received Custom Job inside OTA Agent which is not supported.
140 7353 [OTA Agent Task] [prvParseJobDoc] Ignoring job without ID.
141 7354 [OTA Agent Task] [prvOTA_Close] Context->0x0x3fff8c40
I (73859) ota_pal: prvPAL_SetPlatformImageState, 4
W (73959) ota_pal: Set image as aborted!
I (73969) esp_ota_ops: aws_esp_ota_get_boot_flags: 1
I (73979) esp_ota_ops: [0] aflags/seq:0x2/0x1, pflags/seq:0xffffffff/0x0
W (73979) ota_pal: Image not in self test mode 2
I (73989) esp_ota_ops: aws_esp_ota_get_boot_flags: 1
I (73989) esp_ota_ops: [0] aflags/seq:0x2/0x1, pflags/seq:0xffffffff/0x0
142 7368 [OTA Agent Task] [prvOTAAgentTask] Handler failed. Current State [WaitingForJob] Event [ReceivedJobDocument] Error Code [603979776]
143 7435 [iot_thread] State: Ready Received: 1 Queued: 0 Processed: 0 Dropped: 0
144 7535 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
145 7635 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
146 7735 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
147 7835 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
148 7935 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
149 8035 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
150 8135 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
151 8235 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
152 8335 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
153 8435 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
154 8535 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
155 8635 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
156 8735 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
157 8835 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
158 8935 [iot_thread] State: WaitingForJob Received: 1 Queued: 0 Processed: 0 Dropped: 0
159 8941 [OTA Agent Task] [prvParseJobDoc] Size of OTA_FileContext_t [64]
160 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ jobId: AFR_OTA-20200106_4 ]
161 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ protocols: ["MQTT"] ]
162 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ streamname: AFR_OTA-c30cb685-9965-47e0-9da2-36ec32d4a205 ]
163 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ filepath: updates ]
164 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ filesize: 1011632 ]
165 8941 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ fileid: 0 ]
166 8942 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ certfile: aws_ota_codesigner_certificate.h ]
167 8942 [OTA Agent Task] [prvParseJSONbyModel] Extracted parameter [ sig-sha256-ecdsa: MEQCIHCs4rIMpRX9/y+AWApczDaCvd5w... ]
168 8942 [OTA Agent Task] [prvParseJobDoc] Job was accepted. Attempting to start transfer.
I (89739) ota_pal: prvPAL_GetPlatformImageState
I (89819) esp_ota_ops: aws_esp_ota_get_boot_flags: 1
I (89819) esp_ota_ops: [0] aflags/seq:0x2/0x1, pflags/seq:0xffffffff/0x0
I (89829) ota_pal: Writing to partition subtype 17 at offset 0x1a0000
169 9049 [iot_thread] State: WaitingForJob Received: 2 Queued: 0 Processed: 0 Dropped: 0
170 9164 [iot_thread] State: WaitingForJob Received: 2 Queued: 0 Processed: 0 Dropped: 0
171 9278 [iot_thread] State: WaitingForJob Received: 2 Queued: 0 Processed: 0 Dropped: 0
I (93829) ota_pal: aws_esp_ota_begin succeeded
172 9351 [OTA Agent Task] [prvSetDataInterface] Data interface is set to MQTT.
173 9351 [OTA Agent Task] [prvProcessJobHandler] Setting OTA data inerface.
174 9351 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForJob] Event [ReceivedJobDocument] New state [CreatingFile]
175 9351 [OTA Agent Task] [INFO ][MQTT][93510] (MQTT connection 0x3ffe1edc) SUBSCRIBE operation scheduled.
176 9351 [OTA Agent Task] [INFO ][MQTT][93510] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3fff3dc4) Waiting for operation completion.
177 9355 [OTA Agent Task] [INFO ][MQTT][93550] (MQTT connection 0x3ffe1edc, SUBSCRIBE operation 0x3fff3dc4) Wait complete with result SUCCESS.
178 9355 [OTA Agent Task] [prvInitFileTransfer_Mqtt] OK: $aws/things/myfreertosthing2/streams/AFR_OTA-c30cb685-9965-47e0-9da2-36ec32d4a205/data/cbor
179 9355 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [CreatingFile] Event [CreateFile] New state [RequestingFileBlock]
180 9357 [OTA Agent Task] [INFO ][MQTT][93570] (MQTT connection 0x3ffe1edc) MQTT PUBLISH operation queued.
181 9357 [OTA Agent Task] [prvRequestFileBlock_Mqtt] OK: $aws/things/myfreertosthing2/streams/AFR_OTA-c30cb685-9965-47e0-9da2-36ec32d4a205/get/cbor
182 9357 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [RequestingFileBlock] Event [RequestFileBlock] New state [WaitingForFileBlock]
183 9378 [iot_thread] State: WaitingForJob Received: 2 Queued: 0 Processed: 0 Dropped: 0
184 9396 [OTA Agent Task] [prvIngestDataBlock] Received file block 3, size 4096
185 9397 [OTA Agent Task] [prvIngestDataBlock] Remaining: 246
186 9397 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
187 9404 [OTA Agent Task] [prvIngestDataBlock] Received file block 0, size 4096
188 9405 [OTA Agent Task] [prvIngestDataBlock] Remaining: 245
189 9405 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
190 9410 [OTA Agent Task] [prvIngestDataBlock] Received file block 2, size 4096
191 9410 [OTA Agent Task] [prvIngestDataBlock] Remaining: 244
192 9410 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
193 9417 [OTA Agent Task] [prvIngestDataBlock] Received file block 1, size 4096
194 9418 [OTA Agent Task] [prvIngestDataBlock] Remaining: 243
195 9418 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
196 9425 [OTA Agent Task] [prvIngestDataBlock] Received file block 6, size 4096
197 9426 [OTA Agent Task] [prvIngestDataBlock] Remaining: 242
198 9426 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
199 9431 [OTA Agent Task] [prvIngestDataBlock] Received file block 4, size 4096
200 9432 [OTA Agent Task] [prvIngestDataBlock] Remaining: 241
201 9432 [OTA Agent Task] [prvOTAAgentTask] Called handler. Current State [WaitingForFileBlock] Event [ReceivedFileBlock] New state [WaitingForFileBlock]
202 9438 [OTA Agent Task] [prvIngestDataBlock] Received file block 7, size 4096
203 9439 [OTA Agent Task] [prvIngestDataBlock] Remaining: 240
シャドウでも、ファームウェアのバージョンが更新されています。
取得した時刻や、ファームウェアのバージョンでシャドウを更新します。
サンプルソースとビルド
サンプルソースは こちら を参照してください。
ビルドは、
git clone https://github.com/fukuen/m5stack-freertos-ota --recursive
ダウンロードしたディレクトリーに移動して、アプリケーションをビルドします。
cd m5stack-freertos-tft
cmake -DCMAKE_TOOLCHAIN_FILE=amazon-freertos/tools/cmake/toolchains/xtensa-esp32.cmake -GNinja -S . -B build
cd build
ninja
メモ
第1回 Amazon FreeRTOSインストール
第2回 Lチカ
第3回 TFT
第4回 SDカード
第5回 AWS Shadows