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.

[参考译文] TM4C129ENCPDT:以太网端口变得不可靠

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1322925/tm4c129encpdt-ethernet-port-becomes-unreliable

器件型号:TM4C129ENCPDT

您好!

我们有一个使用 TM4C129ENCPDT 的以太网网络产品。 我们需要找出原因来解决这个问题。

设备有时会在接收和传输以太网数据包方面变得不可靠。

我们有一个测试设备、能够不断通过以太网向其他设备发送测试数据包。 被测器件只需退回测试数据包、以便测试器件可以比较发送和接收的数据包数量。 如果这两个数字不匹配、则表示数据包丢失。

当问题发生时、我们发现在测试过程中有很多丢失的数据包。

一个有趣的现象是、在不重置器件(即固件重置)的情况下、我们可以从外部触发器件中的一个过程(通过命令)。 此过程将重置以太网端口。 此后、问题将被清除、并且不会检测到丢失的数据包。

问题似乎与固件无关、而与以太网控制器硬件有关。 我的问题是、为了防止固件出现以太网 MAC 内部可能会出现什么问题?

可以解决此问题的步骤如下:


InitializeEthernet()
{
   //
   //启用并重置以太网模块。
   //
   SysCtlPeripheralEnable (SYSCTL_Periph_EMAC0);
   SysCtlPeripheralEnable (SYSCTL_Periph_EPHY0);
   SysCtlPeripheralReset (SYSCTL_Periph_EMAC0);
   SysCtlPeripheralReset (SYSCTL_Periph_EPHY0);
   //
   //等待 MAC 准备就绪。
   //
   while (! SysCtlPeripheralReady (SYSCTL_Periph_EMAC0){
       WdogTemporyFeed ();
   }
   //
   //配置为与内部 PHY 一起使用。
   //
   EMACPHYConfigSet (EMAC0_BASE、(EMAC_PHY_TYPE_INTERNAL | EMAC_PHY_INT_MDIX_EN | EMAC_PHY_AN_100B_T_FULL_DUPLEX));
   //
   //重置 MAC 以锁存 PHY 配置。
   //
   EMACReset (EMAC0_BASE);
   //
   //初始化 MAC 并设置 DMA 模式。
   //
   EMACInit (EMAC0_BASE、SysClock、EMAC_BCONFIG_MISCD_BURST | EMAC_BCONFIG_PRIORY_FIXED、4、4、4 0);
   //
   //设置 MAC 配置选项。
   //
   EMACConfigSet (EMAC0_BASE、(EMAC_CONFIG_FULL_DUPLEX | EMAC_CONFIG_CHECKSUM_OFFLOAD   | EMAC_CONFIG_7BYTE_PREAMBLE |
                        EMAC_CONFIG_IF_GAP_96BITS |   EMAC_CONFIG_USE_MACADDR0 | EMAC_CONFIG_SA_FROM _描述符|
                        EMAC_CONFIG_BO_LIMIT_1024)、
                      (emac_mode_RX_store_forward | emac_mode_TX_store_forward | emac_mode_TX_threshold_64_Bytes |
                        EMAC_MODE_RX_THRESHOLD_64_BYTES)、0);
   //
   //初始化以太网 DMA 描述符。
   //
   InitDescriptors (EMAC0_BASE);
   //
   //使用其 MAC 地址对硬件进行编程(用于过滤)。
   //
   EMACAddrSet (EMAC0_BASE、0、macaddr);

   //
   //启用以太网 RX 数据包中断源。
   //
   EMACIntEnable (EMAC0_BASE、EMAC_INT_RECEIVE | EMAC_INT_PHY);

   SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
   GPIOPinTypeEthernetLED (GPIO_PORTF_BASE、GPIO_PIN_0 | GPIO_PIN_1);
   GPIOPinConfigure (GPIO_PF0_EN0LED0);
   GPIOPinConfigure (GPIO_PF1_EN0LED2);

   EMCPHYExtendedWrite (EMAC0_BASE、0、EPHY_LEDCR、EPHY_LEDCR_BLINKRATE_20Hz);
   EMCPHYExtendedWrite (EMAC0_BASE、0、EPHY_LEDCFG、EPHY_LEDCF_LED0_LINK | EPHY_LEDCF_LED2_RxTx);

   //驱动程序库不正确。 该位实际上控制 LED 指示灯的极性、
   //
   HWREG (EMAC0_BASE + EMAC_O_CC)|= EMAC_CC_ECEXT;

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

    问题似乎与固件无关、而与以太网控制器硬件有关。 我的问题是、为了防止固件出现以太网 MAC 内部可能会出现什么问题?

    可以解决此问题的步骤如下:

    [/报价]

    您好!

     我认为 ,初始化 EMAC 时的 InitializeEthernet()与通过外部命令再次调用时的情况相同。 是这样吗?

     能否在运行相同固件的 LaunchPad 上重复同样的问题? 是否看到丢失的数据包?

     如果 LaunchPad 可以工作、那么您能否比较以太网接口的原理图是否有差异? 您是否遵循了 TM4C129系统设计指南第4.1节?  https://www.ti.com/lit/pdf/spma056

     

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

    尊敬的 Charles:

    是的、这与启动时和通过外部命令调用的过程相同。

    由于硬件差异太大、我无法在 LaunchPad 上运行固件。 我计划尝试使用命令调用的过程来确定这是与 MAC 还是 PHY 有关。 由于该问题很少发生、因此可能需要一些时间才能获得一些结果。

    同时、如果对以下问题有答案、此时将会有所帮助:

    MAC/PHY 是否可能卡在某种显示此类症状的错误状态?  

    部分更新:

    看来这个问题更多地与以太网发送端有关。 该设备具有音频流功能。 该问题导致来自此设备并在其他网络设备上播放的流式传输音频听起来不可靠、这意味着某些音频数据包丢失(未发送)。

    此致、

    天磊

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于硬件差异太大,我无法在 LaunchPad 上运行固件。 我计划尝试使用命令调用的过程来确定这是与 MAC 还是 PHY 有关。 由于问题很少发生,因此可能需要一些时间才能获得一些结果。

    您好,天磊,

     我不确定为什么数据包会丢失。 Wireshark 显示什么?  

     只是为了确保它不是网络问题、您可以尝试使用其他网络吗? 另一台交换机或路由器? 您看到同样的问题吗? 如何使用交叉电缆将 MCU 直接连接到音频设备? 您看到同样的问题吗?

    是否可能 MAC/PHY 卡在某种显示此症状的错误状态?  [/报价]

    您只是在丢失数据包吗? 换言之、在某些数据包丢失后、EMAC 将继续发送更多数据包。 是这样吗? 这意味着 MAC/PHY 未卡住。 如果卡滞、我认为传输将完全停止。  

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

    尊敬的 Charles:

    该问题显示在不同的网络上。 此外、我们有多款产品销量较高、但这一问题仅发生在一款产品上。 因此、我确信数据包会丢失在设备内部、而不是来自网络。 破解声音意味着数据包连续发送、有时会丢失一些数据包。

    音频包由计时器调度。 由于该问题只能通过复位 MAC 或 PHY 来解决、因此这意味着它不是调度问题。

    我的计划是隔离出错的是 MAC 还是 PHY。 我会随时向您通报最新情况。

    此致、

    天磊

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

    您好,天磊,

     是的、请在您的调查中随时告知我。 您能否确认、一旦您发送命令以重新初始化 EMAC/PHY、传输将无限期地继续而不丢弃数据包?

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

    在重新初始化 EMAC/PHY 后、器件恢复正常。

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

    好的。 请使用 Wireshark 检查第一次初始化与第二次初始化之间网络流量的任何差异。 您能否在同一设计的另一个板上重复同样的问题。 如果问题仅发生在特定电路板上、可以通过这种方法来隔离。  

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

    我们在多个板上看到了该问题。 客户告知此类设备有时从网络中丢失。 由于监控数据包丢失了回复数据包、这可能是同一个问题。

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

    尊敬的 Charles:

    我在这个问题上取得了一些进展。 此问题与 PHY 无关。 当出现问题时、我使用了此命令来复位 PHY、但该命令没有帮助。

    问题很可能与 Tx 描述符的使用有关。 虽然在实际操作中很难重现问题、但我找到了一种触发几乎相同症状的问题的方法。 问题的根源很可能是相同的。

    我之所以触发该问题、是为了破坏 Tx 描述符索引。  该索引(g_ui32TxDescIndex)的常规用法如下

    #define NUM_TX_DODERS 16

    tEMACDMADescriptor g_psTxDescriptor[NUM_TX_描述 符]__attribute__(已对齐(16));

    int32_t
    PacketTransmit (uint8_t * pui8Buf、int32_t i32BufLen)
    {
       uint32_t next=g_ui32TxDescIndex + 1;
       if (next == NUM_TX_DODERS){
          下一个=0;
       }

       tEMACDMADescriptor *desc=g_psTxDescriptor + next;

       while (desc->ui32CtrlStatus 和   DES0_TX_CTRL_own)
       {   }

       desc -> ui32Count =(uint32_t) i32BufLen > 68? i32BufLen:68;
       desc->pvBuffer1 = pui8Buf;
       DESC->ui32CtrlStatus =(DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG |
                         DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_IP_ALL_CKHSUMS |
                         DES0_TX_CTRL_Chained | DES0_TX_CTRL_own);

       G_ui32TxDescIndex=下一个;

       EMACTxDMAPollDemand (EMAC0_BASE);
       返回(i32BufLen);

    这是当远程命令调用以下过程时我会中断它的方法。


    TxDescriptor IndexChange ()
    {
       G_ui32TxDescIndex += 15;
       if (g_ui32TxDescIndex >= NUM_TX_DODERS){
          G_ui32TxDescIndex -= NUM_TX_描述 符;
       }

    上述过程有意强制索引向后移动1。 这就产生了一个条件、即当发送下一个数据包时、它被放入 DMA 控制器无法找到的错误描述符中、并且这个数据包会卡在描述符中。 但是、next14数据包将正常发送、因为它们使用的描述符将与 DMA 控制器匹配。 由于索引环回了、因此将发送第15个数据包、然后是第一个阻塞的数据包。

    如果我的上述理解是正确的、那么问题应该在发送15个数据包后自行恢复。 但事实并非如此。 此问题将在注入错误后永久存在。

    但是、我可以通过触发以下过程来清除此问题:


    TxDescriptor Reset()
    {
       uint32_t ui32Loop;
       tEMACDMADescriptor *描述符;
       for (ui32Loop = 0;ui32Loop < NUM_TX_DERS;ui32Loop++){
          DESC=g_psTxDescriptor + ui32Loop;
          DESC->ui32CtrlStatus =(DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG |
                            DES0_TX_CTRL_INTERRUPT | DES0_TX_CTRL_LINKED |
                            DES0_TX_CTRL_IP_ALL_CKHSUMS);
       }

    此时、我无法弄清楚 Tx 描述符索引在实际操作中是如何中断的。 调用 PacketTransmit()函数时,中断将始终被禁用。 但是,如果我能找到一个简单的方法来解决问题,这也可能是我们的一个解决办法。 因此、以下问题的答案对我来说是导入的:

    为什么注入的错误(通过中断 Tx 描述符索引)无法自行恢复?

    谢谢

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

    您好,天磊,

     您能否告诉我您是否正在使用 TI-RTOS NDK? PacketTransmit 在哪个文件中? 是您自己的代码吗? 如果您使用的是 NDK、您能否看一下这篇文章、看看它是否适用于您。 如果您使用 NDK、该帖子似乎描述了一个与您的问题相比非常类似的问题。  

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/710149/rtos-tm4c1290ncpdt-ndk-in-ti-rtos-works-intermittently-after-being-shutdown-and-restarted

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

    尊敬的 Charles:

    我不使用 TI-RTOS NDK、 这是一个裸机项目。 该帖子似乎与我们的问题无关。

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

    您好,天磊,

     您是否使用任何 TCP/IP 堆栈? 如果是、是哪一个?   PacketTransmit 你自己的代码?  

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

    尊敬的 Charles:

    我们不使用 TCP/IP 堆栈。 PacketTransmit 从某个地方复制而来、我不记得可能是从 Tivaware 示例项目的上复制到了哪里。

    现在我有了更多的进步、我可以解释相关行为。

    问题的根源(在我之前的文章中已确认是真实问题还是引发问题)是有一些未释放的 Tx DMA 描述符(总是设置 DES0_TX_CTRL_own)卡在描述符链中。 未释放描述符的原因未知。

    总共有16个 Tx 描述符。 这些描述符在循环中链接在一起。 假设第10个描述符未释放、并且当前 g_ui32TxDescIndex 与 DMA 控制器的当前 Tx 描述符指针同步。 在使用第9个描述符之前、数据包的传输会正常进行。 此时、将发送新的数据包、并且还将发送卡在第10个描述符中的数据包。 在此之后、DMA 控制器指向第11个描述符、但 g_ui32TxDescIndex 仅递增一次、因此它将指向第10个描述符。 下一次数据包传输将使用第10个描述符、但由于位置与 DMA 不匹配、因此不会发送该数据包。 结果是第10个描述符再次卡住。 因此、任何使用第10个描述符的数据包都将始终延迟16个数据包、更糟糕的是、在数据包发送时、数据包数据可能已被代码的其他部分更改。

    这就是为什么此类情况永远无法恢复的原因、并在测试中显示丢失的数据包、以及在流式传输音频时出现裂纹声音。

    目前、我有一个被动的问题解决方案。 每次发送数据包时、软件都会检查索引是否与 DMA 指针不同步、如果是、则校正索引。

    int32_t
    PacketTransmit (uint8_t * pui8Buf、int32_t i32BufLen)
    {
       uint32_t next=g_ui32TxDescIndex + 1;
       if (next == NUM_TX_DODERS){
          下一个=0;
       }

       tEMACDMADescriptor *desc=g_psTxDescriptor + next;

       ///未释放 Tx 脚本的被动解决方案
       tEMACDMA 描述符*CURRENT=EMACTxDMACurrentDescriptorGet (EMAC0_BASE);
       if (desc->DES3.plink == CURRENT){
          G_ui32TxDescIndex=下一个;
          返回(0);
       }

       while (desc->ui32CtrlStatus 和   DES0_TX_CTRL_own)
       {
       }

       desc -> ui32Count =(uint32_t) i32BufLen > 68? i32BufLen:68;
       desc->pvBuffer1 = pui8Buf;
       DESC->ui32CtrlStatus =(DES0_TX_CTRL_LAST_SEG | DES0_TX_CTRL_FIRST_SEG |
                         DES0_TX_CTRL_IP_ALL_CKHSUMS |
                         DES0_TX_CTRL_Chained | DES0_TX_CTRL_own);

       G_ui32TxDescIndex=下一个;

       EMACTxDMAPollDemand (EMAC0_BASE);
       返回(i32BufLen);

    我将继续调查导致描述符未发布的原因。

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们不使用 TCP/IP 堆栈。 PacketTransmit 是从某个地方复制的,我不记得可能是从 Tivaware 示例项目的上复制到了哪里。

    您好,天磊,

     之前、我在搜索 PacketTransmit、在 TivaWare 库中找不到任何引用。 通常、使用 lwIP 之类的 TCP/IP 堆栈从硬件中进行提取、并根据 TCP/IP 协议管理连接的主机之间的数据传输。 如果您正在自行管理描述符、则很难进行诊断 、因为您正在像处理链接的描述符那样直接处理 EMAC 硬件。 CPU 和 DMA 之间可能存在一些关于谁拥有描述符的竞态条件。 我想这就是您最有可能面临的问题。  

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

    尊敬的 Charles:

    是否有可以参考的标准 EMAC 处理代码(未与 TCP/IP 绑定)?

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

    您好,天磊,

     我建议您查看 C:\ti\TivaWare_C_Series-2.2.0.295\third_party\lwip-1.4.1\ports\Tiva-tm4c129\netif\Tiva_tm4c129.c 文件。 该文件处理 TX 和 RX 描述符管理以及各种器件驱动程序以接收和发送以太网帧。  

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

    尊敬的 Charles:

    找到问题的原因。 我们有一个定义的宏、通过将 BASEPRI 寄存器设置为特定的值来禁用中断。 不过、我们使用的值恰好为零、这意味着屏蔽功能被禁用、该宏不会有任何效果。 这会导致函数 PacketTransmit 不受保护,并随着时间的推移重新进入。

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

    您好,天磊,

     超级棒! 非常高兴您自己解决了该问题。  

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

    您好、Charles、感谢您的帮助。