目录
1.问题现象
2.数据流分析
3.代码分析
3.1 AllocDAQ
3.2 AllocOdt
3.3 AllocOdtEntry
4.根因分析及解决方法
4.1 根因分析
4.2 解决方案
1
问题现象
解释一下
为了测试XCP协议栈,我的算法为:Mea#i = Cal#i (i = 0-20)。
当我选择所有观测量均通过10ms的周期进行上传时,数据显示没问题,即Mea10[0-9] = 10,Mea11[0-9] = 11;但是当我以1ms周期观测 Mea10,10ms周期观测Mea11,出问题了;如上图所示,本来应该都为11的,但是显示了一些我看不懂的数值。
首先想到的是Slave拿数据拿错了,为什么会拿错呢?那肯定是ODT描述的element对应地址有问题。所以我们先来看看数据流,有图有真相。
2
数据流分析
3
代码分析
既然是ODT地址问题,那我们就从DAQ变量分配的地址开始查起来;我们根据XCP标准推荐的DAQ配置时序开始:
3.1 AllocDAQ
这里会给DAQ分配一个buffer,如下:
编辑
编辑
调试发现分配了两个DaqList,这里没问题;
3.2 AllocOdt
这部分具体代码如下:
代码行数 |
作用 |
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[pos+1]的地址为当前daq的odt的下一个odt的首地址;那么第二次给daq1给配3个odt的时候,使用的地址就为[pos+1]的地址;这样就把daq0的第二个odt给覆盖了;
但是还是没能找到在代码什么位置给赋值,在allocodtentry函数里给Xcp_DynDaqOdt里写数据(每一条分配一个地址),包括地址和entrysize:
很明显这里面只有6个odt(正确应是9个),第二个odt里面放的地址是70004018,如下:
编辑
正常情况下,第二个odt里应该放置的Xcp_DynDaqBuffer[1]的地址;也印证了之前odt被覆盖的猜想。
3.3 AllocOdtEntry
上位机通过指令ODT ENTRY(D3)分配Entry,这里就是给每一帧数据分配几个数据,还是接着上面的,第一帧可上传7个字节的数据,那么如果每个数据的大小均为4个字节,就只能上传1个数据加上下一个数据的前三个字节,因此ODTENTRY为2;那么第二帧接着上面的就可以上传第一帧未传完的剩余一个字节(1byte)、第三个数据(4byte)以及第四个数据的前两个字节(2byte),所以第二帧的ODTENTRY为3;以此类推。数据流如下:
调试结果如下:
4
根因分析及解决方法
4.1 根因分析
DAQ上传的具体线路:
4.2 解决方案
数据显示正常:
编辑
原文始发于微信公众号(汽车MCU软件设计):硬核:汽车标定–多周期测量显示异常