低功耗蓝牙库 - FreeRTOS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

如果我们为英文版本指南提供翻译,那么如果存在任何冲突,将以英文版本指南为准。在提供翻译时使用机器翻译。

低功耗蓝牙库

Overview

FreeRTOS 支持通过代理设备(例如手机)使用低功耗蓝牙功能发布和订阅 MQTT 主题。与 FreeRTOS 蓝牙低能量 库,您的微型处理器可以安全地与 AWS IoT MQTTbroker。

通过适用于 FreeRTOS 蓝牙设备的移动开发工具包,您可以编写本机移动应用程序以通过低功耗蓝牙与微控制器上的嵌入式应用程序进行通信。有关移动开发工具包的更多信息,请参阅适用于 FreeRTOS 蓝牙设备的移动开发工具包

FreeRTOS 低功耗蓝牙库包含一些服务以配置 Wi-Fi 网络,传输大量数据以及通过低功耗蓝牙提供网络抽象。FreeRTOS 低功耗蓝牙库还包括中间件和低级别 API 以便更直接地控制低功耗蓝牙堆栈。

Architecture

FreeRTOS 低功耗蓝牙库由三层组成:服务、中间件和低级别包装程序。

Services

的 FreeRTOS 蓝牙低能量服务层由四个通用属性(GATT)服务组成,这些服务利用中间件API: 设备信息、Wi-Fi配置、网络抽象和大对象传输。

设备信息

设备信息服务可收集有关微控制器的信息,其中包括:

  • 您的设备正在使用的 FreeRTOS 的版本。

  • 为其注册的账户的 AWS IoT 终端节点。

  • 低功耗蓝牙最大传输单元 (MTU)。

Wi-Fi 预置

利用 Wi-Fi 预置服务,具有 Wi-Fi 功能的微控制器可执行以下操作:

  • 列出范围内的网络。

  • 将网络和网络凭证保存到闪存。

  • 设置网络优先级。

  • 从闪存中删除网络和网络凭证。

网络抽象

网络抽象服务将应用程序的网络连接类型抽象化。通用 API 与您的设备的 Wi-Fi、以太网和低功耗蓝牙硬件堆栈交互,使得应用程序兼容多种连接类型。

大型对象传输

大型对象传输服务向客户端发送数据并从客户端接收数据。Wi-Fi 预置和网络抽象等其他服务使用大型对象传输服务来发送和接收数据。您还可以使用大型对象传输 API 来直接与服务交互。

Middleware

FreeRTOS 低功耗蓝牙中间件是来自低级别 API 的抽象层。中间件 API 构成了一个面向低功耗蓝牙堆栈的更方便用户使用的界面。

利用中间件 API,您可以跨多个层将多个回调注册到单个事件。初始化低功耗蓝牙中间件还会初始化服务并启动通告。

灵活的回调订阅

假设您的低功耗蓝牙硬件断开连接,并且低功耗蓝牙 MQTT 服务需要检测断开连接事件。您编写的应用程序可能还需要检测相同的断开连接事件。低功耗蓝牙中间件可以将事件路由到已注册回调的代码的各个部分,而不会让较高的层争用低级别资源。

低级别包装程序

低级别 FreeRTOS 低功耗蓝牙包装程序是从制造商的低功耗蓝牙堆栈的抽象。低级别包装程序提供了一组可直接控制硬件的通用 API。低级别 API 优化了 RAM 的使用,但功能有限。

使用低功耗蓝牙服务 API 可与低功耗蓝牙服务交互。该服务 API 相比低级别 API 需要更多资源。

依赖项和要求

低功耗蓝牙库具有以下直接依赖项:

  • 线性容器库

  • 一个平台层,直接与操作系统交互用于线程管理、计时器、时钟功能和网络访问。

只有 Wi-Fi 预置服务具有 FreeRTOS 库依赖项:

GATT 服务 依赖关系
Wi-Fi 预置 Wi-Fi 库

要与 AWS IoT MQTT 代理进行通信,您必须有一个 AWS 账户,并且您必须将设备注册为 AWS IoT 事物。有关设置的更多信息,请参阅 AWS IoT 开发人员指南

FreeRTOS 低功耗蓝牙使用 Amazon Cognito 在您的移动设备上进行用户身份验证。要使用 MQTT 代理服务,您必须创建一个 Amazon Cognito 身份和用户池。每个 Amazon Cognito 身份 必须附加了适当的策略。有关更多信息,请参阅 Amazon Cognito 开发人员指南

