赞
踩
做这个实验(https://blog.csdn.net/wofreeo/article/details/89450713)时的备忘笔记。
1. Wireshark -> 分析 ->启用的协议对话框,勾选esl_eth,目的是可以让ET2000 Probe给EtherCAT包打上时间戳。
2.在Wireshark的filter里输入类似于
(frame.number>=657)&&(frame.number<=2656)&& (ecat.cnt == 0)
的约束条件,可以摘取相应的包,然后选择“文件->导出特定分组...”,注意不要选择“另存为...”。选择“另存为...”不会把通过约束条件摘取的包存下来。
3.在shell里使用tshark命令时需要cd到wireshark安装目录下,如下:
改进版本:编写批处理脚本jitter_test,不用再一点点敲命令行。
- @echo off
-
- set cmdto=cd
- set wsdir="C:\Program Files\Wireshark"
- set cdir="C:\"
- set wscmd=tshark
- set pcapdir=%cd%
- set csvdir=%cd%
- set pcapname=%1
- set csvname=%pcapname:~0,-5%.csv
- set exceldir="C:\Program Files\Microsoft Office\Office16"
-
- ::echo pcapdir = %pcapdir%
- ::echo csvdir = %csvdir%
- ::echo pcapname = %pcapname%
- ::echo csvname = %csvname%
-
- %wsdir%\tshark -r "%pcapdir%\%pcapname%" -n -T fields -e esl.timestamp > "%csvdir%\%csvname%"
- if exist %csvname% (echo output csv file successfully!)
- if not exist %csvname% (echo output csv file failed!)
-
- ::echo open csv file
- ::%exceldir%\EXCEL.EXE "%csvdir%\%csvname%"
-
- pause
-
- exit
将cmd.exe复制到pcap文件目录下,点击cmd.exe,输入jitter_test.bat空格pcap文件名即可
4.导出结果为CSV文件,注意不要直接导出为xls文件。导出到CSV文件后第一时间另存为xls文件,这样xls公式可以有效保存。
5.注意Excel中对于数值计算有位数限制,实验中最多10位16进制,因此需要截短(被截短的数据的前N位基本不变,因此不影响结果)
6.十六进制在Excel中无法直接加减,需要HEX2DEC()转换成十进制。
7. 将ns转换为us
8.选中一列数据,选择插入->图表->散点图,即可在Excel中添加数据统计图。
9.注意到有奇点产生,回溯到串口助手打印的数据,发现奇点与串口数据中乱码的地方是对应的。看来是printf函数的延时也会对其产生影响。
测试了一下osal_usleep()函数,发现确实可以产生精度为1us的时延。printf产生的时延确实会影响,经过测试发现printf打印一个字符串的时间是359us,将printf的语句注释掉发现确实osal_usleep()函数没有问题。
10. 注释掉simple_test里在for循环中的printf,再次测试,发现还是有奇点产生。不过非奇点区域的jitter变小了,看来printf确实有影响。
11. 注意到奇点的数值比较稳定,因此猜测可能是代码中某地方有影响。
发现有相差2ms的,正好是EC_TIMEOUTRET值。因此判断是ec_send_processdata()和ec_receive_processdata()这里的问题。应该是有部分帧接收超时(超过2ms)。当然也抓过没有一帧超时的数据。
12. 大概发现是ecx_recvpkt函数里的一个bug,改动之后就不存在超时的问题了。同时将数据分析时的数值调整到小数点后一位,这样保证1us的精度是在个位。
13. 或许代码里还有没找到的delay,先找到delay。这两天看了一下ST官方的STM32以太网的视频,https://www.moore8.com/courses/trainning_playback/1580 。需要注意的是数据帧的流向。
DMA的作用是将片上外设SRAM的数据搬到FIFO中,有两种模式,一种是门限模式,比如到256Byte就发;一种是存储转发模式,搬完全的一帧。
接收数据时,有两种,一种是中断接收(RTOS),一种是轮训接收(无OS)。
代码里现在的FIFO模式是存储转发模式,只要FIFO里满一帧就发。
排除1us延时函数的问题,100us ——> 137.4us,200us ——> 237.4us,而且都是±3.5us。如果是延时函数的问题,想必这个延时应该不会是固定的值。
继续看TX端,发现LRW和FRMW报文,其中LRW是data,FRMW是dc值,如果去掉FRMW,又会得到更好的结果
- if(first)//支持DC分布式时钟,first置1
- {
- context->DCl = sublength;//length of DC datagram
- /* FPRMW in second datagram */
- context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]),
- EC_CMD_FRMW, idx, FALSE,context->slavelist[context->grouplist[group].DCnext].configadr,
- ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
- //position of DC datagram in process data packet
- first = FALSE;
- }
LRW + FRMW:100us ——> 137.4us ± 3.5us
LRW: 100us ——> 130.2us ± 2us
14. 用TIM3定时器中断,每100us发送一个frame,
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance == htim7.Instance)//TIM7 counter overflow after 65535(16 bit)
- {
- TIMEOFDAY_Numof65536us++;//every 65536us==65.536ms,TIMEOFDAY_US++
- }
-
- if(htim->Instance == htim3.Instance)//TIM3 counter overflow every 100us
- {
- flag_hal_eth_transmitframe = 1;
- }
- }
- /*Tx every 100us*/
- while(flag_hal_eth_transmitframe==0)
- {
- delayXus(1);
- }
- HAL_ETH_TransmitFrame(&heth,lp);
- flag_hal_eth_transmitframe=0;
100us ——> 100us ± 1us左右
但是还有个问题就是第一帧总是时间差距87us左右,似乎提前进入中断?
类似于这样的问题,一开启定时器中断立刻进入中断 http://www.openedv.com/thread-97072-1-7.html?/news/guonei/90232906577/
不过经过验证,似乎单纯跑定时器中断不存在这个提前进入中断的问题?
如上图,高电平250us,低电平150us,然后高低交错100us,似乎第一次进入定时器中断的时间就是100us左右 ,而且非但没有提前进,反而稍微有点错后,103us,103us然后是98.625us,然后是100us,100us,99.875us。。。
20000帧结果,注意是第1帧和第2帧之间是87.5us,之后正常100us左右
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。