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

MQTT 库,版本 1.0.0

概述

FreeRTOS 包括一个开源 MQTT 客户端库,您可以使用它来创建发布和订阅 MQTT 主题的应用程序,就像网络上的 MQTT 客户端。

MQTT 库版本 2.0.0 可供 FreeRTOS 版本 201960.00 及更高版本使用。此较新的库与所有传输类型兼容,意味着您可以将其用于低功耗蓝牙和 TCP/IP。有关更多信息,请参阅MQTT 库,版本 2.0.0

FreeRTOS MQTT 代理

FreeRTOS 还包括一个名为“FreeRTOS MQTT 代理”的开源守护程序,可用于管理 MQTT 库。MQTT 代理提供了一个简单接口以通过底层 MQTT 库连接、发布和订阅 MQTT 主题。

MQTT 代理运行在一个单独的 FreeRTOS 任务中,并按照 MQTT 协议规范中的规定,自动发送常规的保持活动消息。所有 MQTT API 均可阻止并采用超时参数,即 API 等待相应操作完成所花费的最长时间值。如果操作在给定时间内未完成,API 会返回超时错误代码。

依赖项和要求

FreeRTOS MQTT 库使用 安全套接字库 和 FreeRTOS 缓冲池库。如果 MQTT 代理连接到安全 MQTT 代理,则库也将使用 传输层安全

功能

回调

您可以指定可选的回调,每当 MQTT 代理 (Agent) 与代理 (Broker) 断开连接或者收到代理 (Broker) 的发布消息时,即调用此回调。收到的发布消息存储在从中央缓冲池获取的缓冲区内。此消息将传递给回调。此回调在 MQTT 任务的上下文中运行,因此必须快速。如果需要更长的处理时间,则必须从回调返回 pdTRUE,以获得缓冲区的所有权。随后,在完成操作后,必须调用 FreeRTOS_Agent_ReturnBuffer 将缓冲区归还给缓冲池。

订阅管理

您可以通过订阅管理,为每个订阅筛选条件注册一个回调。在订阅时提供此回调。每当与主题筛选条件匹配的主题收到发布消息时,即调用此回调。缓冲区所有权的工作方式与通用回调情况中所述相同。

MQTT 任务唤醒

每当用户调用 API 执行任何操作,或者收到代理的发布消息时,便会唤醒 MQTT 任务唤醒功能。如果平台能够将连接套接字上接收的数据通知主机 MCU,则在该平台上有可能实现基于发布消息接收的异步唤醒。如果平台不具备此功能,则需要 MQTT 任务持续轮询连接套接字上接收的数据。为确保接收发布消息与调用回调之间的延迟时间最短,mqttconfigMQTT_TASK_MAX_BLOCK_TICKS 宏会控制 MQTT 任务保持“被阻止”状态的最长时间。对于无法将连接套接字上接收的数据通知主机 MCU 的平台,该值必须很小。

主要配置

在 MQTT 连接请求期间,可以指定以下标志:

  • mqttconfigKEEP_ALIVE_ACTUAL_INTERVAL_TICKS:保持活动消息的发送频率。

  • mqttconfigENABLE_SUBSCRIPTION_MANAGEMENT:启用订阅管理。

  • mqttconfigMAX_BROKERS:同时运行的 MQTT 客户端的最大数量。

  • mqttconfigMQTT_TASK_STACK_DEPTH:任务堆栈深度。

  • mqttconfigMQTT_TASK_PRIORITY:MQTT 任务的优先级。

  • mqttconfigRX_BUFFER_SIZE:用于接收数据的缓冲区的长度。

  • mqttagentURL_IS_IP_ADDRESS:如果提供的 URL 是 IP 地址,则在 xFlags 中设置此位。

  • mqttagentREQUIRE_TLS:在 xFlags 设置此位以使用 TLS。

  • mqttagentUSE_AWS_IOT_ALPN_443:在 xFlags 中设置此位,以使用 AWS IoT 对 TLS 端口 443 上的 MQTT 的支持。

有关 ALPN 的更多信息,请参阅 AWS IoT 开发人员指南中的 AWS IoT 协议,以及 AWS 上的物联网博客上的 MQTT 及端口 443 上的 TLS 客户端身份验证:为什么有用及其工作原理博客帖子。

优化

及时处理接收的数据包

