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.

[参考译文] EK-TM4C1294XL:LWIP Raw API - TCP 问题

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/784424/ek-tm4c1294xl-lwip-raw-api---tcp-issues

器件型号:EK-TM4C1294XL

大家好、


因此、我一直在尝试使用实用程序库中提供的 LWIP 使 TM4C 上的 TCP 工作。
它将添加到现有项目中、因此使用 TI-RTOS 会带来痛苦(或者可能会带来更小的痛苦?)

无论如何,我看到了回声示例,在对它进行了一些熏蒸之后,我遇到了一些问题,因为我从未使用过类似的东西。
其原理是基本上使用它来与 python 应用程序之间传输数据。 没什么特别的、它基本上是一个串行端口。 我进行的测试以2kHz 的频率生成消息、所有48字节的大小都必须最终到达 python 应用。

我为此制定了一个测试计划。 它不是理想的、但它本身应该起作用。
我遇到了一些与此 "="" bug"="">"已修复"错误相关的问题。 让我们将其称为 test1
在 test1中、我使用 putty 读取 TCP 数据。 它基本上是读取器和丢弃器。 我主要观察的变量表明"有人"是否丢弃了字节(在我现在拥有解决方案之前)。 30分钟内没有问题。
但是,似乎印刷电路板->snd_queuelen 基本值持续增长如此缓慢。 我尝试在测试过程中禁用消息发生器, 但 snd_queuelen 没有减少!  

其他问题。 让我们将其称为 test2。
基本上相同、区别在于我使用的是 python 应用。 它不是 python 测试代码、而是具有扭曲特性的应用、它在从套接字缓冲器中获取时立即丢弃所有内容。 以消除可能的瓶颈。 嗯、它可以正常工作、直到 TM4C 停止发送数据。 它没有冻结、计时器中断不断被调用、消息发生器工作、连接已建立、没有故障、lwip TCP 队列似乎没有满。  它只是停止发送数据。 PCB 或 lwip_stats 中可能存在我可能缺少的某些内容(很可能)、但它看起来很奇怪。  
Wireshark 显示"TCP 不按顺序"


我仍然没有检查两个测试所需的所有内容、但由于至少前1个测试似乎让人想起了旧的错误、我决定 在这里发布。 第2次测试可能是我不知道的标志中显而易见的、因此经验的帮助将是极好的。


接下来、我们将详细介绍我实施的措施:



Nagle 已启用
一些选择是为了确保在同一上下文中进行所有原始 API 调用。 由于 main 中调用了1个 tcp_write、但它具有 IntMasterDisable、因此我希望没有问题。

-我有一个函数"serial_lwIP_Send"。 它从主代码调用。 也可以

  • 它使用 IntMasterDisable 调用 tcp_write。 当发生这种情况时(sentEvent)、将标志设置为0、只有 在 sentEvent =1或循环缓冲区为空时才会执行此操作。
  • 如果 sentEvent == 0,则它加载循环缓冲区
  • 如果 tcp_write 返回 err_mem、则会加载循环缓冲区。

-对"tcp_sent (tcp_sent)"进行了回调。 我在每个 tcp_write 之前调用"tcp_sent

  • 如果 循环缓冲区中有数据,则负责执行 sentEvent=1并调用 tcp_write()。 仅为 tcp_write()提供 tcp_sndbuf()的最大值
  • 实际上只有这样做

-生成了周期为5ms 的周期性计时器 ISR

  • 此 ISR 的优先级(应该)高于以太网 ISR
  • 每10个中断调用一次 tcp_output (因此周期为50ms)
  • 调用 lwIPTimer




