查看: 1769|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
沙发
发表于 2015-4-2 16:59:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

// 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;
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表