库配置文件

使用 FreeRTOS 低功耗蓝牙 MQTT 服务的应用程序必须提供一个定义了配置参数的 iot_ble_config.h 标头文件。未定义的配置参数将采用 iot_ble_config_defaults.h 中指定的默认值。

一些重要的配置参数包括:

IOT_BLE_ADD_CUSTOM_SERVICES

允许用户创建其自己的服务。

IOT_BLE_SET_CUSTOM_ADVERTISEMENT_MSG

允许用户自定义通告和扫描响应消息。

有关更多信息,请参阅低功耗蓝牙 API 参考

Optimization

在优化主板性能时,请注意以下事项:

  • 低级别 API 占用的 RAM 更少,但它提供的功能有限。

  • 您可以将 iot_ble_config.h 标头文件中的 bleconfigMAX_NETWORK 参数设置为一个较小的值来减少使用的堆栈量。

  • 您可以将 MTU 大小增至其最大值来限制消息缓冲,并加快代码运行速度和减少占用的 RAM。

使用限制

默认情况下,FreeRTOS 低功耗蓝牙库将 eBTpropertySecureConnectionOnly 属性设置为 TRUE,这会将设备置于“仅安全连接”模式。按照蓝牙核心规范 5.0 版第 3 册 C 部分 10.2.4 中所述,当设备处于“仅安全连接”模式中时,需要最高 LE 安全模式 1 级别(级别 4)才能访问任何权限高于最低 LE 安全模式 1 级别(级别 1)的属性。在 LE 安全模式 1 级别 4,设备必须具有输入和输出功能才能进行数字比较。

此处列出了支持的模式及其关联属性:

模式 1、级别 1(不安全)
/* Disable numeric comparison */ #define IOT_BLE_ENABLE_NUMERIC_COMPARISON ( 0 ) #define IOT_BLE_ENABLE_SECURE_CONNECTION ( 0 ) #define IOT_BLE_INPUT_OUTPUT ( eBTIONone ) #define IOT_BLE_ENCRYPTION_REQUIRED ( 0 )
模式 1、级别 2(无身份验证配对,有加密)
#define IOT_BLE_ENABLE_NUMERIC_COMPARISON ( 0 ) #define IOT_BLE_ENABLE_SECURE_CONNECTION ( 0 ) #define IOT_BLE_INPUT_OUTPUT ( eBTIONone )
模式 1、级别 3(有身份验证配对,有加密)

不支持此模式。

模式 1、级别 2(有身份验证 LE 安全连接配对,有加密)

默认支持此模式。

有关 LE 安全模式的信息,请参阅蓝牙核心规范 5.0 版第 3 册 C 部分 10.2.1。

Initialization

如果您的应用程序通过中间件与低功耗蓝牙堆栈交互,则您只需初始化中间件即可。中间件负责初始化堆栈的较低层。

Middleware

初始化中间件

  1. 在调用低功耗蓝牙中间件 API 之前初始化任意低功耗蓝牙硬件驱动程序。

  2. 启用低功耗蓝牙。

  3. 使用 IotBLE_Init() 初始化中间件

    注意

    如果您运行 AWS 演示,则此初始化步骤非必需。演示初始化由网络管理器处理,该管理器位于 freertos/demos/network_manager

低级别 API

如果您不想使用 FreeRTOS 低功耗蓝牙 GATT 服务,则可绕过中间件,并直接与低级别 API 交互以节省资源。

初始化低级别 API

  1. 在调用 API 之前初始化所有低功耗蓝牙硬件驱动程序。驱动程序初始化不是低功耗蓝牙低级别 API 的一部分。

  2. 低功耗蓝牙低级别 API 提供了对低功耗蓝牙堆栈的启用/禁用调用以优化功率和资源。在调用 API 之前,您必须启用低功耗蓝牙。

    const BTInterface_t * pxIface = BTGetBluetoothInterface(); xStatus = pxIface->pxEnable( 0 );
  3. 蓝牙管理器包含低功耗蓝牙的和蓝牙经典功能的通用 API。常见管理器的回调必须是第二个初始化的。

    xStatus = xBTInterface.pxBTInterface->pxBtManagerInit( &xBTManagerCb );
  4. 低功耗蓝牙适配器位于常见 API 的上方。您必须初始化其回调,就像您初始化常见 API 一样。

    xBTInterface.pxBTLeAdapterInterface = ( BTBleAdapter_t * ) xBTInterface.pxBTInterface->pxGetLeAdapter(); xStatus = xBTInterface.pxBTLeAdapterInterface->pxBleAdapterInit( &xBTBleAdapterCb );
  5. 注册新的用户应用程序。

    xBTInterface.pxBTLeAdapterInterface->pxRegisterBleApp( pxAppUuid );
  6. 初始化对 GATT 服务器的回调。

    xBTInterface.pxGattServerInterface = ( BTGattServerInterface_t * ) xBTInterface.pxBTLeAdapterInterface->ppvGetGattServerInterface(); xBTInterface.pxGattServerInterface->pxGattServerInit( &xBTGattServerCb );

    在初始化低功耗蓝牙适配器后,您可以添加 GATT 服务器。一次只能注册一个 GATT 服务器。

    xStatus = xBTInterface.pxGattServerInterface->pxRegisterServer( pxAppUuid );
  7. 设置应用程序属性,如仅安全连接和 MTU 大小。

    xStatus = xBTInterface.pxBTInterface->pxSetDeviceProperty( &pxProperty[ usIndex ] );

