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.

[参考译文] TMS320F28388D:TMS320F28388D lwip FreeRTOS 问题

Guru**** 2847400 points

Other Parts Discussed in Thread: TMS320F28388D, C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1587519/tms320f28388d-tms320f28388d-lwip-freertos-issue

器件型号: TMS320F28388D
主题: C2000WARE 中讨论的其他器件

您好、
我在运行 lwIP FreeRTOS 示例时也遇到问题。
我还没有找到解决方案、下面的相关链接没有帮助:
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1563127/tms320f28388d-lwip-with-freertos?keyMatch=lwip%20freertos&tisearch=universal_search

我发现在 TMS320F28388D 上运行 lwIP FreeRTOS 示例的唯一方法是使用 CCS 12.8。 我猜测如果我在 CCS 20.3.1 中安装了正确的编译器、这可能是有效的、但问题出在导入工程中、CCS 20.3.1 没有正确的编译器。

对于导入工程、我使用 ethernet_ipc_ex1_basic_c28x1 并更改了代码以保留 CPU1 行、例如 while(1); 在此处放置。 我认为该示例 ethernet_ipc_ex1_basic_c28x1 会初始化运行 lwIP 所需的正确引脚。

因此、我使用该 ethernet_ipc_ex1_basic_c28x1 工程作为 CPU1 的基础、还将该 enet_lwip_freertos 工程添加到了我的工作区中。 要调试和运行 lwIP ,我刷新了 CPU1, ethernet_ipc_ex1_basic_c28x1 选择了 CM enet_lwip_freertos . 我开始调试并运行 CPU1、然后运行 CM、但软件在断言时至少停止 6 次。

我还修改了 lwIP、以创建正确运行的 UDP 服务器。 为了测试接口、我开发了一个小型工具来连接 TMS320F28388D。 基本上、该工具会连接、发送消息、等待回复、然后断开连接。 该工具可以循环以 10ms 的频率多次发送相同的消息。

在服务器端 (TMS320F28388D)、它会接收该消息、打开或关闭 GPIO、然后将消息发送回客户端(我的工具)。 系统运行大约 30 分钟、然后 TMS320F28388D 执行相同的断言功能: vAssertCalled

有时我会停止我的客户端工具、等待大约 5 分钟、然后 TMS320F28388D 恢复、我可以再次从客户端工具发送消息。

我的主要问题是:

  1. 运行 TMS320F28388D lwIP FreeRTOS 示例的正确方法是什么?

  2. 使用我提到的基础设施、我期望系统从一开始就运行、而不命中断点 6 次。

附加信息:在连接接受中、我只保留对活动连接的引用、在主循环中、我清理不再使用的连接。 我假设 lwIP 应该管理此、但无论如何都要管理。

