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

Вниз

вопрос к спецам по портами ! ...   Найти похожие ветки 

 
Godness   (2003-05-21 22:12) [0]

Здраствуйте ... Имею следующую проблему с портом:
Вот такой значит код в потоке - ...
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure T.Execute;
begin
//prtMask := EV_CTS;
prtMask := EV_RXCHAR;
buffer[0] := 0;
prtHandle := CreateFile(PChar(prtPort), GENERIC_READ, 0,
nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

if prtHandle = INVALID_HANDLE_VALUE then begin
ShowMessage("не могу открыть порт !");
Exit;
end;

GetCommState(prtHandle, prtDCB);
prtDCB.BaudRate := prtSpeed;
prtDCB.ByteSize := 8;
prtDCB.Parity := NOPARITY;
prtDCB.StopBits := ONESTOPBIT;

if not SetCommState(prtHandle, prtDCB) then begin
ShowMessage("не могу принять настроек порта !");
CloseHandle(prtHandle);
Exit;
end;

GetCommTimeOuts(prtHandle, prtTimeOut);
prtTimeOut.ReadIntervalTimeout := MAXDWORD;
prtTimeOut.ReadTotalTimeoutMultiplier := MAXDWORD;
prtTimeOut.ReadTotalTimeoutConstant := 500;


if not SetCommTimeOuts(prtHandle, prtTimeOut) then begin
ShowMessage("не могу принять настроек порта !");
CloseHandle(prtHandle);
Exit;
end;

PurgeComm(prtHandle,PURGE_RXCLEAR);
FillChar(prtOverlapped, sizeof(prtOverlapped), 0);
prtOverlapped.hEvent := CreateEvent(nil, true, false, nil);

SetCommMask(prtHandle, prtMask);

repeat
WaitCommEvent(prtHandle, prtMask, @prtOverlapped);
ReadFile(prtHandle, buffer[0], 4, count, nil);
if not (count = 0) then begin Synchronize(ShowBuffer); end;
count := 0;
until Terminated;

MessageBeep(MB_OK);
CloseHandle(prtOverlapped.hEvent);
CloseHandle(prtHandle);
end;

procedure T.ShowBuffer;
begin
MainForm.Label1.Caption := "Принят символ: $" + inttostr(buffer[0]);
end;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
вроде все нормально, все работает, принимает символы с порта ... однако при этом !!! 100 !!! % загрузка процессора ... :( Подскажите, пожалуйста, что не так ??? ...


 
N125   (2003-05-21 22:59) [1]

Вставить Sleep(10) в некритичном месте


 
Digitman   (2003-05-22 10:10) [2]

Тебе о чем-то говорит вот этот фрагмент хэлпа в описании функции (!!! она возвращает результат !!!) WaitCommEvent() ?

If the overlapped operation cannot be completed immediately, the function returns FALSE and the GetLastError function returns ERROR_IO_PENDING, indicating that the operation is executing in the background. When this happens, the system sets the hEvent member of the OVERLAPPED structure to the not-signaled state before WaitCommEvent returns, and then it sets it to the signaled state when one of the specified events or an error occurs. The calling process can use one of the wait functions to determine the event object"s state and then use the GetOverlappedResult function to determine the results of the WaitCommEvent operation. GetOverlappedResult reports the success or failure of the operation, and the variable pointed to by the lpEvtMask parameter is set to indicate the event that occurred.


 
Godness   (2003-05-22 16:17) [3]

Я, конечно постараюсь перевести всю эту бредятину :) ... но, ты не мог бы привести конкретный пример ...


 
Digitman   (2003-05-22 16:28) [4]


> эту бредятину


это ? "бредятина" ?? ну уж - извини)))) ...
когда ф-ция бездумно используется как процедура - вот это уж точно "бредятина")

нет, ну а все же - почитать для начала ?


 
Godness   (2003-05-22 16:37) [5]

Да я шучу ... ты, что не рубиш ?! Просто не шарю я в английском - жопаделаеш :) ...
Кто-нить, приведите пример если не трудно, пожалуйста ...


 
pasha676   (2003-05-22 16:42) [6]

В цикле приема не вижу

1) Проверки маски prtMask - на предмет, а какое все же событие произошло
Points to a 32-bit variable that receives a mask indicating the type of event that occurred. If an error occurs, the value is zero;
Вдруг у тебя там сплошные нули прут и цикл начинает крутиться со страшной силой, чем и забивает остальные процессы (да и подвесить винду могет). Впрочем я вроде пишу тоже что и Digitman но другими словами.

2) Я обычно после прихода эвента и проверки тот ли это эвент делаю ClearCommError. Он вроде сбрасывает флаг о приходе события.
Поправьте если я ошибаюсь.


 
Digitman   (2003-05-22 17:41) [7]


> Godness


да, ты, чувствуется, и по-русски не "рубиш")