请提供任何帮助。
我可以提供 lwipopts.h 我不相信内存是问题、可能我的需求太大了。 但是、与 PBufs 相关的问题可能不是最好的。

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

    很抱歉、我不确定测试2中的问题是什么。 希望论坛中有更多经验丰富的 LwIP 用户能够为您提供一些帮助。 当您说不再有数据被发送时,应用程序是否在此期间继续调用 tcp_write()? 从 MCU 侧看、test1和 test2之间有何区别? 它们是否运行相同的应用程序? 如果您禁用 Nagle、它会产生影响吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    我最后修复了它、至少对于测试代码来说、仍然没有时间在真实代码中尝试它。

    "当您说没有发送更多数据时,应用程序是否在此期间继续调用 tcp_write()? "
    是的。 实际上、有时它在经过 pbuf 时卡在 tcp_write 中、但在我在这里报告的情况下不会卡在其中。

    "MCU 端的 test1和 test2之间有什么区别? "
    test1与 test2。 客户端是 PuTTY 与 Python 应用程序。
    存在差异的事实可能只是随机的。

    "他们是否运行相同的应用程序? "
    微控制器在两个测试中运行完全相同的代码。

    "如果您禁用 Nagle、它会产生什么影响吗?"
    Naggle 的行为很奇怪、在这里段将直接达到最大值并冻结整个东西。 (故障或无故障、但代码的其余部分会冻结、因为即使调用了 tcp_write、代码填充后也不会出现任何情况)


    好的、但问题是什么? 可重入性。
    "线程":(我真的不喜欢端口如何与以太网 ISR 中的几乎所有内容一同提供、顺便说一下)
    以太网 ISR (除其他所有内容外、tcp_sent 回调基本上在这里)
    - Timer1 ISR - lwIPTimer 调用方和 tcp_output。

    嗯、问题是 Timer1正在调用 tcp_output、并且其优先级高于以太网 ISR!
    从 Timer1_ISR 中删除了 tcp_output 并创建了与以太网 ISR 具有相同优先级的 Timer2_ISR 以调用 tcp_output。 仅用于测试。 这样、到目前为止、代码的工作方式是"正常"。

    这里需要额外计时器而不仅仅是更改 Timer1_ISR 优先级的原因是、由于 Timer1_ISR 调用 lwIPTimer、它需要(显然)比以太网 ISR 更高的优先级。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Luis、

    Timer1的时钟速度可能大于5ms? LWIP SW 触发中断(lwiplib.c)对间隔定时器(lwipopts.h)有其限制、并且它应该是 Timer1 (n)的倍数。 Pubf 池崩溃、TCP 路由器出现故障、如果将 HAL 推至小于75ms 的硬周期、设备层 TM4_129.c HAL 将变得很难。 例如、每个 LaunchPad 上加载的 IOT 项目运行良好、n=70或350ms 周期。 我当前运行 telnet 75ms (n=3)。 唯一很少发生的情况是 telnet 客户端断开超时。

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

    您好、Luis、

     感谢您的更新。

    [引用 user="Luis Afonso"]好的、但问题是什么? 可重入性。
    "线程":(我真的不喜欢端口如何与以太网 ISR 中的几乎所有内容一同提供、顺便说一下)
    以太网 ISR (除其他所有内容外、tcp_sent 回调基本上在这里)
    - Timer1 ISR - lwIPTimer 调用方和 tcp_output。 [/报价]

    以太网的中断矢量表中只有一个矢量。 这就是 EtherNet/MCU 的架构设计方式 我们目前无法对其进行任何更改。  

    [引用 USER="Luis Afonso")问题是 Timer1正在调用 tcp_output 并且其优先级高于以太网 ISR!
    从 Timer1_ISR 中删除了 tcp_output 并创建了与以太网 ISR 具有相同优先级的 Timer2_ISR 以调用 tcp_output。 仅用于测试。 这样、到目前为止代码的工作方式为"正常"[/quot]

     我还建议您更改 Timer1优先级。 但您似乎找到了更好的解决方案。 如果使用 Timer2是更可靠的解决方案、请稍后再报告并与社区分享。 我相信社区中的人会从您的解决方案中受益。

     我现在将关闭该线程。 如果您对解决方案有更多更新、请与我们分享。