Перекрытый файл чтения Win32 на COM-порте, возвращающий - PullRequest
2 голосов
/ 21 ноября 2008

Хорошо, один для ТАКОГО ума улья ...

У меня есть код, который до сегодняшнего дня прекрасно работал на многих системах и развернут на многих сайтах. Он включает в себя чтение потоков и запись данных из последовательного порта.

При попытке проверить новое устройство мой код был забит ошибками 995 ERROR_OPERATION_ABORTED, вызывающими GetOverlappedResult после ReadFile. Иногда чтение будет работать, в других случаях я получаю эту ошибку. Просто игнорирование ошибки и повторная попытка - что удивительно - работало бы без удаления каких-либо данных. Не требуется ClearCommError.

Вот фрагмент.

if (!ReadFile(handle,&c,1,&read, &olap))
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            logger().log_api(LOG_ERROR,"ser_rx_char:ReadFile");
            throw Exception("ser_rx_char:ReadFile");
        }
    }

    WaitForSingleObjectEx(r_event, INFINITE, true);  // alertable, so, thread can be closed correctly.

    if (GetOverlappedResult(handle,&olap,&read, TRUE) != 0)
    {
        if (read != 1)
            throw Exception("ser_rx_char: no data");

        logger().log(LOG_VERBOSE,"read char %d ( read = %d) ",c, read);
    }
    else
    {
        DWORD err = GetLastError();
        if (err != 995)   //Filters our ERROR_OPERATION_ABORTED
        {
            logger().log_api(LOG_ERROR,"ser_rx_char: GetOverlappedResult");
            throw Exception("ser_rx_char:GetOverlappedResult");
        }
    }

Мое первое предположение - обвинить драйвер COM-порта, который я не использовал ранее (это порт RS422 на Blackmagic Decklink, FYI), но это похоже на отбой.

Да, и Vista SP1 Business 32-разрядная, за мои грехи.

Прежде чем я просто объясню это "Чьей-то проблемой", у кого-нибудь есть идеи, что может вызвать это?

Ответы [ 2 ]

4 голосов
/ 21 ноября 2008

Как вы настраиваете структуру OVERLAPPED перед ReadFile? - Я всегда обнуляю их (кроме hEvent, очевидно), что, возможно, является частичным суеверием, но у меня есть ощущение, что это вызывало у меня проблемы в прошлом.

Боюсь, обвинять водителя (если он не MS, а не просто крошечный твик из ссылки) не совсем нереально. Написать драйвер COM - невероятно сложная вещь, и сложность его тестирования заключается в том, что каждое когда-либо написанное приложение использует последовательные порты и их IOCTL немного по-разному.

Другая распространенная проблема - не настроить весь порт, например, не вызывая SetCommTimeouts или SetupComm. Я понятия не имею, делаете ли вы такую ​​ошибку, но я встречал людей, которые говорят, что они не используют тайм-ауты, когда на самом деле имеют в виду, что они не вызывали SetCommTimeouts, поэтому они используют их, но не имеют понятие, что они установлены ...

Подобные вещи могут быть убийством для сторонних COM-драйверов, потому что людям часто сходит с рук любое старое дерьмо с драйвером MS, и оно не всегда работает одинаково с другим устройством.

0 голосов
/ 06 мая 2009

в дополнение к обнулению OVERLAPPED вы также можете проверить, как вы устанавливаете olap.hEvent, то есть, каковы ваши аргументы для CreateEvent? Если вы создаете событие, которое было предварительно сигнализировано (т. Е. Третий аргумент CreateEvent равен TRUE), я ожидал бы немедленного возврата. Кроме того, не забывайте, что если вы укажете manualReset (второй аргумент CreateEvent) как FALSE, GetOverlappedResult () поможет вам очистить событие - что может объяснить, почему оно работает во второй раз.

Не могу сказать по вашему фрагменту, влияет ли это на вас, надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...