я ж тебе уже "перевел" : WaitCommEvent() - это ФУНКЦИЯ ! Где анализ результата, возвращаемого ей ? Ты ж где-то этот пример содрал) ... Что, там так и бло - вызов WaitCommEvent() как процедуры ? И безо всяких комментариев ?))


 
Godness   (2003-05-22 18:12) [8]

> WaitCommEvent() - это ФУНКЦИЯ !
Какой ты умный !!! А то я и не знал, что это ФУНКЦИЯ !

> Что, там так и бло - вызов WaitCommEvent() как процедуры ? И безо всяких комментариев ?)) Как ты можеш догадаться так и бло ...

> Где анализ результата, возвращаемого ей ? нЭтУ ...

Я чего-же и хочу - примера (!!!) ... это, что так трудно если ты такой умный. А говорить и копировать хэлп я и сам могу не хуже тебя ;( ...


 
AlexRush   (2003-05-22 19:17) [9]

Для чтения данных из com порта WaitCommEvent в общем-то и ни к чему. Ждать данных в данном случае предпочтительно с пом. overlaped I/O и WaitForSingleObject. Привожу реально работающий код:


UINT __stdcall CCommPort_ReadCommThreadProc(void *pParam){
if(pParam) ((CCommPort*)pParam)->ReadCommThreadProc();
ExitThread(0);
return 0;
}

void __stdcall CCommPort::ReadCommThreadProc(){
DWORD dwReaded,dwTransfered;
char buf[COMM_BUF_SIZE];

//if(GetCurrentThread()!=hThread) return;

while(TRUE){
ZeroMemory(buf,COMM_BUF_SIZE);
dwReaded = 0;
dwTransfered = 0;
if(fOnWaitAnswerProc)fOnWaitAnswerProc(this,1);
if(!ReadFile(hComm,
buf,
COMM_BUF_SIZE,
&dwReaded,
&ovr)
){
switch(GetLastError()){
case ERROR_IO_PENDING:
if(WAIT_OBJECT_0
==
WaitForSingleObject(ovr.hEvent,INFINITE)
){
if(!GetOverlappedResult(hComm,&ovr,&dwTransfered,TRUE)){
fSuccessful = FALSE;
return;
}
else dwReaded = dwTransfered;
}
else return;
break;
}
}//if(!ReadFile(pObj->GetCommHandle(),
if(fOnWaitAnswerProc)fOnWaitAnswerProc(this,0);
if(dwReaded) OnDataRead(buf,dwReaded);
Sleep(20);
}// wtd
}


 
AlexRush   (2003-05-22 19:21) [10]

Чего неясно - объясню :)


 
Godness   (2003-05-23 20:01) [11]

... ничерта не ясно :). Я в С ничего не понимаю. Вижу ты используеш специализированный класс Си - CCommPort, а что же в Delphi ?.. Я могу конечно использовать готовую компоненту Delphi, но хочу разобраться с СОМ портом на уровне API ... Вся проблема у меня, как вижу, в асинхронном ожидании (WaitSingleObject, GetOverlappedResult и т.д.). Не знаю когда, что нужно вызывать. Переведи это все на Delphi или кинь какую-нить толковую(!) ссылку, плз ... Хотелось бы также и с WaitCommEvent разобраться ...


 
Slym   (2003-05-25 10:01) [12]

Попробуй так

> repeat
> if WaitCommEvent(prtHandle, prtMask, @prtOverlapped)<>0 then
begin
WaitForSingleObject(prtOverlapped.hEvent,INFINITE);

ReadFile(prtHandle, buffer[0], 4, count, nil);
> if not (count = 0) then
Synchronize(ShowBuffer);
end;
> count := 0;
> until Terminated;
>


 
Verg   (2003-05-25 13:49) [13]


> Просто не шарю я в английском - жопаделаеш :) ...

.....

> Я в С ничего не понимаю.


Огласите весь список, пжаста....


 
AlexRush   (2003-05-26 12:06) [14]

>> Godness © (23.05.03 20:01) >> C желателно знать :))
Класс в примере - мой собственный.
А делать следует так:

0 Открываем файл COMx с пом. CreateFile и устанавливаем флаг FILE_FLAG_OVERLAPPED для асинхронного I/O
1 Пытаемся читать из файла (порта).
1.1 Если ReadFile вернет FALSE (а так и должно быть)
проверяем GetLastError() на код последней ошибки.
Если ошибка - ERROR_IO_PENDING - все в порядке,система поставила запрос на чтение в очередь. Нужно подождать, пока данные поступят в порт и будут прочитаны в буфер.
Для этого вызываем
WaitForSingleObject(ovr.hEvent,INFINITE), где ovr - cтруктура OVERLAPPED.
После того, как она вернет, проверяем результат I/O GetOverlappedResult(hComm,&ovr,&dwTransfered,TRUE)
Если все в порядке, буфферр уже содержит данные.
1.2 Если ReadFile вернет TRUE, то, вероятно, данные уже были в порте и сразу были вычитаны в буфер (но не уверен).


 
Digitman   (2003-05-26 12:46) [15]


