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:使用 LwIP 端口发送原始以太网帧

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1064831/tm4c129encpdt-sending-raw-ethernet-frames-using-the-lwip-port

器件型号:TM4C129ENCPDT

你(们)好

是否有人在使用 TM4C129E 上的 LwIP (1.4.1)发送原始以太网帧方面有过经验?

我可以将 LwIP 用于 UDP 和 TCP 连接、但有特定要求发送原始以太网以便与测试设备进行通信、我很难找到实现此目的所需步骤的任何描述。 从我可以收集的信息中、我需要使用 ethernetif.c、就我可以确定的范围而言、该文件包含在 Tiva-tm4c129.c 中

我遵循了设置 TCP 连接 lwIPInit()的流程,该连接又调用 lwIPPrivateInit()。 从这里我对是否需要调用 lwip_init()有点不确定? 我认为这不是,我只是在打电话:

netif_add (&g_sNetIF、&IP_addr、&net_mask、&gw_addr、NULL、 TIVaif_init、Ethernet_input);

netif_set_default (&g_sNetIF);

netif_set_up (&g_sNetIF);

在退出 lwIPInit()之前 ,该函数将返回到我的应用程序。 但现在、我一直在讨论如何填充 802.3以太网数据包并将数据粘贴到线路上。 任何帮助都将不胜感激。

