stm32+lwip(五):以太网帧发送测试
我是卓波,很高兴你来看我的博客。
系列文章:
stm32+lwip(一):使用STM32CubeMX生成项目
很多时候,我们想直接获取以太网帧的数据或者直接发送以太网帧数据。在使用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.linkoutput和ethernet_output最终调用的还是low_level_output。
上面测试的数据包是给IP:192.168.2.194端口:8881发送”hello zorb”数据,网络调试助手能正确收到数据:
最后
本文主要介绍了怎样发送以太网帧数据,当能给网络发送任意数据,就可以做一些有趣的事情。
github:https://github.com/54zorb/stm32-lwip
版权所有,转载请打赏哟
如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