Форум: "Начинающим";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
ВнизНепонятка с передачей данных (COM порт) Найти похожие ветки
← →
POP (2007-05-14 16:39) [0]Юзаю такой код:
Overlapped.hEvent:= CreateEvent(nil, false, false, nil);
WriteFile(ComFile, dd, ii, BytesWritten, @Overlapped);
if WaitForSingleObject(Overlapped.hEvent,2000) <> WAIT_OBJECT_0 then
Goto error_message;
CloseHandle(Overlapped.hEvent);
SetCommMask(ComFile, EV_RXFLAG);
Overlapped.hEvent:= CreateEvent(nil, false, false, nil);
WaitCommEvent(ComFile, BytesWritten, @Overlapped);
if WaitForSingleObject(Overlapped.hEvent,2000) <> WAIT_OBJECT_0 then
Goto error_message;
//Sleep(500);
ClearCommError(ComFile, Err, @ComStat);
CountB:= ComStat.cbInQue;
if CountB = 0 then
Goto error_message; //**************
CloseHandle(Overlapped.hEvent);
SetCommMask(ComFile, 0);
Overlapped.hEvent:= CreateEvent(nil, false, false, nil);
ReadFile(ComFile, dd, CountB, BytesReadDM, @Overlapped);
if WaitForSingleObject(Overlapped.hEvent,2000) <> WAIT_OBJECT_0 then
Goto error_message;
То есть сначала отсылаю команду, далее устанавливаю маску ожидания определенного байта, который означает конец пакета, далее ожидаю (WaitCommEvent) этот байт, если это событие произошло, значит пришли и все предыдущие байты. Далее делаю ClearCommError для того чтобы определить сколько байт пришло и далее читаю это количество байтов ф-й ReadFile.
Все работает, с физическими COM портами и с некоторыми виртуальными (USB дрова мобильников).
Но с одними дровами обнаружил такую проблему, посылается в телефон две одинаковые команды подряд, первая проходит нормально, а на вторую ответ не успевает прийти и выполняется команда где звездочки. То есть команда ClearCommError выдает 0 байт.
Если же разкоментировать команду Sleep , то есть сделать небольшую задержку, то все работает нормально.
Так вот непонятно, почему так?
Ведь если я дождался события WaitCommEvent прихода байта означающего конец пакета, то по любому должно быть не ноль байтов, а команда ClearCommError выдает 0.
Почему?
← →
tesseract © (2007-05-14 16:47) [1]
> Ведь если я дождался события WaitCommEvent прихода байта
> означающего конец пакета, то по любому должно быть не ноль
> байтов, а команда ClearCommError выдает 0.
А CTS/RTS анализируешь? Не факт что ус-во успеет проанализировать пакет после того как ты его запишешь, для этого и нужны
эти линии.
Код странный донельзя. GetOverLappedResult где, зачем overlapped-у сбрасываешь event?
← →
POP (2007-05-14 17:09) [2]
> А CTS/RTS анализируешь? Не факт что ус-во успеет проанализировать
> пакет после того как ты его запишешь, для этого и нужны
>
> эти линии.
Обмен идет по двум проводам, RX и TX и все, плюс земля. Так что CTS/RTS не катит.
> GetOverLappedResult где
Он здесь не нужен, я создаю обьект события ф-й CreateEvent, далее опрашиваю созданный обьект ф-й WaitForSingleObject, по таймауту в 2сек, если ничего не пришло, считаю что устройство не отвечает.
Но у меня проблема в другом, таймауты не наступают, наоборот, приходит событие сигнализируещее, что обнаружен завершающий байт в пакете, а значит я уже могу читать не ноль байтов.
Но:
ClearCommError(ComFile, Err, @ComStat);
CountB:= ComStat.cbInQue;
Мне выдает что cbInQue = 0, то есть число символов в приемном буфере которые могут быть считаны ф-й Readfile.
Но такого не может быть, тк перед этим мне был сигнал что прилетело не ноль байтов.
Вот где загвоздка.
← →
tesseract © (2007-05-14 17:19) [3]Слишком мало всяких проверок, нет анализа возвращаемых кодов. Фиг разберёшь :-)
пример :
SetCommMask(ComFile, EV_RXFLAG not EV_RING); // вроде так баг с модемом лечиться,
if WaitCommEvent(ComFile, BytesWritten, @Overlapped)<> o then
if ByteWritten=EV_RXCHAR then
begin
end;
else
GetLatErorr........
> Мне выдает что cbInQue = 0, то есть число символов в приемном
> буфере которые могут быть считаны ф-й Readfile.
for i:=1 to MaxFail do
begin
if Get>Need then break;
sleep(50);
end;
← →
POP (2007-05-14 17:35) [4]
> SetCommMask(ComFile, EV_RXFLAG not EV_RING); // вроде так
> баг с модемом лечиться,
А что за баг с модемом?
Я работаю с мобильниками через виртуальные COM порты которые USB дрова создают.
> if WaitCommEvent(ComFile, BytesWritten, @Overlapped)<>
> o then
Для чего ты проверку делаешь? Режим работы с портом асинхронный, поэтому WaitCommEvent завершиться сразу как началась, она ничего не ждет, в независимости... поэтому событие ожидается в течении 2 сек. по
WaitForSingleObject(Overlapped.hEvent,2000)
И проверка на результат выполнения делается только у этой ф-и.
> for i:=1 to MaxFail do
> begin
> if Get>Need then break;
> sleep(50);
> end;
Хех, то есть ты предлагаешь грубо говоря через жопу все реализовать, можно конечно и так, но мне непонятна сама логикак о которой я выше написал.
← →
tesseract © (2007-05-14 17:52) [5]
> Хех, то есть ты предлагаешь грубо говоря через жопу все
> реализовать, можно конечно и так, но мне непонятна сама
> логикак о которой я выше написал.
Девайс не готов. EV_RXCHAR должен срабатывать на помещение 1-го байта, а не всей посылки, чтобы дождаться всей посылки нужно время. Если нет CTS/RTS то можно так, или через отложенное чтение по одному байту etc.
> А что за баг с модемом?
Что-то там с фальшивым срабатыванием event при установленном модеме. Точно не помню.
← →
POP (2007-05-14 18:00) [6]
> Девайс не готов. EV_RXCHAR должен срабатывать на помещение
> 1-го байта, а не всей посылки, чтобы дождаться всей посылки
> нужно время. Если нет CTS/RTS то можно так, или через отложенное
> чтение по одному байту etc.
Я не юзаю EV_RXCHAR, я юзаю EV_RXFLAG, посмотри внимательно на код, это две разные вещи.
В структуре DCB у меня задан байт, который и отслеживается по EV_RXFLAG, этот байт в потоке встречается только в одном месте, в конце пакета, значит если это событие наступило, значит прилетел весь пакет.
А раз он прилетел, значит по:
ClearCommError(ComFile, Err, @ComStat);
CountB:= ComStat.cbInQue;
в CountB у меня должно лежать количество прилетевших байт.
← →
tesseract © (2007-05-15 10:58) [7]
> Я не юзаю EV_RXCHAR, я юзаю EV_RXFLAG, посмотри внимательно
> на код, это две разные вещи.
Не такие уж разные.
> значит если это событие наступило, значит прилетел весь
> пакет.
Этого в коде не видно. Возможно дрова кривые. Но по ReadFile строго рекомендуется вызывать GetOverlappedResult.
← →
POP (2007-05-16 03:18) [8]Вообщем сделал через жопу, как ты и советовал. Проблема не в том что по ClearCommError он выдает ноль, хотя событие наступило (хотя и в этом тоже), а в том, что тел. не успевает обработать инфу, по ClearCommError может показать и не ноль, но далее по ReadFile вычитает неполный пакет.
Поэтому я в цикле сделал две проверки с задержками по 20ms, все пашет на медленных и тормознутых в этом смысле мобилах.
Но вопрос остается в силе:
Почему при наступлении события сигнализирующего о том что пришел последний байт пакета ( а значит не ноль байтов пришло), далее по ClearCommError может выдать о том что в буфере лежит ноль байтов?
Или я не понимаю как работает COM порт? Где тормозит виртуальный COM порт по сравнению с обычными портами?
Такая проблема только на некоторых виртуальных портах.
← →
POP (2007-05-16 03:25) [9]
> Этого в коде не видно. Возможно дрова кривые. Но по ReadFile
> строго рекомендуется вызывать GetOverlappedResult.
PS При использовании GetOverlappedResult софт не будет пахать на Win95,98, Me, а это не есть гуд.
← →
tesseract © (2007-05-16 10:38) [10]
> PS При использовании GetOverlappedResult софт не будет пахать
> на Win95,98, Me,
Мой пашет, хотя на Win95 не проверял.
Requirements
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.
> Такая проблема только на некоторых виртуальных портах.
Ты ещё с COM-TCP преобразователями не работал. Там реально задержка виртпорта жесть. Приходиться изголяться пытаясь уложиться в 200 мс реакции девайса.
ЗЫ : с преобразователями только через их протокол, никаких "виртуальностей"!
Так что "советский" метод я из личного опыта предложил.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.06.03;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.046 c