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

Вниз

Проблема с записью информации в COM-порт под WinXP   Найти похожие ветки 

 
MAPIIIAJL   (2003-08-07 21:41) [0]

Люди нужна ваша помощь. Осуществляю обмен с устройством в WinXP, формирую посылку длинной 16 байт, пытаюсь отправить ее в COM порт, но Функция WriteFile отказывается работать, выдает сообщение: "Протекает наложенное событие ввода/вывода". Когда вместо праметра этой функции "@ovr", ставлю "nil", возникает другая ошибка после ее выполнения "Параметр задан неверно". Не знаю что делать. Подскажите. Вот пример кода:
Запись в порт:
function WriteCom(l: Integer): boolean;
var
i: Integer;
dwCommEvent: DWORD;
lpMsgBuf:pchar;
ovr:TOVERLAPPED;
comst:TCOMSTAT;
begin
dwSize:=0;
ovr.Internal:=0;ovr.InternalHigh:=0;ovr.Offset:=0;
ovr.OffsetHigh:=0;ovr.hEvent:=0;
ovr.hEvent:=CreateEvent(nil,True,False,nil);
ks(l);//Расчет контрольной суммы
if not EscapeCommFunction(hCommPort,CLRDTR) then begin result:=False; exit; end;
hCommSetTimeOuts(50,5,100,5,1);
if not WriteFile(hCommPort,buf,l,dwSize,@ovr) then begin
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER or
FORMAT_MESSAGE_FROM_SYSTEM or
FORMAT_MESSAGE_IGNORE_INSERTS,
nil,
GetLastError(),
LANG_NEUTRAL , // Default language
@lpMsgBuf,
0,
nil);
Application.MessageBox(lpMsgBuf,"Error",MB_OK or MB_ICONINFORMATION );
result:=false; exit;
end;
if not EscapeCommFunction(hCommPort,SETDTR) then begin result:=False; exit; end;
C_Wr:=C_Wr+1;
result:= TRUE;
end;

Установка таймаутов:
procedure hCommSetTimeOuts(Rit: DWORD; Rttm: DWORD;
Rttc: DWORD; Wttm: DWORD; Wttc: DWORD);
var
t: TCOMMTIMEOUTS;
begin
GetCommTimeouts(hCommPort,t);
t.ReadIntervalTimeout:= Rit;
t.ReadTotalTimeoutMultiplier:=Rttm;
t.ReadTotalTimeoutConstant:=Rttc;
t.WriteTotalTimeoutMultiplier:=Wttm;
t.WriteTotalTimeoutConstant:=Wttc ;
if Not(SetCommTimeouts(hCommPort,t)) then SystemMessError();
end;

Аналогичная бодяга творится и с функцией ReadFile. Когда вместо WriteFile, я использую функцию TransmitCommChar (т.е. передаю всю посылку побайтно). Такая фишка работает прекрасно в 98-х виндах, но не в XP.


 
Digitman   (2003-08-08 09:37) [1]


> выдает сообщение: "Протекает наложенное событие ввода/вывода".
> Когда вместо праметра этой функции "@ovr", ставлю "nil",
> возникает другая ошибка после ее выполнения "Параметр задан
> неверно".


все верно. так и должно быть.

коль скоро ты создал коммуникационный файл с флагом FILE_FLAG_OVERLAPPED, ты обязан указать именно @ovr - адрес структуры-оверлэпа, а не nil.

поскольку использование системного оверлэп-механизма ввода/вывода подразумевает асинхронные операции в/в, то возврат ф-циями ввода/вывода кода ошибки ERROR_IO_PENDING - вполне нормальное явление, которое следует интерпретировать не как отказ, а как извещение о старте "фоновой" операции. О факте завершения и результатах стартованной таким образом операции система сообщит "просигналив" ивентом, что ты создал и указал в оверлэп-структуре, передав хендл ивента (hEvent).
При получении ERROR_IO_PENDING как результата GetLastError после "неуспешного" завершения ф-ций в/в, необходимо действовать в соответствии со след.рекомендациями (ниже - цитата из станд.хэлпа):

Overlapped operations enable a thread to execute a time-consuming I/O operation in the background, leaving the thread free to perform other tasks. To enable overlapped I/O operations on a communications resource, the thread must specify the FILE_FLAG_OVERLAPPED flag in the CreateFile function when the handle is opened. To execute the ReadFile or WriteFile function as an overlapped operation, the calling thread must specify a pointer to an OVERLAPPED structure.The OVERLAPPED structure must contain a handle to a manual-reset (not an auto-reset) event object. The system sets the state of the event object to not-signaled when a call to the I/O function returns before the operation has been completed. The system sets the state of the event object to signaled when the operation has been completed. The thread uses a wait function to check the current state of the event object or to wait for its state to be signaled.

The ReadFileEx and WriteFileEx functions can be performed only as overlapped operations. The calling thread specifies a pointer to the FileIOCompletionRoutine function, which is executed when the overlapped operation is completed. The completion routine is executed only if the calling thread performs an alertable operation.
For more information about event objects, wait functions, alertable waits, and completion routines, see Synchronization.


 
N169   (2003-08-08 10:23) [2]