> Godness



> А то я и не знал, что это ФУНКЦИЯ !


Ну так а почему же ты не задаешь вопрос, что означает тот или иной результат, возвращаемый этой ф-цией ? Или, по кр.мере, не просишь перевести фрагмент хэлпа, раз "не рубиш" ?

Если текущая запрошенная overlapped-операция не может быть полностью выполнена (еще не завершилась) непосредственно на момент вызова WaitCommEvent(), то ф-ция возвращает FALSE, а GetLastError() возвращает значение ERROR_IO_PENDING, означающее, что интересующая операция еще продолжает выполняться в "фоновом" режиме. Когда такая ситуация (с незавершенностью операции) имеет место быть, система в ходе исполнения ф-ции WaitCommEvent()устанавливает объект hEvent OVERLAPPED-структуры в несигнальное состояние, и впоследствии, когда операция полностью завершится, система переведет объект hEvent OVERLAPPED-структуры в сигнальное состояние (что будет означать фактическое завершение операции, успешное либо прерванное системой по возникшей ошибке)
Вызывающий ф-цию процесс может использовать одну из системных ф-ций ожидания событий для определения состояния объекта hEvent, и по завершению ф-ции ожидания может узнать о результатах "отложенного" вызова WaitCommEvent() с помощью GetOverlappedResult().
По реззультату вызова ф-ции GetOverlappedResult() можно судить об успешном завершении операции либо ее прерыванию по отказу в ходе выполнения, а битовые флаги в переменной, на которую ссылается поле lpEvtMask, укажут на то, о каких конкретно событиях просигнализировала систем а установкой объекта hEvent в сигнальное состояние.

Надеюсь, не слишком "умно" будет выглядеть сей "художественный" перевод ?)


 
Digitman   (2003-05-26 12:52) [16]

Только не спрашивай, что такое "системный объект синхронизации", ибо дальнейшие "рассуждения"на тему "как все это сделать на WinAPI" бессмысленны для краткого изложения в рамках форума... уж слищком "заумно" будет это выглядеть для тебя))


 
Godness   (2003-05-27 20:33) [17]

Ура - разобрался ! Спасибо !!! :))) ... Может кому интересно, привожу все это в нормальный вид:

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
repeat
ReadFile(prtHandle, prtBuffer[0], 100, count, @prtOverlapped);
if GetLastError = ERROR_IO_PENDING then
case WaitForSingleObject(prtOverlapped.hEvent, INFINITE) of
WAIT_OBJECT_0:
begin
GetOverlappedResult(prtHandle, prtOverlapped, count, true);
Synchronize(ShowBuffer);
PurgeComm(prtHandle, PURGE_RXCLEAR+PURGE_RXABORT);
end
end
until Terminated;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
... или так ...
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
SetCommMask(prtHandle, EV_RXCHAR);
repeat
WaitCommEvent(prtHandle, mask, @prtOverlapped);
case WaitForSingleObject(prtOverlapped.hEvent, 1000) of
WAIT_OBJECT_0:
if (mask and EV_RXCHAR) = EV_RXCHAR then begin
ReadFile(prtHandle, prtBuffer[0], 100, count, @prtOverlapped);
if GetOverlappedResult(prtHandle, prtOverlapped, count, true) then
Synchronize(ShowBuffer);
end;
WAIT_TIMEOUT: MessageBeep(MB_OK);
end;
until Terminated;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

Последнее удобно тем, что можно маску порта установить, однако нельзя поставить INFINITE в WaitForSingleObject, т.к. если ничего не придет на порт, то эта функция будет ждать вечно. В отличие от первого варианта, в котором событие всегда вернется по истечению тайм-аута порта ... Если где-то не прав - поправьте !.., но все это нормально работает ... проверял


 
Godness   (2003-05-27 20:56) [18]

> Огласите весь список, пжаста....

:) ...

> Только не спрашивай, что такое "системный объект синхронизации" - ладно, не буду ... :)


 
Godness   (2003-05-27 21:20) [19]

Удалено модератором
Примечание: Дальше тема уйдет в корзину.


 
Godness   (2003-05-27 21:54) [20]

я просто попросил модератора обьяснить - почему эта тема необоснованно попала в "потрепаться"

полный произвол !!!


 
Godness   (2003-05-27 22:02) [21]

... причем довольно вежливо ;( ...



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

Форум: "Потрепаться";
Текущий архив: 2003.06.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.008 c
3-34680
Andy Eremin
2003-05-20 07:48
2003.06.12
Базы данных


6-34948
Sherbacov
2003-04-08 21:05
2003.06.12
Как создать свой протокол.


1-34908
Salvator
2003-05-28 11:48
2003.06.12
Работа с Word через Delphi


14-34995
Vitas2
2003-05-26 13:19
2003.06.12
SQL


1-34834
HardClubber
2003-06-02 01:22
2003.06.12
Перемещение формы





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