现象描述
发送除connect指令之外的任何指令,下位机都不会有任何回应。发送connect可得到正常的回应。
如:发送SET_MAT指令,正常应该回应一条报文:
FF 00 03 FE 39 00 00 00
如果回调函数 ccpSendCallBack() 配置错误,则不会得到任何报文回应。
但 CONNECT 指令除外,这是由于**ccpCommand()**源码的设定导致的,下面我们来分析一下。
原因分析
源码太长,我这里将其折叠之后截图显示给大家
在整体结构上,CONNECT指令和其他指令使分开处理的,其他指令的处理代码在else if (ccp.SessionStatus&SS_CONNECTED) {}
里,因此才会有上述所描述的错误现象。只有当下位机首先接收到CONNECT指令后,才会在下次接到其他指令的时候做出应答,应答的代码在 ccpSendCrm()
里。
我们接着看ccpSendCrm()
函数源码
可以看到,只有当ccp.SendStatus&CCP_SEND_PENDING
为假的时候,才会调用 ccpSend()
函数将应答发送出去。ccp.SendStatus
的初值为0,因此首次进入 ccpSendCrm()
函数时可以进入else 语句,但是同时由于
ccp.SendStatus |= CCP_CRM_PENDING;
ccp.SendStatus
被置位为0x10(CCP_SEND_PENDING = 0x10),那么如果ccp.SendStatus
不被重置,下次再进入 ccpSendCrm()
时将不会进入else分支,表现出来的现象就是ccp不会发送应答报文。
那么 ccp.SendStatus
又是在哪里被调用的呢?通过查找,我们发现在ccpSendCallBack()
函数中有它的身影。
好了,到此,问题的原因找到了,由于在ccp服务函数中没有调用ccpSendCallBack()
函数,因此不会做出应答。
解决办法:
在ccp服务函数中ccpCommand() 之后调用 ccpSendCallBack()
即可,代码如下:
for(;;)
{ // calculate checksum
if (MSCAN0GetMsg(&msg_get))
{
if(msg_get.id == CCP_CRO_ID && (!msg_get.RTR))
{
ccpCommand(msg_get.data);
}
}
CCP_DISABLE_INTERRUPT;
if (ccpBootTransmitCrmPossible()){
ccpSendCallBack();
}
CCP_ENABLE_INTERRUPT;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15