Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.053 c
2-1179338905
Strate
2007-05-16 22:08
2007.06.03
Функция проверки строки...


2-1179142023
ыавпып
2007-05-14 15:27
2007.06.03
String


2-1179307471
V9
2007-05-16 13:24
2007.06.03
Подскажите функцию определения високосного года


3-1173958678
SergTT
2007-03-15 14:37
2007.06.03
Как обойти ситуацию с заполнением значения ключевого поля


15-1178518779
db2admin
2007-05-07 10:19
2007.06.03
Модульное ПО





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский