stm32+lwip(五):以太网帧发送测试

我是卓波,很高兴你来看我的博客。

系列文章:

stm32+lwip(一):使用STM32CubeMX生成项目

stm32+lwip(二):UDP测试

stm32+lwip(三):TCP测试

stm32+lwip(四):网页服务器测试

stm32+lwip(五):以太网帧发送测试

很多时候,我们想直接获取以太网帧的数据或者直接发送以太网帧数据。在使用STM32CubeMX生成的工程当中,有两个函数就是直接跟以太网通信有关:

 1 /**
 2  * This function should do the actual transmission of the packet. The packet is
 3  * contained in the pbuf that is passed to the function. This pbuf
 4  * might be chained.
 5  *
 6  * @param netif the lwip network interface structure for this ethernetif
 7  * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
 8  * @return ERR_OK if the packet could be sent
 9  *         an err_t value if the packet couldn't be sent
10  *
11  * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
12  *       strange results. You might consider waiting for space in the DMA queue
13  *       to become availale since the stack doesn't retry to send a packet
14  *       dropped because of memory failure (except for the TCP timers).
15  */
16 
17 static err_t low_level_output(struct netif *netif, struct pbuf *p)
1 /**
2  * Should allocate a pbuf and transfer the bytes of the incoming
3  * packet from the interface into the pbuf.
4  *
5  * @param netif the lwip network interface structure for this ethernetif
6  * @return a pbuf filled with the received packet (including MAC header)
7  *         NULL on memory error
8    */
9 static struct pbuf * low_level_input(struct netif *netif)

这两个函数就是实现与以太网的通信,本来需要我们自己实现。现在STM32CubeMX已经帮我们实现好,因此收发以太网数据可以通过调用或修改这两个函数实现。

发送测试

  1 /**
  2   *****************************************************************************
  3   * @file    ethernet_test.c
  4   * @author  Zorb
  5   * @version V1.0.0
  6   * @date    2018-09-04
  7   * @brief   以太网帧数据发送与接收测试的实现
  8   *****************************************************************************
  9   * @history
 10   *
 11   * 1. Date:2018-09-04
 12   *    Author:Zorb
 13   *    Modification:建立文件
 14   *
 15   *****************************************************************************
 16   */
 17 
 18 #include "stm32f4xx_hal.h"
 19 #include "lwip.h"
 20 
 21 /******************************************************************************
 22  * 描述  : 以太网帧发送测试1
 23  * 参数  : 无
 24  * 返回  : 无
 25 ******************************************************************************/
 26 void ethernet_sendtest1(void)
 27 {
 28     uint8_t frame_data[] =
 29     {
 30         /* 以太网帧格式 */
 31         0x50,0xFA,0x84,0x15,0x3C,0x3C,                            /* 远端MAC */
 32         0x0,0x80,0xE1,0x0,0x0,0x0,                                /* 本地MAC */
 33         0x8,0x0,                                                  /* ip类型 */
 34         0x45,0x0,0x0,0x26/*l*/,0x0,0x0,0x0,0x0,0xFF,0x11,0x0,0x0, /* UDP报头 */
 35         0xC0,0xA8,0x2,0x8,                                        /* 本地IP */
 36         0xC0,0xA8,0x2,0xC2,                                       /* 远端IP */
 37         0x22,0xB0,                                                /* 本地端口 */
 38         0x22,0xB1,                                                /* 远端端口 */
 39         0x0,0x12,                                                 /* UDP长度 */
 40         0x0,0x0,                                                  /* UDP校验和 */
 41         0x68,0x65,0x6C,0x6C,0x6F,0x20,0x7A,0x6F,0x72,0x62         /* 数据 */
 42     };
 43         
 44     struct pbuf *p;
 45     
 46     /* 分配缓冲区空间 */
 47     p = pbuf_alloc(PBUF_TRANSPORT, 0x26 + 14, PBUF_POOL);
 48     
 49     if (p != NULL)
 50     {
 51         /* 填充缓冲区数据 */
 52         pbuf_take(p, frame_data, 0x26 + 14);
 53 
 54         /* 把数据直接通过底层发送 */
 55         gnetif.linkoutput(&gnetif, p);
 56 
 57         /* 释放缓冲区空间 */
 58         pbuf_free(p);
 59     }
 60 }
 61 
 62 /******************************************************************************
 63  * 描述  : 以太网帧发送测试2
 64  * 参数  : 无
 65  * 返回  : 无
 66 ******************************************************************************/
 67 void ethernet_sendtest2(void)
 68 {
 69     uint8_t dstAddr[6] = {0x50,0xFA,0x84,0x15,0x3C,0x3C};         /* 远端MAC */
 70     
 71     uint8_t frame_data[] =
 72     {
 73         /* UDP帧格式 */
 74         0x45,0x0,0x0,0x26/*l*/,0x0,0x0,0x0,0x0,0xFF,0x11,0x0,0x0, /* UDP报头 */
 75         0xC0,0xA8,0x2,0x8,                                        /* 本地IP */
 76         0xC0,0xA8,0x2,0xC2,                                       /* 远端IP */
 77         0x22,0xB0,                                                /* 本地端口 */
 78         0x22,0xB1,                                                /* 远端端口 */
 79         0x0,0x12,                                                 /* UDP长度 */
 80         0x0,0x0,                                                  /* UDP校验和 */
 81         0x68,0x65,0x6C,0x6C,0x6F,0x20,0x7A,0x6F,0x72,0x62         /* 数据 */
 82     };
 83         
 84     struct pbuf *p;
 85     
 86     /* 分配缓冲区空间 */
 87     p = pbuf_alloc(PBUF_TRANSPORT, 0x26, PBUF_POOL);
 88     
 89     if (p != NULL)
 90     {
 91         /* 填充缓冲区数据 */
 92         pbuf_take(p, frame_data, 0x26);
 93         
 94         /* 把数据进行以太网封装,再通过底层发送 */
 95         ethernet_output(&gnetif, p, (const struct eth_addr*)gnetif.hwaddr,
 96             (const struct eth_addr*)dstAddr, ETHTYPE_IP);
 97 
 98         /* 释放缓冲区空间 */
 99         pbuf_free(p);
100     }
101 }
102 
103 /******************************** END OF FILE ********************************/

gnetif.linkoutputethernet_output最终调用的还是low_level_output

上面测试的数据包是给IP:192.168.2.194端口:8881发送”hello zorb”数据,网络调试助手能正确收到数据:

 

最后

本文主要介绍了怎样发送以太网帧数据,当能给网络发送任意数据,就可以做一些有趣的事情。

github:https://github.com/54zorb/stm32-lwip

版权所有,转载请打赏哟

如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

原文地址:https://www.cnblogs.com/54zorb/p/9609237.html