This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS:阻塞套接字(MQTT)的设计模式请求

Guru**** 2478485 points
Other Parts Discussed in Thread: EK-TM4C129EXL

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/681741/rtos-design-pattern-request-for-blocking-sockets-mqtt

Thread 中讨论的其他器件:EK-TM4C129EXL

工具/软件:TI-RTOS

尊敬的社区:

我有以下问题、我想通过某种方式解决。 (RTOS 是最新的、器件是 EK-TM4C129EXL)  

UC 有不同的线程、用于处理 ADC 和其他 IO 端口管理。 生成数据的 ADC 和 IO 正在接收来自外部世界的工作。 为了与器件 MQTT 协议进行交互、最新版本选择了 MQTT 协议、但在前一版本中、我使用了一个标准 TCP/IP 协议、该协议具有自定义数据包格式。 我要处理的问题是如何管理与线程间通信的网络通信、而不会在邮箱上等待大量时间或阻止套接字操作。

在上一个设计中、我共享了一个连接的插座、在两个任务中、一个用于读取、另一个用于发送数据。 模型如下所示:

socketReaderThread{

//阻止套接字读取操作
int count = recv (sharedSocket、...、...);

//根据请求代码
Mailbox_post (myTaskMailbox、request、BIOS_wait_forever)将请求发送到正确的任务;

}

socketTaskThread{

//等待任何任务 Response
Mailbox_pend...(myTaskMailbox、Response、Response、forever、BIOS_wait...);send

= forever…

……… 

上述解决方案具有巨大优势、我可以在消息发生时立即发送和接收消息。  

现在我想更新 MQTT 的通信 、我已经将 PAHO C 示例代码(MQTTPacket)移植到 TI RTOS、这是我的问题:

while (1){

//等待任务响应、并处理 BIOS_no_wait
if (Mailbox_pend (myTaskMailbox、mbResponse、BIOS_no_wait)){

MQTT_PUB (套接字、mbResponse、...)
}

//此调用会阻止整个任务
MQTT_SUB (socket、sub_buffer、...);


} 

在上面的代码中、MQTT_SUB 根据 SO_RCVTIMEO 参数阻止整个任务。 根据我的理解、SO_RCVTIMEO 的值应该足够大、以便等待我的 pub 请求的 pub_ACK。 (处理网络不确定性)、但1秒对于阻止我的整个任务来说是非常长的时间。

如何在 MQTT_SUB 上实现这一点不会阻止这么长的时间?

我不认为更改 SO_RCVTIMEO 是我的问题的关键...  

期待您的回复。

PS.:我实施了一个解决方案,其中 UC 使2 MQTT 客户端连接一个用于发布,另一个用于订阅。 这种方法非常有效、但此模型会导致两个 MQTT 客户端具有重复的身份验证、client_id、并在物联网平台中显示为两个器件。

 更新了:我认为针对 TM4C 的 MQTT 的非阻塞实现是最好的。 但是、正如我看到的、没有任何一个。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Daniel:

    我们最近发布的软件对我们的网络堆栈进行了一些内部更改。 精确知道您使用的是哪个版本非常重要。 对于 EK-TM4C129EXL、我们有以下版本:

    TI-RTOS TivaC 2.16.01.14
    NS 1.11.00.10
    NDK 2.25.00.09

    请确认这是否是您正在使用的内容。

    您从何处获取 MQTT 实现? 它是来自 TI 软件还是来自第三方?

    根据您的描述、您有一个任务(使用者)在调用 MQTT_SUB ()时被阻止(超时一秒)。 但是、您希望当邮箱中有新数据时、此任务立即返回。 即使套接字上没有数据、也应该发生这种情况。 对吧? 此外、我假设您还有 另一个任务(生产者)、它将新数据放入邮箱。 我是否正确?

    一个想法是使用 localhost (127.0.0.1)在两个任务之间进行通信。 在消费型任务中、打开要读取的本地主机套接字。 在调用 MQTT_pub()之前,使用两个套接字(localhost、MQTT)调用 select()。 当 select()返回时,使用 readfds 确定哪个套接字具有数据。 在您的生产者任务中、打开一个到 localhost 的套接字进行写入。 此任务将新数据放入邮箱后、写入 localhost 套接字。 这应立即唤醒在 select()中等待的使用者任务

    您对此想法有何看法?

    ~Ramsey

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Ramsey:

    感谢您的回答。 我具有以下版本:
    RTOS 2.16.0.08以及 ns 和 NDK 是相同的、因为 tirtos_tivac_2_16_00_08\products 文件夹中存在这些内容。 我假设在我的项目中使用了此版本。

    我正在使用 eclipse PAHO MQTT 实施(www.eclipse.org/.../ ),但我想使用 SimpleLink 的 MQTT 库。 我已经使用 MSP432以太网 Launchpad 检查了 MQTT 示例、我非常喜欢该实现。 (基于 RTOS 并使用子系统的回调。) 我厌倦了将 simplelink MQTT 移植到 TM4C RTOS 项目、但我失败了。 我想我将开始新的主题、寻求帮助。

    你很好地理解了我的问题。

    我非常喜欢您的想法。 值得一试。
    1.你有一个示例或我可以使用的东西吗?
    2.您认为 SimpleLink MQTT 可用于 TM4C 吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Daniel:

    很抱歉、我没有任何代码示例可供分享。 如果我遇到一些问题、我会发布它。

    我认为在 Tiva C 上将 SimpleLink MQTT 移植回 TI-RTOS 需要付出巨大的努力。我们对从 TM4C 到 MSP432的网络堆栈实施进行了一些重大更改 MQTT 层需要进行最新的网络更改。

    您是否可以继续使用 MSP432E4? SimpleLink 软件在 EMAC 驱动程序方面也有了一些很好的改进。

    ~Ramsey

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Daniel、您好!

    您是否需要有关此主题的更多支持?

    TM4C 器件不支持 SimpleLink SDK。 正如 Ramsey 所指出的、将 SimpleLink SDK 中的 MQTT 库移植到用于 TivaC 封装的 TI-RTOS 可能需要大量工作。

    谢谢、
    SAI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Ramsey:

    我们已转向 MSP432平台并将代码移植到新平台。 感谢您的建议、很抱歉我迟到的回复!