Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.47 MB
Время: 0.054 c
4-1100584362
paa
2004-11-16 08:52
2005.01.02
Узнать имя DLL которую загрузил мой процесс


1-1103207093
Bless
2004-12-16 17:24
2005.01.02
Что вызывается вместо inherited в данном случае?


14-1102883236
Mihey_temporary
2004-12-12 23:27
2005.01.02
Соответствие кода стандартам HTML 4.01


9-1093616835
Just3r
2004-08-27 18:27
2005.01.02
Interceptors - космическая аркада


3-1101986159
Chery
2004-12-02 14:15
2005.01.02
Стринг - Дата - Максимальное значение.




   Наверх