教程:使用 FreeRTOS 低功耗蓝牙在 Espressif ESP32 上执行 OTA 更新 - FreeRTOS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

教程:使用 FreeRTOS 低功耗蓝牙在 Espressif ESP32 上执行 OTA 更新

重要

该参考集成托管在已弃用的 Amazon-FreeRTOS 存储库中。当您创建新项目时,我们建议从此处开始。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目,请参阅 Amazon-FreeRTOS Github 存储库迁移指南

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

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

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

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

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

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

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

  5. 配置 Android 应用程序:设置凭证提供程序、用户群体,并将应用程序部署到 Android 设备。

  6. 运行 OTA 更新脚本:要启动 OTA 更新,请使用 OTA 更新脚本。

有关更新工作的更多信息,请参阅 FreeRTOS 空中下载更新。有关如何设置低功耗蓝牙 MQTT 代理功能的其他信息,请参阅 Richard Kang 的博文:在 Espressif ESP32 上将低功耗蓝牙与 FreeRTOS 配合使用

先决条件

要执行本教程中的步骤,您需要以下资源:

  • 一个 ESP32 开发主板。

  • 一根 MicroUSB 转 USB A 电缆。

  • 一个 Amazon 账户(免费套餐即可)。

  • 一台使用 Android v 6.0 或更高版本和蓝牙版本 4.2或更高版本的 Android 手机。

在开发计算机上,您需要:

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

步骤 1:配置存储

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

  2. 创建 OTA 更新服务角色 并为角色添加以下托管策略:

    • AWSIotLogging

    • AWSIoTRuleActions

    • AWSIoTThingsRegistration

    • AWSFreeRTOSOTAUpdate

  3. 创建可执行 OTA 更新的用户。该用户可以在账户中的 IoT 设备上签名和部署固件更新,并且有权在所有设备上执行 OTA 更新。访问权限应仅限于可信实体。

  4. 按照步骤创建 OTA 用户策略并将其附加到您的用户。

步骤 2:创建代码签名证书

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

  2. 创建可用于对固件进行签名的代码签名证书。导入证书时,记录证书的 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 身份验证配置

创建 Amazon IoT 策略
  1. 登录到 Amazon IoT 控制台

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

  3. 在左侧导航窗格中,选择 Settings (设置)。在设备数据端点下,记下端点值。该端点的值类似于 xxxxxxxxxxxxxx.iot.us-west-2.amazonaws.com。在本示例中,Amazon 区域为“us-west-2”。

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

  5. 输入策略的名称,例如,“esp32_mqtt_proxy_iot_policy”。

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

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:aws-region:aws-account-id:*" }, { "Effect": "Allow", "Action": "iot:Publish", "Resource": "arn:aws:iot:aws-region:aws-account-id:*" }, { "Effect": "Allow", "Action": "iot:Subscribe", "Resource": "arn:aws:iot:aws-region:aws-account-id:*" }, { "Effect": "Allow", "Action": "iot:Receive", "Resource": "arn:aws:iot:aws-region:aws-account-id:*" } ] }
  7. 选择 Create(创建)。

创建 Amazon IoT 事物。
  1. 登录到 Amazon IoT 控制台

  2. 在左侧导航窗格中选择管理,然后选择事物

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

  4. 创建 Amazon IoT事物页面上,选择创建单个事物

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

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

创建 Amazon Cognito 应用程序客户端
  1. 登录 Amazon Cognito 控制台

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

  3. 输入群体名称(例如,“esp32_mqtt_proxy_user_pool”)。

  4. 选择 Review defaults (查看原定设置)

  5. 应用程序客户端中,选择添加应用程序客户端,然后选择添加应用程序客户端

  6. 输入应用程序客户端名称(例如,“mqtt_app_client”)。

  7. 确保选中生成客户端密钥

  8. 选择 Create app client(创建应用程序客户端)。

  9. 选择 Return to pool details(返回池详细信息)。

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

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

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

