WinCE 6.0中串口读数据函数代码分析

如下函数是在WINCE600/PUBLIC/COMMON/OAK/DRIVERS/USB/CLASS/USBSER目录下的示例数据读取代码,看了好多次,总是觉得这部分数据处理有点问题。详细的解释在代码中有解释。我认为目前这段代码还出现的原因就是出错的情况很小很小。大家都没有注意到这个问题。现在标出望高手指点一下,菜鸟小弟在此谢谢先!

//---------------------------------------------------------------------------------------------------------

// PUCHAR pRxBuffer          临时数据缓存区的空闲空间的起始地址

// ULONG *pBufflen            临时数据缓存区的空闲空间的剩余长度的指针         

//---------------------------------------------------------------------------------------------------------

 BOOL SerialDataIn::ReceiveInterruptHandler(PUCHAR pRxBuffer,ULONG *pBufflen)
{
    Lock();
    BOOL bReturn = FALSE;
    if (pRxBuffer && pBufflen && *pBufflen) {
        DWORD dwBufferSize = *pBufflen ;
        *pBufflen = 0 ;
        if ( IsFrontArmedTransferComplete () ) {

            // 上一次数据处理完成的判断
            if (m_dwSegDataDataLen[m_dwCurIndex] == 0) { // Have't update the Transfer Status yet.
                DWORD dwClientInfo = GetClientInfo();
                ASSERT((dwClientInfo & SERIAL_DATAIN_COOKIE_MASK)== SERIAL_DATAIN_COOKIE);

                // 检验数据包传输的连续性
                ASSERT(m_dwCurIndex == (dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK)));
                m_dwCurIndex =(dwClientInfo & (~SERIAL_DATAIN_COOKIE_MASK));

                
                DWORD dwError = USB_NO_ERROR;
                DWORD dwLength;

                // 检测这次数据传输是否正确
                if (GetFrontArmedTransferStatus(&dwLength, &dwError) && dwError == USB_NO_ERROR) { // Complete with no error.
                    m_dwSegDataOffset[m_dwCurIndex] = 0;

                    // 获取这一次数据传输的长度,保存在m_dwSegDataDataLen[m_dwCurIndex]。‘

                    // 个人感觉应该不会出现 dwLength > m_dwSegmentSize 的情况吧?
                    m_dwSegDataDataLen[m_dwCurIndex] = min(dwLength,m_dwSegmentSize);

                    // 这一次循环需要拷贝的数据的长度
                    DWORD dwCopyLength = min(m_dwSegDataDataLen[m_dwCurIndex],dwBufferSize);
                    memcpy(pRxBuffer,m_VirtualAddress + m_dwSegmentSize*m_dwCurIndex ,dwCopyLength);

                    // 保存当前已经拷贝数据的长度 m_dwSegDataOffset[m_dwCurIndex]。
                    m_dwSegDataOffset[m_dwCurIndex] = dwCopyLength;

                    // 返回这一数据拷贝的长度。这就是为什么这个数据要以指针传入的原因。
                    *pBufflen = dwCopyLength;
                    bReturn = TRUE;
                    DEBUGMSG(ZONE_READ,(TEXT("ReceiveInterruptHandler:%d Copied  ,Transfer Size=%d"),dwCopyLength,dwLength));
                }
                else {
                    DEBUGMSG(ZONE_ERROR,(TEXT("ReceiveInterruptHandler:Transfer Error %d ,dwLength=%d"),dwError,dwLength));
                   
                }
            }

           

            // 进入这个if的情况是 m_dwSegDataDataLen[m_dwCurIndex] > dwBufferSize

            // 但是我觉得进入这种情况下,数据处理就出错了啊!

            // 首先, dwBufferSize 在上面的情况中没有做相应的处理,这个时候已经没有代表正确的值了。

            // 其次, *pBufflen = dwCopyLen 这个语句也不对了,应该是*pBufflen += dwCopyLen;
            if (m_dwSegDataOffset[m_dwCurIndex] < m_dwSegDataDataLen[m_dwCurIndex] ){ // We have Extra.
                DWORD dwCopyLen = min (dwBufferSize, m_dwSegDataDataLen[m_dwCurIndex] - m_dwSegDataOffset[m_dwCurIndex]) ;
                memcpy(pRxBuffer,m_VirtualAddress + (m_dwSegmentSize*m_dwCurIndex + m_dwSegDataOffset[m_dwCurIndex]) ,dwCopyLen);
                *pBufflen = dwCopyLen;
                m_dwSegDataOffset[m_dwCurIndex] += m_dwSegDataOffset[m_dwCurIndex];
                bReturn = TRUE;
            }
            if (m_dwSegDataOffset[m_dwCurIndex]>= m_dwSegDataDataLen[m_dwCurIndex] ){
                CloseFrontArmedTransfer();
                m_dwSegDataOffset[m_dwCurIndex]= m_dwSegDataDataLen[m_dwCurIndex] =  0 ;
                BOOL bResult = BulkOrIntrTransfer(USB_NO_WAIT|USB_SHORT_TRANSFER_OK,
                    m_dwSegmentSize,
                    m_VirtualAddress+ (m_dwCurIndex * m_dwSegmentSize),
                    m_PhysicalAddress.LowPart+(m_dwCurIndex*m_dwSegmentSize),
                    SERIAL_DATAIN_COOKIE+m_dwCurIndex);
                ASSERT(bResult==TRUE);
                m_dwCurIndex ++;
                if (m_dwCurIndex>=NUM_OF_IN_TRANSFER)
                    m_dwCurIndex = 0;
            }
        }
    }
    Unlock();
    return bReturn;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值