API 参考

有关完整 API 参考,请参阅低功耗蓝牙 API 参考

示例用法:

以下示例说明了如何将低功耗蓝牙库用于通告和创建新服务。有关所有 FreeRTOS 低功耗蓝牙的演示应用程序,请参阅低功耗蓝牙演示应用程序

Advertising

  1. 在您的应用程序中,设置通告 UUID:

    static const BTUuid_t _advUUID = { .uu.uu128 = IOT_BLE_ADVERTISING_UUID, .ucType = eBTuuidType128 };
  2. 然后,定义 IotBle_SetCustomAdvCb 回调函数:

    void IotBle_SetCustomAdvCb( IotBleAdvertisementParams_t * pAdvParams, IotBleAdvertisementParams_t * pScanParams) { memset(pAdvParams, 0, sizeof(IotBleAdvertisementParams_t)); memset(pScanParams, 0, sizeof(IotBleAdvertisementParams_t)); /* Set advertisement message */ pAdvParams->pUUID1 = &_advUUID; pAdvParams->nameType = BTGattAdvNameNone; /* This is the scan response, set it back to true. */ pScanParams->setScanRsp = true; pScanParams->nameType = BTGattAdvNameComplete; }

    此回调在通告消息中发送 UUID,在扫描响应中发送全名。

  3. 开放 vendors/vendor/boards/board/aws_demos/config_files/iot_ble_config.h,然后设置 IOT_BLE_SET_CUSTOM_ADVERTISEMENT_MSG1。这触发了 IotBle_SetCustomAdvCb 回拨。

添加新服务

有关服务的完整示例,请参阅 freertos/.../ble/services

  1. 为服务的特性和描述符创建 UUID:

    #define xServiceUUID_TYPE \ {\ .uu.uu128 = gattDemoSVC_UUID, \ .ucType = eBTuuidType128 \ } #define xCharCounterUUID_TYPE \ {\ .uu.uu128 = gattDemoCHAR_COUNTER_UUID,\ .ucType = eBTuuidType128\ } #define xCharControlUUID_TYPE \ {\ .uu.uu128 = gattDemoCHAR_CONTROL_UUID,\ .ucType = eBTuuidType128\ } #define xClientCharCfgUUID_TYPE \ {\ .uu.uu16 = gattDemoCLIENT_CHAR_CFG_UUID,\ .ucType = eBTuuidType16\ }
  2. 创建缓冲区以注册特性和描述符的处理:

    static uint16_t usHandlesBuffer[egattDemoNbAttributes];
  3. 创建属性表。为节省一些 RAM,请将表定义为 const

    重要

    始终按顺序创建属性,将服务作为第一个属性。

    static const BTAttribute_t pxAttributeTable[] = { { .xServiceUUID = xServiceUUID_TYPE }, { .xAttributeType = eBTDbCharacteristic, .xCharacteristic = { .xUuid = xCharCounterUUID_TYPE, .xPermissions = ( IOT_BLE_CHAR_READ_PERM ), .xProperties = ( eBTPropRead | eBTPropNotify ) } }, { .xAttributeType = eBTDbDescriptor, .xCharacteristicDescr = { .xUuid = xClientCharCfgUUID_TYPE, .xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM ) } }, { .xAttributeType = eBTDbCharacteristic, .xCharacteristic = { .xUuid = xCharControlUUID_TYPE, .xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM ), .xProperties = ( eBTPropRead | eBTPropWrite ) } } };
  4. 创建回调阵列。此回调阵列必须与以上定义的表阵列采用相同的顺序。

    例如,如果在访问 xCharCounterUUID_TYPE 时触发 vReadCounter,并在访问 xCharControlUUID_TYPE 时触发 vWriteCommand,则定义阵列如下:

    static const IotBleAttributeEventCallback_t pxCallBackArray[egattDemoNbAttributes] = { NULL, vReadCounter, vEnableNotification, vWriteCommand };
  5. 创建服务:

    static const BTService_t xGattDemoService = { .xNumberOfAttributes = egattDemoNbAttributes, .ucInstId = 0, .xType = eBTServiceTypePrimary, .pusHandlesBuffer = usHandlesBuffer, .pxBLEAttributes = (BTAttribute_t *)pxAttributeTable };
  6. 使用您在上一步中创建的结构调用 API IotBle_CreateService。中间件同步所有服务的创建,因此在触发 IotBle_AddCustomServicesCb 回调时必须已经定义好了所有新服务。

    1. 设置 IOT_BLE_ADD_CUSTOM_SERVICES1vendors/vendor/boards/board/aws_demos/config_files/iot_ble_config.h.

    2. 在应用程序中创建 IotBle_AddCustomServicesCb:

      void IotBle_AddCustomServicesCb(void) { BTStatus_t xStatus; /* Select the handle buffer. */ xStatus = IotBle_CreateService( (BTService_t *)&xGattDemoService, (IotBleAttributeEventCallback_t *)pxCallBackArray ); }

