

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Over-the-air 更新演示应用程序
<a name="ota-demo"></a>

FreeRTOS 包含一个演示应用程序，用于演示 (OTA) 库 over-the-air的功能。OTA 演示应用程序位于 `freertos/demos/ota/ota_demo_core_mqtt/ota_demo_core_mqtt.c` 或 `freertos/demos/ota/ota_demo_core_http/ota_demo_core_http.c` 文件中。

OTA 演示应用程序执行以下操作：

1. 初始化 FreeRTOS 网络堆栈和 MQTT 缓冲池。

1. 使用 `vRunOTAUpdateDemo()` 创建任务来执行 OTA 库。

1. 使用 `_establishMqttConnection()` 创建 MQTT 客户端。

1. 使用连接到 AWS IoT MQTT 代理`IotMqtt_Connect()`并注册 MQTT 断开连接回调:。`prvNetworkDisconnectCallback`

1. 调用 `OTA_AgentInit()` 创建 OTA 任务，并注册在 OTA 任务完成时使用的回调。

1. 使用 `xOTAConnectionCtx.pvControlClient = _mqttConnection;` 重用 MQTT 连接。

1. 如果 MQTT 断开连接，应用程序将暂停 OTA 代理，尝试使用带有抖动的指数延迟重新连接，然后恢复 OTA 代理。

在使用 OTA 更新之前，请完成 [FreeRTOS 更新 Over-the-Air](freertos-ota-dev.md) 中的所有先决条件

在完成 OTA 更新的设置后，在支持 OTA 功能的平台上下载、构建、刷写并运行 FreeRTOS OTA 演示。设备特定的演示说明可用于以下取得 FreeRTOS 认证的设备：
+ [德州仪器 CC3220 SF-LAUNCHXL](download-ota-ti.md)
+ [微芯片好奇号 PIC32 MZEF](download-ota-mchip.md)
+ [Espressif ESP32](download-ota-esp.md)
+ [在瑞萨 N 上下载、构建、刷新并运行 FreeRTOS OTA 演示 RX65](download-rx65n-ota.md)

在设备上构建、刷新和运行 OTA 演示应用程序后，您可以使用 AWS IoT 控制台或创建 OTA 更新任务。 AWS CLI 在您创建 OTA 更新任务之后，连接到终端仿真器以查看 OTA 更新的进度。记下此过程中生成的任何错误。

成功 OTA 更新作业会显示类似以下内容的输出。为简便起见，在本示例中，我们删除了列表中的一些行。

```
    249 21207 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    250 21247 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=601.
    251 21247 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    252 21248 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPubAckSend.
    253 21249 [MQTT Agent Task] [ota_demo_core_mqtt.c:976] [INFO] [MQTT] Received job message callback, size 548.
    254 21252 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobId: AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb]
    255 21253 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.streamname: AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f]
    256 21255 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.protocols: ["MQTT"]]
    257 21256 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[filepath: aws_demos.bin]
    258 21257 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[filesize: 1164016]
    259 21258 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileid: 0]
    260 21259 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[certfile: ecdsa-sha256-signer.crt.pem]
    261 21260 [OTA Agent Task] [ota.c:1575] [INFO] [OTA] Extracted parameter [ sig-sha256-ecdsa: MEQCIE1SFkIHHiZAvkPpu6McJtx7SYoD... ]
    262 21261 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileType: 0]
    263 21262 [OTA Agent Task] [ota.c:2199] [INFO] [OTA] Job document was accepted. Attempting to begin the update.
    264 21263 [OTA Agent Task] [ota.c:2323] [INFO] [OTA] Job parsing success: OtaJobParseErr_t=OtaJobParseErrNone, Job name=AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb
    265 21318 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    266 21418 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    267 21469 [OTA Agent Task] [ota.c:938] [INFO] [OTA] Setting OTA data interface.
    268 21470 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[CreatingFile], Event=[ReceivedJobDocument], New state=[CreatingFile]
    269 21482 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=3.
    270 21483 [OTA Agent Task] [ota_demo_core_mqtt.c:1503] [INFO] [MQTT] SUBSCRIBED to topic $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/data/cbor to bro
    271 21484 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[RequestingFileBlock], Event=[CreateFile], New state=[RequestingFileBlock]
    272 21518 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    273 21532 [MQTT Agent Task] [core_mqtt_agent_command_functions.c:76] [INFO] [MQTT] Publishing message to $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/
    274 21534 [OTA Agent Task] [ota_demo_core_mqtt.c:1553] [INFO] [MQTT] Sent PUBLISH packet to broker $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/get/cbor
    275 21534 [OTA Agent Task] [ota_mqtt.c:1112] [INFO] [OTA] Published to MQTT topic to request the next block: topic=$aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a1
    276 21537 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[WaitingForFileBlock], Event=[RequestFileBlock], New state=[WaitingForFileBlock]
    277 21558 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=4217.
    278 21559 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    279 21560 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPublishDone.
    280 21561 [MQTT Agent Task] [ota_demo_core_mqtt.c:1026] [INFO] [MQTT] Received data message callback, size 4120.
    281 21563 [OTA Agent Task] [ota.c:2464] [INFO] [OTA] Received valid file block: Block index=0, Size=4096
    282 21566 [OTA Agent Task] [ota.c:2683] [INFO] [OTA] Number of blocks remaining: 284
     
    ... // Output removed for brevity
     
    3672 42745 [OTA Agent Task] [ota.c:2464] [INFO] [OTA] Received valid file block: Block index=284, Size=752
    3673 42747 [OTA Agent Task] [ota.c:2633] [INFO] [OTA] Received final block of the update.
    (428298) ota_pal: No such certificate file: ecdsa-sha256-signer.crt.pem. Using certificate in ota_demo_config.h.
    3674 42818 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 285   Queued: 285   Processed: 284   Dropped: 0
    3675 42918 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 285   Queued: 285   Processed: 284   Dropped: 0
     
    ... // Output removed for brevity
     
    3678 43197 [OTA Agent Task] [ota.c:2654] [INFO] [OTA] Received entire update and validated the signature.
    3685 43215 [OTA Agent Task] [ota_demo_core_mqtt.c:862] [INFO] [MQTT] Received OtaJobEventActivate callback from OTA Agent.
     
    ... // Output removed for brevity
     
    2 39 [iot_thread] [INFO ][DEMO][390] ---------STARTING DEMO---------
     
    [0;32mI (3633) WIFI: WIFI_EVENT_STA_CONNECTED
    [0;32mI (4373) WIFI: SYSTEM_EVENT_STA_GOT_IP
     
    ... // Output removed for brevity 
     
    4 351 [sys_evt] [INFO ][DEMO][3510] Connected to WiFi access point, ip address: 255.255.255.0.
    5 351 [iot_thread] [INFO ][DEMO][3510] Successfully initialized the demo. Network type for the demo: 1
    6 351 [iot_thread] [ota_demo_core_mqtt.c:1902] [INFO] [MQTT] OTA over MQTT demo, Application version 0.9.1
    7 351 [iot_thread] [ota_demo_core_mqtt.c:1323] [INFO] [MQTT] Creating a TLS connection to <endpoint>-ats.iot.us-west-2.amazonaws.com:8883.
    9 718 [iot_thread] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=2.
    10 718 [iot_thread] [core_mqtt_serializer.c:970] [INFO] [MQTT] CONNACK session present bit not set.
    11 718 [iot_thread] [core_mqtt_serializer.c:912] [INFO] [MQTT] Connection accepted.
     
    ... // Output removed for brevity
     
    17 736 [OTA Agent Task] [ota_demo_core_mqtt.c:1503] [INFO] [MQTT] SUBSCRIBED to topic $aws/things/__test_infra_thing71/jobs/notify-next to broker.
    18 737 [OTA Agent Task] [ota_mqtt.c:381] [INFO] [OTA] Subscribed to MQTT topic: $aws/things/__test_infra_thing71/jobs/notify-next
    30 818 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    31 819 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobId: AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb]
    32 820 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[execution.statusDetails.updatedBy: 589824]
    33 822 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.streamname: AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f]
    34 823 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.protocols: ["MQTT"]]
    35 824 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[filepath: aws_demos.bin]
    36 825 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[filesize: 1164016]
    37 826 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileid: 0]
    38 827 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[certfile: ecdsa-sha256-signer.crt.pem]
    39 828 [OTA Agent Task] [ota.c:1575] [INFO] [OTA] Extracted parameter [ sig-sha256-ecdsa: MEQCIE1SFkIHHiZAvkPpu6McJtx7SYoD... ]
    40 829 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileType: 0]
    41 830 [OTA Agent Task] [ota.c:2102] [INFO] [OTA] In self test mode.
    42 830 [OTA Agent Task] [ota.c:1936] [INFO] [OTA] New image has a higher version number than the current image: New image version=0.9.1, Previous image version=0.9.0
    43 832 [OTA Agent Task] [ota.c:2120] [INFO] [OTA] Image version is valid: Begin testing file: File ID=0
    53 896 [OTA Agent Task] [ota.c:794] [INFO] [OTA] Beginning self-test.
    62 971 [OTA Agent Task] [ota_demo_core_mqtt.c:1553] [INFO] [MQTT] Sent PUBLISH packet to broker $aws/things/__test_infra_thing71/jobs/AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb/update to br63 971 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    65 973 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPublishDone.
    64 973 [OTA Agent Task] [ota_demo_core_mqtt.c:902] [INFO] [MQTT] Successfully updated with the new image.
```

# Over-the-air 演示配置
<a name="ota-demo-specific-config"></a>

