基于STM32&lwip实现ping命令

Ping命令实现之Lwip—基于stm32F103

1、Ping命令原理

​ ping命令属于Network layerICMP(Internet control massage protol)协议构成,ICMP报文可以分为两大类:

ICMP报文种类type功能*
错误报告报文3目的站不可达
4源站抑制
5重定向(改变路由)
11数据包超时
12数据包参数错误
查询报文0/8会话请求或回答
9/10路由器询问或通告
13/14时间戳请求或回答
15/16信息请求或回答
17/18地址掩码请求或回答

ICMP报文格式

在这里插入图片描述

在这里插入图片描述

Ping 命令在ICMP报文中的类型

ping命令主要是用来测试两个IP地址之间的网络是否能够连通,确定具有一条通路。在Windows 控制台中我们可以使用Ping命令来测试我们的主机是否能与其他主机通信,格式如下:

ping xxx.xxx.xxx.xxx(dest IP_addr)

​ 在测试TCP/IP协议栈是否移植成功时,一个简便的方法就是测试 ping命令是否能够应答成功,效果如下:
在这里插入图片描述

Ping命令的帧格式

​ 先给出ping命令的帧格式

在这里插入图片描述

  • type:指ICMP报文的类型,例如ICMP两大类报文:差错报告报文和查询报文,其中含有许多不同类型的功能报文,因此对其分类。
  • code:对于每种不同类型(type)的报文在又含有不同的编码信息,例如差错报告报文中的数据包超时报文,就可分为两种:数据包分片超时和TTL超时。
  • Identifier:标识符,没有指明其正式定义,可自行定义。
  • Seq number:序列号,没有正式指明其定义,可自行定义。

2、代码设计

MCU启动Ping数据包接收或发送

void Ping_Init(void)
{
#if FUNC_DBG_ON        
    printf("run in %s .\r\n",__FUNCTION__);
#endif     
    IP4_ADDR(&dest_ip,192,168,1,31);
    IP4_ADDR(&local_ip,192,168,1,10);
    /*bind local IP.*/
    printf("local IP address:%4d.%4d.%4d.%4d\r\n",ip4_addr1(&local_ip),\
                                                    ip4_addr2(&local_ip),\
                                                    ip4_addr3(&local_ip),\
                                                    ip4_addr4(&local_ip));
    /*bind dest IP.*/
    printf("dest IP address:%4d.%4d.%4d.%4d\r\n", ip4_addr1(&dest_ip),\
                                                    ip4_addr2(&dest_ip),\
                                                    ip4_addr3(&dest_ip),\
                                                    ip4_addr4(&dest_ip));    
    /*allocate a new pcb*/
    ping_pcb = raw_new(IP_PROTO_ICMP);//set IP protocol type to ICMP
    if(NULL == ping_pcb) {
        printf("get n new raw pcb failed.\r\n");
        return;
    }
    
    PingCmd_start(ping_pcb);
}

void PingCmd_start(struct raw_pcb *pcb)
{
#if FUNC_DBG_ON        
    printf("run in %s .\r\n",__FUNCTION__);
#endif   
    raw_bind(pcb,&local_ip);//bind local IP to pcb.
  //  raw_connect(pcb,&dest_ip);
    raw_recv(pcb,recv_callback,NULL);
   // ping_cnt--; 
    /*sys_timeout()为注册一个单次定时事件,当计时结束后,会主动发送REQUEST包,PC会给予响应 
    * 接收Ping命令时关闭,MCU发起ping请求时打开。
    */
   //  sys_timeout(PING_DELAY,timeoutHandle,pcb);//set a oneshot time event for periodicly.
}

MCU接收数据

Windows终端对MCU已设置好的IP地址进行ping命令调试,PC端发出的ICMP报文中type应为0x08code0x00,identifierseq number可随意指定,故在MCU端接收代码可设置为如下格式:

u8_t recv_callback(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr)
{                   //  p->payload point the IP header/Ethernet frame data field.

    struct icmp_echo_hdr *icmp_hdr = NULL;
    struct ip_hdr *ip_hdr = NULL;
    u8_t ip_hlen = 0;
    u8_t *data_ptr = NULL;
#if FUNC_DBG_ON        
    printf("run in %s .\r\n",__FUNCTION__);
#endif     		
		(void)arg;
    if(ip_addr_cmp(&dest_ip,addr) &&\
         p->tot_len > (IP_HLEN + sizeof(struct icmp_echo_hdr)))//process packet
    {
        ip_hdr = (struct ip_hdr *)p->payload; //point to IP header
        ip_hlen = IPH_HL(ip_hdr)*4;           //1 len means 4 bytes.

        //adjust p->payload point ICMP header.
        if(pbuf_header(p,-ip_hlen))
            printf("Adjust header failed.\r\n");
        icmp_hdr = (struct icmp_echo_hdr *)p->payload;
        if(0x00 == icmp_hdr->code)
        {
            data_ptr = (u8_t*)p->payload + sizeof(struct icmp_echo_hdr);
            printf("icmp_hdr->type %d .\r\n",icmp_hdr->type);            
            switch (icmp_hdr->type)
            {
            case PING_REPLY:    //receive a reply message.
                printf("[Receive message]:%s.\r\n",data_ptr);
                printf("[ID]:%x.\r\n",icmp_hdr->id);
                printf("[SEQ Number]:%x.\r\n",icmp_hdr->seqno);   
                sys_timeout(PING_DELAY,timeoutHandle,pcb);//continue to send a ping REQUEST packet.           
                break;
            case PING_REQUEST:  //need ack
                printf("Receive a REQUEST message.\r\n");
                printf("[Receive message]:%s.\r\n",data_ptr);
                printf("[ID]:%x.\r\n",icmp_hdr->id);
                printf("[SEQ Number]:%x.\r\n",icmp_hdr->seqno); 

                /*change type,reset checksum*/
                ICMPH_TYPE_SET(icmp_hdr,PING_REPLY);//set type.
                /*checksum*/
                if(icmp_hdr->chksum >= htons(0xffffU - (PING_REQUEST<<8)))
                    icmp_hdr->chksum +=htons(PING_REQUEST<<8 + 1);
                else
                    icmp_hdr->chksum +=htons(PING_REQUEST<<8);
                raw_sendto(pcb,p,addr);

                break;
            
            default:
                break;
            }  
        }
        else
            printf("[ERROR]:It's not a ping format packet.\r\n");
    }
    pbuf_free(p);
    return 1;//delete pbuf.
}

该代码块流程如下:
在这里插入图片描述

从代码块中可以看出,在处理接收pbuf时与发送pbuf时不同。发送时申请的pbuf为IP层pbuf模型,Lwip默认将IP首部预留给底层函数添加其信息,而payload指针直接指向其数据区;接收时,下层处理函数直接将完整的pbuf数据包传递给pcb控制块,关于为何没有直接将payload指向IP数据区,有待研究。

PC发送ping命令REQUEST包—Wireshark抓包测试

  • PC端IP:192.168.1.31
  • MCU端IP:192.168.1.10

PC终端发起ping请求:

在这里插入图片描述

WireShark抓包结果

在这里插入图片描述

MCU发起Ping请求

​ ping数据区域值为This a ping test,only for REQUSET message.,由于MCU是在上电启动后自动执行ping命令,直接给出WireShark抓包结果。

在这里插入图片描述

查看数据是否正确

在这里插入图片描述

从结果来看,PC端正确接收数据,至此关于MCU发起、接收ping命令结束,当然,MCU程序设计还有些许不足,没有对ping包进行数量限制,而是持续发送。


工程源码