创建一个 Amazon Cognito 身份池
  1. 登录 Amazon Cognito 控制台

  2. 选择 Create new identity pool(创建新身份池)。

  3. 输入身份池的名称(例如,“mqtt_proxy_identity_pool”)。

  4. 展开身份验证提供程序

  5. 选择 Cognito 选项卡。

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

  7. 选择 Create Pool(创建池)。

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

  9. 记下身份池 ID,其格式为 us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

将 IAM policy 附加到经过身份验证的身份。
  1. 打开 Amazon Cognito 控制台

  2. 选择刚才创建的身份池(例如,“mqtt_proxy_identity_pool”)。

  3. 选择编辑身份池

  4. 记下分配给经过身份验证的角色的 IAM 角色(例如,“cognito_mqtt_proxy_identity_poolauth_Role”)。

  5. 打开 IAM 控制台

  6. 在导航窗格中,选择 Roles (角色)

  7. 搜索分配的角色(例如,“cognito_mqtt_proxy_identity_poolauth_Role”),然后将其选中。

  8. 选择添加内联策略,然后选择 JSON

  9. 输入以下策略:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:AttachPolicy", "iot:AttachPrincipalPolicy", "iot:Connect", "iot:Publish", "iot:Subscribe" ], "Resource": "*" }] }
  10. 请选择查看策略

  11. 输入策略名称(例如,“mqttProxyCognitoPolicy”)。

  12. 选择 Create policy(创建策略)

步骤 4:配置 Amazon FreeRTOS

  1. FreeRTOS GitHub 存储库下载最新版本的 Amazon FreeRTOS 代码。

  2. 要启用 OTA 更新演示,请按照开始使用 Espressif ESP32-DevKit C 和 ESP-WROVER-KIT中的步骤操作。

  3. 在以下文件中进行这些修改:

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

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

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

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

    4. 打开 vendors/espressif/boards/esp32/aws_demos/config_files/aws_iot_network_config.h 并更改 configSUPPORTED_NETWORKSconfigENABLED_NETWORKS,以便仅包含 AWSIOT_NETWORK_TYPE_BLE

    5. 打开 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 应用程序

  1. amazon-freertos-ble-android-sdk GitHub 存储库中下载 Android 低功耗蓝牙开发工具包和示例应用程序。

  2. 打开文件 app/src/main/res/raw/awsconfiguration.json,并按照以下 JSON 示例中的说明填写群体 ID、区域、AppClientId 和 AppClientSecret。

    { "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)" } } }
  3. 打开 app/src/main/java/software/amazon/freertos/DemoConstants.java 并输入之前创建的策略名称(例如,esp32_mqtt_proxy_iot_policy)和区域(例如,us-east-1)。

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

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

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

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

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

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

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

    7. 将找到的设备的滑块移至

    8. 在 ESP32 的串行端口调试控制台上按 y

    9. 选择配对并连接

  5. 建立连接后,更多...链接会变为活动状态。连接完成后,Android 设备 logcat 中的连接状态会更改为“BLE_CONNECTED”:

    2019-06-06 20:11:32.160 23484-23497/software.amazon.freertos.demo I/FRD: BLE connection state changed: 0; new state: BLE_CONNECTED
  6. 在传输消息之前,Amazon FreeRTOS 设备和 Android 设备会协商 MTU。您会在 logcat 中看到以下输出:

    2019-06-06 20:11:46.720 23484-23497/software.amazon.freertos.demo I/FRD: onMTUChanged : 512 status: Success
  7. 设备连接到应用程序并开始使用 MQTT 代理发送 MQTT 消息。要确认设备可通信,请确保 MQTT_CONTROL 特征数据值已更改为 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
  8. 设备配对后,您会在 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 更新脚本

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

    pip3 install boto3
    pip3 install pathlib
  2. demos/include/aws_application_version.h 中增加 FreeRTOS 应用程序的版本。

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

  4. 下载 python 脚本 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)
  5. 如果您使用提供的 Amazon 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
  6. OTA 更新完成后,设备将按照 OTA 更新过程的要求重新启动。然后,它会尝试使用更新的固件进行连接。如果升级成功,则会将更新后的固件标记为活动状态,您会在控制台中看到更新的版本:

    13 13498 [iot_thread] OTA demo version 0.9.21