最近一直挺忙的,项目临近交付,上位机那边反馈给我两个bug,同时还要进行新板子的测试,一块通信板,五块底层采集板都需要进行联合调试测试,还要重新制定与上位机的通信协议,因为新的板子和旧板子有些差异。
1.当上位机发错信息时,导致我这边的通信板不能正常工作。
2.当上位机宕机或上位机突然断电时,导致上位机再想进行连接时就会连接不到。
上诉的两个bug当我这边复位,重新启动之后是可以解决的。
讲真上位机告诉我这两个bug的时候,我是很无语的,首先都不是我这边程序逻辑直接出问题,其次都是上位机那边出问题了,导致我这边无法正常工作,而且只要重新启动就可以消除这些问题了。我能怎么办,我也很绝望。
心里面的职业素养告诉自己,我这边确实也有问题,程序的容错性不高,健壮性太差。
最终还是都解决了bug,哈哈,感觉自己的抗压能力加强了,哈哈哈
一 首先解决第一个bug
通信板与上位机 的通信是使用网卡进行通信的,使用了modbus-tcp协议。
上位机发送错误信息后,导致我这边不能正常收发。
查找正常接收程序的执行流程和接收错误信息时程序执行流程的不同。
通过设置断点查找问题出错的范围,首先确定出错的地方地方在应用层,就不用考虑驱动层了。
找到大概的出错范围后,再对该段程序进行详细的分析,设置断点一步一步进行分析。
还有就是观察某些变量的值,在接收错误数据前后数值上的差异,程序如下:
BOOL
xMBPortTCPPool( void )
{
int n;
int ret;
USHORT usLength;
ret = recv(xListenSocket, &aucTCPBuf[usTCPBufPos], MB_TCP_BUF_SIZE, 0 );
if(ret == -1)
return FALSE;
usTCPBufPos += ret;
//usTCPFrameBytesLeft -= ret;
if( usTCPBufPos >= MB_TCP_FUNC )
{
/* Length is a byte count of Modbus PDU (function code + data) and the
* unit identifier. */
usLength = aucTCPBuf[MB_TCP_LEN] << 8U;
usLength |= aucTCPBuf[MB_TCP_LEN + 1];
/* Is the frame already complete. */
if( usTCPBufPos < ( MB_TCP_UID + usLength ) )
{
//usTCPFrameBytesLeft = usLength + MB_TCP_UID - usTCPBufPos;
}
/* The frame is complete. */
else if( usTCPBufPos == ( MB_TCP_UID + usLength ) )
{
( void )xMBPortEventPost( EV_FRAME_RECEIVED );
return TRUE;
}
else //add new code
{
usTCPBufPos -= ret;
return FALSE;
} //new code end
/* This can not happend because we always calculate the number of bytes
* to receive. */
}
return TRUE;
}
最终找到这条判断语句,else if( usTCPBufPos == ( MB_TCP_UID + usLength ) )
当正常数据发送时,判断句结果为真,这里解释一下,if语句:
这里进行一个校验,接收数据的长度和上位机传输过来的长度是否对应
usTCPBufPos 上位传输过来的数据长度,
usLength 实际接收的数据长度
MB_TCP_UID 宏定义好的 modbus-tcp 协议控制字
当发送错误数据时,判断句结果为假。而 usTCPBufPos += ret; usTCPBufPos是进行累加的,正常的数据,接收数据累加后会执行下面的应用层函数,而错误的不会再向下执行,但usTCPBufPos,还是会进行累加,这样就会导致再次接收到正确的数据时,也不能继续向下执行。
解决方案就是,添加了四行代码,当接收到错误数据时,减掉其对应的累加值,如下:
else //add new code
{
usTCPBufPos -= ret;
return FALSE;
} //new code end
然后,就是调试测试了,用modbus-tcp调试测试助手,故意发错一个,再发送正常的数据,结果显示可以正常运行,至此第一个bug解决了。