Асинхронное чтение из СОМ-порта

Тема в разделе "WASM.WIN32", создана пользователем Topor, 22 окт 2007.

  1. Topor

    Topor New Member

    Публикаций:
    0
    Регистрация:
    21 ноя 2005
    Сообщения:
    31
    Господа, прошу помощи:
    Делается операция асинхронного чтения из СОМ-порта (ReadFile)
    Далее проверяется результат возвращаемый ф-ей ReadFile:
    Если "1", то операция полностью завершена и мы прочитали столько байт из порта сколько и запрашивали.
    Если "0" и ф-я GetLastError возвращает нам ERROR_IO_PENDING, значит операция ReadFile выполняется в фоне и мы ожидаем ее завершения в функции GetOverlappedResult.
    Так вот, GetOverlappedResult возвращает нам не все байты, которые были приняти из СОМ-порта, а только часть. Оставшаяся часть сидит где-то в буферах винды и выйдет оттуда только при следующем приеме.
    Тоесть винда отдает нам байты принятые из СОМ-порта порциями, примерно по 10 .. 30 байт и пока она эту порцию не накопит, она нам ничего не отдаст.
    Тоесть если длина сообщения допустим равна 15 байт, то мы либо сразу можем их все получить(Readfile возвратил 1), либо получить 10 байт(после GetOverlappedResult) , а оставшеся 5 засядут в приемном буфере винды.
    Вот собственно и вопрос: Как сделать, чтобы GetOverlappedResult возвращал нам ВСЕ, что накоплено в приемном буфере допустим по истечении таймаута ? (SetCommTimeouts у меня установлен в заведомо большее значение, чем требуется для приема необходимого числа байт)

    Код (Text):
    1. ;процедура приема данных
    2. ;вход: lpBuff  -  указатель на буфер, dwSize  -  размер буфера
    3. ;выход: eax == число прочитанных байт
    4. ReadCOM     proc lpBuff, dwSize: DWORD
    5.     invoke  ReadFile, hCOM, lpBuff, dwSize , offset dwLength, offset o2     ; Читаем из порта асинхронно
    6.     test    eax, eax                                                        ; Ноль ?
    7.     jne     @end                                                            ; Нет. Операция завершена
    8.     invoke  GetLastError                                                    ; Да ноль.
    9.     cmp     eax, ERROR_IO_PENDING                                           ; Операция выполняется в фоне ?
    10.     jnz     @Err                                                            ; Нет ? Ну тогда ошибка !
    11.     invoke  GetOverlappedResult, hCOM, offset o2, offset dwLength, 1        ; Да. Ждем ее завершения
    12.     test    eax,eax                                                         ; Не выйдет пока не завершится операция чтения
    13.     jne     @end                                                            ; Все ок, валим отсюда.
    14. @Err:
    15.     invoke  ClearCommError, hCOM, offset tmp1, offset ComStat
    16.     sub     eax, eax
    17.     ret
    18. @end:
    19.     invoke  ResetEvent, o2.hEvent                                           ; Сбросили событие. Все прочитано
    20.     mov     eax, dwLength                                                   ; Сколько прочитали байтов.
    21.     ret
    22. ReadCOM endp