链接:https://pan.baidu.com/s/1ez-gm1TW0rLBo6xK2aNGFA?pwd=lfds
提取码:lfds

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: "stm32f4 lwip开发手册.pdf" 是一本关于在STM32F4微控制器上使用lwIP(轻量级IP)协议栈进行网络开发的技术手册。 lwIP是一个开源的TCP/IP协议栈,专为嵌入式系统设计的,它具有精简、高效的特点,适用于资源有限的嵌入式设备。 这本开发手册提供了使用lwIP协议栈在STM32F4微控制器上构建网络应用程序所需的详细指南和实例。 其中,手册的首部主要介绍了lwIP协议栈的基本概念、架构和功能,以及STM32F4微控制器的网络相关硬件特性。 接着,手册提供了lwIP协议栈在STM32F4微控制器上的移植方法和配置步骤,包括网络接口配置、IP地址配置、以太网驱动配置等。 然后,手册详细介绍了lwIP协议栈的各种功能和组件,例如TCP/IP协议、UDP协议、socket编程接口、IPv6支持、DHCP、DNS等。 此外,手册还提供了一些基于lwIP协议栈的网络应用示例,如Web服务器、FTP服务器、ping应用等,以帮助开发者更好地理解和应用lwIP协议栈。 最后,手册附录部分提供了一些实用的工具和资源,如lwIP软件包下载链接、开发板的硬件连接图等。 总之,"stm32f4 lwip开发手册.pdf" 是一本对于在STM32F4微控制器上进行lwIP协议栈网络开发的详尽指南,对于嵌入式开发者在网络应用开发方面提供了重要的参考和帮助。 ### 回答2: 《stm32f4 lwip开发手册.pdf》是一本关于STM32F4系列微控制器使用lwIP协议栈进行网络开发的手册。lwIP是一个轻量级的开源TCP/IP协议栈,适用于嵌入式系统。 这本手册主要介绍了如何在STM32F4微控制器上使用lwIP协议栈进行网络开发。其中包含了lwIP的基本原理、配置方法以及相关的应用示例。手册详细讲解了lwIP的各个模块、接口和功能,包括网络连接、数据传输、协议栈配置等。 手册首先介绍了lwIP协议栈的概念和基本原理,包括IP协议、TCP协议和UDP协议等。然后详细介绍了如何在STM32F4微控制器上配置lwIP协议栈,包括网络接口的配置、IP地址的分配、网络连接的建立等。 手册还提供了一些实际的应用示例,例如使用STM32F4微控制器实现Web服务器、FTP服务器和TCP客户端等。这些示例代码可以帮助读者更好地理解和应用lwIP协议栈。 总的来说,这本手册是一本很好的学习和参考资料,对于想要在STM32F4微控制器上进行网络开发的工程师和开发者来说非常有价值。它详细介绍了lwIP协议栈的原理和配置方法,并提供了一些实际的应用示例,帮助读者更好地理解和应用lwIP协议栈。 ### 回答3: 《STM32F4 LWIP开发手册.pdf》是一本关于STM32F4微控制器与LWIP(轻量级IP协议栈)开发的手册。LWIP是一个开源的TCP/IP协议栈,适用于嵌入式设备的网络通信。而STM32F4是STMicroelectronics(意法半导体)公司推出的一款高性能32位ARM Cortex-M4内核的微控制器。 这本手册分为多个章节,介绍了如何在STM32F4微控制器上进行LWIP开发。首先,手册介绍了LWIP协议栈的基本原理和架构,包括网络层、传输层和应用层的功能和特点。接着,手册详细介绍了如何在STM32F4微控制器上搭建LWIP开发环境,包括安装所需软件、配置开发工具以及连接硬件设备。 手册还介绍了如何使用LWIP库函数来实现网络通信功能,包括创建、配置和管理网络接口,设置IP地址和子网掩码,实现TCP和UDP协议的数据传输,以及处理网络中断和错误。 此外,手册还提供了大量的示例代码和实验步骤,帮助读者快速上手并理解LWIPSTM32F4微控制器上的应用。通过学习这本手册,开发人员可以了解和掌握如何利用STM32F4和LWIP进行嵌入式网络通信的开发,以实现各种网络应用,如网络控制、数据传输和远程监控等。 总而言之,《STM32F4 LWIP开发手册.pdf》是一本指导开发人员在STM32F4微控制器上进行LWIP开发的详细手册,通过学习和实践可以掌握嵌入式网络通信的技术和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值