简体   繁体   English

使用 WinAPI 获取串行通信溢出错误指示

[英]Getting Serial communication Overrun error indication using WinAPI

Overview: I'm trying to trigger an Overrun error indication, by issuing long delays between each byte read from the serial port.概述:我试图通过在从串行端口读取的每个字节之间发出长延迟来触发溢出错误指示。 To make long story short - I don't get this event.长话短说 - 我不明白这个事件。

The test: The DTE is configured to work at 920000BPS 8N1, no flow control.测试:DTE配置为920000BPS 8N1,无流量控制。 The DTE is connected to my Windows10 host via "Silicon Labs CP210x USB to UART Bridge" device. DTE 通过“Silicon Labs CP210x USB to UART Bridge”设备连接到我的 Windows10 主机。

The provided code fragment opens the port, calls the SetCommMask function.提供的代码片段打开端口,调用 SetCommMask 函数。 A delay of 10 seconds was inserted between each call to ReadFile within a loop.在循环内每次调用 ReadFile 之间插入了 10 秒的延迟。 The DTE continuously sends data at a stable rate. DTE 以稳定的速率持续发送数据。

The problem: I don't get any Overrun signal from WaitCommEvent.问题:我没有从 WaitCommEvent 得到任何溢出信号。

Question: Is there a problem with my code?问题:我的代码有问题吗? is there some known limitation with the USB driver? USB 驱动程序是否有一些已知的限制? Do I need to use flow control to get noticed about overrun events?我是否需要使用流控制来注意到溢出事件?

#include <Windows.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    HANDLE hComm;  // Handle to the Serial port
    BOOL   Status; // Status
    DCB dcbSerialParams = { 0 };  // Initializing DCB structure
    COMMTIMEOUTS timeouts = { 0 };  //Initializing timeouts structure
    char SerialBuffer[64] = { 0 }; //Buffer to send and receive data
    DWORD BytesWritten = 0;          // No of bytes written to the port
    DWORD dwEventMask;     // Event mask to trigger
    char  ReadData;        //temperory Character
    DWORD NoBytesRead;     // Bytes read by ReadFile()
    unsigned char loop = 0;
    wchar_t pszPortName[10] = { 0 }; //com port id
    wchar_t PortNo[20] = { 0 }; //contain friendly name
    //Enter the com port id
    do
    {
        printf_s("Enter the Com Port: ");
        wscanf_s(L"%s", pszPortName, (unsigned)_countof(pszPortName));
        swprintf_s(PortNo, 20, L"\\\\.\\%s", pszPortName);
        //Open the serial com port
        hComm = CreateFile(PortNo, //friendly name
            GENERIC_READ | GENERIC_WRITE,      // Read/Write Access
            0,                                 // No Sharing, ports cant be shared
            NULL,                              // No Security
            OPEN_EXISTING,                     // Open existing port only
            0,                                 // Non Overlapped I/O
            NULL);                             // Null for Comm Devices
        if (hComm == INVALID_HANDLE_VALUE)
        {
            printf_s("\n Port can't be opened\n\n");
            break;
        }
        //Setting the Parameters for the SerialPort
        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
        Status = GetCommState(hComm, &dcbSerialParams); //retreives  the current settings
        if (Status == FALSE)
        {
            printf_s("\nError to Get the Com state\n\n");
            break;
        }
        dcbSerialParams.BaudRate = 920000;//CBR_9600;      //BaudRate = 9600
        dcbSerialParams.ByteSize = 8;             //ByteSize = 8
        dcbSerialParams.StopBits = ONESTOPBIT;    //StopBits = 1
        dcbSerialParams.Parity = NOPARITY;      //Parity = None
        Status = SetCommState(hComm, &dcbSerialParams);
        if (Status == FALSE)
        {
            printf_s("\nError to Setting DCB Structure\n\n");
            break;
        }
        //Setting Timeouts
        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        timeouts.WriteTotalTimeoutConstant = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;
        if (SetCommTimeouts(hComm, &timeouts) == FALSE)
        {
            printf_s("\nError to Setting Time outs");
            break;
        }

        //Setting Receive Mask
        Status = SetCommMask(hComm, EV_ERR| EV_RX80FULL| EV_BREAK/*EV_RXCHAR*/);
        if (Status == FALSE)
        {
            printf_s("\nError to in Setting CommMask\n\n");
            break;
        }
        //Read data and store in a buffer
        do
        {
            Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL);
            //Setting WaitComm() Event
            Sleep(10000); /* Ten seconds */
            Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
            if (Status == FALSE)
            {
                printf_s("\nError! in Setting WaitCommEvent()\n\n");
                break;
            }

            SerialBuffer[loop] = ReadData;
            ++loop;
        } while (NoBytesRead > 0);
        --loop; //Get Actual length of received data
        printf_s("\nNumber of bytes received = %d\n\n", loop);
        //print receive data on console
        printf_s("\n\n");
        int index = 0;
        for (index = 0; index < loop; ++index)
        {
            printf_s("%c", SerialBuffer[index]);
        }
        printf_s("\n\n");
    } while (0);

    CloseHandle(hComm);//Closing the Serial Port
    system("pause");
    return 0;
}


Serial port overrun errors should occur as data is sent even after the interface chip and device driver buffers are full.即使在接口芯片和设备驱动程序缓冲区已满后,发送数据时也会发生串行端口溢出错误。
And a narrow definition overrun will only signal what the interface chip(8250/16550/etc) has detected.窄定义溢出只会发出接口芯片(8250/16550/etc)检测到的信号。

So it's unclear if it will occur even if you take a long interval to call ReadFile.因此,即使您花费很长时间来调用 ReadFile,也不清楚它是否会发生。

Please try the following.请尝试以下操作。

However, no matter what you do, it may not occur if you are using a USB serial conversion chip.但是,无论您做什么,如果您使用的是USB串行转换芯片,则可能不会发生。

At the same time as trying the above, please ask the chip vendor if there is an overrun error or if it may be detected, and if so, how to try it.在尝试上述方法的同时,请询问芯片供应商是否有溢出错误或者是否可以检测到,如果有,如何尝试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM