ReadFile重叠访问 - 错误170(资源正在使用中)

时间:2018-01-08 15:16:45

标签: winapi serial-port readfile modbus overlapped-io

我的目标: 我正在编写一个应用程序,一次将文件写入串口128字节(总共137个,带有ModBUS头和CRC)并等待回复。我已成功实现了写作。在发送一个137字节的数据包之后,我想在串口com上等待回复并处理它,以防抛出modbus异常。

我的问题: ReadFile函数返回170,从windows文档中,它是170(0xAA) - 请求的资源正在使用中。我实际使用的唯一资源是串口句柄,我怀疑是这个,错误是指。

注意 -   - 没有使用可用的ModBUS库,因为我以特定的方式使用地址寄存器,需要完全控制   - 我只使用重叠I / O,因为(根据WinApi doc)如果串口没有字节,ReadFile永远不会返回;如果超时需要重叠访问是必须的(如果我错了,请纠正我)。   - 我有2秒的最大超时(实际等待回复的超时)和字节之间的20毫秒;如果字节之间超过20毫秒,我认为不再有字节;

有没有人有过使用ReadFile和Erro 170的经验?感谢我能得到的所有帮助。

我的部分代码:

u8 WaitModBusReply(void)
{
u8 i = 0;
u8 ReplyStatus = 0xAA;
u8 ReplyBuff[ReplyBuffSize];
u8 * ptr = &ReplyBuff[0];
static u16 TotalRX_Bytes;

DWORD dwCommEvent;
DWORD dwBytesRead;
COMSTAT ComStatus;
DWORD comErrors = 0;
OVERLAPPED read_s = {0};

read_s.hEvent = CreateEvent(
            NULL,   // default security attributes
            TRUE,   // manual-reset event
            FALSE,  // not signaled
            NULL    // no name
    );

for (int z=0; z< ReplyBuffSize; z++)
    ReplyBuff[z] = 0;

ClearCommError(ModBUS_Port, &comErrors, &ComStatus);
ResetEvent(read_s.hEvent);

if ( !WaitCommEvent(ModBUS_Port, &dwCommEvent, &read_s) )
{
    //byte_timeout += MCU_Getms_TimeConsumption();
    if ( (ReadFile(ModBUS_Port, ptr+TotalRX_Bytes, ReplyBuffSize-
    TotalRX_Bytes, &dwBytesRead, NULL) )) //&dwBytesRead &modbus_reply
    {
        fprintf(stderr, "\n EXEC 3");
        // ReadFile(PC_TestCenterPort, pBufPtr+TotalRX_Bytes, BufSize-
        TotalRX_Bytes, &BytesRead, NULL);
        TotalRX_Bytes += dwBytesRead;
        i++;
        ReplyStatus = Reply_Received;
    }
}

else
    printf("Error setting Com event mask:%d ", GetLastError());

if ( ReplyStatus == Reply_Received)
{
    fprintf(stderr, "\nExit error3: %d\n", GetLastError() );
    if ( (i == 4) ) // Exception returned. Parse it
    {
        if ( !ModBus_CRC16 (&ReplyBuff[0], i, READ) )
            ReplyStatus = Reply_CRCError;

        else
            ReplyStatus = ReplyBuff[i-2];
    }

    else if ( (i == 7) ) // Reply returned
    {
        if ( !ModBus_CRC16 (&ReplyBuff[0], i, READ) )
            ReplyStatus = Reply_CRCError;

        else
            ReplyStatus = Reply_OK;
    }
}
/*
for ( int j=0; j<= 256; j++)
    printf("\nReplyBuff[%d]: %X", j, ReplyBuff[j]); */

return ReplyStatus;
}

检查应答数组的逻辑未实现,因此忽略该部分。 该函数由:

调用
u8 SerialDataSend(void)
{
    u8 t_status = BufferSent;
    int write_status = -1;
    int read_status = -1;
    DWORD bytes_written = 0;
    OVERLAPPED write_s;
    memset(&write_s, 0, sizeof(write_s));

    write_s.Internal = 0;
    write_s.InternalHigh = 0;
    write_s.Offset = 0;
    write_s.OffsetHigh = 0;

    write_s.hEvent = CreateEvent(
                NULL,   // default security attributes
                TRUE,   // manual-reset event
                FALSE,  // not signaled
                NULL    // no name
        );

    if ( !SerialInit() )
    {
        while (!t_status)
        {
            fprintf(stderr, "Starting transmission -\n");

            while(packages_left > 0 && !t_status)
            {
                write_status = WriteFile(ModBUS_Port, ModBUS_Buffer(), 137, 
             &bytes_written, &write_s); //&write_s
                fprintf(stderr,"\r  ModBUS transaction - Packages left:%4d", 
              packages_left);

                if( write_status ) // Return values for success and 
             overlapped access ongoing
                {
                    fprintf(stderr, "Error :%d.\n", GetLastError());
                    t_status = BufferFailed;
                    CloseHandle(ModBUS_Port);
                    break;
                }
                //FlushFileBuffers(ModBUS_Port);

                read_status = WaitModBusReply();
                printf("READ STATUS: %d\n", read_status);
                if ( !read_status && !write_status )
                {
                    fprintf(stderr, "\n------------------------------------------------------------");
                    fprintf(stderr, "\n Exception occurred: %X\n", 
                    read_status);
                    t_status = BufferFailed;
                    Sleep(1);
                    break;
                }
                packages_left--;
                Sleep(200);
            }

            //printf("EXEC 1\n");
            if (!t_status)
            {
                fprintf(stderr, "\n\nTransaction Complete. Bytes written : 
             %d\n", FileSize);
                packages_left = 10;
            }
            break;
        }

        fclose(HMI_Program);

        if (  t_status != BufferFailed )
        {
            fprintf(stderr, "Closing serial port - ");
            if ( !CloseHandle(ModBUS_Port) )
                fprintf(stderr, "Error :%d.\n", GetLastError());
            else
                fprintf(stderr, "OK.\n");
        }
    }
    fflush(stdout);
    fflush(stderr);

    return t_status;
}

和初始化串口的功能:

u8 SerialInit(void)
{
    memset(&SerialSettings,0,sizeof(SerialSettings));
    SerialSettings.DCBlength = sizeof(SerialSettings);
    SerialSettings.BaudRate = CBR_115200;
    SerialSettings.ByteSize = 8;
    SerialSettings.StopBits = TWOSTOPBITS;
    SerialSettings.Parity = NOPARITY;

    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;

    timeouts.ReadIntervalTimeout = 20;
    timeouts.ReadTotalTimeoutConstant = 2000;
    timeouts.ReadTotalTimeoutMultiplier = 1 ;
    memset(&timeouts,0,sizeof(timeouts));

    fprintf(stderr, "Opening serial port - ");
    sprintf(COM_Port, "\\\\.\\COM%d", port_no);

    ModBUS_Port = CreateFile(COM_Port, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );

    if (ModBUS_Port == INVALID_HANDLE_VALUE)
        fprintf(stderr, "Error\n\n");

    else
        fprintf(stderr, "OK\n");

    if ( !GetCommState(ModBUS_Port, &SerialSettings) )
    {
        fprintf(stderr, "Error getting device state.");
        CloseHandle(ModBUS_Port);
    }

    else if( !SetCommState(ModBUS_Port, &SerialSettings) )
    {
        fprintf(stderr, "Error setting device parameters.");
        CloseHandle(ModBUS_Port);
    }

    else if ( !SetCommTimeouts(ModBUS_Port, &timeouts) )
    {
        fprintf(stderr, "Error setting timeouts.");
        CloseHandle(ModBUS_Port);
    }

    else if ( !SetCommMask(ModBUS_Port, EV_RXCHAR | EV_ERR ) )
    {
        fprintf(stderr, "\nError setting com mask.");
        CloseHandle(ModBUS_Port);
    }
    return GetLastError();
}

感谢。

0 个答案:

没有答案