我是卓波,很高兴你来看我的博客。
系列文章:
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
版权所有,转载请打赏哟
如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟
来源:oschina
链接:https://my.oschina.net/u/4344016/blog/3833645