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

Вниз

Необходимо ли операции с СОМ портом, выполняемые из различных..   Найти похожие ветки 

 
Balkon   (2006-06-08 12:45) [0]

потоков, выносить в критические секции.
Спасибо за внимание.


 
tesseract ©   (2006-06-08 13:08) [1]

Если один поток - один порт, то в секции надо выносить только передачу данных в главный поток.


 
Balkon   (2006-06-08 13:41) [2]

Спасибо.
А если порт один, а потоков несколько - пишущий, читающий и меняющий настройки (интерфейсный)?


 
tesseract ©   (2006-06-08 13:52) [3]


> Спасибо.А если порт один, а потоков несколько - пишущий,
>  читающий и меняющий настройки (интерфейсный)?

Это уже критические извращения, не делай так никогда.


 
Balkon   (2006-06-08 14:03) [4]

:) странные мне вещи вы говорите.

Как же тогда реализовывать, скажем, опрос порта, в цыкле?
Я так понимаю что "спящий" до появления новых данных отдельный
поток опроса порта- это вполне оправданное решение.


 
Сергей М. ©   (2006-06-08 14:13) [5]


> :) странные мне вещи вы говорите.


Да нет, вовсе не странные это вещи...

Транспортный поток должен быть один и тот же, его ф-ция - прием/передача неких данных... Подготовка/обработка же (передаваемых/принимаемых) данных должна в этом случае быть возложена на один или более других потоков.


 
Сергей М. ©   (2006-06-08 14:19) [6]


> Как же тогда реализовывать, скажем, опрос порта, в цыкле?


А нечего его опрашивать !
Он сам сообщит о событиях, в нем произошедших ..
На то существует overlapped - режим и completion routines - режим ..
Без цикла здесь и вправду не обойтись, но цикл этот занимается не только и не столько неким "опросом", сколько ожиданием неких событий в неких подсистемах ввода-вывода, в частности - подсистеме файлововго ввода-вывода, к коей принадлежит и ввод-вывод подсистемы последовательных коммуникаций.

См. WinAPI Wait-функции.


 
tesseract ©   (2006-06-08 14:21) [7]


> На то существует overlapped - режим и completion routines
> - режим ..

Лучше использовать маску EV_RXCHAR,  тогда порт реально сообщит, что что-то пришло. а overlapped просто помогает дожаться нужного кол-ва данных.


 
Balkon   (2006-06-08 14:35) [8]

Спасибо опять...
Не знаю зачем, но делаю отдельные потоки пишущий и читающий.
Вот кусок процедуры читающего потока:

FillChar(ReadOL, SizeOf(ReadOL), 0);
   ReadOL.hEvent:= CreateEvent(nil, True, True, nil);
   SetCommMask(FPortHandle, EV_RXCHAR);
   while (not Terminated)  do
   begin
     WaitCommEvent(FPortHandle, Mask, @ReadOL);
     Signaled:= WaitForSingleObject(ReadOL.hEvent, 1000);
     if (Signaled  = WAIT_OBJECT_0)and
       GetOverlappedResult(FPortHandle, ReadOL, BytesTrans, False) then
     begin
       If (Mask and EV_RXCHAR) <> 0 then
       begin
           ...


И будте добры поясните, почему транспортный поток должен быть один и тот же? Вроде бы в различных компонентах и в книге Агурова чтение из порта выносится в отдельный поток. Или я что-то неправильно понял?


 
Сергей М. ©   (2006-06-08 14:38) [9]


> Вот кусок процедуры читающего потока:


Давай уж тогда и кусок пишущего приводи ..


 
Balkon   (2006-06-08 14:46) [10]

Сделано все для того, чтобы на посылку команды некому девайсу получить от него ответ, либо по таймауту повторить команду.

процедура пишушего потока:

 FillChar(WriteOL, SizeOf(WriteOL), 0);
 WriteOL.hEvent:= CreateEvent(nil, True, True, nil);
 FinpAKRThread := TinpAKRThread.Create(false,FOwner,FPortHandle,FComandPackage,FThreadAnswer); //Создаю читающий поток
 Try
   WriteFile(FPortHandle, FComandPackage, SizeOf(FComandPackage), RealWrite, @WriteOL);
   Signaled:= WaitForSingleObject(WriteOL.hEvent, INFINITE);
   if (Signaled = WAIT_OBJECT_0) and
     (GetOverlappedResult(FPortHandle, WriteOL, BytesTrans, False)) then
   begin
     FinpAKRThread.WaitFor;


Обмениваются данными потоки в критической секции.


 
Balkon   (2006-06-08 14:57) [11]

Прошу прощения,
ухожу из сети.

Завтра с удовольствием почитаю совтеы и ответы ежели таковые будут.
Спасибо. Берегите сябя. ;)


 
Сергей М. ©   (2006-06-08 15:14) [12]


> на посылку команды некому девайсу получить от него ответ


Ну и зачем при этом, спрашивается, два потока ?

Очевидно же - одного достаточно ...

function Get(Request: TSomeRequestType): TSomeResultType;

В теле подобной ф-ции, исполняемой контексте некоего транспортного потока, дивайсу посылаются данные в формате TSomeRequestTypeт и ожидается/возвращается от дивайса ответ в формате TSomeResultType.

Ы ?


 
Balkon   (2006-06-09 11:03) [13]

Привет опять. Спасибо.
Переписал используя один поток, который при создании своем открывает порт и наоборот соотсно.

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

Ниже приведена реализация. Нет ли в ней чего зазорного?


procedure TAKRThread.Execute;
Var
   CurrentState : TComStat;
   AvaibleBytes, ErrCode, RealRead : Cardinal;
   ReadOL : TOverLapped;
   Signaled, Mask : DWORD;
   BytesTrans : DWORD;

   TmpPackage: TReadPackage;
Begin
 if WriteAKRComand then
 Try
   FillChar(ReadOL, SizeOf(ReadOL), 0);
   ReadOL.hEvent:= CreateEvent(nil, True, True, nil);
   SetCommMask(FPortHandle, EV_RXCHAR);
   while (not Terminated)  do
   begin
     WaitCommEvent(FPortHandle, Mask, @ReadOL);
     Signaled:= WaitForSingleObject(ReadOL.hEvent, 1000);
     if (Signaled  = WAIT_OBJECT_0)and
        GetOverlappedResult(FPortHandle, ReadOL, BytesTrans, False) then
     begin
        If (Mask and EV_RXCHAR) <> 0 then
        begin
         ClearCommError(FPortHandle, ErrCode, @CurrentState);
         AvaibleBytes:= CurrentState.cbInQue;
         if (AvaibleBytes > 0) and
           ReadFile(FPortHandle, TmpPackage, AvaibleBytes, RealRead, @ReadOL) then
             CheckBytes(TmpPackage,AvaibleBytes);
       End;
     end
     else
       RepeatAKRComand;
   End;
 Finally
   CloseHandle(ReadOL.hEvent);
   SetCommMask(FPortHandle, 0);
 End;
End;

function TAKRThread.WriteAKRComand: boolean;
var
 Signaled, RealWrite, BytesTrans : Cardinal;
 WriteOL : TOverLapped;
begin
 FillChar(WriteOL, SizeOf(WriteOL), 0);
 WriteOL.hEvent:= CreateEvent(nil, True, True, nil);
 Try
   WriteFile(FPortHandle, FComandPackage, SizeOf(FComandPackage), RealWrite, @WriteOL);
   Signaled:= WaitForSingleObject(WriteOL.hEvent, INFINITE);
   Result := (Signaled = WAIT_OBJECT_0) and
     GetOverlappedResult(FPortHandle, WriteOL, BytesTrans, False);
 Finally
   CloseHandle(WriteOL.hEvent);
 End;
end;


Процедура CheckBytes(TmpPackage,AvaibleBytes) проверяет после каждой порции прилетевший байт набрался ли ответ и анализирует его корректность.


 
Сергей М. ©   (2006-06-09 12:05) [14]


> Нет ли в ней чего зазорного?


Есть.

Отсутствует анализ результатов, возвращаемых ф-циями Read/WriteFile, WaitCommEvent


 
Balkon   (2006-06-09 13:49) [15]

Спасибо большое.


 
Ihor Osov'yak ©   (2006-06-09 18:00) [16]

Зависит от архитектуры приложения и способа работы с портом.  Для примера, в своих поделках, имеющих отношение к ком-портам,  хотя они почти все многопоточные, я ни разу не использовал критических секций. Не возникало необходимости.


 
tesseract ©   (2006-06-10 09:30) [17]


>  хотя они почти все многопоточные, я ни разу не использовал
> критических секций. Не возникало необходимости.

я просто для перестраховки их использовал. Вдруг чего, не так.


 
Ihor Osov'yak ©   (2006-06-11 02:01) [18]

2 tesseract,

вспомнил одну байку, из глубокого детсва...

- слуш, зачем ты два талона компостируешь?
- а вдруг один потеряю, а тут контроль?
- а если оба потеряешь?
- ну, на этот случай у меня проездной..


 
tesseract ©   (2006-06-12 09:27) [19]


> Ihor Osov"yak ©   (11.06.06 02:01) [18]


Кто знает, вдруг больше потоков придёться создавать?



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

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

Наверх




Память: 0.52 MB
Время: 0.046 c
15-1159470172
EkZot
2006-09-28 23:02
2006.10.22
Как прервать цикл for


2-1160033184
Fostr
2006-10-05 11:26
2006.10.22
CheckBox


2-1159869536
exreler
2006-10-03 13:58
2006.10.22
Thumbnail в эксплорере


4-1149959106
suharew
2006-06-10 21:05
2006.10.22
ComPort компонент


2-1160383341
aht
2006-10-09 12:42
2006.10.22
Access+ADO