我需要官方基础设施或方法才能至少成功运行 TI lwIP FreeRTOS 示例。 我们也欢迎关于 TMS320F28388D 在大约 30 分钟后停止的建议。

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

    您好、

    因此、我使用该 ethernet_ipc_ex1_basic_c28x1 工程作为 CPU1 的基础、还将该工程添加 enet_lwip_freertos 到了我的工作区中。 要调试和运行 lwIP ,我刷新了 CPU1, ethernet_ipc_ex1_basic_c28x1 选择了 CM enet_lwip_freertos . 我开始调试并运行 CPU1、然后运行 CM、但软件在断言时至少停止 6 次。

    你能解释代码在哪里达到断言. 您能给我分享一下调用栈吗?

    ]运行 TMS320F28388D lwIP FreeRTOS 示例的正确方法是什么?

    你所做的方式是好的。 您还可以从 driverlib/f2838x/example/cm/ethernet 导入工程、并使用 ethernet_cm_config 在 CPU1 上编译和运行。

    您是否还可以在达到 Assert 后定义 Ethernet_debug 和共享 g_uiEnetStats。

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

    您好、
    Gouri、感谢您调查这个问题。
    我使用 CPU1 的另一个示例 (driverlib/f2838x/example/cm/ethernet) 运行了一些测试、并使用了 ethernet_cm_config。
    行为是相同的;它在置位时仍停止。 我还注意到、在未连接网络电缆的情况下启动两个内核 (CPU1 和 CM) 时、问题不会出现。
    但是、当我在连接网络电缆的情况下启动两个内核 (CPU1 和 CM) 时、它会在置位处停止。 在调试器中执行几个“播放“操作后、它就能保持正常运行。就像我提到的、在断言处大约有六个或更多个停止。
    例如、我让应用程序运行了大约 72 小时、每 10ms 发送一次 UDP 消息、直到我手动将其关闭、它才会冻结一次。
    但当我再次启动它时、也会出现同样的行为。
    我收集了调用堆栈信息和 g_uiEnetStats 变量;我附加了它在 Assert 处停止的一些图像。

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

    似乎任何不稳定性(例如插入或移除网络电缆)都会导致其在断言处停止。

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

    您好、

    我假设即使在带缓冲器的 Rx 通道初始化之前、它也必须面对一些传入的数据包。 您能确认一下吗?

    因此、它将进入名为 RBU(接收缓冲器不可用)的状态、这将生成中断。

    当前、软件在中断发生时重新初始化 Rx 通道。 因此、在这里我们从中断上下文调用临界区、这就是现在配置 CONFIG_ASSERT 的原因。 从 C2000ware 的下一版本开始、此问题将得到解决。

    您可以在发生时尝试禁用 RBU 中断、在 Rx 任务完成一次执行后尝试启用 Re。

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

    您好、

    我假设即使在具有缓冲区的 Rx 通道初始化之前、它也必须面对一些传入的数据包。 您能确认一下吗?

    我并不总是收到数据包、但 TMS320F28388D 连接到交换机、因此可能存在网络流量。

    您可以尝试在发生 RBU 中断时禁用 Re 中断、在 Rx 任务完成一次执行后启用 RBU。

    您能否提供补丁或在代码中指明如何执行此操作?

    我假设禁用的点在这里:

    IF ((Ethernet_DMA_CH0_STATUS_AIS |
                      Ethernet_DMA_CH0_STATUS_RBU)=
                      (HWREG (Ethernet_device_struct.baseAddresses.enet_base +
                      Ethernet_O_DMA_CH0_STATUS)&
                      (uint32_t)(Ethernet_DMA_CH0_STATUS_AIS |
                      Ethernet_DMA_CH0_STATUS_RBU))

      //在此处禁用

      Enet_driver_stats_INC (RBUinterrupt);
    }

    要启用、请执行以下操作:

    void RxTask (void *pvParameters)

     while (1)
     {
      if (xSemaphoreTake (RxSem、portMAX_DELAY)== pdTRUE)
      {
       Ethernet_removePacketsFromRxQueueCustom (
       &ethernet_device_struct.dmaObj.rxDma[ethernet_DMA_channel_NUM_0]、ethernet_completion_normal);

          //在此处启用
      }
     }
     }

    顺便说一下、目前我已注释掉 assert 函数中的断点、但如果出现另一个问题、我将没有调用栈的上下文。 最好是禁用/启用 RBU。

    void vAssertCalled(const char *文件、int 行)

     lastline = line;
     lastfile =(char *) file;
     //__asm(“ bkpt #0“);
    }

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

    您好、  

    您是对的。

    您能否提供补丁或在代码中指明如何执行此操作?

    补丁附加在此处。

    diff --git a/driver/ethernet.c b/driver/ethernet.c
    index a2e40df..5c31424 100644
    --- a/driver/ethernet.c
    +++ b/driver/ethernet.c
    @@ -693,55 +693,59 @@ interrupt void Ethernet_genericISRCustom(void)
                */
     
                 /* Upon RBU error, discard all previously received packets */
    -            if(Ethernet_device_struct.initConfig.pfcbDeletePackets != NULL)
    -                (*Ethernet_device_struct.initConfig.pfcbDeletePackets)();
    -
    -            rxChan =
    -               &Ethernet_device_struct.dmaObj.rxDma[ETHERNET_DMA_CHANNEL_NUM_0];
    -            txChan=
    -               &Ethernet_device_struct.dmaObj.txDma[ETHERNET_DMA_CHANNEL_NUM_0];
    -
    -            /*
    -            * Need to disable multiple interrupts, so protect the code to do so within
    -            * a global disable block (to prevent getting interrupted in between)
    -            */
    -
    -            if(NULL!= Ethernet_device_struct.ptrPlatformInterruptDisable)
    -            {
    -                (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
    -                    Ethernet_device_struct.interruptNum[
    -                        ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
    -
    -                (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
    -                    Ethernet_device_struct.interruptNum[
    -                        ETHERNET_GENERIC_INTERRUPT]);
    -            }
    -            /* verify we have full capacity in the descriptor queue */
    -            if(rxChan->descQueue.count < rxChan->descMax) {
    -              /* The queue is not at full capacity due to OOM errors.
    -              Try to fill it again */
    -                Ethernet_addPacketsIntoRxQueue(rxChan);
    -            }
    -
    -            Ethernet_initRxChannel(
    -                    &Ethernet_device_struct.initConfig.chInfo[ETHERNET_CH_DIR_RX][0]);
    -
    -            Ethernet_writeRxDescTailPointer(
    -                Ethernet_device_struct.baseAddresses.enet_base,
    -                0,
    -                (&Ethernet_device_struct.rxDesc[
    -                 ((uint32_t)ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL) *
    -                  (0 + (uint32_t)1U)]));
    -
    -            if(NULL!= Ethernet_device_struct.ptrPlatformInterruptEnable)
    -            {
    -                (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
    -                    Ethernet_device_struct.interruptNum[
    -                        ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
    -                (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
    -                    Ethernet_device_struct.interruptNum[
    -                        ETHERNET_GENERIC_INTERRUPT]);
    -            }
    +            // if(Ethernet_device_struct.initConfig.pfcbDeletePackets != NULL)
    +            //     (*Ethernet_device_struct.initConfig.pfcbDeletePackets)();
    +
    +            // rxChan =
    +            //    &Ethernet_device_struct.dmaObj.rxDma[ETHERNET_DMA_CHANNEL_NUM_0];
    +            // txChan=
    +            //    &Ethernet_device_struct.dmaObj.txDma[ETHERNET_DMA_CHANNEL_NUM_0];
    +
    +            // /*
    +            // * Need to disable multiple interrupts, so protect the code to do so within
    +            // * a global disable block (to prevent getting interrupted in between)
    +            // */
    +
    +            // if(NULL!= Ethernet_device_struct.ptrPlatformInterruptDisable)
    +            // {
    +            //     (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
    +            //         Ethernet_device_struct.interruptNum[
    +            //             ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
    +
    +            //     (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
    +            //         Ethernet_device_struct.interruptNum[
    +            //             ETHERNET_GENERIC_INTERRUPT]);
    +            // }
    +            // /* verify we have full capacity in the descriptor queue */
    +            // if(rxChan->descQueue.count < rxChan->descMax) {
    +            //   /* The queue is not at full capacity due to OOM errors.
    +            //   Try to fill it again */
    +            //     Ethernet_addPacketsIntoRxQueue(rxChan);
    +            // }
    +
    +            // Ethernet_initRxChannel(
    +            //         &Ethernet_device_struct.initConfig.chInfo[ETHERNET_CH_DIR_RX][0]);
    +
    +            // Ethernet_writeRxDescTailPointer(
    +            //     Ethernet_device_struct.baseAddresses.enet_base,
    +            //     0,
    +            //     (&Ethernet_device_struct.rxDesc[
    +            //      ((uint32_t)ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL) *
    +            //       (0 + (uint32_t)1U)]));
    +
    +            // if(NULL!= Ethernet_device_struct.ptrPlatformInterruptEnable)
    +            // {
    +            //     (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
    +            //         Ethernet_device_struct.interruptNum[
    +            //             ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
    +            //     (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
    +            //         Ethernet_device_struct.interruptNum[
    +            //             ETHERNET_GENERIC_INTERRUPT]);
    +            // }
    +
    +            Ethernet_disableDmaInterrupt(Ethernet_device_struct.baseAddresses.enet_base,
    +                                 0, (ETHERNET_DMA_CH0_INTERRUPT_ENABLE_AIE |
    +                                     ETHERNET_DMA_CH0_INTERRUPT_ENABLE_RBUE));
     
     
         }
    diff --git a/examples/enet_lwip_freertos/cm/enet_lwip_freertos.c b/examples/enet_lwip_freertos/cm/enet_lwip_freertos.c
    index f2caba6..3949e56 100644
    --- a/examples/enet_lwip_freertos/cm/enet_lwip_freertos.c
    +++ b/examples/enet_lwip_freertos/cm/enet_lwip_freertos.c
    @@ -546,6 +546,13 @@ void RxTask(void *pvParameters)
             {
                  Ethernet_removePacketsFromRxQueueCustom(
                     &Ethernet_device_struct.dmaObj.rxDma[ETHERNET_DMA_CHANNEL_NUM_0], ETHERNET_COMPLETION_NORMAL);
    +
    +            if((HWREG(EMAC_BASE + ETHERNET_O_DMA_CH0_INTERRUPT_ENABLE) & ETHERNET_DMA_CH0_INTERRUPT_ENABLE_RBUE) == 0U)
    +            {
    +                Ethernet_enableDmaInterrupt(EMAC_BASE,
    +                                 0, (ETHERNET_DMA_CH0_INTERRUPT_ENABLE_AIE |
    +                                     ETHERNET_DMA_CH0_INTERRUPT_ENABLE_RBUE));
    +            }
             } 
         }
     }