实施 MQTT 代理的任务大部分时间都处于阻止状态(因此,不使用任何 CPU 周期),等待事件处理。通过在从网络接收到 MQTT 数据包后取消阻止代理任务来最大化 MQTT 吞吐量。如果这样做了,就会尽早处理接收到的数据包。如果没有这样做,接收到的数据包将不会得到处理,直到 MQTT 代理出于其他原因不再处于阻止状态。

通过执行由名为 SOCKETS_SetSockOpt() 的 MQTT 代理安装的回调,并将 lOptionName 参数设置为 SOCKETS_SO_WAKEUP_CALLBACK 来使 MQTT 代理不再处于阻止状态。这里需要安全套接字文档的链接。如果您使用的是 FreeRTOS+TCP TCP/IP 堆栈,则将在正确的时间执行回调,前提是在 FreeRTOSIPConfig.h(它是 TCP/IP 堆栈的配置文件)中将 ipconfigSOCKET_HAS_USER_WAKE_CALLBACK 设置为 1。如果您未使用 FreeRTOS+TCP TCP/IP 堆栈,则安全套接字可确保此功能包含为使用中的堆栈实施的安全套接字抽象层中。

如果 TCP/IP 堆栈无法在接收到数据时取消阻止 MQTT 代理,则通过 mqttconfigMQTT_TASK_MAX_BLOCK_TICKS 常量设置正在接收的数据包和正在处理的数据包之间的最大时间。

最小化 RAM 消耗

以下配置常量会直接影响 MQTT 代理所需的 RAM 量:

  • mqttconfigMQTT_TASK_STACK_DEPTH

  • mqttconfigMQTT_TASK_STACK_DEPTH

  • mqttconfigMAX_BROKERS

  • mqttconfigMAX_PARALLEL_OPS

  • mqttconfigRX_BUFFER_SIZE

您应将这些常量设置为可能的最小值。

要求和使用限制

使用 xTaskCreateStatic() API 函数创建 MQTT 代理任务 - 以便在编译时静态分配任务的堆栈和控制块。这将确保 MQTT 代理可用于不允许动态内存分配的应用程序,但意味着依赖于在 FreeRTOSConfig.h 中将 configSUPPORT_STATIC_ALLOCATION 设置为 1。

MQTT 代理使用 FreeRTOS 定向到任务通知功能。调用 MQTT 代理 API 函数可能会更改调用任务的通知值和状态。

MQTT 数据包存储在缓冲池模块提供的缓冲区中。强烈建议确保池中的缓冲区数量至少为任何时候都在进行的 MQTT 事务数的两倍。

开发人员支持

mqttconfigASSERT

mqttconfigASSERT() 与 FreeRTOS configASSERT() 宏等效,并且二者的使用方式完全相同。如果您需要断言 MQTT 代理中的语句,请定义 mqttconfigASSERT()。如果您不需要断言 MQTT 代理中的语句,请将 mqttconfigASSERT() 保持未定义状态。如果您定义 mqttconfigASSERT() 来调用 FreeRTOS configASSERT()(如下所示),则 MQTT 代理将仅包含断言语句(如果定义了 FreeRTOS configASSERT())。

#define mqttconfigASSERT( x ) configASSERT( x )

mqttconfigENABLE_DEBUG_LOGS

mqttconfigENABLE_DEBUG_LOGS 设置为 1 可通过调用 vLoggingPrintf() 来打印调试日志。

初始化

在尝试 MQTT 通信前,必须初始化 MQTT 代理与其依赖库,如下所示。在建立网络连接后初始化库。

BaseType_t SYSTEM_Init() { BaseType_t xResult = pdPASS; /* The bufferpool libraries provides the buffers use to store MQTT packets.*/ xResult = BUFFERPOOL_Init(); if( xResult == pdPASS ) { /* Create the MQTT Agent task. */ xResult = MQTT_AGENT_Init(); } if( xResult == pdPASS ) { /* Initialize the secure sockets abstraction layer.*/ xResult = SOCKETS_Init(); } return xResult; }

API 参考

有关完整 API 参考,请参阅 MQTT (v1.0.0) 库 API 参考 MQTT(v1) 代理 API 参考

移植

必须将 MQTT 代理调用的安全套接字抽象层移植到特定的架构。有关更多信息,请参阅 FreeRTOS 移植指南中的移植安全套接字库