当前位置: 首页 > news >正文

STM32:实现ping命令(lwip)

目录

    • 0.协议介绍
      • ICMP数据包格式
      • ping指令发送的ICMP回声请求消息
      • ping指令接收的ICMP回声应答消息
    • 1.实现步骤
    • 2.源码分析
      • 2.1 初始化函数
      • 2.2 发送函数
      • 2.3 回调函数
        • 2.3.1 函数定义:
        • 2.3.2 解析数据包:
        • 2.3.3.处理ICMP数据包:
        • 2.3.4 资源释放:
        • 2.3.5 返回值:
    • 3.源码展示
    • 4.源码链接
    • 5.问题排查解决
      • 问题1:MCU发送ping后,没有回复

0.协议介绍

ping指令实际上并不直接对应一个“协议”,而是使用ICMP(Internet Control Message Protocol,互联网控制消息协议)协议来实现其功能。ICMP是IP(Internet Protocol,互联网协议)的一个辅助协议,用于在IP主机、路由器之间传递控制消息。ping指令通过发送ICMP回声请求消息(ICMP Echo Request)并等待ICMP回声应答消息(ICMP Echo Reply)来测试目标主机的可达性。
以下是ping指令使用的ICMP数据包的格式:

ICMP数据包格式

ICMP数据包封装在IP数据包内,其格式通常包括以下几个部分:
1.IP头部:包含源IP地址、目的IP地址、协议号(对于ICMP,协议号为1)、总长度、TTL(Time To Live,生存时间)等字段。
2.ICMP头部
类型(Type):8位,表示ICMP消息的类型。对于回声请求消息,类型为8;对于回声应答消息,类型为0。
3.代码(Code):8位,与类型字段一起表示ICMP消息的具体种类。对于回声请求和回声应答消息,代码字段通常为0。
4.校验和(Checksum):16位,用于校验ICMP头部的正确性。
5.标识符(Identifier):16位,用于标识发送者的身份,以便接收者能够匹配请求和应答。
6.序列号(Sequence Number):16位,用于标识每个ICMP消息的序列号,以便在多个消息之间建立关联。
7.可选数据(Optional Data):对于回声请求和回声应答消息,这个部分通常包含用户定义的数据(即ping指令发送的数据)。这个数据可以是任意长度的,但通常不会太长,以避免数据包过大而导致的分片。

ping指令发送的ICMP回声请求消息

当使用ping指令发送ICMP回声请求消息时,数据包通常包含以下字段:

**IP头部:**源IP地址设置为发送ping指令的主机的IP地址,目的IP地址设置为要测试的目标主机的IP地址。
**ICMP头部:**类型字段设置为8(表示回声请求消息),代码字段设置为0,校验和字段根据ICMP头部的内容计算得出,标识符和序列号由发送者自行选择。
**可选数据:**通常包含一些固定的文本(如“PING”或“Hello, World!”),以及发送者的时间戳等信息。

ping指令接收的ICMP回声应答消息

当目标主机接收到ICMP回声请求消息后,会发送一个ICMP回声应答消息作为回应。这个数据包通常包含以下字段:

**IP头部:**源IP地址设置为目标主机的IP地址,目的IP地址设置为发送ping指令的主机的IP地址。
**ICMP头部:**类型字段设置为0(表示回声应答消息),代码字段设置为0,校验和字段根据ICMP头部的内容计算得出,标识符和序列号与接收到的回声请求消息中的相应字段保持一致。
**可选数据:**与接收到的回声请求消息中的可选数据保持一致(如果有的话)。
通过比较发送的回声请求消息和接收到的回声应答消息,ping指令可以计算出往返时间(RTT,Round-Trip Time),从而评估网络的延迟情况。如果目标主机不可达或设置了ICMP数据包过滤(如防火墙),则可能无法接收到回声应答消息,此时ping指令会显示相应的错误信息(如“请求超时”或“目标主机不可达”)。

1.实现步骤