非常感谢

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

    嗨、Hairy、

     读取 lwipplib.c 中的代码, lwIPPrivateInit()将调用 lwip_init()来设置栈。 如果没有 lwip_init(),就不会设置任何堆栈,而不仅仅是您不打算使用的 TCP/UDP 堆栈,还会设置内存、pbuf、nitif、ARP 和计时器,据我所知,这些堆栈对以太网的运行至关重要。  

    void
    lwip_init(void)
    {
      /* Modules initialization */
      stats_init();
    #if !NO_SYS
      sys_init();
    #endif /* !NO_SYS */
      mem_init();
      memp_init();
      pbuf_init();
      netif_init();
    #if LWIP_SOCKET
      lwip_socket_init();
    #endif /* LWIP_SOCKET */
      ip_init();
    #if LWIP_ARP
      etharp_init();
    #endif /* LWIP_ARP */
    #if LWIP_RAW
      raw_init();
    #endif /* LWIP_RAW */
    #if LWIP_UDP
      udp_init();
    #endif /* LWIP_UDP */
    #if LWIP_TCP
      tcp_init();
    #endif /* LWIP_TCP */
    #if LWIP_SNMP
      snmp_init();
    #endif /* LWIP_SNMP */
    #if LWIP_AUTOIP
      autoip_init();
    #endif /* LWIP_AUTOIP */
    #if LWIP_IGMP
      igmp_init();
    #endif /* LWIP_IGMP */
    #if LWIP_DNS
      dns_init();
    #endif /* LWIP_DNS */
    
    #if LWIP_TIMERS
      sys_timeouts_init();
    #endif /* LWIP_TIMERS */

    没有使用 TCP/IP 堆栈、我就没有进行任何以太网通信。 因此,很抱歉,我可能无法提供良好的指导。 我想、如果您访问 LwIP 论坛、那里的专家可能会提供一些提示。 无论如何、在假日期间、LwIP 或此处的响应都将延迟很长时间。 我将在明年结束工作。  

    虽然这可能不是您要寻找的解决方案、但我建议您看看以太网引导加载程序如何将原始数据包发送到服务器。 请参阅以下 BL_EMAC.c 文件中的代码片段。 SendBOOTPRequest()构造 BootP 数据包,并使用 UIP_UDP_SEND 发送原始数据包。 请注意、这不是使用 LwIP、而是使用 UIP 进行基本的以太网数据包传输。 不确定这是否是适合您的解决方案。 同样、请务必联系 LwIP 论坛获取反馈。 很抱歉、我没有获得指导、我将从今天开始离开办公室。  

    //*****************************************************************************
    //
    //! Constructs and sends a BOOTP request packet.
    //!
    //! This function constructs a BOOTP request packet and sends it as a broadcast
    //! message to the network.
    //!
    //! \return None.
    //
    //*****************************************************************************
    static void
    SendBOOTPRequest(void)
    {
        uint8_t *pui8Packet = (uint8_t *)uip_appdata;
        tBOOTPPacket *psBOOTP = (tBOOTPPacket *)uip_appdata;
        uint32_t ui32Idx;
    
        //
        // Zero fill the BOOTP request packet.
        //
        for(ui32Idx = 0; ui32Idx < sizeof(tBOOTPPacket); ui32Idx++)
        {
            pui8Packet[ui32Idx] = 0;
        }
    
        //
        // Construct a BOOTP request.
        //
        psBOOTP->ui8Op = BOOTP_REQUEST;
    
        //
        // Set the hardware type to Ethernet.
        //
        psBOOTP->ui8HType = 0x01;
    
        //
        // Set the hardware address length to 6.
        //
        psBOOTP->ui8HLen = 0x06;
    
        //
        // Choose a random number for the transaction ID.
        //
        psBOOTP->ui32XID = g_ui32XID = RandomNumber();
    
        //
        // Set the number of seconds since we started.
        //
        psBOOTP->ui16Secs = HTONS(g_ui32Ticks / SYSTICKHZ);
    
        //
        // Fill in the Ethernet MAC address.
        //
        for(ui32Idx = 0; ui32Idx < 6; ui32Idx++)
        {
            psBOOTP->pui8CHAddr[ui32Idx] = g_sMACAddr.addr[ui32Idx];
        }
    
        //
        // Set the server name if defined.
        //
    #ifdef ENET_BOOTP_SERVER
        for(ui32Idx = 0;
            (psBOOTP->pcSName[ui32Idx] = ENET_BOOTP_SERVER[ui32Idx]) != 0;
            ui32Idx++)
        {
        }
    #endif
    
        //
        // Send the BOOTP request packet.
        //
        uip_udp_send(sizeof(tBOOTPPacket));
    }

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

    您好、Charles、

    感谢您提供指向  bl_emac.c 文件的指针。 我将深入研究并报告。

    HL

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

    看起来我已经过度思考了。 事实证明、调用 lwIPInit、分配要向其发送的帧的 pbuf、然后 直接使用 linkoutput 函数发送帧都是必需的

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

    嗨、Hairy、

     非常高兴您知道如何实现它。 您能不能很好地展示一些代码片段、这些代码片段可能会让社区中的其他人受益、包括我。 :-)

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

    您好、Charles、

    enet_lwip 示例可用于初始化 LwIP、完成后、可使用以下函数将原始帧放置到线路上:

    void 
    SendRawEnet(void)
    {
        uint8_t data[0x4D] =
        {    
            0xff,0xff,0xff,0xff,0xff,0xff,
            0x08,0x00,0x28,0x5A,0x91,0x92,
            0x88,0xb5,
            0xcb,0xda,0xe9,0xf8,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x03,
            0x00,0x00,0x00,
            0x27,0x2d,0x10,0x35,0xc8,0xff,0x09,0x89,0xdd,0x00,0x8a,0x13,0x42,0x40,0xf5,0x0b,
            0x00,0x00,0xe8,0x0b,0x00,0x00,0x21,0x00,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x20,
            0x00,0x00,0x00,0x00,0x93,0x00,0x00
        };
            
        struct pbuf *p_pbuf;
        
        /**  Assign buffer space. */
        p_pbuf = pbuf_alloc(PBUF_TRANSPORT, 0x4D, PBUF_POOL);
        
        if (NULL != p_pbuf)
        {
            /**  Add the frame to the buffer. Copy application supplied data into a pbuf */
            pbuf_take(p_pbuf, data, 0x4D);
    
            /** Send the data directly to the link medium. */
            g_sNetIF.linkoutput(&g_sNetIF, p_pbuf);
    
            pbuf_free(p_pbuf);
        }
    }

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

    嗨、Hairy、

     谢谢!