+ Кстати насчёт "EscapeCommFunction(hCommPort,SETDTR)"

Если задана аппаратная поддержка квитирования, DTR управляется автоматически, и эта ф-я всегда будет возвращать FALSE, так что разумно игнорировать её возврат


 
MAPIIIAJL   (2003-08-08 12:20) [3]

Digitman ©, Я попробую сделать ожидание окончания операции передачи таким макаром:

WriteFile(hCommPort,buf,l,dwSize,@ovr);
if(WaitForSingleObject(ovr.hEvent,2000)=WAIT_OBJECT_0) then
( hCommPort,ovr,dwSize,FALSE)
Digitman ©, Я попробую сделать ожидание окончания операции передачи таким макаром:

WriteFile(hCommPort,buf,l,dwSize,@ovr);
if(WaitForSingleObject(ovr.hEvent,2000)=WAIT_OBJECT_0) then
GetOverlappedResult(hCommPort,ovr,dwSize,FALSE)
else begin
// Обработка ошибки //
result:= False;
end;

Но, проблема в том что я не вижу посылки на осцилографе.
Однако при использовании TransmitCommChar, я ее вижу.
А допустим мне ненужна асинхронная приемопередача. Как мне сделать так, чтобы при синронной приемопередаче функция WriteFile работала нормально?


 
Digitman   (2003-08-08 13:20) [4]

оставь свой осциллограф на время в покое)

ответь на вопросы :

1. если WriteFile() возвратил False, то каков код отказа, возвращаемый GetLastError() ?

2. если WriteFile() возвратил True, то дожидаешься ли условия WaitForSingleObject()=WAIT_OBJECT_0 ? Если нет, то каков код отказа, возвращаемый WaitForSingleObject() ?


 
MAPIIIAJL   (2003-08-10 01:13) [5]

Отвечаю:
1. если WriteFile() возвратил False, то каков код отказа, возвращаемый GetLastError() ?
WriteFile возвращает False. Код возврата GetLastError соответствует 997!
Извени что так долго, инет отрубили.




 
Nucl   (2003-08-10 16:58) [6]

http://delphibase.endimus.com/?action=viewfunc&topic=hardsystem&id=104 52


 
MAPIIIAJL   (2003-08-10 20:31) [7]

Nucl © В том примере, что ты мне дал есть небольшое НО.
Ограничения: D6, WinXP. У меня стоит D7 и WinXP.
Если ты прочитал вопрос, то стоит проблема работы в WinXP.
Конечно, необходимо чтобы все работало и в 98, и в WinXP.
И еще компоненты различные тоже брать не очень хочется, мне кажется что просто все решается с помощью API функций.


 
Nucl   (2003-08-10 20:57) [8]

2 Маршал
да нет его там, рулит везде (сам проверял)


 
MAPIIIAJL   (2003-08-11 00:27) [9]

Nucl ©
Ок. Спасибо, попробую. Заманчивый код.


 
Digitman   (2003-08-11 09:25) [10]


> WriteFile возвращает False. Код возврата GetLastError соответствует
> 997!


Все верно. ERROR_IO_PENDING = 997, как и ожидалось.

Далее - что возвращает WaitForSingleObject() ?


 
MAPIIIAJL   (2003-08-11 10:44) [11]

WaitForSingleObject(ovr.hEvent,2000) возвращает 0. Как я понимаю, что соответствует WAIT_OBJECT_0.


 
Digitman   (2003-08-11 11:18) [12]

т.е. оверлэп-операция завершилась.

следом же д.б. вызов GetOverlappedResult(), который даст инф-цию о числе байт, успешно отправленных в результате операции

см.

pNumberOfBytesTransferred

Points to a 32-bit variable that receives the number of bytes that were actually transferred by a read or write operation


 
MAPIIIAJL   (2003-08-11 12:01) [13]

GetOverlappedResult(hCommPort,ovr,dwSize,FALSE);
Все правильно и эта функция возвращает True. Значит операция успешно завершилась. И в счетчике байт dwSize стоит 16. Поеду на работу сгоняю проверю, как это все с устройством работает. Отпишусь как приеду. Спасиб.


 
MAPIIIAJL   (2003-08-11 21:05) [14]

Digitman
Все заработало в лучшем виде. Все оказалось очень просто. Единственное что я не уяснил, это: что именно ожидает функция WaitForSingleObject?


 
Digitman   (2003-08-12 08:31) [15]

WaitForSingleObject() ожидает перевода системой объекта hEvent в сигналящее состояние


 
MAPIIIAJL   (2003-08-12 09:54) [16]

Digitman
Огромное тебе спасибо за помощь.



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

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

Наверх





Память: 0.49 MB
Время: 0.012 c
3-73973
AlexGof
2003-10-01 11:43
2003.10.23
Нужен DataSet позволящий подсоединять несколько мастер таблиц


1-74231
MakNik
2003-10-09 15:07
2003.10.23
CRC-код файла


6-74358
Infinity1
2003-08-24 23:21
2003.10.23
Как получить данные POSTDATA из TWebBroweser ?


3-74075
Ada
2003-09-25 11:29
2003.10.23
Создание индекса таблицы dBaseIII+


1-74273
REA
2003-10-13 09:54
2003.10.23
Компилятор





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