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

Вниз

Проблема с организацией работы с железкой через 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 вся ветка

Текущий архив: 2005.01.02;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.042 c
14-1102938643
antonn
2004-12-13 14:50
2005.01.02
Звуки на мобилу


4-1099157058
TankMan
2004-10-30 21:24
2005.01.02
Как правильно запускать сервис во время проэктирования?


1-1103203996
socol
2004-12-16 16:33
2005.01.02
перевод в другой вид представления


1-1103222533
Dmitry_04
2004-12-16 21:42
2005.01.02
Определить какие файлы в папке


3-1102320495
AleKo
2004-12-06 11:08
2005.01.02
ClientDataSet