在STM32上使用LwIP库实现ping功能涉及几个步骤。LwIP(Lightweight IP)是一个轻量级的TCP/IP协议栈,它被设计为可以在资源有限的系统中运行。为了在STM32上实现ping功能,你需要确保以下几点:

  1. 配置和初始化LwIP:
    •确保你已经在你的STM32项目中正确地集成了LwIP库。
    •配置网络接口(例如以太网或Wi-Fi),包括MAC地址、IP地址、子网掩码和默认网关。
    •初始化LwIP堆栈。
  2. 设置网络接口:
    •如果你使用的是以太网,需要配置并启用以太网外设。
    •如果是无线网络,则需要配置Wi-Fi模块,并连接到一个可用的无线网络。
  3. 创建Ping线程或任务:
    •在FreeRTOS环境中,你可以创建一个新的任务来处理Ping请求。
    •如果没有操作系统,你可以将Ping代码放在主循环中的适当位置。
  4. 编写Ping函数:
    •使用LwIP提供的API来发送ICMP Echo请求(即Ping请求)。这通常涉及到调用icmp_ping_send函数或类似的功能。
    •你可以通过ping命令行工具或者自己实现一个简单的用户界面来触发Ping操作。
  5. 处理响应:
    •LwIP会自动处理接收到的ICMP Echo回复,并调用相应的回调函数。
    •你需要实现一个回调函数来处理这些回复,比如计算往返时间(RTT)并打印结果。
  6. 测试和调试:
    •连接到你的开发板,并尝试Ping一个已知的IP地址(如8.8.8.8,这是Google的公共DNS服务器之一)。
    •检查输出结果,确认是否成功接收到了回复。

2.源码分析

2.1 初始化函数

设置目标IP地址和本地IP地址,创建并绑定一个新的协议控制块(PCB),以及设置接收回调函数

