Конференция "WinAPI" » COM порт, асинхронные чтение запись
 
  • tesseract © (23.05.08 16:55) [60]

    > См. выше про DTR и уход последнего бита


    Уход последнего байта ловят по TX_EMPTY.  Список проблем, позволяет поставить диагноз, что у тебя всё-таки с указателями, где-то что-то не так, и NX  срабатывает, или перезаписываешь, что-то не то.
  • DiamondShark © (23.05.08 18:42) [61]
    Редкостное извращение: и таймауты и оверлапед.
    Сам усложнил логику (совершенно необосновано) -- сам огрёб.
  • REA (26.05.08 11:35) [62]
    >Если контрольная сумма совпадает, то это не лишнии байты.
    Контрольная сумма совпадает по числу байт из заголовка, остальные не учитываю. Работает нестабильно. Пока не могу сказать еще как - сам не понял.

    >Уход последнего байта ловят по TX_EMPTY
    Так и ловлю, но мне нужен еще уход последнего бита.

    >у тебя всё-таки с указателями, где-то что-то не так
    На одном компьютере все так, а на другом не так? Вряд ли...

    >Сам усложнил логику (совершенно необосновано) -- сам огрёб.
    Без таймаутов порта вообще не работает - не вылезает из WaitFSO. Даже по межбайтовому вылезает не всегда.
  • REA (26.05.08 12:55) [63]
    С лишними байтами разобрался - я переделал, чтобы оно читало не заданное количество байт, а все что есть, а по протоколу передатчик может послать сразу несколько кадров, а я про это уже забыл. Придется переделать обратно и добиваться чтобы работало... Причем таймаутов там никаких особых между кадрами нету и желательно чтобы WaitFSO возвращалось после чтения 2х начальных байт, а она этого делать не желает иногда... копаем дальше.
  • REA (26.05.08 13:16) [64]
    Переделал все примерно как было с начала. Проблема та же: ошибок при чтении и ожидании не возникает, но кадры куда то теряются - GetOverlappedResult возвращает 0 байт (если снова попытаться прочитать ReadFile, то все равно 0 байт и таймаутов никаких не возникает). Т.е. как бы данные есть, но их 0.
  • ага0 (26.05.08 14:26) [65]
    2 REA

    Показал бы лучше полный код
  • REA (26.05.08 14:44) [66]
    Сейчас локальная функция чтения выглядит так:

    Function ReadAsync: Boolean;
    Var
     IO: TOverlapped;
     WaitRes: Integer;
     ReadMore: Integer;
     DummyBytes: DWORD;
    Begin
     FillChar(IO, SizeOf(IO), 0);
     IO.hEvent := FIOEvent;
     Bytes := 0;
     ReadMore := ToRead; // Сначала 2 байта, потом остальное
     Result := ReadFile(idComm, Buf[1], ReadMore, DummyBytes, @IO);
     If (Not Result) Then
     Begin
       If (GetLastError = ERROR_IO_PENDING) Then
       Begin
         WaitRes := WaitForSingleObject(IO.hEvent, 200);
         If WaitRes = WAIT_TIMEOUT Then
           OutputDebugString(PChar('Timeout'));
         Result := WaitRes = 0;
         If (Result) Then
           Result := GetOverlappedResult(idComm, IO, Bytes, False);
       End Else OutputDebugString(PChar('ReadFile bug'));
     End Else Result := GetOverlappedResult(idComm, IO, Bytes, False);
     If Not Result Then
       OutputDebugString(PChar('Wait bug: ' + SysErrorMessage(GetLastError)));
    End;

    Ошибок чтения не возникает, результат иногда = 0 байт.
  • tesseract © (26.05.08 15:30) [67]

    >  IO.hEvent := FIOEvent;


    Лучше событие пересоздавать. А то при многопоточности, ерунда может выйти.
  • ага0 (26.05.08 15:54) [68]
    Ну и иде настройка порта? Я почему спрашиваю-та - ежель

    > ошибок при чтении и ожидании не возникает, но кадры куда
    > то теряются - GetOverlappedResult возвращает 0 байт (если
    > снова попытаться прочитать ReadFile, то все равно 0 байт
    > и таймаутов никаких не возникает). Т.е. как бы данные есть,
    >  но их 0.

    то возможно чтение завершается по таймауту порта, тыж статус порта не проверяешь
  • REA (26.05.08 17:53) [69]
    >Лучше событие пересоздавать. А то при многопоточности, ерунда может выйти.

    Пробовал, то же самое.

    >Ну и иде настройка порта? Я почему спрашиваю-та - ежель

    Уж какие я только не ставил вариации из таймаутов. Межбайтовый таймаут особенно не влияет на результат, а вот общий таймаут на чтение, если не поставить, то иногда будет подвисать в WaitFSO.
    Сейчас стоит межбайтовый 1мс и общий 50 мс.
    Действительно, в мониторе на операции чтения написано сейчас TIMEOUT, но откуда бы ему взяться? Если читать одним куском, а не как сейчас в два захода, то все работало. кажется...
  • ага0 (26.05.08 18:25) [70]

    > то все работало. кажется...

    Креститься надо, када кажется:) Шютка, не обижайся. Ежель неуверенно чуйствуешь себе в таймаутах порта, то есть железный способ - отключить их нафиг. Далее ставишь маску эвентов SetCommEvent ждешь прихода байтов асинхронным вызовом WaitCommEvent с ...WaitFor... и нужным по логике приложения таймаутом или бесконечно. На срабатывание делаешь GetOverlappedResult и смотришь маску, которую передавал в WaitCommEvent. Ежель там EV_RXCHAR, вызываешь ReadFile и читаешь либо все, что пришло, либо сколько нужно до полного пакета. Далее цикл по новой - WaitCommEvent etc. Набрав целый пакет, вызываешь его обработку. Способ железобетонный, когда девайс шлет не шибко периодично, то пусто то густо. Если пакеты идут с хорошей периодичностью, то да, таймауты порта удобны, а иначе - ну их нахвиг.
  • tesseract © (26.05.08 21:44) [71]

    > Ежель там EV_RXCHAR, вызываешь ReadFile


    Вызываешь ClearComError - смотришь сколько пришло. Таймауты порта на старом железе и при хорошей длине кабеля - вещь важная.
  • REA (27.05.08 10:05) [72]
    >Ежель неуверенно чуйствуешь себе в таймаутах порта, то есть железный способ - отключить их нафиг.

    Без них не работает в таком виде как сейчас. Неуверенно чувствую, потому что результаты получаются непредсказуемые. В принципе можно и так сделать, как ты описал, но проще сделать самому тогда уж буферизацию и читать одним куском с выходом из чтения по таймауту. Но медленнее будет. Хотя в этом случае придется и логику программы переделывать...
    Пакеты идут сильно периодично - практически всегда, когда не передаются данные.

    >Вызываешь ClearComError - смотришь сколько пришло. Таймауты порта на старом железе и при хорошей длине кабеля - вещь важная.

    Железо нормальное хоть и самодельное. Кабель тоже не длинный - метра 3-4. Попробую ClearComError еще, но сдается мне монитор правильно показывает.
  • ага0 (27.05.08 12:05) [73]

    > Без них не работает в таком виде как сейчас

    Естессно, нать как я писал.

    > то иногда будет подвисать в WaitFSO.

    Вот те и ответ - есть дыры между посылками. Неча читать она и висит. А ставишь таймаут - она по нему выкидыват. Тут ты ноль и читашь. Тут прынцип какой - не дергаться без нужды. Пришли байтики - читаем, нет - сопим в тряпочку то бишь спим. Вынеси всю эту беду в отдельный поток пусть се спит скока влезет. Можь ваще там синхронно читать, поставить таймаут милисек 500 - Terminate проверять и все дела. Хотя по мне асинхронка удобней даж в отдельном потоке, управляемость выше.

    > Межбайтовый таймаут особенно не влияет на результат

    Ты чет иль путаешь иль оценивашь результат. Должны влиять. Если канечна я чего по склерозности не путал:) Давай, кажи таймауты и описалово протокола. Будет время помедитирую.
  • REA (27.05.08 15:21) [74]
    >Вынеси всю эту беду в отдельный поток пусть се спит скока влезет.

    так и есть

    >Можь ваще там синхронно читать, поставить таймаут милисек 500
    Так и было - см. выше. А похоже оно и в синхронном режиме кадры теряет, т.е. может проблема еще и в самой железке.

    >Давай, кажи таймауты и описалово протокола.
    Он длинный. Подобие SDLC
  • JUDAS (11.01.09 16:52) [75]
    Удалено модератором
    Примечание: Задай вопрос в своей ветке
 
Конференция "WinAPI" » COM порт, асинхронные чтение запись
Есть новые Нет новых   [134435   +36][b:0][p:0]