Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.06.03;
Скачать: CL | DM;

Вниз

Непонятка с передачей данных (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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.045 c
2-1179310746
Шакал
2007-05-16 14:19
2007.06.03
Удаление из нескольких таблиц


3-1174040531
salexn
2007-03-16 13:22
2007.06.03
Как прервать выполнение запроса в TClientDataSet


2-1179219374
leshas0
2007-05-15 12:56
2007.06.03
функция - вернуть массив


15-1178529482
lu4ina
2007-05-07 13:18
2007.06.03
TreeView


2-1179381387
Oleg_teacher
2007-05-17 09:56
2007.06.03
Фильтрацыя