OTA 演示配置是在 `aws_iot_ota_update_demo.c` 中提供的特定于演示的配置选项。这些配置与在 OTA 库配置文件中提供的 OTA 库配置不同。

**OTA\$1DEMO\$1KEEP\$1ALIVE\$1SECONDS**  
对于 MQTT 客户端，此配置是从完成一个控制数据包的传输到开始发送下一个控制数据包之间可能经过的最大时间间隔。如果没有控制数据包，则发送 PINGREQ。如果时间达到此保持活动时间间隔的一倍半而内未发送消息或 PINGREQ 数据包，则代理必须断开客户端。请根据应用程序的要求调整此配置。

**OTA\$1DEMO\$1CONN\$1RETRY\$1BASE\$1INTERVAL\$1SECONDS**  
重试网络连接之前的基本间隔（以秒为单位）。OTA 演示将在此基本间隔后尝试重新连接。每次尝试失败后，间隔都会增加一倍。间隔中还会添加一个随机延迟，最高为该基本延迟的最大值。

**OTA\$1DEMO\$1CONN\$1RETRY\$1MAX\$1INTERVAL\$1SECONDS**  
重试网络连接之前的最大间隔（以秒为单位）。每次尝试失败时，重新连接延迟都会增加一倍，但最多只能达到这一最大值加同一间隔的抖动。

# 在德州仪器 SF-LAUNCHXL 上下载、构建、刷新和运行 FreeRTOS OTA 演示 CC3220
<a name="download-ota-ti"></a>

**重要**  <a name="deprecation-message"></a>
该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。<a name="download-demo"></a>