void Ping_Init(void)
{ IP4_ADDR(&dest_ip,192,168,1,188);IP4_ADDR(&local_ip,192,168,1,30);/*bind local IP.*/LOG_INFO("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.*/LOG_INFO("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 ICMPif(NULL == ping_pcb) {LOG_INFO("get n new raw pcb failed.\r\n");return;}raw_bind(ping_pcb,&local_ip);//bind local IP to pcb.raw_recv(ping_pcb,recv_callback,NULL);
}

2.2 发送函数

函数参数:
1.void *arg:这是一个指向raw_pcb结构体的指针,该结构体代表一个原始协议控制块(PCB),用于处理原始套接字通信。在这个函数中,它被用来发送ICMP Echo请求(即Ping请求)。
2.ip_addr_t dst_ip:这是目标IP地址,表示Ping请求应该发送到的设备。
3.Ping任务状态检查:
首先,函数检查一个全局变量ping_completed,以确定Ping任务是否已经完成。如果已完成,则函数立即返回。
4.发送次数检查:
接着,函数检查已发送的Ping请求数量(ping_count)是否已达到预设的最大值(PING_MAX_COUNT)。如果是,则将ping_completed设置为1,将ping_state设置为PING_STATE_COMPLETED,并记录已收到的回复数量(reply_count),然后返回。
5.获取PCB:
从arg参数中获取raw_pcb结构体的指针。
6.分配pbuf:
使用pbuf_alloc函数为ICMP Echo请求分配内存。请求的内存大小是ICMP头部大小加上一个消息字符串的大小(message),这里假设message是一个在函数外部定义的全局变量或常量字符串。
如果内存分配失败,则记录错误并返回。
7.检查pbuf大小:
确保分配的pbuf足够大,以容纳ICMP头部和消息数据。如果不够大,则释放pbuf并返回。
8.设置ICMP头部:
初始化ICMP Echo请求的头部字段,包括类型(type,设置为Ping请求)、代码(code)、校验和(chksum,这里初始化为0,因为LwIP协议栈在发送前会自动计算并填充正确的校验和)、标识符(id)和序列号(seqno)。
9.添加数据:
将消息数据复制到ICMP Echo请求的数据部分。这里假设message是一个包含要发送数据的字节数组。
10.发送数据包:
使用raw_sendto函数发送ICMP Echo请求。这个函数需要PCB、pbuf和目标IP地址作为参数。
记录发送时间和请求数量:
更新全局变量last_send_time为当前系统时间(使用sys_now函数获取),并增加ping_count的值。
11.释放pbuf:
在发送之后,释放之前为ICMP Echo请求分配的pbuf。

void Ping_Send(void *arg,ip_addr_t dst_ip)
{struct pbuf *icmp_pbuf = NULL;struct raw_pcb  *pcb = NULL;struct icmp_echo_hdr *icmp_hdr = NULL;u8_t *data_ptr = NULL;u8_t i =0;// 检查Ping任务是否已完成if (ping_completed) {return;}// 检查是否达到最大发送次数if (ping_count >= PING_MAX_COUNT) {ping_completed = 1;ping_state = PING_STATE_COMPLETED;LOG_INFO("Ping completed: max count reached, %d replies received.\r\n", reply_count);return;}pcb = (struct raw_pcb*)arg;/* IP header(pre allocated) + payload(ICMP header + data)    */icmp_pbuf = pbuf_alloc(PBUF_IP,sizeof(struct icmp_echo_hdr) + sizeof(message),PBUF_POOL);//allocate memory;if(NULL == icmp_pbuf){LOG_INFO("pbuf_alloc() failed.\r\n");return;

相关文章:

STM32:实现ping命令(lwip)

目录 0.协议介绍ICMP数据包格式ping指令发送的ICMP回声请求消息ping指令接收的ICMP回声应答消息1.实现步骤2.源码分析2.1 初始化函数2.2 发送函数2.3 回调函数2.3.1 函数定义:2.3.2 解析数据包:2.3.3.处理ICMP数据包:2.3.4 资源释放:2.3.5 返回值:3.源码展示4.源码链接5.问…...

nvm安装指定版本显示不存在及nvm ls-remote 列表只出现 iojs 而没有 node.js 解决办法

在使用 nvm install 18.20.3 安装 node 时会发现一直显示不存在此版本 Version 18.20.3 not found - try nvm ls-remote to browse available versions.使用 nvm ls-remote 查看可安装列表时发现,列表中只有 iojs 解决方法: 可以使用以下命令查看可安装…...

Spring Boot 中 WebClient 的实践详解

在现代微服务架构中,服务之间的通信至关重要。Spring Boot 提供了 WebClient,作为 RestTemplate 的替代方案,用于执行非阻塞式的 HTTP 请求。本文将详细讲解 WebClient 的实践,包括配置、使用场景以及常见的优化策略,帮…...

在GITHUB上传本地文件指南(详细图文版)

这份笔记简述了如何在GITHUB上上传文件夹的详细策略。 既是对自己未来的一个参考,又希望能给各位读者带来帮助。 详细步骤 打开目标文件夹(想要上传的文件夹) 右击点击git bash打开 GitHub创立新的仓库后,点击右上方CODE绿色按…...

【大模型系列篇】LLaMA-Factory大模型微调实践 - 从零开始

前一次我们使用了NVIDIA TensorRT-LLM 大模型推理框架对智谱chatglm3-6b模型格式进行了转换和量化压缩,并成功部署了推理服务,有兴趣的同学可以翻阅《NVIDIA TensorRT-LLM 大模型推理框架实践》,今天我们来实践如何通过LLaMA-Factory对大模型…...

30天学会Go--第7天 GO语言 Redis 学习与实践

30天学会Go–第7天 GO语言 Redis 学习与实践 文章目录 30天学会Go--第7天 GO语言 Redis 学习与实践前言一、Redis 基础知识1.1 Redis 的核心特性1.2 Redis 常见使用场景 二、安装 Redis2.1 在 Linux 上安装2.2 在 Windows 上安装2.3 使用 Docker 安装 Redis 三、Redis 常用命令…...

java 使用JSqlParser和CCJSqlParser 解析sql

maven <dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.9</version> </dependency>解析SQL String sql "select aa,bb from b"; Statement statementCCJSq…...

基于spring boot的高校专业实习管理系统的设计与实现

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 设计题目&#xff1a;基于spring boot的高校专业实习管理系统的设计与实现 摘 要 随着国内市场经济这几十年来的蓬勃发展&#xff0c;突然遇到了从国外传入国内的互联网技术&#xff0c;互联网产业从开…...

OpenCV相机标定与3D重建(11)机器人世界手眼标定函数calibrateRobotWorldHandEye()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算机器人世界/手眼标定&#xff1a; w T b _{}^{w}\textrm{T}_b w​Tb​ 和 c T g _{}^{c}\textrm{T}_g c​Tg​。 cv::calibrateRobotWorldHa…...

计算机网络ENSP课设--三层架构企业网络

本课程设计搭建一个小型互联网&#xff0c;并模拟Internet的典型Web服务过程。通过此次课程设计&#xff0c;可以进一步理解Internet的工作原理和协议过程&#xff0c;并提高综合知识的运用能力和分析能力。具体目标包括&#xff1a; &#xff08;1&#xff09;掌握网络拓扑的…...

【openwrt】openwrt-21.02 基于IP地址使用ipset实现策略路由操作说明

openwrt版本信息 DISTRIB_ID=OpenWrt DISTRIB_RELEASE=21.02-SNAPSHOT DISTRIB_REVISION=r0-6bf6af1d5 DISTRIB_TARGET=mediatek/mt7981 DISTRIB_ARCH=aarch64_cortex-a53 DISTRIB_DESCRIPTION=OpenWrt 21.02-SNAPSHOT r0-6bf6af1d5 DISTRIB_TAINTS=no-all busybox override …...

Git:常用命令

一、查看当前分支 git branch 二、查看所有分支 git branch -a 三、切换到远程分支 git checkout origin/分支名 示例&#xff1a;git checkout origin/dev 四、拉取远程分支代码 git pull origin 分支名 示例&#xff1a;git pull origin dev 五、常用指令 查看暂存区…...

【2025最新版】搭建个人博客教程

【2025最新版】搭建个人博客教程 –小记&#xff1a; 在搭建我的这个博客之前我在CSDN也发布过一些文章&#xff0c;目前应该也是几千粉丝了&#xff0c;但是看到别人都是用自己博客写的就感觉自己很LOW&#xff0c;所以就想自己来搭建一个属于自己的个人博客。当然搭建博客的…...

微信小程序实现联动删除输入验证码框

以下是json代码 {"component": true,"usingComponents": {} }以下是wxml代码 <van-popup show"{{ show }}" bind:close"onClose" custom-class"extract"><image src"../../images/extract/icon1.png"…...

数据库中decimal、float 和 double区别

在计算机科学中&#xff0c;decimal、float 和 double 是用于表示和处理数值的不同数据类型。 - decimal 是一种精确的十进制浮点数表示&#xff0c;通常用于需要高精度计算的场景&#xff0c;比如财务应用。它能够精确表示小数&#xff0c;并且不会出现浮点数运算误差。 - flo…...

网络编程01

1. 概念 通过网络&#xff0c;让两个主机之间能够进行通信&#xff0c;基于这样的通信完成一定的功能 只要满足进程不同即可&#xff0c;即使是同一个主机&#xff0c;只要是不同的进程&#xff0c;基于网络完成编程 进行网络编程时&#xff0c;需要操作系统提供一组API&…...

el-dialog修改其样式不生效加deep也没用

场景 el-dialog标签直接写在了template下。 解决方法 在template中先写一层div&#xff0c;包裹住el-dialog。...

三天精通一算法之快速排序

力扣链接912. 排序数组 - 力扣&#xff08;LeetCode&#xff09;注意这题快排不能用递归&#xff0c;否则堆会爆 快速排序&#xff08;Quicksort&#xff09;是一种高效的排序算法&#xff0c;通常使用分治法来将一个列表分成较小的子列表&#xff0c;然后递归地排序这些子列表…...

互联网、物联网的相关标准

互联网的相关标准 网络通信协议&#xff1a; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff1a;用于在网络中传输文本、图像、音频和视频等数据的协议。它基于请求-响应模型&#xff0c;客户端发送请求给服务器&#xff0c;服务器返回响应。HTTPS&a…...

Linux题库及答案

填空题 1. 建立用户账号的命令是__useradd________。 2. 修改账号密码的命令是__passwd________。 3. 更改用户密码过期信息的命令是__chage________。 4. 创建一个新组的命令是___groupadd_______。 5. 用于在不注销的情况下切换到系统中的另一个用户的命令是___su_…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!

多连接 BLE 怎么设计服务不会乱&#xff1f;分层思维来救场&#xff01; 作者按&#xff1a; 你是不是也遇到过 BLE 多连接时&#xff0c;调试现场像网吧“掉线风暴”&#xff1f; 温度传感器连上了&#xff0c;心率带丢了&#xff1b;一边 OTA 更新&#xff0c;一边通知卡壳。…...