在线培训网站,网站建设员是做什么的,企业专属空间登录,php 做网站目录
1.问题现象
2.数据流分析
3.代码分析
3.1 AllocDAQ
3.2 AllocOdt
3.3 AllocOdtEntry
4.根因分析及解决方法
4.1 根因分析
4.2 解决方案 1.问题现象 在手撸XCP代码时#xff0c; DAQ的实现是一大头痛的事情。最初单周期实现还好一点#xff0c;特别是…目录
1.问题现象
2.数据流分析
3.代码分析
3.1 AllocDAQ
3.2 AllocOdt
3.3 AllocOdtEntry
4.根因分析及解决方法
4.1 根因分析
4.2 解决方案 1.问题现象 在手撸XCP代码时 DAQ的实现是一大头痛的事情。最初单周期实现还好一点特别是当出现了多周期的情况时就出现了如下现象。 解释一下i 为了测试XCP协议栈我的算法为Mea#i Cal#i (i 0-20)。 当我选择所有观测量均通过10ms的周期进行上传时数据显示没问题即Mea10[0-9] 10Mea11[0-9] 11但是当我以1ms周期观测 Mea1010ms周期观测Mea11出问题了如上图所示本来应该都为11的但是显示了一些我看不懂的数值。 首先想到的是Slave拿数据拿错了为什么会拿错呢那肯定是ODT描述的element对应地址有问题。所以我们先来看看数据流有图有真相。
2.数据流分析 当有两个daqlist的时候CANape在动态配置时顺序如下AllocDAQ(分配2个daqlist)、AllocOdt(给两个daqlist分配好odt)、AllocOdtEntry给2个daqlist的odt分配好entry并不是之前我理解的每一个daqlist分配好odt和entry之后再处理另一个daq具体看如下log截图 分配完毕之后再设置daq指针往该地址里写相应的测量量的数据如下 3.代码分析 既然是ODT地址问题那我们就从DAQ变量分配的地址开始查起来我们根据XCP标准推荐的DAQ配置时序开始 从AllocDaq、ODT、ODT Entry开始查起来
3.1 AllocDAQ 上位机通过指令(0xD5)告诉ECU现在需要分配两个Daq List 这里会给DAQ分配一个buffer如下 调试发现分配了两个DaqList这里没问题
3.2 AllocOdt 通过分配ODTD4数据流如下 这部分具体代码如下 代码行数 作用 831 odtCount表示这个DAQlist有多少条odt(可以想成多少条报文)所以就是DAQ列表的大小 834/5 给PID赋值同时给下一个DAQlist的首个ODT的PID赋值 837 将xcp_dyndaqodt[pos]的首地址赋给当前daq的odt 839 在动态daqbuffer的Odt位置加1 840-844 给odt分配odtcount 845 给当前daq分配状态 846 给daq配置时序分配处于odt配置状态 完成之后配置结果如下 这里发现第一个odt和第二个odt的地址不止8个字节一帧报文这里可能有点问题 0x70003fe8对应的是动态daqbuffer的首地址 找到该地址看里面的数据如下 发现数据存放并不是连续的而是直接跳了24个字节怀疑这里应该存在问题看代码中只是对Xcp_DynDaqOdtPos进行了加1但是从log来看的话 应该是给daq0分配了6个odt然后再给daq1分配了3个odt如果只对位置进行加1的话也就是Xcp_DynDaqOdt[pos1]的地址为当前daq的odt的下一个odt的首地址那么第二次给daq1给配3个odt的时候使用的地址就为[pos1]的地址这样就把daq0的第二个odt给覆盖了 但是还是没能找到在代码什么位置给赋值在allocodtentry函数里给Xcp_DynDaqOdt里写数据每一条分配一个地址包括地址和entrysize 很明显这里面只有6个odt正确应是9个第二个odt里面放的地址是70004018如下 正常情况下第二个odt里应该放置的Xcp_DynDaqBuffer[1]的地址也印证了之前odt被覆盖的猜想。
3.3 AllocOdtEntry 上位机通过指令ODT ENTRYD3分配Entry这里就是给每一帧数据分配几个数据还是接着上面的第一帧可上传7个字节的数据那么如果每个数据的大小均为4个字节就只能上传1个数据加上下一个数据的前三个字节因此ODTENTRY为2那么第二帧接着上面的就可以上传第一帧未传完的剩余一个字节1byte、第三个数据4byte以及第四个数据的前两个字节2byte所以第二帧的ODTENTRY为3以此类推。数据流如下 调试结果如下 ODTEntry里面包含了entry的地址需要上传数据的地址、长度等且ODTentry本身的地址是动态daqbuffer里的地址即是说我们是通过将数据放到动态daqbuffer里然后再上传。
4.根因分析及解决方法
4.1 根因分析 DAQ上传的具体线路 首先在AllocOdt这条指令下将Xcp_DynOdtBuffer的地址赋给DAQ[x].odt[y] 然后在AllocOdtEntry将Xcp_DynDaqBuffer地址赋给OdtEntry 最后在writeDaq里将变量的地址写到给OdtEntryXcp_DynDaqBuffer里即在Xcp_DynDaqBuffer里存放实际测量量的地址、DynOdtBuffer存放的是odtentry的地址。 由于在alloctOdt时覆盖了DAQ0的第2-4个ODT所以会出现如下现象 并没有一一对应。
4.2 解决方案 那么修改代码如下 数据显示正常 哭了注释一行代码调试了一周。 还是当时设计时没有理清思路给自己埋下了大坑。