**下载 FreeRTOS 和 OTA 演示代码**
+ 你可以在 [https://github.com/FreeRTOS/FreeRTOS GitHub ](https://github.com/FreeRTOS/FreeRTOS) 网站上下载源代码。<a name="build-demo"></a>

**构建演示应用程序**

1. 按照中的[开始使用 FreeRTOS](freertos-getting-started.md)说明将`aws_demos`项目导入 Code Composer Studio，配置您的 AWS IoT 终端节点、Wi-Fi SSID 和密码以及主板的私钥和证书。

1.  打开 `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`，注释掉 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED` 并定义 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 或 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`。

1. 构建解决方案，并确保其构建没有错误。

1. 启动终端模拟器，并使用以下设置连接到主板：
   + 波特率：115200
   + 数据位：8
   + 奇偶校验：无
   + 停止位：1

1. 在主板上运行项目，确认它可以连接到 Wi-Fi 和 AWS IoT MQTT 消息代理。

终端模拟器在运行时应当显示类似以下内容的文本：

```
    0 1000 [Tmr Svc] Simple Link task created
    Device came up in Station mode
    1 2534 [Tmr Svc] Write certificate...
    2 5486 [Tmr Svc] [ERROR] Failed to destroy object. PKCS11_PAL_DestroyObject failed.
    3 5486 [Tmr Svc] Write certificate...
    4 5776 [Tmr Svc] Security alert threshold = 15
    5 5776 [Tmr Svc] Current number of alerts = 1
    6 5778 [Tmr Svc] Running Demos.
    7 5779 [iot_thread] [INFO ][DEMO][5779] ---------STARTING DEMO---------
    8 5779 [iot_thread] [INFO ][INIT][5779] SDK successfully initialized.
    Device came up in Station mode
    [WLAN EVENT] STA Connected to the AP: afrlab-pepper , BSSID: 74:83:c2:b4:46:27
    [NETAPP EVENT] IP acquired by the device
    Device has connected to afrlab-pepper
    Device IP Address is 192.168.36.176 
    9 8283 [iot_thread] [INFO ][DEMO][8282] Successfully initialized the demo. Network type for the demo: 1
    10 8283 [iot_thread] [INFO] OTA over MQTT demo, Application version 0.9.0
    11 8283 [iot_thread] [INFO] Creating a TLS connection to <endpoint>-ats.iot.us-west-2.amazonaws.com:8883.
    12 8852 [iot_thread] [INFO] Creating an MQTT connection to <endpoint>-ats.iot.us-west-2.amazonaws.com.
    13 8914 [iot_thread] [INFO] Packet received. ReceivedBytes=2.
    14 8914 [iot_thread] [INFO] CONNACK session present bit not set.
    15 8914 [iot_thread] [INFO] Connection accepted.
    16 8914 [iot_thread] [INFO] Received MQTT CONNACK successfully from broker.
    17 8914 [iot_thread] [INFO] MQTT connection established with the broker.
    18 8915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    19 8953 [OTA Agent T] [INFO] Current State=[RequestingJob], Event=[Start], New state=[RequestingJob]
    20 9008 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=3.
    21 9015 [OTA Agent T] [INFO] SUBSCRIBED to topic $aws/things/__test_infra_thing73/jobs/notify-next to broker.
    22 9015 [OTA Agent T] [INFO] Subscribed to MQTT topic: $aws/things/__test_infra_thing73/jobs/notify-next
    23 9504 [MQTT Agent ] [INFO] Publishing message to $aws/things/__test_infra_thing73/jobs/$next/get.
    24 9535 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=2.
    25 9535 [MQTT Agent ] [INFO] Ack packet deserialized with result: MQTTSuccess.
    26 9536 [MQTT Agent ] [INFO] State record updated. New state=MQTTPublishDone.
    27 9537 [OTA Agent T] [INFO] Sent PUBLISH packet to broker $aws/things/__test_infra_thing73/jobs/$next/get to broker.
    28 9537 [OTA Agent T] [WARN] OTA Timer handle NULL for Timerid=0, can't stop.
    29 9537 [OTA Agent T] [INFO] Current State=[WaitingForJob], Event=[RequestJobDocument], New state=[WaitingForJob]
    30 9539 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=120.
    31 9539 [MQTT Agent ] [INFO] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    32 9540 [MQTT Agent ] [INFO] State record updated. New state=MQTTPublishDone.
    33 9540 [MQTT Agent ] [INFO] Received job message callback, size 62.
    34 9616 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution
    35 9616 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobId
    36 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument
    37 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota
    38 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota.protocols
    39 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota.files
    40 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=filesize
    41 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=fileid
    42 9619 [OTA Agent T] [INFO] Failed to parse JSON document as AFR_OTA job: DocParseErr_t=7
    43 9619 [OTA Agent T] [INFO] No active job available in received job document: OtaJobParseErr_t=OtaJobParseErrNoActiveJobs
    44 9619 [OTA Agent T] [ERROR] Failed to execute state transition handler: Handler returned error: OtaErr_t=OtaErrJobParserError
    45 9620 [OTA Agent T] [INFO] Current State=[WaitingForJob], Event=[ReceivedJobDocument], New state=[CreatingFile]
    46 9915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    47 10915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    48 11915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    49 12915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    50 13915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    51 14915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
```

# 在 Microchip Curiosity MZEF 上下载、构建、刷新和运行 FreeRTOS OTA 演示 PIC32
<a name="download-ota-mchip"></a>

**重要**  <a name="deprecation-message"></a>
该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。

**注意**  
根据Microchip的协议，我们将从FreeRTOS参考集成存储库主分支中删除好奇号 PIC32 MZEF (DM320104)，并且将在新版本中不再使用它。Microchip已发布[官方通知](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/DM320104)，不再建议将 PIC32 MZEF (DM320104) 用于新设计。 PIC32MZEF 项目和源代码仍然可以通过之前的版本标签进行访问。Microchip 建议客户使用好奇号 [ PIC32MZ-EF-2.0 开发板 () DM320209](https://devices.amazonaws.com/detail/a3G0h0000077I69EAE/Curiosity-PIC32MZ-EF-2-0-Development-Board) 进行新设计。该 PIC32MZv1 平台仍然可以在 FreeRTOS 参考集成存储库的 [v202012.](https://github.com/aws/amazon-freertos/tree/202012.00) 00 中找到。但是，FreeRTOS 参考的 [v202107.00](https://github.com/aws/amazon-freertos/tree/202107.00) 不再支持该平台。<a name="mch-dowload-demo"></a>

**下载 FreeRTOS OTA 演示代码**
+ 你可以在 [https://github.com/FreeRTOS/FreeRTOS GitHub ](https://github.com/FreeRTOS/FreeRTOS) 网站上下载源代码。<a name="mch-build-demo"></a>

**构建 OTA 更新演示应用程序**

1. 按照中的[开始使用 FreeRTOS](freertos-getting-started.md)说明将`aws_demos`项目导入 MPLAB X IDE，配置您的 AWS IoT 端点、Wi-Fi SSID 和密码以及主板的私钥和证书。

1. 打开 `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h` 文件，然后输入您的证书。

   ```
   [] = "your-certificate-key";
   ```

1. 将代码签名证书的内容粘贴到此处：

   ```
   #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
   ```

   采用与 `aws_clientcredential_keys.h` 相同的格式，每一行必须以换行符 ('\$1n') 结束，并用引号括起来。

   例如，证书看起来应当如下所示：

   ```
   "-----BEGIN CERTIFICATE-----\n"
   "MIIBXTCCAQOgAwIBAgIJAM4DeybZcTwKMAoGCCqGSM49BAMCMCExHzAdBgNVBAMM\n"
   "FnRlc3Rf62lnbmVyQGFtYXpvbi5jb20wHhcNMTcxMTAzMTkxODM1WhcNMTgxMTAz\n"
   "MTkxODM2WjAhMR8wHQYDVQBBZZZ0ZXN0X3NpZ25lckBhbWF6b24uY29tMFkwEwYH\n"
   "KoZIzj0CAQYIKoZIzj0DAQcDQgAERavZfvwL1X+E4dIF7dbkVMUn4IrJ1CAsFkc8\n"
   "gZxPzn683H40XMKltDZPEwr9ng78w9+QYQg7ygnr2stz8yhh06MkMCIwCwYDVR0P\n"
   "BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMAoGCCqGSM49BAMCA0gAMEUCIF0R\n"
   "r5cb7rEUNtWOvGd05MacrgOABfSoVYvBOK9fP63WAqt5h3BaS123coKSGg84twlq\n"
   "TkO/pV/xEmyZmZdV+HxV/OM=\n"
   "-----END CERTIFICATE-----\n";
   ```

1. 安装 [Python 3](https://www.python.org/downloads/) 或更高版本。

1. 运行 `pip install pyopenssl` 来安装 `pyOpenSSL`。

1. 复制路径 `demos/ota/bootloader/utility/codesigner_cert_utility/` 下 .pem 格式的代码签名证书。重命名证书文件 `aws_ota_codesigner_certificate.pem`。

1.  打开 `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`，注释掉 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED` 并定义 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 或 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`。

1. 构建解决方案，并确保其构建没有错误。

1. 启动终端模拟器，并使用以下设置连接到主板：
   + 波特率：115200
   + 数据位：8
   + 奇偶校验：无
   + 停止位：1

1. 从开发板上拔下调试器，然后在主板上运行项目，确认它可以连接到 Wi-Fi 和 AWS IoT MQTT 消息代理。

运行项目时，MPLAB X IDE 应当打开输出窗口。确保选中该**ICD4**选项卡。您应当看到如下输出。

```
Bootloader version 00.09.00
[prvBOOT_Init] Watchdog timer initialized.
[prvBOOT_Init] Crypto initialized.

[prvValidateImage] Validating image at Bank : 0
[prvValidateImage] No application image or magic code present at: 0xbd000000
[prvBOOT_ValidateImages] Validation failed for image at 0xbd000000

[prvValidateImage] Validating image at Bank : 1
[prvValidateImage] No application image or magic code present at: 0xbd100000
[prvBOOT_ValidateImages] Validation failed for image at 0xbd100000

[prvBOOT_ValidateImages] Booting default image.


>0 36246 [IP-task] vDHCPProcess: offer ac140a0eip
                                                 1 36297 [IP-task] vDHCPProcess: offer ac140a0eip
                 2 36297 [IP-task]

IP Address: 172.20.10.14
3 36297 [IP-task] Subnet Mask: 255.255.255.240
4 36297 [IP-task] Gateway Address: 172.20.10.1
5 36297 [IP-task] DNS Server Address: 172.20.10.1


6 36299 [OTA] OTA demo version 0.9.2
7 36299 [OTA] Creating MQTT Client...
8 36299 [OTA] Connecting to broker...
9 38673 [OTA] Connected to broker.
10 38793 [OTA Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/devthingota/jobs/$next/get/accepted
11 38863 [OTA Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/devthingota/jobs/notify-next
12 38863 [OTA Task] [OTA_CheckForUpdate] Request #0
13 38964 [OTA] [OTA_AgentInit] Ready.
14 38973 [OTA Task] [prvParseJSONbyModel] Extracted parameter [ clientToken: 0:devthingota ]
15 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: execution
16 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: jobId
17 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: jobDocument
18 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: streamname
19 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: files
20 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: filepath
21 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: filesize
22 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: fileid
23 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: certfile
24 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: sig-sha256-ecdsa
25 38975 [OTA Task] [prvParseJobDoc] Ignoring job without ID.
26 38975 [OTA Task] [prvOTA_Close] Context->0x8003b620
27 38975 [OTA Task] [prvPAL_Abort] Abort - OK
28 39964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
29 40964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
30 41964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
31 42964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
32 43964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
33 44964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
34 45964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
35 46964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
36 47964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
```

终端模拟器应当显示类似以下内容的文本：

```
AWS Validate: no valid signature in descr: 0xbd000000
AWS Validate: no valid signature in descr: 0xbd100000


>AWS Launch:  No Map performed. Running directly from address: 0x9d000020?
AWS Launch:  wait for app at: 0x9d000020
WILC1000: Initializing...
0 0 

>[None] Seed for randomizer: 1172751941
1 0 [None] Random numbers: 00004272 00003B34 00000602 00002DE3
Chip ID 1503a0

[spi_cmd_rsp][356][nmi spi]: Failed cmd response read, bus error...

[spi_read_reg][1086][nmi spi]: Failed cmd response, read reg (0000108c)...

[spi_read_reg][1116]Reset and retry 10 108c

Firmware ver. : 4.2.1

Min driver ver : 4.2.1

Curr driver ver: 4.2.1

WILC1000: Initialization successful!

Start Wi-Fi Connection...
Wi-Fi Connected
2 7219 [IP-task] vDHCPProcess: offer c0a804beip
3 7230 [IP-task] vDHCPProcess: offer c0a804beip
4 7230 [IP-task] 

IP Address: 192.168.4.190
5 7230 [IP-task] Subnet Mask: 255.255.240.0
6 7230 [IP-task] Gateway Address: 192.168.0.1
7 7230 [IP-task] DNS Server Address: 208.67.222.222


8 7232 [OTA] OTA demo version 0.9.0
9 7232 [OTA] Creating MQTT Client...
10 7232 [OTA] Connecting to broker...
11 7232 [OTA] Sending command to MQTT task.
12 7232 [MQTT] Received message 10000 from queue.
13 8501 [IP-task] Socket sending wakeup to MQTT task.
14 10207 [MQTT] Received message 0 from queue.
15 10256 [IP-task] Socket sending wakeup to MQTT task.
16 10256 [MQTT] Received message 0 from queue.
17 10256 [MQTT] MQTT Connect was accepted. Connection established.
18 10256 [MQTT] Notifying task.
19 10257 [OTA] Command sent to MQTT task passed.
20 10257 [OTA] Connected to broker.
21 10258 [OTA Task] Sending command to MQTT task.
22 10258 [MQTT] Received message 20000 from queue.
23 10306 [IP-task] Socket sending wakeup to MQTT task.
24 10306 [MQTT] Received message 0 from queue.
25 10306 [MQTT] MQTT Subscribe was accepted. Subscribed.
26 10306 [MQTT] Notifying task.
27 10307 [OTA Task] Command sent to MQTT task passed.
28 10307 [OTA Task] [OTA] Subscribed to topic: $aws/things/Microchip/jobs/$next/get/accepted

29 10307 [OTA Task] Sending command to MQTT task.
30 10307 [MQTT] Received message 30000 from queue.
31 10336 [IP-task] Socket sending wakeup to MQTT task.
32 10336 [MQTT] Received message 0 from queue.
33 10336 [MQTT] MQTT Subscribe was accepted. Subscribed.
34 10336 [MQTT] Notifying task.
35 10336 [OTA Task] Command sent to MQTT task passed.
36 10336 [OTA Task] [OTA] Subscribed to topic: $aws/things/Microchip/jobs/notify-next

37 10336 [OTA Task] [OTA] Check For Update #0
38 10336 [OTA Task] Sending command to MQTT task.
39 10336 [MQTT] Received message 40000 from queue.
40 10366 [IP-task] Socket sending wakeup to MQTT task.
41 10366 [MQTT] Received message 0 from queue.
42 10366 [MQTT] MQTT Publish was successful.
43 10366 [MQTT] Notifying task.
44 10366 [OTA Task] Command sent to MQTT task passed.
45 10376 [IP-task] Socket sending wakeup to MQTT task.
46 10376 [MQTT] Received message 0 from queue.
47 10376 [OTA Task] [OTA] Set job doc parameter [ clientToken: 0:Microchip ]
48 10376 [OTA Task] [OTA] Missing job parameter: execution
49 10376 [OTA Task] [OTA] Missing job parameter: jobId
50 10376 [OTA Task] [OTA] Missing job parameter: jobDocument
51 10378 [OTA Task] [OTA] Missing job parameter: ts_ota
52 10378 [OTA Task] [OTA] Missing job parameter: files
53 10378 [OTA Task] [OTA] Missing job parameter: streamname
54 10378 [OTA Task] [OTA] Missing job parameter: certfile
55 10378 [OTA Task] [OTA] Missing job parameter: filepath
56 10378 [OTA Task] [OTA] Missing job parameter: filesize
57 10378 [OTA Task] [OTA] Missing job parameter: sig-sha256-ecdsa
58 10378 [OTA Task] [OTA] Missing job parameter: fileid
59 10378 [OTA Task] [OTA] Missing job parameter: attr
60 10378 [OTA Task] [OTA] Returned buffer to MQTT Client.
61 11367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
62 12367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
63 13367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
64 14367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
65 15367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
66 16367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
```

此输出显示 Microchip Curi PIC32 osity MZEF 可以连接 AWS IoT 和订阅 OTA 更新所需的 MQTT 主题。出现 `Missing job parameter` 消息在预料之中，因为没有待处理的 OTA 更新作业。

# 在 Espressif 上下载、构建、刷新和运行 FreeRTOS OTA 演示 ESP32
<a name="download-ota-esp"></a>

**重要**  <a name="deprecation-message"></a>
该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。

1. 从中下载 FreeRTOS 源代码。[GitHub](https://github.com/aws/amazon-freertos)有关说明，请参阅 [README.md](https://github.com/aws/amazon-freertos/blob/main/README.md) 文件。在 IDE 中创建一个项目，其中包含所有所需的源和库。

1. 按照 [Espressif 入门](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)中的说明，设置所需的基于 GCC 的工具链。

1. 打开 `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`，注释掉 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED` 并定义 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 或 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`。

1. 在 `vendors/espressif/boards/esp32/aws_demos` 目录中运行 `make`，构建演示项目。您可以按照 [Espressif 入门](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)中所述，刷写演示程序并通过运行 `make flash monitor` 来验证其输出。

1. 运行 OTA 更新演示之前：
   + 打开 `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`，注释掉 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED` 并定义 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 或 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`。
   + 打开 `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h` 并在下面复制您的 SHA-256/ECDSA 代码签名证书：

     ```
     #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
     ```

# 在瑞萨 N 上下载、构建、刷新并运行 FreeRTOS OTA 演示 RX65
<a name="download-rx65n-ota"></a>

**重要**  <a name="deprecation-message"></a>
该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。

本章向您展示如何在瑞萨 N 上下载、构建、刷新和运行 FreeRTOS OTA 演示应用程序。 RX65

**Topics**
+ [设置操作环境](#download-rx65n-ota-environment)
+ [设置您的 AWS 资源](#download-rx65n-ota-setup)
+ [导入、配置头文件并构建 aws\$1demos 和 boot\$1loader](#download-rx65n-ota-import-configure)

## 设置操作环境
<a name="download-rx65n-ota-environment"></a>

在本节中，此过程使用以下环境：
+ **IDE**：e2 studio 7.8.0、e2 studio 2020-07
+ **工具链**：CCRX Compiler v3.0.1
+ **目标设备**： RSKRX65N-2MB
+ **调试程序**：E2、E2 Lite 模拟器
+ **软件**：Renesas Flash Programmer、Renesas Secure Flash Programmer.exe、Tera Term

**设置硬件**

1. 将 E 2 Lite 仿真器和 USB 串行端口连接到 RX65 N 主板和电脑。

1. 将电源连接到 RX65 N。

## 设置您的 AWS 资源
<a name="download-rx65n-ota-setup"></a>

1. 要运行 FreeRTOS 演示，您必须拥有 AWS 一个拥有有权访问服务的 IAM 用户的账户。 AWS IoT 如果尚未执行此操作，请按照[设置您的AWS账户和权限](freertos-prereqs.md#freertos-account-and-permissions)中的步骤操作。

1. 要设置 OTA 更新，请按照 [OTA 更新先决条件](ota-prereqs.md)中的步骤操作。特别是，请按照[使用 MQTT 的 OTA 更新的先决条件](ota-mqtt-freertos.md)中的步骤操作。

1. 打开 [AWS IoT 控制台](https://console.aws.amazon.com/iot/home)。

1. 在左侧导航窗格中选择**管理**，然后选择**事物**，以便创建事物。

   事物是 AWS IoT中的特定设备或逻辑实体的表示形式。它可以是物理设备或传感器（例如，灯泡或墙壁上的开关）。它也可以是一个逻辑实体，例如应用程序或物理实体的实例 AWS IoT，它不连接但与连接的设备相关（例如，带有发动机传感器或控制面板的汽车）。 AWS IoT 提供了一个事物注册表，可帮助您管理事物。

   1. 选择**创建**，然后选择**创建单个事物**。

   1. 输入事物的**名称**，然后选择**下一步**。

   1. 选择**创建证书**。

   1. 下载创建的三个文件，然后选择**激活**。

   1. 选择**附加策略**。  
![\[显示要下载的文件的控制台屏幕\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/download-these-files-rx65n.png)

   1. 选择在 [设备策略](ota-mqtt-freertos.md#ota-mqtt-freertos-device-policy) 中创建的策略。

      每台使用 MQTT 接收 OTA 更新的设备都必须注册为事物， AWS IoT 并且该设备必须具有与列出的策略类似的附加策略。您可以在 [AWS IoT 核心策略操作](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policy-actions.html)和 [AWS IoT 核心操作资源](https://docs.aws.amazon.com/iot/latest/developerguide/iot-action-resources.html)中找到有关 `"Action"` 和 `"Resource"` 对象中项目的更多信息。

**注意**
      + 这些`iot:Connect`权限允许您的设备通过 MQTT AWS IoT 进行连接。
      + 利用 AWS IoT 作业 (`.../jobs/*`) 主题的 `iot:Subscribe` 和 `iot:Publish` 权限，连接的设备能够接收作业通知和作业文档，并发布作业执行的完成状态。
      +  AWS IoT OTA 直播主题的`iot:Subscribe`和`iot:Publish`权限 (`.../streams/*`) 允许连接的设备从中获取 OTA 更新数据 AWS IoT。在通过 MQTT 执行固件更新时，需要这些权限。
      + 这些`iot:Receive`权限 AWS IoT Core 允许将有关这些主题的消息发布到连接的设备。每次传输 MQTT 消息时，都将检查此权限。您可以使用此权限，撤消对当前订阅主题的客户端的访问权限。

1. 创建代码签名配置文件并在上注册代码签名证书。 AWS

   1. 要创建密钥和认证，请参阅[瑞](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy)萨微控制器固件更新设计政策中的第 7.3 节 “使用 OpenSSL 生成 ECDSA-SHA256 密钥对”。

   1. 打开 [AWS IoT 控制台](https://console.aws.amazon.com/iot/home)。在左导航窗格中，选择**管理**，然后选择**作业**。选择**创建作业**，然后选择**创建 OTA 更新作业**。

   1. 在**选择要更新的设备**下，选择**选择**，然后选择之前创建的事物。选择**下一步**。

   1. 在**创建 FreeRTOS OTA 更新作业**页面上，执行以下操作：

      1. 在**选择固件映像传输协议**中，选择 **MQTT**。

      1. 对于**选择并签署固件映像**，选择**为我签署一个新的固件映像**。

      1. 对于**代码签名配置文件**，选择**创建**。

      1. 在**创建代码签名配置文件**窗口中，输入**配置文件名称**。对于**设备硬件平台**，选择 **Windows 模拟器**。对于**代码签名证书**，选择**导入**。

      1. 浏览以选择证书 (`secp256r1.crt`)、证书私钥 (`secp256r1.key`) 和证书链 (`ca.crt`)。

      1. 输入**设备上代码签名证书的路径名**。然后选择**创建**。

1. 要授予对的代码签名的访问权限 AWS IoT，请按照中的步骤操作[授予对代码签名的访问权限 AWS IoT](code-sign-policy.md)。

如果你的电脑上没有安装 Tera Term，你可以从 [https://ttssh2.osdn.jp/index.html.en](https://ttssh2.osdn.jp/index.html.en) 下载并按此处所示进行设置。确保将设备的 USB 串行端口插入 PC。

![\[Tera Term 串行端口设置窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/tera-team-rx65n.png)


## 导入、配置头文件并构建 aws\$1demos 和 boot\$1loader
<a name="download-rx65n-ota-import-configure"></a>

首先，您需要选择最新版本的 FreeRTOS 软件包，该软件包将 GitHub 从项目中下载并自动导入到项目中。这样，您就可以专注于配置 FreeRTOS 和编写应用程序代码。

1. 启动 e2 Studio。

1. 选择**文件**，然后选择**导入…**。

1. 选择**瑞萨电子 FreeRTO GitHub S（含物联网库）项目。**  
![\[e-squared studio 导入窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/import-renesas-project-rx65n.png)

1. 选择**查看更多版本…**以显示下载对话框。  
![\[e-squared studio 下载对话框窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/check-more-version-rx65n.png)

1. 选择最新的程序包。  
![\[e-squared studio 模块下载对话框窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/choose-latest-version-rx65n.png)

1. 选择**同意**以接受最终用户许可协议。  
![\[e-squared studio EULA 对话框\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/eula-rx65n.png)

1. 等待下载完成。  
![\[下载进度条\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/downloading-rx65n.png)

1. 选择 **aws\$1demos** 和 **boot\$1loader** 项目，然后选择**完成**以将其导入。  
![\[导入项目窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/import-projects-rx65n.png)

1. 对于这两个项目，打开项目属性。在导航窗格中，选择**工具链编辑器**。

   1. 选择**当前工具链**。

   1. 选择**当前生成器**。  
![\[e-squared studio 属性窗口\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/project-properties-rx65n.png)

1. 在导航窗格中，选择**设置**。选择**工具链**选项卡，然后选择工具链**版本**。  
![\[Renesas CCRX 版本 v3.01.00 的工具链集成设置，其中包含更改工具链的选项。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/project-properties-toolchain-rx65n.png)

   选择**工具设置**选项卡，展开**转换器**，然后选择**输出**。在主窗口中，确保选中**输出十六进制文件**，然后选择**输出文件类型**。  
![\[C/C++ 构建配置设置窗口，展示了编译器和链接器选项（如输出 hex 文件、输出文件类型、输出目录和文件拆分选项）。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/project-properties-settings-rx65n.png)  
![\[界面设置树，其中包含“对战分析”、“工具链编辑器”、“C/C++ 常规”、“MCU”、“项目参考”等选项。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/project-properties-settings-2-rx65n.png)

1. 在引导加载程序项目中，打开 `projects\renesas\rx65n-rsk\e2studio\boot_loader\src\key\code_signer_public_key.h` 并输入公钥。[有关如何创建公钥的信息，请参阅[如何在 N 上使用 Amazon Web Services 实现 FreeRTOS OTA](https://www.renesas.com/us/en/document/apn/rx-family-how-implement-freertos-ota-using-amazon-web-services-rx65n) 和瑞萨 MCU 固件更新设计政策中的第 7.3 节 “使用 OpenSSL 生成 ECDSA-SHA256 密钥对”。 RX65](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy)  
![\[代码编辑器，展示了一个 C 表头文件，其中包含 CODE_SIGNER_PUBLIC_KEY 的定义以及一个 PEM 编码的代码签署者公钥变量。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/open-bootloader-project-rx65n.png)

   然后构建项目以创建 `boot_loader.mot`。

1. 打开 `aws_demos` 项目。

   1. 打开 [AWS IoT 控制台](https://console.aws.amazon.com/iot/home)。

   1. 在左侧导航窗格中，选择**设置**。在**设备数据端点**文本框中记下自定义端点。

   1. 选择**管理**，然后选择**事物**。记下你的棋盘上的 AWS IoT 事物名称。

   1. 在 `aws_demos` 项目中，打开 `demos/include/aws_clientcredential.h` 并指定以下值。

      ```
      #define clientcredentialMQTT_BROKER_ENDPOINT[] = "Your AWS IoT endpoint";
      #define clientcredentialIOT_THING_NAME "The AWS IoT thing name of your board"
      ```  
![\[显示 AWS IoT 事物名称和代理端点配置设置的代码片段。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/client-credential-rx65n.png)

   1. 打开 `tools/certificate_configuration/CertificateConfigurator.html` 文件。

   1. 导入之前下载的证书 PEM 文件和私钥 PEM 文件。

   1. 选择**生成并保存 aws\$1clientcredential\$1keys.h**，并在 `demos/include/` 目录下替换此文件。  
![\[证书配置工具，其中包含用于从 AWS IoT 控制台提供客户端证书和私钥 PEM 文件的字段，以及一个用于生成和保存 aws_clientcredial_keys.h 文件的按钮。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/certificate-config-tool-rx65n.png)

   1. 打开 `vendors/renesas/boards/rx65n-rsk/aws_demos/config_files/ota_demo_config.h` 文件，并指定这些值。

      ```
      #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
      ```

      文件中的*your-certificate-key*值在哪里`secp256r1.crt`。记得在证书的每一行后面加上“\$1”。[有关创建`secp256r1.crt`文件的更多信息，请参阅[如何在 N 上使用 Amazon Web Services 实现 FreeRTOS OTA](https://www.renesas.com/us/en/document/apn/rx-family-how-implement-freertos-ota-using-amazon-web-services-rx65n) 和瑞萨 MCU 固件更新设计政策中的第 7.3 节 “使用 OpenSSL 生成 ECDSA-SHA256 密钥对”。 RX65](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy)  
![\[源代码文件，展示了一段 C 代码，该代码定义了 PEM 编码的代码签署者证书常量字符串，证书数据已被编辑。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/codesigner-cert-rx65n.png)

1. **任务 A：安装固件的初始版本**

   1. 打开 `vendors/renesas/boards/board/aws_demos/config_files/aws_demo_config.h` 文件，注释掉 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`，然后定义 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 或 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`。

   1. 打开 `demos/include/ aws_application_version.h` 文件，并将固件的初始版本设置为 `0.9.2`。  
![\[代码片段，展示了应用程序的版本定义，包括主版本号、次要版本号和构建版本号的宏。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/firmware-version-rx65n.png)

   1. 在**部分查看器**中更改以下设置。  
![\[段查看器窗口，展示了内存地址、段名称（如 SU 和 SI）寄存器和接口组件（如网络缓冲区、异常和操作按钮）。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/section-viewer-rx65n.png)

   1. 选择**构建**以创建 `aws_demos.mot` 文件。

1. 使用 Renesas Secure Flash Programmer 创建文件 `userprog.mot`。`userprog.mot` 是 `aws_demos.mot` 和 `boot_loader.mot` 的组合。您可以将此文件刷新到 RX65 N-RSK 以安装初始固件。

   1. 下载[ https://github.com/renesas/亚马逊 FreerTOS-Too](https://github.com/renesas/Amazon-FreeRTOS-Tools) ls 并打开。`Renesas Secure Flash Programmer.exe`

   1. 选择**初始固件**选项，然后设置以下参数：
      + **私钥路径** – `secp256r1.privatekey` 的位置。
      + **引导加载程序文件路径** – `boot_loader.mot` (`projects\renesas\rx65n-rsk\e2studio\boot_loader\HardwareDebug`) 的位置。
      + **文件路径** – `aws_demos.mot` (`projects\renesas\rx65n-rsk\e2studio\aws_demos\HardwareDebug`) 的位置。  
![\[Renesas 安全闪存编程器窗口，其中包含 MCU、固件验证、序列号、AES 密钥路径和文件路径字段。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/secure-flash-rx65n.png)

   1. 创建一个名为 `init_firmware` 的目录，生成 `userprog.mot`，并将其保存到 `init_firmware` 目录中。验证生成是否成功。

1. 在 RX65 N-RSK 上刷新初始固件。

   1. 从 [ https://www.renesas.com/tw/en/products/software-tools/tools/programmer/renesas-flash-programmer-programming-gui](https://www.renesas.com/tw/en/products/software-tools/tools/programmer/renesas-flash-programmer-programming-gui.html) .html 下载最新版本的瑞萨 Flash Programmer（编程 GUI）。

   1. 打开 `vendors\renesas\rx_mcu_boards\boards\rx65n-rsk\aws_demos\flash_project\erase_from_bank\ erase.rpj` 文件以擦除库中的数据。

   1. 选择**开始**以擦除库。  
![\[Renesas 闪存编程器窗口，展示了 RX 系列微控制器项目详细信息、文件路径和闪存操作选项（如“擦除”、“程序”和“验证”），以及“启动”和“确定”按钮。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/flash-programmer-erasing-rx65n.png)

   1. 要刷写 `userprog.mot`，请选择**浏览...**，导航到 `init_firmware` 目录，选择 `userprog.mot` 文件，然后选择**开始**。  
![\[Renesas 闪存编程器窗口，展示了“擦除”操作设置，包括微控制器 RX 系列、浏览程序文件的选项、“擦除”和“启动”按钮以及要擦除的选定块的状态详细信息。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/flash-programmer-complete-rx65n.png)

1. 固件的 0.9.2 版（初始版本）已安装到您 RX65的 N-RSK 上。 RX65N-RSK 董事会现在正在监听 OTA 更新。如果您在 PC 上打开 Tera Term，则当初始固件运行时，您会看到类似以下的内容。

   ```
   -------------------------------------------------
   RX65N secure boot program
   -------------------------------------------------
   Checking flash ROM status.
   bank 0 status = 0xff [LIFECYCLE_STATE_BLANK]
   bank 1 status = 0xfc [LIFECYCLE_STATE_INSTALLING]
   bank info = 1. (start bank = 0)
   start installing user program.
   copy secure boot (part1) from bank0 to bank1...OK
   copy secure boot (part2) from bank0 to bank1...OK
   update LIFECYCLE_STATE from [LIFECYCLE_STATE_INSTALLING] to [LIFECYCLE_STATE_VALID]
   bank1(temporary area) block0 erase (to update LIFECYCLE_STATE)...OK
   bank1(temporary area) block0 write (to update LIFECYCLE_STATE)...OK
   swap bank...
   -------------------------------------------------
   RX65N secure boot program
   -------------------------------------------------
   Checking flash ROM status.
   bank 0 status = 0xf8 [LIFECYCLE_STATE_VALID]
   bank 1 status = 0xff [LIFECYCLE_STATE_BLANK]
   bank info = 0. (start bank = 1)
   integrity check scheme = sig-sha256-ecdsa
   bank0(execute area) on code flash integrity check...OK
   jump to user program
   0 1 [ETHER_RECEI] Deferred Interrupt Handler Task started
   1 1 [ETHER_RECEI] Network buffers: 3 lowest 3
   2 1 [ETHER_RECEI] Heap: current 234192 lowest 234192
   3 1 [ETHER_RECEI] Queue space: lowest 8
   4 1 [IP-task] InitializeNetwork returns OK
   5 1 [IP-task] xNetworkInterfaceInitialise returns 0
   6 101 [ETHER_RECEI] Heap: current 234592 lowest 233392
   7 2102 [ETHER_RECEI] prvEMACHandlerTask: PHY LS now 1
   8 3001 [IP-task] xNetworkInterfaceInitialise returns 1
   9 3092 [ETHER_RECEI] Network buffers: 2 lowest 2
   10 3092 [ETHER_RECEI] Queue space: lowest 7
   11 3092 [ETHER_RECEI] Heap: current 233320 lowest 233320
   12 3193 [ETHER_RECEI] Heap: current 233816 lowest 233120
   13 3593 [IP-task] vDHCPProcess: offer c0a80a09ip
   14 3597 [ETHER_RECEI] Heap: current 233200 lowest 233000
   15 3597 [IP-task] vDHCPProcess: offer c0a80a09ip
   16 3597 [IP-task] IP Address: 192.168.10.9
   17 3597 [IP-task] Subnet Mask: 255.255.255.0
   18 3597 [IP-task] Gateway Address: 192.168.10.1
   19 3597 [IP-task] DNS Server Address: 192.168.10.1
   20 3600 [Tmr Svc] The network is up and running
   21 3622 [Tmr Svc] Write certificate...
   22 3697 [ETHER_RECEI] Heap: current 232320 lowest 230904
   23 4497 [ETHER_RECEI] Heap: current 226344 lowest 225944
   24 5317 [iot_thread] [INFO ][DEMO][5317] ---------STARTING DEMO---------
   
   25 5317 [iot_thread] [INFO ][INIT][5317] SDK successfully initialized.
   26 5317 [iot_thread] [INFO ][DEMO][5317] Successfully initialized the demo. Network type for the demo: 4
   27 5317 [iot_thread] [INFO ][MQTT][5317] MQTT library successfully initialized.
   28 5317 [iot_thread] [INFO ][DEMO][5317] OTA demo version 0.9.2
   
   29 5317 [iot_thread] [INFO ][DEMO][5317] Connecting to broker...
   
   30 5317 [iot_thread] [INFO ][DEMO][5317] MQTT demo client identifier is rx65n-gr-rose (length 13).
   31 5325 [ETHER_RECEI] Heap: current 206944 lowest 206504
   32 5325 [ETHER_RECEI] Heap: current 206440 lowest 206440
   33 5325 [ETHER_RECEI] Heap: current 206240 lowest 206240
   38 5334 [ETHER_RECEI] Heap: current 190288 lowest 190288
   39 5334 [ETHER_RECEI] Heap: current 190088 lowest 190088
   40 5361 [ETHER_RECEI] Heap: current 158512 lowest 158168
   41 5363 [ETHER_RECEI] Heap: current 158032 lowest 158032
   42 5364 [ETHER_RECEI] Network buffers: 1 lowest 1
   43 5364 [ETHER_RECEI] Heap: current 156856 lowest 156856
   44 5364 [ETHER_RECEI] Heap: current 156656 lowest 156656
   46 5374 [ETHER_RECEI] Heap: current 153016 lowest 152040
   47 5492 [ETHER_RECEI] Heap: current 141464 lowest 139016
   48 5751 [ETHER_RECEI] Heap: current 140160 lowest 138680
   49 5917 [ETHER_RECEI] Heap: current 138280 lowest 138168
   59 7361 [iot_thread] [INFO ][MQTT][7361] Establishing new MQTT connection.
   62 7428 [iot_thread] [INFO ][MQTT][7428] (MQTT connection 81cfc8, CONNECT operation 81d0e8) Wait complete with result SUCCESS.
   63 7428 [iot_thread] [INFO ][MQTT][7428] New MQTT connection 4e8c established.
   64 7430 [iot_thread] [OTA_AgentInit_internal] OTA Task is Ready.
   65 7430 [OTA Agent T] [prvOTAAgentTask] Called handler. Current State [Ready] Event [Start] New state [RequestingJob]
   66 7431 [OTA Agent T] [INFO ][MQTT][7431] (MQTT connection 81cfc8) SUBSCRIBE operation scheduled.
   67 7431 [OTA Agent T] [INFO ][MQTT][7431] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Waiting for operation completion.
   68 7436 [ETHER_RECEI] Heap: current 128248 lowest 127992
   69 7480 [OTA Agent T] [INFO ][MQTT][7480] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Wait complete with result SUCCESS.
   70 7480 [OTA Agent T] [prvSubscribeToJobNotificationTopics] OK: $aws/things/rx65n-gr-rose/jobs/$next/get/accepted
   71 7481 [OTA Agent T] [INFO ][MQTT][7481] (MQTT connection 81cfc8) SUBSCRIBE operation scheduled.
   72 7481 [OTA Agent T] [INFO ][MQTT][7481] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Waiting for operation completion.
   73 7530 [OTA Agent T] [INFO ][MQTT][7530] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Wait complete with result SUCCESS.
   74 7530 [OTA Agent T] [prvSubscribeToJobNotificationTopics] OK: $aws/things/rx65n-gr-rose/jobs/notify-next
   75 7530 [OTA Agent T] [prvRequestJob_Mqtt] Request #0
   76 7532 [OTA Agent T] [INFO ][MQTT][7532] (MQTT connection 81cfc8) MQTT PUBLISH operation queued.
   77 7532 [OTA Agent T] [INFO ][MQTT][7532] (MQTT connection 81cfc8, PUBLISH operation 818b80) Waiting for operation completion.
   78 7552 [OTA Agent T] [INFO ][MQTT][7552] (MQTT connection 81cfc8, PUBLISH operation 818b80) Wait complete with result SUCCESS.
   79 7552 [OTA Agent T] [prvOTAAgentTask] Called handler. Current State [RequestingJob] Event [RequestJobDocument] New state [WaitingForJob]
   80 7552 [OTA Agent T] [prvParseJSONbyModel] Extracted parameter [ clientToken: 0:rx65n-gr-rose ]
   81 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: execution
   82 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: jobId
   83 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: jobDocument
   84 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: afr_ota
   85 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: protocols
   86 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: files
   87 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: filepath
   99 7651 [ETHER_RECEI] Heap: current 129720 lowest 127304
   100 8430 [iot_thread] [INFO ][DEMO][8430] State: Ready  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   101 9430 [iot_thread] [INFO ][DEMO][9430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   102 10430 [iot_thread] [INFO ][DEMO][10430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   103 11430 [iot_thread] [INFO ][DEMO][11430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   104 12430 [iot_thread] [INFO ][DEMO][12430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   105 13430 [iot_thread] [INFO ][DEMO][13430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   106 14430 [iot_thread] [INFO ][DEMO][14430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   107 15430 [iot_thread] [INFO ][DEMO][15430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   ```

1. **任务 B：更新固件版本**

   1. 打开 `demos/include/aws_application_version.h` 文件并将 `APP_VERSION_BUILD` 令牌值增加至 `0.9.3`。

   1. 重新构建项目。

1. 使用 Renesas Secure Flash Programmer 创建 `userprog.rsu` 文件以更新固件版本。

   1. 打开 `Amazon-FreeRTOS-Tools\Renesas Secure Flash Programmer.exe` 文件。

   1. 选择**更新固件**选项卡并设置以下参数：
      + **文件路径** – `aws_demos.mot` 文件 (`projects\renesas\rx65n-rsk\e2studio\aws_demos\HardwareDebug`) 的位置。

   1. 创建一个名为 `update _firmware` 的目录。生成 `userprog.rsu` 并将其保存到 `update_firmware` 目录。验证生成是否成功。  
![\[Renesas 安全闪存编程器窗口，其中包含 MCU 选择、固件验证类型、序列号、AES MAC 密钥字段以及用于生成安全的固件的文件路径输入。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/update-firmware-rx65n.png)

1. 如[创建 Amazon S3 存储桶以存储更新](dg-ota-bucket.md)中所述，将固件更新 `userproj.rsu` 上传到 Amazon S3 存储桶。  
![\[Amazon S3 存储桶管理界面，其中包含文件夹、上传、版本和权限选项\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/upload-firmware-rx65n.png)

1. 创建任务以更新 RX65 N-RSK 上的固件。

   AWS IoT Jobs 是一项向一台或多台连接的设备通知待处理[任务](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)的服务。作业可用于管理设备队列、更新设备上的固件和安全证书，或者执行管理任务，例如重新启动设备和执行诊断。

   1. 登录 [AWS IoT 控制台](https://console.aws.amazon.com/iotv2/)。在导航窗格中，选择**管理**，然后选择**作业**。

   1. 选择**创建作业**，然后选择**创建 OTA 更新作业**。选择一个事物，然后选择**下一步**。

   1. 按照以下方式创建 FreeRTOS OTA 更新作业：
      + 选择 **MQTT**。
      + 选择在上一节中创建的代码签名配置文件。
      + 选择上传到 Amazon S3 存储桶的固件映像。
      + 对于**设备上固件映像的路径名**，请输入**test**。
      + 选择在上一部分中创建的 IAM 角色。

   1. 选择**下一步**。  
![\[固件映像签名和 OTA 更新设置，其中包含签署新固件、选择之前签署的固件、使用自定义已签署固件、指定代码签名配置文件、固件映像文件、设备上的路径以及 OTA 更新作业的 IAM 角色的选项。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/create-job-next-rx65n.png)

   1. 输入一个 ID，然后选择**创建**。

1. 重新打开 Tera Term 以验证固件是否已成功更新到 OTA 演示版 0.9.3。  
![\[命令行输出，展示了线程的初始化以及与代理的连接。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/update-successful-rx65n.png)

1. 在 AWS IoT 控制台上，验证任务状态是否为 “**成功**”。  
![\[AFR OTA-demo 测试作业概览，展示了 1 个资源已成功。\]](http://docs.aws.amazon.com/zh_cn/freertos/latest/userguide/images/completed-succeeded-rx65n.png)

# 教程：使用 ESP32 FreeRTOS 低功耗蓝牙在 Espressif 上执行 OTA 更新
<a name="ota-updates-esp32-ble"></a>

**重要**  <a name="deprecation-message"></a>
该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时，我们建议[从此处开始](freertos-getting-started-modular.md)。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目，请参阅 [Amazon-FreeRTOS Github 存储库迁移指南](github-repo-migration.md)。

本教程向您展示如何在 Android 设备上更新连接到 MQTT 低功耗蓝牙代理的乐鑫 ESP32 微控制器。它使用 AWS IoT Over-the-air (OTA) 更新任务更新设备。设备 AWS IoT 使用在安卓演示应用程序中输入的 Amazon Cognito 凭证进行连接。经过身份验证的操作员从云端启动 OTA 更新。当设备通过 Android 演示应用程序进行连接时，OTA 更新即会启动，设备上的固件也会更新。

FreeRTOS 版本 2019.06.00 主版本及更高版本包括蓝牙低功耗 MQTT 代理支持，可用于 Wi-Fi 配置和服务安全连接。 AWS IoT 通过使用低功耗蓝牙功能，您可以构建低功耗设备，这些设备无需 Wi-Fi 即可与移动设备配对，从而进行连接。设备可以通过使用通用接入配置文件 (GAP) 和通用属性 (GATT) 配置文件的 Android 或 iOS 低功耗 SDKs 蓝牙进行连接，从而使用 MQTT 进行通信。

为了允许通过低功耗蓝牙进行 OTA 更新，我们将按照以下步骤操作：

1. **配置存储**：创建 Amazon S3 存储桶和策略，并配置可执行更新的用户。

1. **创建代码签名证书**：创建签名证书并允许用户签署固件更新。

1. **配置 Amazon Cognito 身份验证**：创建凭证提供程序、用户群体和应用程序对用户群体的访问权限。

1. **配置 FreeRTOS**：设置低功耗蓝牙、客户端凭证和代码签名公共证书。

1. **配置 Android 应用程序**：设置凭证提供程序、用户群体，并将应用程序部署到 Android 设备。

1. **运行 OTA 更新脚本**：要启动 OTA 更新，请使用 OTA 更新脚本。

有关更新工作的更多信息，请参阅 [FreeRTOS 更新 Over-the-Air](freertos-ota-dev.md)。有关如何设置低功耗蓝牙 MQTT 代理功能的更多信息，请参阅 Richard Kang 在 Espressif 上的《在 FreeRTOS [上使用低功耗蓝牙 FreeRTOS》 ESP32](https://aws.amazon.com/blogs/iot/using-bluetooth-low-energy-with-amazon-freertos-on-espressif-esp32/)一文。

## 先决条件
<a name="ota-updates-esp32-ble-prereq"></a>

要执行本教程中的步骤，您需要以下资源：
+  ESP32 开发板。
+ 一根 MicroUSB 转 USB A 电缆。
+ 一个 AWS 账户（免费套餐就足够了）。
+ 一台使用 Android v 6.0 或更高版本和蓝牙版本 4.2或更高版本的 Android 手机。

在开发计算机上，您需要：
+ 有足够的磁盘空间（约 500 Mb）来存放 Xtensa 工具链和 FreeRTOS 源代码和示例。
+ 已安装 Android Studio
+ 已安装 [AWS CLI](https://aws.amazon.com/cli/)。
+ 已安装 Python3。
+ 适用于 Py [thon 的 boto3 AWS 软件开发套件 (SDK)](https://github.com/boto/boto3)。

本教程中的步骤假设 Xtensa 工具链、ESP-IDF 和 FreeRTOS 代码已安装在主目录的 `/esp` 目录中。您必须将 `~/esp/xtensa-esp32-elf/bin` 添加到 `$PATH` 变量中。

## 步骤 1：配置存储
<a name="ota-updates-esp32-ble-step1"></a>

1. [创建 Amazon S3 存储桶以存储更新](dg-ota-bucket.md) 并启用版本控制来保留固件映像。

1. [创建 OTA 更新服务角色](create-service-role.md) 并为角色添加以下托管策略：
   + AWSIot正在记录
   + AWSIotRuleActions
   + AWSIotThingsRegistration
   + AWSFreeRTOSOTAUpdate

1. [创建可执行 OTA 更新的用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)。该用户可以在账户中的 IoT 设备上签名和部署固件更新，并且有权在所有设备上执行 OTA 更新。访问权限应仅限于可信实体。

1. 按照步骤[创建 OTA 用户策略](create-ota-user-policy.md)并将其附加到您的用户。

## 步骤 2：创建代码签名证书
<a name="ota-updates-esp32-ble-step2"></a>

1. 创建启用版本控制的 Amazon S3 存储桶来保留固件映像。

1. 创建可用于对固件进行签名的代码签名证书。导入证书时，记录证书的 Amazon 资源名称 (ARN)。

   ```
   aws acm import-certificate --profile=ota-update-user --certificate file://ecdsasigner.crt --private-key file://ecdsasigner.key
   ```

   输出示例：

   ```
   {
   "CertificateArn": "arn:aws:acm:us-east-1:<account>:certificate/<certid>"
   }
   ```

   稍后您将使用 ARN 创建签名配置文件。如果需要，您可以立即使用以下命令创建该配置文件：

   ```
   aws signer put-signing-profile --profile=ota-update-user --profile-name esp32Profile --signing-material certificateArn=arn:aws:acm:us-east-1:account:certificate/certid --platform AmazonFreeRTOS-Default --signing-parameters certname=/cert.pem
   ```

   输出示例：

   ```
   {
   "arn": "arn:aws:signer::<account>:/signing-profiles/esp32Profile"
   }
   ```

## 步骤 3：Amazon Cognito 身份验证配置
<a name="ota-updates-esp32-ble-step3"></a>

**创建 AWS IoT 策略**

1. 登录 [AWS IoT 控制台](https://console.aws.amazon.com/iot/)。

1. 在控制台的右上角，选择**我的账户**。在**账户设置**下，记下您的 12 位账户 ID。

1. 在左侧导航窗格中，选择**设置**。在**设备数据端点**下，记下端点值。该端点的值类似于 `xxxxxxxxxxxxxx.iot.us-west-2.amazonaws.com`。在本示例中， AWS 区域为“us-west-2”。

1. 在左导航窗格中依次选择**安全**、**策略**和**创建**。如果您的账户中没有任何策略，则会看到“您还没有任何政策”消息，并且您可以选择**创建政策**。

1. 输入策略的名称，例如，“esp32\$1mqtt\$1proxy\$1iot\$1policy”。

1. 在**添加语句**部分中，选择**高级模式**。将以下 JSON 复制并粘贴到策略编辑器窗口中。将 `aws-account-id` 替换为您的账户 ID，并将 `aws-region` 替换为您的区域（例如，“us-west-2”）。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iot:Connect",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Publish",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Subscribe",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Receive",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           }
       ]
   }
   ```

------

1. 选择**创建**。

**创建 AWS IoT 事物**

1. 登录 [AWS IoT 控制台](https://console.aws.amazon.com/iot/)。

1. 在左侧导航窗格中选择**管理**，然后选择**事物**。

1. 在右上角，选择**创建**。如果您的账户中没有注册任何事物，则会显示消息“您还没有任何事物”，并且您可以选择**注册事物**。

1. 在**创建 AWS IoT 事物**页面上，选择**创建单个事物**。

1. 在**将设备添加到事物注册表**页面上，为您的事物输入一个名称（例如，“esp32-ble”）。仅允许使用字母数字字符、连字符 (-) 和下划线 (\$1) 字符。选择**下一步**。

1. 在**添加事物的证书**页面上的**跳过证书并创建事物**下，选择**创建没有证书的事物**。由于我们使用 BLE 代理移动应用程序，该应用程序使用 Amazon Cognito 凭证进行身份验证和授权，因此不需要设备证书。

**创建 Amazon Cognito 应用程序客户端**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/users/)。

1. 在右上角的导航横幅中选择**创建用户群体**。

1. 输入群体名称（例如，“esp32\$1mqtt\$1proxy\$1user\$1pool”）。

1. 选择 **Review defaults (查看原定设置)**。

1. 在**应用程序客户端**中，选择**添加应用程序客户端**，然后选择**添加应用程序客户端**。

1. 输入应用程序客户端名称（例如，“mqtt\$1app\$1client”）。

1. 确保选中**生成客户端密钥**。

1. 选择**创建应用程序客户端**。

1. 选择 **Return to pool details**（返回池详细信息）。

1. 在用户群体的**审核**页面上，选择**创建群体**。您应该会看到一条“已成功创建用户池”的消息。记下该群体 ID。

1. 在导航窗格中选择**应用程序客户端**。

1. 选择**显示详细信息**。记录应用程序客户端 ID 和应用程序客户端密钥。

**创建 Amazon Cognito 身份池**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/federated)。

1. 选择**创建新身份池**。

1. 输入身份池的名称（例如，“mqtt\$1proxy\$1identity\$1pool”）。

1. 展开**身份验证提供程序**。

1. 选择 **Cognito** 选项卡。

1. 输入在前面的步骤中记下的用户群体 ID 和应用程序客户端 ID。

1. 选择**创建池**。

1. 在下一页上，要为经过身份验证和未经过身份验证的身份创建新角色，请选择**允许**。

1. 记下身份池 ID，其格式为 `us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`。

**将 IAM policy 附加到经过身份验证的身份。**

1. 打开 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/federated)。

1. 选择刚才创建的身份池（例如，“mqtt\$1proxy\$1identity\$1pool”）。

1. 选择**编辑身份池**。

1. 记下分配给经过身份验证的角色的 IAM 角色（例如，“cognito\$1mqtt\$1proxy\$1identity\$1poolauth\$1Role”）。

1. 打开 [IAM 控制台](https://console.aws.amazon.com/iam/home)。

1. 在导航窗格中，选择**角色**。

1. 搜索分配的角色（例如，“cognito\$1mqtt\$1proxy\$1identity\$1poolauth\$1Role”），然后将其选中。

1. 选择**添加内联策略**，然后选择 **JSON**。

1. 输入以下策略：

------
#### [ JSON ]

****  

   ```
   {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
          {
             "Effect": "Allow",
             "Action": [
                "iot:AttachPolicy",
                "iot:AttachPrincipalPolicy",
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe"
             ],
             "Resource": "*"
          }]
       }
   ```

------

1. 选择**查看策略**。

1. 输入策略名称（例如，“mqttProxyCognito策略”）。

1. 选择**创建策略**。

## 步骤 4：配置 Amazon FreeRTOS
<a name="ota-updates-esp32-ble-step4"></a>

1. [从 FreeRTOS 存储库下载最新版本的亚马逊 FreeRTOS 代码。 GitHub ](https://github.com/aws/amazon-freertos)

1. 要启用 OTA 更新演示，请按照[开始使用 Espressif ESP32-C 和 DevKit ESP-WROVER-KIT](getting_started_espressif.md)中的步骤操作。

1. 在以下文件中进行这些修改：

   1. 打开 `vendors/espressif/boards/esp32/aws_demos/config_files/aws_demo_config.h` 并定义 `CONFIG_OTA_UPDATE_DEMO_ENABLED`。

   1. 打开 `vendors/espressif/boards/esp32/aws_demos/common/config_files/aws_demo_config.h` 并将 `democonfigNETWORK_TYPES` 更为为 `AWSIOT_NETWORK_TYPE_BLE`。

   1. 打开 `demos/include/aws_clientcredential.h` 并输入 `clientcredentialMQTT_BROKER_ENDPOINT` 的端点 URL。

      输入 `clientcredentialIOT_THING_NAME` 的事物名称（例如，“esp32-ble”）。使用 Amazon Cognito 凭证时，无需添加证书。

   1. 打开 `vendors/espressif/boards/esp32/aws_demos/config_files/aws_iot_network_config.h` 并更改 `configSUPPORTED_NETWORKS` 和 `configENABLED_NETWORKS`，以便仅包含 `AWSIOT_NETWORK_TYPE_BLE`。

   1. 打开 `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h` 文件，然后输入您的证书。

      ```
      #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
      ```

   应用程序应该会启动并输出演示版本：

   ```
   11 13498 [iot_thread] [INFO ][DEMO][134980] Successfully initialized the demo. Network type for the demo: 2
   12 13498 [iot_thread] [INFO ][MQTT][134980] MQTT library successfully initialized.
   13 13498 [iot_thread] OTA demo version 0.9.20
   14 13498 [iot_thread] Creating MQTT Client...
   ```

## 步骤 5：配置 Android 应用程序
<a name="ota-updates-esp32-ble-step5"></a>

1. 从 [amazon-freertos-ble-android-sdk 存储库中下载安卓蓝牙低功耗 SDK](https://github.com/aws/amazon-freertos-ble-android-sdk) GitHub 和示例应用程序。

1. 打开文件`app/src/main/res/raw/awsconfiguration.json`并填写池 ID AppClientId、区域，然后 AppClientSecret 按照以下 JSON 示例中的说明进行操作。

   ```
   {
     "UserAgent": "MobileHub/1.0",
     "Version": "1.0",
     "CredentialsProvider": {
       "CognitoIdentity": {
         "Default": {
           "PoolId": "Cognito->Manage Identity Pools->Federated Identities->mqtt_proxy_identity_pool->Edit Identity Pool->Identity Pool ID",
           "Region": "Your region (for example us-east-1)"
         }
       }
     },
   
     "IdentityManager": {
       "Default": {}
     },
   
     "CognitoUserPool": {
       "Default": {
         "PoolId": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> PoolId",
         "AppClientId": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> App clients ->Show Details",
         "AppClientSecret": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> App clients ->Show Details",
         "Region": "Your region (for example us-east-1)"
       }
     }
   }
   ```

1. 打开`app/src/main/java/software/amazon/freertos/DemoConstants.java`并输入您之前创建的策略名称（例如*esp32\$1mqtt\$1proxy\$1iot\$1policy*）和区域（例如*us-east-1*）。

1. 构建和安装演示应用程序。

   1. 在 Android Studio 中，选择**构建**，然后选择**创建模块应用程序**。

   1. 选择**运行**，然后选择**运行应用程序**。您可以转到 Android Studio 中的 logcat 窗格来监控日志消息。

   1. 在 Android 设备上，通过登录屏幕创建一个账户。

   1. 创建用户。如果用户已存在，请输入凭证。

   1. 允许 Amazon FreeRTOS 演示访问设备的位置。

   1. 扫描低功耗蓝牙设备。

   1. 将找到的设备的滑块移至**开**。

   1. 在串行端口调试控制台上按 **y** ESP32。

   1. 选择**配对并连接**。

1. 建立连接后，**更多...**链接会变为活动状态。连接完成后，Android 设备 logcat 中的连接状态会更改为“BLE\$1CONNECTED”：

   ```
   2019-06-06 20:11:32.160 23484-23497/software.amazon.freertos.demo I/FRD: BLE connection state changed: 0; new state: BLE_CONNECTED
   ```

1. 在传输消息之前，Amazon FreeRTOS 设备和 Android 设备会协商 MTU。您会在 logcat 中看到以下输出：

   ```
   2019-06-06 20:11:46.720 23484-23497/software.amazon.freertos.demo I/FRD: onMTUChanged : 512 status: Success
   ```

1. 设备连接到应用程序并开始使用 MQTT 代理发送 MQTT 消息。要确认设备可通信，请确保 MQTT\$1CONTROL 特征数据值已更改为 01：

   ```
   2019-06-06 20:12:28.752 23484-23496/software.amazon.freertos.demo D/FRD: <-<-<- Writing to characteristic: MQTT_CONTROL with data: 01
   2019-06-06 20:12:28.839 23484-23496/software.amazon.freertos.demo D/FRD: onCharacteristicWrite for: MQTT_CONTROL; status: Success; value: 01
   ```

1. 设备配对后，您将在 ESP32 主机上看到提示。要启用 BLE，请按 **y**。在执行此步骤后，演示才能运行。

   ```
   E (135538) BT_GATT: GATT_INSUF_AUTHENTICATION: MITM Required
   W (135638) BT_L2CAP: l2cble_start_conn_update, the last connection update command still pending.
   E (135908) BT_SMP: Value for numeric comparison = 391840
   15 13588 [InputTask] Numeric comparison:391840
   16 13589 [InputTask] Press 'y' to confirm
   17 14078 [InputTask] Key accepted
   W (146348) BT_SMP: FOR LE SC LTK IS USED INSTEAD OF STK
   18 16298 [iot_thread] Connecting to broker...
   19 16298 [iot_thread] [INFO ][MQTT][162980] Establishing new MQTT connection.
   20 16298 [iot_thread] [INFO ][MQTT][162980] (MQTT connection 0x3ffd5754, CONNECT operation 0x3ffd586c) Waiting for operation completion.
   21 16446 [iot_thread] [INFO ][MQTT][164450] (MQTT connection 0x3ffd5754, CONNECT operation 0x3ffd586c) Wait complete with result SUCCESS.
   22 16446 [iot_thread] [INFO ][MQTT][164460] New MQTT connection 0x3ffc0ccc established.
   23 16446 [iot_thread] Connected to broker.
   ```

## 步骤 6：运行 OTA 更新脚本
<a name="ota-updates-esp32-ble-step6"></a>

1. 要安装先决条件，请运行下面的命令：

   ```
   pip3 install boto3
   ```

   ```
   pip3 install pathlib
   ```

1. 在 `demos/include/aws_application_version.h` 中增加 FreeRTOS 应用程序的版本。

1. 构建一个新的 .bin 文件。

1. 下载 python 脚本 [start\$1ota.py](https://github.com/aws-samples/amazon-freertos-ota-scripts/blob/master/scripts/start_ota.py)。要查看脚本的帮助内容，请在终端窗口中运行以下命令：

   ```
   python3 start_ota.py -h
   ```

   您应看到类似于以下内容的信息：

   ```
   usage: start_ota.py [-h] --profile PROFILE [--region REGION]
                       [--account ACCOUNT] [--devicetype DEVICETYPE] --name NAME
                       --role ROLE --s3bucket S3BUCKET --otasigningprofile
                       OTASIGNINGPROFILE --signingcertificateid
                       SIGNINGCERTIFICATEID [--codelocation CODELOCATION]
   Script to start OTA update
   optional arguments:
   -h, --help            show this help message and exit
   --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 folder location (can be relative)
   ```

1. 如果您使用提供的 CloudFormation 模板创建资源，请运行以下命令：

   ```
   python3 start_ota_stream.py --profile otausercf --name esp32-ble --role ota_ble_iot_role-sample --s3bucket afr-ble-ota-update-bucket-sample --otasigningprofile abcd --signingcertificateid certificateid
   ```

   你应该在 ESP32 调试控制台中看到更新开始：

   ```
   38 2462 [OTA Task] [prvParseJobDoc] Job was accepted. Attempting to start transfer.
   ---
   49 2867 [OTA Task] [prvIngestDataBlock] Received file block 1, size 1024
   50 2867 [OTA Task] [prvIngestDataBlock] Remaining: 1290
   51 2894 [OTA Task] [prvIngestDataBlock] Received file block 2, size 1024
   52 2894 [OTA Task] [prvIngestDataBlock] Remaining: 1289
   53 2921 [OTA Task] [prvIngestDataBlock] Received file block 3, size 1024
   54 2921 [OTA Task] [prvIngestDataBlock] Remaining: 1288
   55 2952 [OTA Task] [prvIngestDataBlock] Received file block 4, size 1024
   56 2953 [OTA Task] [prvIngestDataBlock] Remaining: 1287
   57 2959 [iot_thread] State: Active  Received: 5   Queued: 5   Processed: 5   Dropped: 0
   ```

1. OTA 更新完成后，设备将按照 OTA 更新过程的要求重新启动。然后，它会尝试使用更新的固件进行连接。如果升级成功，则会将更新后的固件标记为活动状态，您会在控制台中看到更新的版本：

   ```
   13 13498 [iot_thread] OTA demo version 0.9.21
   ```