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

对WireShark 中的EtherCAT抓包数据进行解析

对WireShark 中的EtherCAT抓包数据进行解析

EtherCAT数据包结构

EtherCAT数据帧结构如下:

在这里插入图片描述

采用 Python 实现对 EtherCAT 数据包进行解析


import numpy as np
import matplotlib.pyplot as plt
from IPython import embed
from collections import Counter
import  pyshark
import pcapng
from datetime import datetime
import dpkt
import socket
from dpkt.utils import mac_to_str, inet_to_str# https://zhuanlan.zhihu.com/p/582336672#打开抓包文件# 位置寻址
#    - APRD(1): Auto Increment Read
#    - APWR(2): Auto Increment Write
#    - APRW(3): Auto Increment Read Write
# # 节点寻址
#    - FPRD(1): Configuration address Read
#    - FPWR(2): Configuration address Write
#    - FPRW(3): Configuration address Read Write
# # 广播寻址
#    - BRD(1): Broadcast Read
#    - BWR(2): Broadcast Write
#    - BRW(3): Broadcast Read Write
# # 逻辑寻址
#    - LRD(1): Logic Memory Read
#    - LWR(2): Logic Memory Write
#    - LRW(3): Logic Memory Read Write
# # 位置寻址
#    - APMW(13): Auto Increment Read Multiple Writecnt =  2
old_timestamp = 0
file_path = "./TestJoint.pcapng"time_list_pc_to_control = []
time_list_control_to_pc = []
data_list = []joint_cmd = []
joint_fd = []
with open(file_path,"rb") as fp:pcapng_data = dpkt.pcapng.Reader(fp)for timestamp, buf  in pcapng_data:eth = dpkt.ethernet.Ethernet(buf)cnt += 1## Ethernet_II 帧格式# ## 1、目标 Mac 地址# eth.dst# ## 2、源 Mac 地址# eth.src## 3、得到Ethernet II 数据帧的类型。类型字段(Type )用于标识数据字段中包含的高层协议。类型字段取值为0x0800的帧代表IP协议帧;类型字段取值为0x0806的帧代表ARP协议帧。## 0x0800: IP IP协议## IPv4:     0x0800## ARP:      0x0806## IPV6:     0x86DD## EtherCAT: 0x88A4# print(hex(eth.type))# 如果是EtherCAT 的数据帧if(eth.type == 0x88a4):ethercat_data = eth.data## 解析EtherCAT 头,数据帧的前两个字节ethercat_data_head = int.from_bytes(ethercat_data[:2], byteorder='little')### 得到数据的长度  11 bit, 后面有一个bit的保留位ethercat_data_length = (ethercat_data_head & 0x0fff)### 得到EtherCAT 的类型 4bitethercat_data_cmd = (ethercat_data_head & 0xf000) >> 12## 解析一个子报文## 解析子报文的头ethercat_subdata_head = int.from_bytes(ethercat_data[2:12], byteorder='little')## 命令 8 bit## LRW = 12ethercat_subdata_head_cmd = ethercat_data[2]if ethercat_subdata_head_cmd == 12:## 索引 8 bitethercat_subdata_head_index = ethercat_data[3]## 地址区 32 bitethercat_subdata_head_address = int.from_bytes(ethercat_data[4:8], byteorder='little')## 长度 11 bit  216 个字节ethercat_subdata_head_length = int.from_bytes(ethercat_data[8:10], byteorder='little') & 0x0eff## R 3 bitethercat_subdata_head_R = (int.from_bytes(ethercat_data[8:10], byteorder='little') & 0x3000) >> 13## C 1 bitethercat_subdata_head_C = (int.from_bytes(ethercat_data[8:10], byteorder='little') & 0x4000) >> 14## M 1 bit## 0: 表示只有 1 包数据## 1:表示后面还有数据包ethercat_subdata_head_M = (int.from_bytes(ethercat_data[8:10], byteorder='little') & 0x8000) >> 15## 状态位 16 bitethercat_subdata_head_status = int.from_bytes(ethercat_data[10:12], byteorder='little')## 1:表示后面还有数据包if(ethercat_subdata_head_M == 1):ethercat_subdata_data = ethercat_data[12:12 + ethercat_subdata_head_length ]j1_cmd = int.from_bytes(ethercat_subdata_data[4:8], byteorder='little', signed = True)j2_cmd = int.from_bytes(ethercat_subdata_data[16:20], byteorder='little', signed = True)j3_cmd = int.from_bytes(ethercat_subdata_data[28:32], byteorder='little', signed = True)j4_cmd = int.from_bytes(ethercat_subdata_data[40:44], byteorder='little', signed = True) j5_cmd = int.from_bytes(ethercat_subdata_data[52:56], byteorder='little', signed = True)j6_cmd = int.from_bytes(ethercat_subdata_data[64:68], byteorder='little', signed = True) j1_fd = int.from_bytes(ethercat_subdata_data[76:80], byteorder='little', signed = True) j2_fd = int.from_bytes(ethercat_subdata_data[100:104], byteorder='little', signed = True) j3_fd = int.from_bytes(ethercat_subdata_data[124:128], byteorder='little', signed = True) j4_fd = int.from_bytes(ethercat_subdata_data[148:152], byteorder='little', signed = True)j5_fd = int.from_bytes(ethercat_subdata_data[172:176], byteorder='little', signed = True)j6_fd = int.from_bytes(ethercat_subdata_data[196:200], byteorder='little', signed = True) joint_cmd.append([j1_cmd, j2_cmd, j3_cmd, j4_cmd, j5_cmd, j6_cmd])joint_fd.append([j1_fd, j2_fd, j3_fd, j4_fd, j5_fd, j6_fd])joint_cmd_1 = np.mat(joint_cmd)
joint_fd_1 = np.mat(joint_fd)for i in range(6):plt.plot(joint_cmd_1[:,i],label = 'cmd')plt.plot(joint_fd_1[:,i],label = 'fd')plt.xlabel("time[ms]")plt.ylabel("pos[cnt]")plt.legend()plt.show()

