Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

и снова про COM порты


TCrash ©   (2003-11-12 00:14:00) 

Сегодня искал здесь как работать с СОМ-портами и остановился на примере по адресу http://www.delphimaster.ru/articles/comport2/index.html
Пока что смущает одно - и я прекрасно понимаю почему так происходит. При запущенной процедуре опроса порта загрузка проца 100%.
Повторюсь, я прекрасно понимаю почему это так, но может кто посоветует, как изменить процедуру, чтобы не было такого "потрясающего" эффекта.

Я так полагаю, это вопрос скорее всего к автору проекта, но буду благодарен всем :-)


y-soft   (2003-11-12 16:57:00) [1]

Sorry за опечатку, следует читать:


...
if not WaitCommEvent(fCommHandle, Evts, @Overlapped) then
...


y-soft   (2003-11-12 16:03:00) [2]

Не поленился и скачал пример. Очень много странностей :))

Например, порт открывается с флагом FILE_FLAG_OVERLAPPED, но процедуры ожидания событий, чтения и записи в порт написаны, как для синхронного ввода/вывода

Правильно делать примерно так (только принцип):

var
Overlapped : TOverlapped;
LastError, Evts, Dummy : DWORD;
begin
FillChar(Overlapped,SizeOf(Overlapped),0);
Overlapped.hEvent := CreateEvent(nil,True,False,nil);
if (Overlapped.hEvent = INVALID_HANDLE_VALUE) then
raise Exception.Create("Ошибка создания события");
try
Evts := 0;
if not WaitCommEvent(fCommHandle, Evts, Overlapped) then
begin
LastError := GetLastError;
if LastError = ERROR_IO_PENDING then
begin
if WaitForSingleObject(Overlapped.hEvent, INFINITE) =
WAIT_OBJECT_0 then
GetOverlappedResult(fCommHandle, Overlapped, Dummy, True)
else
raise Exception.Create("Ошибка WaitForSingleObject");
end
else
raise Exception.Create(SysErrorMessage(LastError));
end;
if Evts and EV_RXFLAG = EV_RXFLAG then
begin
if not ClearCommError(fComHandle,LastError,nil) then
raise Exception.Create("Ошибка ClearCommError");
//Далее аналогичным образом читаем из порта...
end;
finally
CloseHandle(Overlapped.hEvent);
end;



Если же перекрытый ввод/вывод не используется, то необходимо обязательно установить таймауты (это в любом случае не лишне)

ЗЫ Можно и не создавать явным образом Event в Overlapped, а в функции ожидания передавать описатель порта, но тогда будет вести себя очень странно в Win9X


Digitman   (2003-11-12 15:26:00) [3]


> TCrash


там же ясно написано :

Процедура ReadComm
Теперь пристально рассмотрим процедуру ReadComm. Во-первых, это обычная процедура, входя состав модуля. Во-вторых, все ее содержимое зацикливается с помощью while true do. Но это не смертельно. Все-таки запускаем процедуру исключительно в отдельном потоке, так что беды не будет

т.е. "это не смертельно", когда цикл организован в доп.код.потоке. К тому же в момент выполнеия WaitCommEvent() код.поток "спит" и не требует временных ресурсов.

так что непонятно, откуда у тебя взялась 100%-я загрузка, если ты придерживаешься упомянутых в статье требований


TCrash   (2003-11-12 09:34:00) [4]

А можно на них взглянуть, если ты, конечно, уже на работе :-)


Talla2k   (2003-11-12 01:05:00) [5]

Там много ошибок!!!
Посылка chr($0)+chr($01) не будет выполнена!
Не совсем верная инициализация!!!
А загрузка у меня 2% !!!(но исходники на работе,извини)


Наверх

Титульная страница Поиск, карта сайта Написать письмо