• 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

    版权所有,转载请打赏哟

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

  • 相关阅读:
    MySQL体系结构
    简单高效的代码部署方法
    笔试算法题(07):还原后序遍历数组 & 半翻转英文句段
    笔试算法题(06):最大连续子数组和 & 二叉树路径和值
    笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素
    笔试算法题(04):实现 string & memcpy & strcpy & strlen
    笔试算法题(03):最小第K个数 & 判定BST后序序列
    笔试算法题(02):N阶阶乘 & 双向循环链表实现
    笔试算法题(01):字符串倒置 & 八皇后问题
    chosen选择框加载数据
  • 原文地址:https://www.cnblogs.com/54zorb/p/9609237.html
Copyright © 2020-2023  润新知