下面是从数据包解析得到的关节1 和 关节 5 的关节脉冲指令值以及反馈值。
在开始阶段需要将当前的脉冲指令值和反馈值进行同步一下。

在这里插入图片描述
在这里插入图片描述

http://www.xdnf.cn/news/8675.html

相关文章:

  • C语言指针进阶:通过地址,直接修改变量的值
  • iOS App启动优化(冷启动、热启动)
  • 2025年渗透测试面试题总结-匿名[实习]安全工程师(安全厂商)(题目+回答)
  • 【HTML-12】HTML表格常用属性详解:从基础到高级应用
  • 显存不够?节约显存高效微调语言模型的五种方法及实验
  • 0基础 Git 代码操作
  • 黑马k8s(十六)
  • 题目 3325: 蓝桥杯2025年第十六届省赛真题-2025 图形
  • whisper相关的开源项目 (asr)
  • 动态规划-蓝桥杯-健身
  • Apache OFBiz 17.12.01 的远程命令执行漏洞 -Java 反序列化 + XML-RPC 请求机制
  • MCP技术体系介绍
  • ETL工具:Kettle,DataX,Flume,(Kafka)对比辨析
  • Java高频面试之并发编程-20
  • 03. C#入门系列【变量和常量】编程世界里的“百变魔盒”与“永恒石碑”
  • XSS脚本攻击-DDoS僵王博士-SQL注入-考试周前的邮件
  • C 语言学习笔记
  • python的pip怎么配置的国内镜像
  • CodeBuddy实现图片压缩工具
  • 第 29 场 蓝桥·算法入门赛
  • Java程序员学从0学AI(三)
  • 实验7 HTTP协议分析与测量
  • LangGraph实现多智能体的方法
  • AI大模型核心基础:向量与张量原理及实践应用指南
  • Level1.7列表
  • 内存越界(Memory Out-of-Bounds)详解
  • 数字图像处理:基于 hough 变换的图像边缘提取
  • vector中reserve导致的析构函数问题
  • MySQL主从同步原理
  • 大模型推理 memory bandwidth bound (4) - Speculative Decoding