Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];

Вниз

Проблема с организацией работы с железкой через Com-порт...   Найти похожие ветки 

 
Balkon   (2004-11-18 16:11) [0]

Приветствую, Мастера!
Будте добры, проконсультируйте.
Пишу программу для работы с некой железкой через com-порт.

Приложение организую следующим образом:

Имеется основной поток MainForm и вторичный поток AKRThread, в котором динамически создается объект ComPort (последний  из ComPortLibv2.64 создает свой поток для работы с портом, но это не суть важно, я только ипользую его функции синхронной записи и чтения из порта, а также его событие ComPort.OnRxChar, возникающее по прилету информации в порт).

Организую выходную и входную очереди команд и ответов для устройства. В основном потоке выходная очередь заполняется, при каждом заполнении посылаю сообщение WM_COMANDWASADDED вторичному потоку, который достает команду из очереди и посылает в порт устройству. При получении ответов от устройства соответственно все наоборот со входной очередью.

Проблема в следующем:
Железка, обрабатывая команду (время до 2 сек, но в основном в течении нескольких миллисекунд), выдает ответ. Все данные которые прилетают во время обработки текущей команды теряются.

Т.о. во вторичном потоке нужно дожидаться ответа на каждую команду из очереди. Я это "как-то" реализовал: При записи команды в порт во вторичном потоке устанавливается флаг WaitForAnswer и снимается при получении ответа. Этот флаг проверяется при прилете сообщения от MainForm от том, что  в выходную очередь поступила команда (WM_COMANDWASADDED). Если в этот момент происходит ожидание ответа, то отсылаю MainForm сообщение WM_TRYAGAIN, на что MainForm опять посылает сообщение WM_COMANDWASADDED потоку AKRThread. Т.о. из выходной очереди ничего не достается и не посылается в порт до тех пор, пока в потоке висит флаг ожидания ответа, а между основным и вторичным потоком циклом летают сообщения.

Все вроде работает, правда изредка за счет этого цикла сообщений использование процессора взлетает до 100% на пару секунд. Однако понимаю, что именно ожидание ответа от устройства вторичным потоком реализованио Коряво!(может даже фатально Коряво :))

Посоветуйте как можно правильнее организовать это ожидание.
Буду очень признателен за комментарии.
В любом случае спасибо что прочли. :)


 
GanibalLector ©   (2004-11-19 02:00) [1]

Могу помочь,но исключительно на API...без всяких там ComPortLibv2.64.А вообще-то статей навалом...особенно на королевстве.


 
Германн ©   (2004-11-19 02:29) [2]

2 Balkon   (18.11.04 16:11)
Для начала объясни, что значит:
"я только ипользую его функции синхронной записи и чтения из порта, а также его событие ComPort.OnRxChar, возникающее по прилету информации в порт".

Синхронная запись и синхронное чтение - несовместимы с "Событием", также как событие OnRxChar - не совместимо с любой "синхронностью"!


 
Balkon   (2004-11-19 10:23) [3]

>GanibalLector ©
>Могу помочь,но исключительно на API...без всяких там ComPortLibv2.64

Буду рад помощи. Но причем тут ComPortLibv2.64 :) Компонент исправно пишет и читает из порта (IMHO). Проблема в правильной идее построения приложения, которой как раз мне и не хватает.

>А вообще-то статей навалом...
Читал коечто. Про то как писать и читать из порта и т.п. Но проблема то не в этом.


 
Balkon   (2004-11-19 10:27) [4]

>Германн ©
Вопрос терминологии.. Я не спец, возможно. Вот пример кода синхронной записи, чтение аналогично...

// perform synchronous write operation
function TCustomComPort.Write(const Buffer; Count: Integer): Integer;
var
 AsyncPtr: PAsync;
begin
 InitAsync(AsyncPtr);
 try
   WriteAsync(Buffer, Count, AsyncPtr);
   Result := WaitForAsync(AsyncPtr);
 finally
   DoneAsync(AsyncPtr);
 end;
end;
// perform asynchronous write operation
function TCustomComPort.WriteAsync(const Buffer; Count: Integer; var AsyncPtr: PAsync): Integer;
var
 Success: Boolean;
 BytesTrans: DWORD;
begin
 if AsyncPtr = nil then
   raise EComPort.CreateNoWinCode(CError_InvalidAsync);
 PrepareAsync(okWrite, Buffer, Count, AsyncPtr);

 Success := WriteFile(FHandle, Buffer, Count, BytesTrans, @AsyncPtr^.Overlapped)
   or (GetLastError = ERROR_IO_PENDING);

 if not Success then
   raise EComPort.Create(CError_WriteFailed, GetLastError);

 SendSignalToLink(leTx, True);
 Result := BytesTrans;
end;



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.035 c
1-1103310754
Жекер
2004-12-17 22:12
2005.01.02
Что за предупреждение?


14-1103087651
antonn
2004-12-15 08:14
2005.01.02
мой препод ваще опух


14-1102704536
_UnderT_
2004-12-10 21:48
2005.01.02
Dial up server


1-1103323717
Вопрос
2004-12-18 01:48
2005.01.02
WorkSheets в EXCEL


14-1103055770
Kein
2004-12-14 23:22
2005.01.02
запись звука с центра





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский