Контроль COM порта (serial) в WINAPI

Не могу найти механизм или функцию мониторинга состояния COM порта в windows, используя WINAPI.

Приходится разбираться в нативных функциях, не используя boost и им подобные библиотеки.

Проблема следующая: написал функцию открытия serial, на другом конце arduino(с ней проблемы нет). В целом всё работает нормально при многократных запусках, но если выскакивает ошибка, то arduino продолжает слать данные в порт. для того чтобы вернуть arduino в режим ожидания, надо послать в порт 0xF0. С этим куском всё в порядке. Теперь о проблеме: Если воспользоваться сторонним терминалом и отправлять туда данные, то закрыв соединение и вернувшись к своей программе , я не могу прочитать что либо из порта, хотя все функции инициализации проходят успешно. Если подождать неопределённое время, то всё начинает работать как было. Соответственно структуры в примере statusSerial, statusError, dcbSerialParams, ctSerialParams - не вызывают нареканий и отображают верные данные. Сама функция из примера полностью отрабатывает без ошибок, а вот дальше прочесть из порта ничего не удаётся. Что я упустил из виду?

#include <stdio.h>  // printf
#include <Windows.h>
// обработчик com порта
HANDLE hSerial;
//структура состояния порта
COMSTAT statusSerial;
DWORD statusError;
int mpc_init(LPCTSTR sPortName)
{
    hSerial = CreateFile(sPortName,             
        GENERIC_READ | GENERIC_WRITE,           
        0,                                      
        0,                                      
        OPEN_EXISTING,                          
        FILE_ATTRIBUTE_NORMAL,                  
        0                                       
    );

    if (hSerial == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            printf("serial port does not exist.\n");
        }
        else printf("some other error occurred.\n");
        exit(-1);
    }

    // структура содержащая настройки com порта
    DCB dcbSerialParams = { 0 };
    COMMTIMEOUTS  ctSerialParams = { 0 };
    // задаём размер структуры
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    // читаем текущие настройки и заполняем структуру
    if (!GetCommState(hSerial, &dcbSerialParams))
    {
        printf("getting state error\n");

    }
    if (!GetCommTimeouts(hSerial, &ctSerialParams))
    {
        printf("getting state error\n");

    }
    if (!BuildCommDCBAndTimeouts(L"baud=500000 parity=N data=8 stop=1 TO=OFF", &dcbSerialParams, &ctSerialParams))
    {
        printf("error setting serial port\n");

    }
    // применяем настройки к порту
    if (!SetCommState(hSerial, &dcbSerialParams))
    {
        printf("error setting serial port state\n");

    }
    if (!SetCommTimeouts(hSerial, &ctSerialParams))
    {
        printf("error setting serial port state\n");

    }
    if (!SetupComm(hSerial, 1024, 1024))
    {
        printf("error buff serial port state\n");
    }

    if (!PurgeComm(hSerial, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT))
    {
        printf("error purge serial port state\n");

    }
    // жду для гарантированного применения настроек
    Sleep(50);
    // отправляем команду перехода в командный режим
    bdm_port.TxBuffer[0] = 0xF0;
    bdm_port.TxIter = 1;
    portw();
    // ждём пока adduino раздуплится
    Sleep(50);
    if (!ClearCommError(hSerial, &statusError, &statusSerial))
    {
        printf("error Status Port");

    }

    if (!PurgeComm(hSerial, PURGE_TXCLEAR | PURGE_RXCLEAR))
    {
        printf("error purge serial port state\n");

    }
    Sleep(50);
    printf("Port open\n");

    return 0;
}

Ответы (0 шт):