串行端口在非固定写入次数后导致死锁(C++) 我已经编写了一个C++的串口应用程序,它可以处理虚拟串口上的双向通信,我已经为ARM微处理器编写了蓝牙栈。p>

串行端口在非固定写入次数后导致死锁(C++) 我已经编写了一个C++的串口应用程序,它可以处理虚拟串口上的双向通信,我已经为ARM微处理器编写了蓝牙栈。p>,c++,windows,io,bluetooth,serial-port,C++,Windows,Io,Bluetooth,Serial Port,我很确定嵌入式方面是好的,因为在另一个主要从微处理器接收数据的应用程序中,不会导致崩溃。在这个应用程序中,我将二进制数据从C++串口应用程序发送到微处理器,在64字节的块中用简单的协议来控制何时停止发送等等。p> sendbuf[0] = 'x'; // The 'x' is just a placeholder sendbuf[1] = 'x'; sendbuf[2] = 'x'; sendbuf[3] = 'x'; sendbuf[4] = 'x'; sendbuf[5] = 'x'; s

我很确定嵌入式方面是好的,因为在另一个主要从微处理器接收数据的应用程序中,不会导致崩溃。在这个应用程序中,我将二进制数据从C++串口应用程序发送到微处理器,在64字节的块中用简单的协议来控制何时停止发送等等。p>
sendbuf[0] = 'x'; // The 'x' is just a placeholder
sendbuf[1] = 'x'; 
sendbuf[2] = 'x';
sendbuf[3] = 'x';
sendbuf[4] = 'x';
sendbuf[5] = 'x';
sendbuf[6] = 'x';
sendbuf[7] = 'x';


printf("Press 1 to begin Upgrade\r\n");


if(_getch() == '1')
{
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    if(Send('x') == SLSEND_OK )
    {
        printf("=> Note 'Set Firmware Mode'");
    }
}

while(1)
{


while(true)
{
    ClearCommError(port_h,&l_dwErrors, &l_ComStat);
    if(l_ComStat.cbInQue)
    {
        ReadFile(port_h, &data, 1, &Received, NULL);
        if(Received == 1)
        {
            Received = DllRxD(DataBuffer,64, data );
            if(Received > 0)
            {
                if (DataBuffer[0] == 'x') //Note received
                {
                    printf("\n\r=> Note ");
                    if(DataBuffer[3] == 'x' && DataBuffer[4] == 'x')
                    {

                        if(DataBuffer[5] == 'x')
                        {
                            if(DataBuffer[6] == 0x00)
                            {
                                printf("'Firmware Packet Received Sucessfully'");
                                result = 1;
                                break;

                            }
                            else
                            {
                                printf("'Error In Packet Message [0x0%d]'",(unsigned int)DataBuffer[6]);
                                result = -1;
                                break;

                            }
                        }
                    }
                    if(DataBuffer[3] =='x' && DataBuffer[4] == 'x')
                    {
                        if(DataBuffer[5] == 'x')
                        {
                            printf("Mode has changed to: Firmware Upgrade Mode");
                            result = 2;
                            break;
                        }

                    }
                }
                else 
                {
                    printf("=> ERRROR 'Unexpected Message'");
                    result =  -2;
                    break;
                }
            }
        }
    }
}//while(true)  

    if(result == 1 || result == 2)
    {

        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);

        for (i = 0; i < 64; i++)
        {
            fread(&Packet[i],1,1,pFile);
            if(feof(pFile))
                Packet[i] = 0xFF;

            if(Packet[i] == 'x')
            {
                UpdateCRC(Packet[i],&crc);
                UpdateCRC(Packet[i],&crc);

            }
            else
                UpdateCRC(Packet[i],&crc);
        }

        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc); 


        Send(x); //framing
        Send(x);
        Send('x');
        Send('x');
        Send('x');
        Send('x');
        Send('x');
        Send('x');

        for (i = 0; i < 64; i++)
        {
            if(Packet[i] == 'x')
            {
                Send(Packet[i]); **//this set of sends is where i receive the deadlock error message, it's not always the same place it happens though**
                Send(Packet[i]);
            }
            else

                Send(Packet[i]);
        }

        Send('x');
        Send('x');
        Send((crc >> 8));
        if(Send((crc & 0xFF)) == SLSEND_OK)
        {
            printf("\n\r\t\t\t\t....Packet Sent (%u Bytes Total)",counter*64);
        }
