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

版權所有,轉載請打賞喲

 

如果你喜歡我的文章,可以通過微信掃一掃給我打賞喲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM