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/TM4C129EKCPDT:TivaC NDK TCP:CAN#39;t Receive large packets ACK PSH ACK is not reveic

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/743122/rtos-tm4c129ekcpdt-tivac-ndk-tcp-can-t-receive-large-packets-ack-psh-ack-is-not-reveice

器件型号:TM4C129EKCPDT
Thread 中讨论的其他器件:SYSBIOSEK-TM4C1294XL

工具/软件:TI-RTOS

 较大的 TCP 数据包>1460,发送 ACK 和 PSH ACK 不会被审查  

NDK 为  NDK_2_25_00_09

代码就是您的示例

这    不能解决问题  

https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/355/p/497052/2108344#2108344

 我认为这是一个错误。

TI 的代码是:


设置为  

Wireshark 的数据包


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

    目标的状态是什么? 您能否暂停并检查 Tools->ROV->SysMin -> outputBuf 以查看是否有任何内容。 也可以是 ROV->BIOS->Scan for Errors。 CCS 控制台上的任何内容(如果目标向其清除任何文本)。

    这是否在开箱即用的 TCP 回波上(仅在上面突出显示的缓冲区设置)? 您在主机端发送了什么?

    Todd
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的目标是我的代码可以 reve1800位数据包。 我在 TCP/IP 和 TI-RTOS 方面很好。 我的代码是 OK 缓冲区是 OK。 我认为我的配置或 NDK 的 somewrong 有问题。 希望您为 TCP 的 revecie 1800位数据包提供一个代码。 TCP WIN >2920。
    我认为这是 NDK 错误,它不支持数据包的1460多个数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

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

    您好!

    您能否为 我附加修改过的 EMACSnow.c 以查看。

    谢谢、
    Gerardo

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    /*
     *版权所有(c) 2014-2015 Texas Instruments Incorporated
     *保留所有权利。
     *
     *以源代码和二进制形式重新分发和使用、有无
     *如果满足以下条件、则允许进行修改
     符合*:
     *
     ** 源代码的重新分发必须保留上述版权
     *  注意、此条件列表和以下免责声明。
     *
     * *二进制形式的再发行必须复制上述版权
     *  请注意、中的此条件列表和以下免责声明
     *  随分发提供的文档和/或其他材料。
     *
     * *德州仪器公司的名称和名称均不相同
     *  其贡献者可用于认可或推广衍生产品
     *  未经特定的事先书面许可。
     *
     *本软件由版权所有者和贡献者"按原样"提供
     *以及任何明示或暗示的保证、包括但不限于:
     *特定适销性和适用性的隐含保证
     *不承认目的。 在任何情况下、版权所有者不得或
     *派遣国应对任何直接、间接、偶然、特殊、
     *典型或必然的损害(包括但不限于
     *采购替代货物或服务;丧失使用、数据或利润;
     *或业务中断)、无论原因是什么以及任何责任理论、
     *无论是合同、严格责任还是侵权行为(包括疏忽或)
     *否则)因使用本软件而以任何方式产生、
     *即使被告知可能会发生此类损坏。
     *
    /*
     * ==== EMACSnow.c ====
     * 此驱动程序当前仅支持1个 EMACSnow 端口。 未来的发展
     * 当需要多个端口时,此驱动程序需要移动所有端口
     * EMACSnow_Data 字段放入 EMACSnow_Object 结构中。 API 所需的所有功能
     * 通过 NETIF_DEVICE 中的 pvt_data 字段访问字段
     * 传入。 必须更改 ROV 以支持更改。
     * NETIF_DEVICE 结构也应进入 EMACSnow_Object。
     *
     * 由于对的影响、目前未进行此更改
     * 代码的复杂性。
     *
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    /*特定于设备的驱动程序包括*/
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    /*设备的名称。 *
    #define ETHERNET_NAME "eth0"
    #ifndef NUM_RX_descriptors
    #define NUM_RX_descriptors 4.
    #endif
    #ifndef NUM_TX_descriptors
    #define NUM_TX_descriptors 4.
    #endif
    #ifndef EMAC_PHY_CONFIG
    #define EMAC_PHY_CONFIG      (EMAC_PHY_TYPE_INTERNAL |            \
                     EMAC_PHY_INT_MDIX_EN |             \
                     EMAC_PHY_AN_100B_T_FULL_DUPLEX)
    #endif
    uint32_t g_ulStatus;
    bool enablePrefetch = false;
    /******** /
    针对 PHY 问题的/*调试计数器           *
    /******** /
    volatile unsigned phyint Counter[3]={0、0、0};
    静态空 EMACSnow_handleRx();
    静态空 EMACSnow_processTransented();
    /*
     * 包含 DMA 描述符的 Helper 结构及其当前引用的 pbuf
      将*更改为。
     *
    typedef 结构{
     tEMACDMADescriptor Desc;
     PBM_Handle hPkt;
    } tDescriptor;
    typedef 结构{
      tDescriptor *pDescriptionors;
      uint32_t   ulNumDescs;
      uint32_t   ulWrite;
      uint32_t   ulRead;
    }描述符列表;
    /*
     *此接口的私有数据的全局变量。  所需的时间
     *中断处理程序在之外访问此信息
     * lwIP 主题的上下文。
     *
    静态 tDescriptor g_pTxDescriptionor[NUM_TX_descriptor];
    静态 tDescriptor g_pRxDescriptors [NUM_RX_descriptor];
    静态 tDescriptionList g_TxDescList ={
      G_pTxDescriptors、NUM_TX_descriptors、0、0
    };
    静态 tDescriptionList g_RxDescList ={
      G_pRxDescriptors、NUM_RX_descriptors、0、0
    };
    /*用于 Snowflake 实施的 EMAC 功能表*/
    CONST EMAC_FxnTable EMACSnow_fxnTable ={
        EMACSnow_init、
        EMACSnow_isLinkUp
    };
    /*需要应用程序来提供此变量*/
    extern EMAC_Config EMAC_CONFIG;
    /*
     * 该结构用于存储 EMACSnow 控制器的私有数据。
     *
    typedef 结构{
      STKEVENT_Handle hEvent;
      PBMQ        PBMQ_TX;
      PBMQ        PBMQ_Rx;
      uint32_t      rxCount;
      uint32_t      rxDroipped;
      uint32_t      txSent;
      uint32_t      已压降;
      uint32_t      异常;
      uint32_t      isrCount;
      uint32_t      LinkUp;
      tDescriptionorList *pTxDescList;
      tDescriptionorList *pRxDescList;
    } EMACSnow_Data;
    /*仅支持一个 EMACSnow 设备*/
    静态 EMACSnow_Data EMACSnow_Private;
    静态易失性 bool EMACSnow_initialized = false;
    #define PHY_PHY_ADDR 1.
    /*
     * ==== signalLinkChange ====
     * 根据 LinkUp 参数向堆栈发送信号。
     *
    静态空 signalLinkChange (STKEVENT_Handle hEvent、uint32_t LinkUp、
        unsigned int 标志)
      if (LinkUp){
        /*向堆栈发出链路已启动的信号*/
        STKEVENT_SIGNAL (hEvent、STKEVENT_LinkUp、FLAG);
      }
      否则{
        /*向堆栈发出链路断开的信号*/
        STKEVENT_SIGNAL (hEvent、STKEVENT_linkdown、flag);
      }
    /*
     * ==== EMACSnow_processPendingTx ===
     *
    静态空 EMACSnow_processPendingTx()
      uint8_t   *pbuffer;
      uint32_t   len;
      PBM_Handle  hPkt;
      tDescriptor *pDesc;
      /*
       * 如果有待处理的数据包,请发送一个。
       * 否则退出循环。
       *
      hPktt = PBMQ_DEQ (&EMACSnow_Private。PBMQ_TX);
      if (hPkt!= NULL){
        PDESC =&(EMACSnow_Private。pTxDescList->pDescriptors [EMACSnow_Private。pTxDescList->ulWrite]);
        if (pDESC->hPkt){
          PBM_FREE (hPktt);
          EMACSnow_Private.txDroipped++;
          返回;
        }
        /*获取指向缓冲区的指针和长度*/
        pbuffer = PBM_getDataBuffer (hPktt)+ PBM_getDataOffset (hPktt);
        len = PBM_getValidLen (hPktt);
        /*填入缓冲区指针和长度*/
        pDESC->DESC.ui32Count = len;
        pDESC->DESC.pvBuffer1 = pbuffer;
        pDESC->DESC.ui32CtrlStatus = DES0_TX_CTRL_FIRST_SEG;
        pDESC->DESC.ui32CtrlStatus |=(/*DES0_TX_CTRL_IP_ALL_CKHSUMS |*/ DES0_TX_CTRL_CHARGERS);
        pDesc->Desc.ui32CtrlStatus |=(DES0_TX_CTRL_LAST_SEG |
                        DES0_TX_CTRL_INTERRUPT);
        EMACSnow_Private .pTxDescList->ulWrite++;
        if (EMACSnow_Private。pTxDescList->ulWrite = NUM_TX_descriptors){
          EMACSnow_Private .pTxDescList->ulWrite = 0;
        }
        pDESC->hPktt = hPkt;
        pDESC->DESC.ui32CtrlStatus |= DES0_TX_CTRL_own;
        EMACSnow_Private.txSent++;
        EMACTxDMAPolland (EMAC0_BASE);
      }
      返回;
    /*
     * ==== EMACSnow_handlePackets ===
     *
    静态空 EMACSnow_handlePackets (UARg arg0、UARg arg1)
      Log_Print1 (Diags_User1、"EMACSnow_handlePackets handling packets handling packets status = 0x%x"、g_ulStatus);
      /*处理发送 DMA 列表,释放所有已有的缓冲区
       *自我们的最后一个中断后发出。
       *
      if (g_ulStatus 和 EMAC_INT_Transmit){
        log_print0 (Diags_User1、"EMACSnow_handlePackets Tx 一个...");
        EMACSnow_processTransente();
      }
      /*
       *处理接收 DMA 列表并传递所有成功接收的数据包
       *堆栈上。  我们还在接收器具有的情况下调用此函数
       由于接收函数将尝试执行此操作、因此由于缺少缓冲区而导致*挂起
       *为没有 pbuf 的描述符条目分配新的 pbuf。
       *
      IF (g_ulStatus &(EMAC_INT_Receive | EMAC_INT_RX_NO_buffer |)
        EMAC_INT_RX_STOPPED){
        log_print0 (Diags_User1、"EMACSnow_handlePackets Rx 一个...);
        EMACSnow_handleRx();
      }
      log_print0 (Diags_User1、"EMACSnow_handlePackets 重新启用外设...");
      EMACIntEnable (EMAC0_BASE、(EMAC_INT_Receive | EMAC_INT_transmit |
                EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_buffer |
                EMAC_INT_RX_STOPPED | EMAC_INT_PHY));
    /*
     * ==== EMACSnow_processTransenter====
     *
    静态空 EMACSnow_processTransente()
      tDescriptor *pDesc;
      uint32_t   ulNumDescs;
      /*
       *在我们检查了所有描述符或到达之前,请查看列表
       *编写指针或查找硬件仍在工作的描述符
       *打开。
       *
      对于(ulNumDescs = 0;ulNumDescs < NUM_TX_descriptor;ulNumDescs++){
        pDesc =&(EMACSnow_prival.pTxDescList->pDescriptors [EMACSnow_Private .pTxDescList->ulRead]);
        /*是否传输了与此描述符相关联的缓冲区? *
        if (pDESC->DESC.ui32CtrlStatus & DES0_TX_CTRL_own){
          /*否-我们已完成。 *
          中断;
        }
        /*此描述符是否附加了缓冲区? *
        if (pDESC->hPkt){
          /*是-如果没有标记为中间 pbuf、请释放它*/
          if (!((uint32_t)(pDESC->hPktt)& 1)){
            PBM_FREE (pDesc->hPktt);
          }
          pDESC->hPktt =空;
        }
        否则{
          /*如果描述符没有缓冲区,我们就完成了。 *
          中断;
        }
        /*继续到下一个描述符。 *
        EMACSnow_Private .pTxDescList->ulRad++;
        if (EMACSnow_Private。pTxDescList->ulRead = NUM_TX_descriptors){
          EMACSnow_Private .pTxDescList->ulRead = 0;
        }
      }
    /*
     * ==== EMACSnow_primeRx ===
     *
    静态空 EMACSnow_primeRx (PBM_Handle hPkt, tDescriptor *desc)
      DESC->hPktt = hPkt;
      DESC->DESC.ui32Count = DES1_RX_CTRL_chained;
      /*我们有一个缓冲区,所以填入有效载荷指针和大小。 *
      DESC->DESC.pvBuffer1 = PBM_getDataBuffer (hPktt)+ PBM_getDataOffset (hPktt);
      DESC->DESC.ui32Count |=(ETH_MAX_PAYLOAD << DES1_RX_CTRL_BUFF1_SIZE);
      /*将此描述符返回到硬件*/
      DESC->DESC.ui32CtrlStatus = DES0_RX_CTRL_own;
    /*
     * ==== EMACSnow_handleRx ===
     *
    静态空 EMACSnow_handleRx()
      PBM_Handle    hPkt;
      PBM_Handle    hPktNew;
      内部32_t      Len;
      tDescriptionorList *pDescList;
      uint32_t      ulDescEnd;
      /*获取指向接收描述符列表的指针。 *
      pDescList = EMACSnow_Private。pRxDescList;
      /*确定描述符列表的开始和结束位置*/
      ulDescEnd = pDescList->ulRead? (pDescList->ulRead -1):(pDescList->ulNumDescs-1);
      /*逐步浏览标记为 CPU 注意的描述符。 *
      while (pDescList->ulRead!= ulDescEnd){
        /*当前描述符是否附加了缓冲区? *
        hPkt=pDescList->pDescriptor[pDescList->ulRead].hPkt;
        if (hPktt){
          /*确定主机是否已填充。 *
          if (pDescList->pDescriptor[pDescList->ulRead].Desc.ui32CtrlStatus &
            DES0_RX_CTRL_own){
           /* DMA 引擎仍然拥有描述符,因此我们完成了。 *
           中断;
          }
          /*是-帧是否包含错误? *
          if (pDescList->pDescriptor[pDescList->ulRead].Desc.ui32CtrlStatus &
            DES0_RX_STAT_ERR){
            /*
             * 这是一个坏帧、因此请丢弃它并更新相关的帧
             * 统计数据。
             *
            LOG_ERR0 ("EMACSnow_handleRx:DES0_RX_STAT_ERR");
            EMACSnow_Private。rxDroipped++;
            EMACSnow_primeRx (hPkt,&(pDescList->pDescriptors [pDescList->ulRead]);
            pDescList->ulRad++;
            中断;
          }
          否则{
            /*为此描述符分配新的缓冲区*/
            hPktNew = PBM_alloc (ETH_MAX_PAYLOAD);
            if (hPktNew == NULL){
              /*
               * 将数据包保留在描述符中并归驱动程序所有。
               * 在下一个中断发生时处理。
               *
              中断;
            }
            /*这是一个很好的帧,所以将它向上传递到栈中。 *
            len =(pDescList->pDescriptor[pDescList->ulRead].Desc.ui32CtrlStatus &
               DES0_RX_STAT_FRAME_LENGTH_M)>> DES0_RX_STAT_FRAME_LENGTH_S;
            /*删除 CRC */
            PBM_setValidLen (hPkt, len - 4);
            /*
             * 将数据包放置到要在中处理的接收队列中
             * EMACSnow_pkt_service 函数(由调用
             * NDK 堆栈)。
             *
            PBMQ_enq (&EMACSnow_Private。PBMQ_Rx、hPktt);
            log_print2 (Diags_User2、"EMACSnow_handleRx:排队的整数数据包0x%x、长度=%d"、
              (Iarg) hpkt, len -4;
            /*更新内部统计信息*/
            EMACSnow_Private。rxCount++;
            /*
             * 通知暂挂 Rx 以太网数据包的 NDK 堆栈和
             * 它是由外部事件触发的。
             *
            STKEVENT_SIGNAL (EMACSnow_Private。hEvent、STKEVENT_Ethernet、1);
            /*为将来的数据包备份接收描述符*/
            EMACSnow_primeRx (hPktNew、
                     &(pDescList->pDescriptor[pDescList->ulRead]);
          }
        }
        /*继续到链中的下一个描述符,并小心换行。 *
        pDescList->ulRad++;
        if (pDescList->ulRead =pDescList->ulNumDescs){
          pDescList->ulRead = 0;
        }
      }
    /*
     * ==== EMACSnow_processPhyInterrupt ===
     *
    空 EMACSnow_processPhyInterrupt ()
      uint16_t 的值、状态;
      uint32_t config、mode、rxMaxFrameSize;
      /*
       *读取 PHY 中断状态。  这将清除所有中断源。
       *请注意、我们仅在 EPHY_MISR1中启用源、因此我们不启用
       *读取 EPHY_MISR2。
       *
      值= EMAC0_BASE、PHY_PHY_ADDR、EPHY_MISR1);
      /*读取当前 PHY 状态。 *
      STATUS = EMAPPHYREAD (EMAC0_BASE、PHY_PHY_ADDR、EPHY_STS);
      /*链接状态是否已更改? *
      if (value & EPHY_MISR1_LINKSTAT){
        /*现在链接是上行还是下行? *
        if (status & EPHY_STS_LINK){
          EMACSnow_Private。LinkUp =真;
        }
        否则{
          EMACSnow_Private。LinkUp = false;
        }
        /*针对此链路状态变化向堆栈发出信号(来自 ISR)*/
        signalLinkChange (EMACSnow_private.hEvent、EMACSnow_private.LinkUp、1);
      }
      /*速度或双工状态是否已更改? *
      if (value &(EPHY_MISR1_SPEED | EPHY_MISR1_SPEED | EPHY_MISR1_ANC){
        /*获取当前 MAC 配置。 *
        EMACConfigGet (EMAC0_BASE、(uint32_t *)&config、(uint32_t *)&mode、
                (uint32_t *)&rxMaxFrameSize);
        /*接口目前的运行速度是多少?
         *
        if (status & EPHY_STS_SPEED){
          /*选择10Mbps */
          Config &=~EMAC_CONFIG_100Mbps;
        }
        否则{
          /*选择100Mbps */
          config |= EMAC_CONFIG_100Mbps;
        }
        /*我们是处于全双工还是半双工模式? *
        if (status & EPHY_STS_DUPLEX){
          /*全双工。 *
          config |= EMAC_CONFIG_FULL_DUPLEX;
        }
        否则{
          /*半双工。 *
          Config &=~EMAC_CONFIG_FULL_DUPLEX;
        }
        /*重新配置 MAC */
        EMACConfigSet (EMAC0_BASE、CONFIG、MODE、rxMaxFrameSize);
      }
    /*
     * ==== EMACSnow_hwiIntFxn ===
     *
    void EMACSnow_hwiIntFxn (UARg 回调)
      EMACSnow_Object *对象=(EMACSnow_Object *)(EMAC_config.object);
      uint32_t status;
      /*检查链接状态*/
      STATUS =(EMAPPHYREAD (EMAC0_BASE、0、EPHY_BMSR)& EPHY_BMRS_LINKSTAT);
      /*如果链路状态更改、则向堆栈发出信号*/
      if (status!= EMACSnow_Private。LinkUp){
        signalLinkChange (EMACSnow_private.hEvent、status、1);
      }
      /*设置链接状态*/
      EMACSnow_Private。LinkUp =状态;
      EMACSnow_Private。isrCount++;
      /*读取和清除中断。 *
      STATUS = EMACIntStatus (EMAC0_BASE、TRUE);
      EMACIntClear (EMAC0_BASE、STATUS);
      /*
       * 禁用以太网中断。  因为中断尚未中断
       * 已处理,它们不会被置位。  以太网处理它们之后
        中断、它将重新启用中断。
       *
      EMACIntDisable (EMAC0_BASE、(EMAC_INT_Receive | EMAC_INT_transmit |
               EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_buffer |
               EMAC_INT_RX_STOPPED | EMAC_INT_PHY));
      if (status & EMAC_INT_NORMAL){
        EMACSnow_Private。异常 Ints++;
      }
      G_ulStatus =状态;
      if (status & EMAC_INT_PHY){
        EMACSnow_processPhyInterrupt ();
      }
      Log_Print1 (Diags_User1、"EMACSnow_hwiIntFxn 过帐 Swi 状态= 0x%x"、g_ulStatus);
      /*让 Swi 处理传入的数据包并重新启用外设*/
      Swi_post (object->swi);
    /*
     * ==== EMACSnow_emacStart ===
     * 该函数用于初始化和启动 EMACSnow
     控制器 和设备。
     *
    int EMACSnow_emacStart (struct NETIF_DEVICE_PTR_NET_DEVICE)
      uint16_t 值;
      EMACSnow_Object *对象=(EMACSnow_Object *)(EMAC_config.object);
      EMACSnow_HWAttrs * hwAttrs =(EMACSnow_HWAttrs *)(EMAC_config.hwAttrs);
      Hwi_Params HwiParams;
      ERROR_Block EB;
      uint32 ui32FlashConf;
      /*
       * 创建处理传入数据包的 Swi。
       * 采用默认参数。
       *
      ERROR_INIT (&EB);
      object->swi = swi_create (EMACSnow_handlePackets、
                   空,&b);
      if (object->swi =NULL){
        log_error0 ("EMACSnow_emacStart:SWI_create failed");
        返回(-1);
      }
      /*创建硬件中断*/
      Hwi_Params_init (hwiParams);
      hwParams.priority = hwAttrs->intPriority;
      object->hwi = hwi_create (hwAttrs->intNum、EMACSnow_hwiIntFxn、
          hwiParams、&EB);
      if (object->hwi == NULL){
        log_error0 ("EMACSnow_emacStart:Hwi_create failed");
        返回(-1);
      }
      /*清除可能被置位的任何杂散 PHY 中断。 *
      值= EMAC0_BASE、PHY_PHY_ADDR、EPHY_MISR1);
      值= EMAC0_BASE、PHY_PHY_ADDR、EPHY_MISR2);
      /*在 PHY 中配置并启用链路状态更改中断。 *
      值= EMAC0_BASE、PHY_PHY_ADDR、EPHY_SCR);
      值|=(EPHY_SCR_INTEN_EXT | EPHY_SCR_INTOE_EXT);
      EMAPPHYWrite (EMAC0_BASE、PHY_PHY_ADDR、EPHY_SCR、VALUE);
      EMACPHYWrite (EMAC0_BASE、PHY_PHY_ADDR、EPHY_MISR1、(EPHY_MISR1_LINKSTATEN |
             EPHY_MISR1_SPEEDEN | EPHY_MISR1_DUPLEXMEN | EPHY_MISR1_ANCEN);
      HWREG (EMAC0_BASE + EMAC_O_CC)|= EMAC_CC_POL;
      /*读取 PHY 中断状态以清除任何杂散事件。 *
      值= EMAC0_BASE、PHY_PHY_ADDR、EPHY_MISR1);
      /*
       * 设置 MAC 过滤选项。  我们接收所有广播和多播
       数据 包以及专门为我们寻址的数据包。
       *
      EMACFrameFilterSet (EMAC0_BASE、(EMAC_FRMFILTER_HASH_AND_Perfect |
                EMAC_FRMFILTER_PASS_MULTIPGAST);
      /*清除所有挂起的中断。 *
      EMACIntClear (EMAC0_BASE、EMACIntStatus (EMAC0_BASE、false));
      /*启用以太网 MAC 发送器和接收器。 *
      EMACTxEnable (EMAC0_BASE);
      EMACRxEnable (EMAC0_BASE);
      /*启用以太网 RX 和 TX 中断源。 *
      EMACIntEnable (EMAC0_BASE、(EMAC_INT_Receive | EMAC_INT_transmit |
             EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_buffer |
             EMAC_INT_RX_STOPPED | EMAC_INT_PHY));
      /*启用以太网中断处理程序。 *
      hwi_enableInterrupt (hwAttrs->intNum);
      EMACPHYWrite (EMAC0_BASE、PHY_PHY_ADDR、EPHY_BMCR、(EPHY_BMCR_ANEN |
             EPHY_BMCR_RESTARTAN));
      log_print0 (Diags_User2、"EMACSnow_emacStart:开始完成");
      /*
       *如果在 EMACSnow_NIMUInit 中禁用了预取缓冲区,则将其打开
       *
      if (enablePrefetch = true){
        ui32FlashConf = HWREG (FLASH_CONF);
        ui32FlashConf &=~(FLASH_CONF_FFOFF);
        ui32FlashConf |= FLASH_CONF_FFON;
        HWREG (FLASH_CONF)= ui32FlashConf;
      }
      返回(0);
    /*
     * ==== EMACSnow_emacStop ===
     * 该函数用于取消初始化并停止 EMACSnow
     控制器 和设备。
     *
    int EMACSnow_emacStop (struct NETIF_DEVICE_PTR_NET_DEVICE)
      EMACSnow_Object *对象=(EMACSnow_Object *)(EMAC_config.object);
      EMACSnow_HWAttrs * hwAttrs =(EMACSnow_HWAttrs *)(EMAC_config.hwAttrs);
      PBM_Handle hPkt;
      int i = 0;
      EMACIntDisable (EMAC0_BASE、(EMAC_INT_Receive | EMAC_INT_transmit |
               EMAC_INT_TX_STOPPED | EMAC_INT_RX_NO_buffer |
               EMAC_INT_RX_STOPPED | EMAC_INT_PHY));
      hwi_disableInterrupt (hwAttrs->intNum);
      if (object->hwi!= NULL){
        hwi_delete (&(object->hwi));
      }
      if (object->swi!= NULL){
        swi_delete (&(object->swi));
      }
      while (PBMQ_count (&EMACSnow_private.PBMQ_Rx){
        /*从驱动程序接收队列发出数据包。 *
        hPktt = PBMQ_DEQ (&EMACSnow_Private。PBMQ_Rx);
        PBM_FREE (hPktt);
      }
      while (PBMQ_count (&EMACSnow_private.PBMQ_TX){
        /*从驱动程序接收队列发出数据包。 *
        hPktt = PBMQ_DEQ (&EMACSnow_Private。PBMQ_TX);
        PBM_FREE (hPktt);
      }
      对于(i = 0;i < NUM_RX_descriptor;i++){
        if (g_pRxDescriptor[i].hPkt!= NULL){
          PBM_FREE (g_pRxDescriptor[i].hPktt);
        }
      }
      log_print0 (Diags_User2、"EMACSnow_emacStop:停止已完成");
      返回(0);
    /*
     * ==== EMACSnow_emacPoll ===
     * 该函数用于轮询 EMACSnow 控制器以进行检查
     * 如果有任何活动
     *
    空 EMACSnow_emacPoll (struct NETIF_DEVICE_PTR_NET_DEVICE、uint timer_tick)
      uint32_t newLinkStatus;
      /*发送待处理的 Tx 数据包*/
      EMACSnow_processPendingTx();
      /*检查链接状态*/
      newLinkStatus =
          (EMAC0_BASE、0、EPHY_BMSR)和 EPHY_BMRS_LINKSTAT);
      /*如果链路状态更改、则向堆栈发出信号*/
      if (newLinkStatus!= EMACSnow_Private。LinkUp){
        signalLinkChange (EMACSnow_private.hEvent、newLinkStatus、0);
      }
      /*设置链接状态*/
      EMACSnow_Private。LinkUp = newLinkStatus;
    /*
     * ==== EMACSnow_emacSend ===
     * 该函数是 NDK 堆栈调用到的接口例程
     * 将数据包传递给驱动程序。
     *
    int EMACSnow_emacSend (struct NETIF_DEVICE_PTR_NET_DEVICE、PBM_Handle hPKT)
      /*
       * 将数据包排队到发送队列的末尾。
       * 这样做是为了确保按顺序发送数据包。
       *
      PBMQ_enq (&EMACSnow_Private。PBMQ_TX、hPktt);
      log_print2 (Diags_User2、"EMACSnow_emacSend:enqueed hPkt=0x%x、len =%d"、(IArg) hPktt、PBM_getValidLen (hPktt));
      /*传输挂起的数据包*/
      EMACSnow_processPendingTx();
      返回(0);
    /*
     * ==== EMACSnow_emacioctl ===
     * NDK 内核堆栈调用该函数以配置驱动程序
     *
    int EMACSnow_emacioctl (struct NETIF_DEVICE_PTR_NET_DEVICE、uint cmd、
            void* pbuf、uint 大小)
      /*此驱动程序当前不支持控制命令*/
      log_print0 (Diags_User2、"EMACSnow_emacioctl:调用 emacioctl");
      if ((cmd =Nimu_Add_multicast_address)||(cmd ==Nimu_del_multicast_address)){
        返回(0);
      }
      返回(-1);
    /*
     * ==== EMACSnow_pkt_service ===
     * NDK 内核堆栈调用该函数以接收任何数据包
     驱动程序中的*。  
     *
    void EMACSnow_pkt_service (NETIF_DEVICE_PTR_NET_DEVICE)
      PBM_Handle hPkt;
      /*将所有排队的数据包发送到堆栈*/
      while (PBMQ_count (&EMACSnow_private.PBMQ_Rx){
        /*从驱动程序接收队列发出数据包。 *
        hPktt = PBMQ_DEQ (&EMACSnow_Private。PBMQ_Rx);
        /*
         * 准备数据包,以便可以将其传递到网络堆栈。
         * 如果未完成此"步骤"、则数据包中的字段不正确
         * 数据包最终将被丢弃。
         *
        PBM_setIFRx (hPktt、ptr_net_device);
        Log_Print1 (Diags_User2、
              "EMACSnow_pkt_service:通过 NIMUReceivePacket 将数据包0x%x 发送到 NDK "、
              (IARg) hPkt);
        /*将数据包传递到 NDK 内核堆栈。 *
        NIMUReceivePacket (hPktt);
      }
      /*工作已完成;接收队列为空。 *
      返回;
    /*
     * ==== EMACSnow_init ====
     * 该函数用于初始化 EMACSnow 驱动程序
     *
    void EMACSnow_init (uint32_t 索引)
      /*目前仅支持1个 EMACSnow 外设*/
      assert_isTrue ((索引=0)、NULL);
      EMACSnow_Initialized = true;
      LOG_print0 (Diags_User2、"EMACSnow_init:安装成功完成");
    /*
     * ==== EMACSnow_InitDMA 描述符===
     *初始化发送和接收 DMA 描述符列表。
     *
    空 EMACSnow_InitDMA 描述符(空)
      int32_t   i;
      PBM_Handle hPkt;
      /*传输列表- 将所有描述符标记为硬件不拥有*/
      对于(i = 0;i < NUM_TX_descriptor;i++){
        G_pTxDescriptors [I].hPktt =空;
        G_pTxDescriptor[I].Desc.ui32Count = 0;
        G_pTxDescriptioners[i]。Desc.pvBuffer1 = 0;
        G_pTxDescriptors [I].DES3.plink =((i =(NUM_TX_descriptors - 1))?
            &g_pTxDescriptor[0].DESC:&g_pTxDescriptionor[I + 1].DESC);
        G_pTxDescriptors [I].Desc.ui32CtrlStatus = DES0_TX_CTRL_INTERRUPT |
                             /*DES0_TX_CTRL_IP_ALL_CKHSUMS |*/
                             DES0_TX_CTRL_ARIGNed;
      }
      /*
       *接收列表- 用缓冲区标记每个描述符并将所有字段设置为
       *允许接收数据包。
       *
      对于(i = 0;i < NUM_RX_descriptor;i++){
        hPkt=PBM_alloc (ETH_MAX_PAYLOAD);
        if (hPktt){
          EMACSnow_primeRx (hPkt,&(g_pRxDescriptioner[i]));
        }
        否则{
          System_abort ("EMACSnow_InitDMA 描述符:PBM_alloc 错误\n");
          G_pRxDescriptioners[i]。Desc.pvBuffer1 = 0;
          G_pRxDescriptor[I].Desc.ui32CtrlStatus = 0;
        }
        G_pRxDescriptors [I].DESC.DES3.plink =
            ((i ==(NUM_RX_descriptors - 1))?
            &g_pRxDescriptions[0].DESC:&g_pRxDescriptions[I + 1].DESC);
      }
      /*在硬件中设置描述符指针。 *
      EMACRxDMADescriptionorListSet (EMAC0_BASE、&g_pRxDescriptor[0].DESC);
      EMACTxDMADescriptionorListSet (EMAC0_BASE、&g_pTxDescriptor[0].DESC);
    /*
     * ==== EMACSnow_NIMUInit ===
     * 该函数用于初始化和注册 EMACSnow
     * 使用网络接口管理单元(NIMU)
     *
    INT EMACSnow_NIMUInit (STKEVENT_Handle hEvent)
      EMACSnow_HWAttrs * hwAttrs =(EMACSnow_HWAttrs *)(EMAC_config.hwAttrs);
      Types_FreqHz 频率;
      NETIF_DEVICE *设备;
      uint32 ui32FlashConf;
      log_print0 (Diags_User2、"EMACSnow_NIMUInit:init called");
      /*确保应用程序已首先初始化 EMAC 驱动程序*/
      assert_isTrue ((EMACSnow_initialized == true)、NULL);
      /*初始化全局结构*/
      memset (&EMACSnow_private、0、sizeof (EMACSnow_Data));
      /*
       * 这是针对上发现的 EMAC 初始化问题的解决方法
       * TM4C129器件。 错误编号为:
       * SDOCM00107378:EK-TM4C1294XL 的 NDK 示例不起作用
       *
       * 以下操作将禁用闪存预取(如果尚未禁用)。
       * 它在 EMACSnow_emacStart()函数中启用。
       *
      ui32FlashConf = HWREG (FLASH_CONF);
      if (((ui32FlashConf &(flash_CONF_FFOFF))= false){
        enablePrefetch =真;
        ui32FlashConf &=~(FLASH_CONF_FFON);
        ui32FlashConf |= FLASH_CONF_FFOFF;
        HWREG (FLASH_CONF)= ui32FlashConf;
      }
      /*为 EMAC 分配内存。 NDK 堆栈中释放的内存关断*
      器件= mmAlloc (sizeof (NETIF_DEVICE));
      if (device == NULL){
        log_error0 ("EMACSnow:未能分配 NETIF_DEVICE 结构");
        返回(-1);
      }
      /*初始化分配的内存块。 *
      mmZeroInit (device、sizeof (NETIF_device));
      device->mac_address[0]= hwAttrs->macAddress[0];
      device->mac_address[1]= hwAttrs->macAddress[1];
      device->mac_address[2]= hwAttrs->macAddress[2];
      device->mac_address[3]= hwAttrs->macAddress[3];
      device->mac_address[4]= hwAttrs->macAddress[4];
      device->mac_address[5]= hwAttrs->macAddress[5];
      /*初始化数据包设备信息结构*/
      PBMQ_init (&EMACSnow_Private。PBMQ_Rx);
      PBMQ_init (&EMACSnow_Private。PBMQ_TX);
      EMACSnow_Private。hEvent    = hEvent;
      EMACSnow_Private .pTxDescList =&g_TxDescList;
      EMACSnow_Private .pRxDescList =&g_RxDescList;
      EMACSnow_Private。rxCount   = 0;
      EMACSnow_Private。rxDroipped  = 0;
      EMACSnow_Private。txSent    = 0;
      EMACSnow_Private.txDroapted  = 0;
      EMACSnow_privace.abnormalInts = 0;
      EMACSnow_Private .isrCount = 0;
      EMACSnow_Private。LinkUp    = false;
      SysCtlPeripheralEnable (SYSCTL_Periph_EMAC0);
      SysCtlPeripheralReset (SYSCTL_Periph_EMAC0);
      SysCtlPeripheralEnable (SYSCTL_Periph_EPHY0);
      SysCtlPeripheralReset (SYSCTL_Periph_EPHY0);
      while (!SysCtlPeripheralReady (SYSCTL_Periph_EPHY0)||
          !SysCtlPeripheralReady (SYSCTL_Periph_EMAC0)){
        /*继续等待... *
        phyCounter[0]++;
      }
      EMAPPHYConfigSet (EMAC0_BASE、EMAC_PHY_CONFIG);
      BIOS_getCpuFreq (&freq);
      EMACInit (EMAC0_BASE、freq.lo、
           EMAC_BCONFIG_Mixed_BURST | EMAC_BCONFIG_PRIORY_FIXED、
           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_FTER_descriptor |
                    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);
      /*将 MAC 地址编程到以太网控制器中。 *
      EMACAddrSet (EMAC0_BASE、0、(uint8_t *) device->mac_address);
      /*初始化 DMA 描述符。 *
      EMACSnow_InitDMA 描述符();
      /*填充网络接口对象。 *
      strcpy (device->name、ethernet_name);
      设备->MTU      = ETH_MAX_PAYLOAD - ETHDR_SIZE;
      DEVICE_>pvt_data  =(void *)&EMACSnow_Private;
      /*填充驱动程序接口功能。 *
      DEVICE_>START    = EMACSnow_emacStart;
      设备->停止     = EMACSnow_emacStop;
      设备->轮询     = EMACSnow_emacPoll;
      设备->发送     = EMACSnow_emacSend;
      DEVICE_>pkt_service = EMACSnow_pkt_service;
      device->ioctl    = EMACSnow_emacioctl;
      DEVICE_>ADD_HEADER = NIMUAddEthernetHeader;
      /*使用 Nimu 注册器件*/
      if (NIMURegister (device)< 0){
        LOG_print0 (Diags_User1、"EMACSnow_NIMUInit:无法向 Nimu"注册);
        返回(-1);
      }
      LOG_print0 (Diags_User2、"EMACSnow_NIMUInit:注册 Nimu");
      返回(0);
    /*
     * ==== EMACSnow_LinkUp ===
     *
    bool EMACSnow_isLinkUp (uint32_t 索引)
      uint32_t newLinkStatus;
      /*检查链接状态*/
      newLinkStatus =
          (EMAC0_BASE、0、EPHY_BMSR)和 EPHY_BMRS_LINKSTAT);
      /*如果链路状态更改、则向堆栈发出信号*/
      if (newLinkStatus!= EMACSnow_Private。LinkUp){
        signalLinkChange (EMACSnow_private.hEvent、newLinkStatus、0);
      }
      /*设置链接状态*/
      EMACSnow_Private。LinkUp = newLinkStatus;
      if (EMACSnow_Private。LinkUp){
        返回(真);
      }
      否则{
        返回(false);
      }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    看起来、您的 EMAC 版本不具有您所附加的主题上详细说明的修复程序。 尝试使用我在此处附加的那个线程中找到的 EMAC 版本。

    谢谢、
    Gerardo

    e2e.ti.com/.../4645.EMACSnow.c

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