我是卓波,很高興你來看我的博客。
系列文章:
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
版權所有,轉載請打賞喲
如果你喜歡我的文章,可以通過微信掃一掃給我打賞喲