Porting

用户输入和输出外围设备

安全连接需要输入和输出以进行数字比较。可使用事件管理器注册 eBLENumericComparisonCallback 事件:

xEventCb.pxNumericComparisonCb = &prvNumericComparisonCb; xStatus = BLE_RegisterEventCb( eBLENumericComparisonCallback, xEventCb );

外围设备必须显示数字密钥,并将比较结果作为输入。

移植 API 实施

要将 FreeRTOS 移植到新目标,您必须为 Wi-Fi 预置服务和低功耗蓝牙的功能实施一些 API。

低功耗蓝牙 API

要使用 FreeRTOS 低功耗蓝牙中间件,您必须实施一些 API。

GAP for Bluetooth Classic 和 GAP for Bluetooth Low Energy 的通用 API
  • pxBtManagerInit

  • pxEnable

  • pxDisable

  • pxGetDeviceProperty

  • pxSetDeviceProperty(所有选项都是强制性的,eBTpropertyRemoteRssieBTpropertyRemoteVersionInfo 除外)

  • pxPair

  • pxRemoveBond

  • pxGetConnectionState

  • pxPinReply

  • pxSspReply

  • pxGetTxpower

  • pxGetLeAdapter

  • pxDeviceStateChangedCb

  • pxAdapterPropertiesCb

  • pxSspRequestCb

  • pxPairingStateChangedCb

  • pxTxPowerCb

特定于低功耗蓝牙 的 GAP 的 API
  • pxRegisterBleApp

  • pxUnregisterBleApp

  • pxBleAdapterInit

  • pxStartAdv

  • pxStopAdv

  • pxSetAdvData

  • pxConnParameterUpdateRequest

  • pxRegisterBleAdapterCb

  • pxAdvStartCb

  • pxSetAdvDataCb

  • pxConnParameterUpdateRequestCb

  • pxCongestionCb

GATT 服务器
  • pxRegisterServer

  • pxUnregisterServer

  • pxGattServerInit

  • pxAddService

  • pxAddIncludedService

  • pxAddCharacteristic

  • pxSetVal

  • pxAddDescriptor

  • pxStartService

  • pxStopService

  • pxDeleteService

  • pxSendIndication

  • pxSendResponse

  • pxMtuChangedCb

  • pxCongestionCb

  • pxIndicationSentCb

  • pxRequestExecWriteCb

  • pxRequestWriteCb

  • pxRequestReadCb

  • pxServiceDeletedCb

  • pxServiceStoppedCb

  • pxServiceStartedCb

  • pxDescriptorAddedCb

  • pxSetValCallbackCb

  • pxCharacteristicAddedCb

  • pxIncludedServiceAddedCb

  • pxServiceAddedCb

  • pxConnectionCb

  • pxUnregisterServerCb

  • pxRegisterServerCb

有关将 FreeRTOS 低功耗蓝牙库移植到您的平台的更多信息,请参阅 FreeRTOS 移植指南中的移植低功耗蓝牙库