我处理这两个应用程序的方式非常相似,所以我想知道当我发送数据而不是接收数据时,是否会有差异,从而导致问题

代码是在VisualStudio2010中编写和调试的

我发现一件非常不寻常的事情是,这个应用程序使用USB到串行有线连接,但通过虚拟com端口死锁!!同时调试uprocessor在这方面似乎没有任何问题,那么是什么导致了这个问题呢

编辑

Hacing深入研究了执行挂起的调用堆栈:

ntdll.dll_ZwWriteFile@36+0x15字节

基本上是这样的:

初始化:

连接:

在这里,我最初创建了第二个线程来处理读取,但认为这可能是死锁的原因。然后我删除了线程并同步运行了所有内容,但仍然存在相同的问题

int Connect(const char *portname,int baudrate)
{

    DCB dev_cont_block;

    if (port_h != INVALID_HANDLE_VALUE)
    {
        return(SLCONNECT_ALREADY_CONNECTED);
    }

    if(strlen(portname)>4) // if COM10 or above use \\.\COM10
    {
        char *longportname;
        int i;
        longportname = (char *) malloc(strlen(portname)+5);
        if(longportname != NULL)
        {
            longportname[0] = '\\';
            longportname[1] = '\\';
            longportname[2] = '.';
            longportname[3] = '\\';
            for(i=0;i<strlen(portname);i++)
                longportname[4+i]=portname[i];
            longportname[4+i] = 0;

            port_h = CreateFile(longportname, GENERIC_READ | GENERIC_WRITE ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
            delete(longportname);
        }
        else
            return(SLCONNECT_CONNECT_FAILED);
    }
    else
        port_h = CreateFile(portname, GENERIC_READ | GENERIC_WRITE ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    if (port_h==INVALID_HANDLE_VALUE)
    {
        return(SLCONNECT_CONNECT_FAILED);
    }

    if (GetCommState(port_h,&dev_cont_block))
    {
        dev_cont_block.BaudRate = baudrate;
        dev_cont_block.ByteSize = 8;
        dev_cont_block.StopBits = ONESTOPBIT;
        dev_cont_block.fParity = FALSE;
        dev_cont_block.Parity = NOPARITY;
        dev_cont_block.fOutxCtsFlow = TRUE;
        dev_cont_block.fOutxDsrFlow = FALSE;
        dev_cont_block.fRtsControl = RTS_CONTROL_DISABLE;

        if (!SetCommState(port_h, &dev_cont_block)) return(SLCONNECT_SETUP_PORT_FAILED);
    }
    else return(SLCONNECT_SETUP_PORT_FAILED);

    PurgeComm(port_h,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    keepLooping=1;
    ///_beginthread(Watcher,0,this);
    //WatcherThread = (HANDLE)_beginthreadex(NULL, 0, Watcher, this, 0, NULL);



    return(SLCONNECT_OK);
}

我根本不是这方面的专家。但是我对串行端口做了一些尝试

我不确定当我读你的代码时是否遗漏了什么,但是我不知道你是否设置了写或读的超时


另外,您如何处理数据终端就绪线路?因此,我发生了各种各样的奇怪的事情..

dev_cont_block.fOutxCtsFlow=TRUE

大宗报价 fOutxCtsFlow 如果此成员为真,则监控CTS清除发送信号以进行输出流量控制。如果此成员为TRUE且CTS已关闭,则输出将暂停,直到再次发送CTS


我现在已经开始处理超时和数据终端就绪线路,我尝试过启用和禁用它。我没有使用真正的硬件线路,因为它完全通过蓝牙,仍然有相同的死锁。这是当线程从当前函数返回时,在调用writefile的行上执行的下一条语句
sendbuf[0] = 'x'; // The 'x' is just a placeholder
sendbuf[1] = 'x'; 
sendbuf[2] = 'x';
sendbuf[3] = 'x';
sendbuf[4] = 'x';
sendbuf[5] = 'x';
sendbuf[6] = 'x';
sendbuf[7] = 'x';


printf("Press 1 to begin Upgrade\r\n");


if(_getch() == '1')
{
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    Send('x');
    if(Send('x') == SLSEND_OK )
    {
        printf("=> Note 'Set Firmware Mode'");
    }
}

while(1)
{


while(true)
{
    ClearCommError(port_h,&l_dwErrors, &l_ComStat);
    if(l_ComStat.cbInQue)
    {
        ReadFile(port_h, &data, 1, &Received, NULL);
        if(Received == 1)
        {
            Received = DllRxD(DataBuffer,64, data );
            if(Received > 0)
            {
                if (DataBuffer[0] == 'x') //Note received
                {
                    printf("\n\r=> Note ");
                    if(DataBuffer[3] == 'x' && DataBuffer[4] == 'x')
                    {

                        if(DataBuffer[5] == 'x')
                        {
                            if(DataBuffer[6] == 0x00)
                            {
                                printf("'Firmware Packet Received Sucessfully'");
                                result = 1;
                                break;

                            }
                            else
                            {
                                printf("'Error In Packet Message [0x0%d]'",(unsigned int)DataBuffer[6]);
                                result = -1;
                                break;

                            }
                        }
                    }
                    if(DataBuffer[3] =='x' && DataBuffer[4] == 'x')
                    {
                        if(DataBuffer[5] == 'x')
                        {
                            printf("Mode has changed to: Firmware Upgrade Mode");
                            result = 2;
                            break;
                        }

                    }
                }
                else 
                {
                    printf("=> ERRROR 'Unexpected Message'");
                    result =  -2;
                    break;
                }
            }
        }
    }
}//while(true)  

    if(result == 1 || result == 2)
    {

        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);
        UpdateCRC('x', &crc);

        for (i = 0; i < 64; i++)
        {
            fread(&Packet[i],1,1,pFile);
            if(feof(pFile))
                Packet[i] = 0xFF;

            if(Packet[i] == 'x')
            {
                UpdateCRC(Packet[i],&crc);
                UpdateCRC(Packet[i],&crc);

            }
            else
                UpdateCRC(Packet[i],&crc);
        }

        UpdateCRC('x', &crc); 
        UpdateCRC('x', &crc); 


        Send(x); //framing
        Send(x);
        Send('x');
        Send('x');
        Send('x');
        Send('x');
        Send('x');
        Send('x');

        for (i = 0; i < 64; i++)
        {
            if(Packet[i] == 'x')
            {
                Send(Packet[i]); **//this set of sends is where i receive the deadlock error message, it's not always the same place it happens though**
                Send(Packet[i]);
            }
            else

                Send(Packet[i]);
        }

        Send('x');
        Send('x');
        Send((crc >> 8));
        if(Send((crc & 0xFF)) == SLSEND_OK)
        {
            printf("\n\r\t\t\t\t....Packet Sent (%u Bytes Total)",counter*64);
        }
int Send(unsigned char sdata)
{
    unsigned long bytesWritten=0;
    unsigned int rtn;

    **//This is where the program stops in the source code i can view**
    //Error received is "this is the next statement to execute when this thread returns from it's current function"
    rtn = WriteFile(port_h,&sdata,1,&bytesWritten,NULL);

    if (rtn)
        return(SLSEND_OK);
    else
        return(SLSEND_UNKNOWN_ERROR);
}