Текущий архив: 2005.08.21;
Скачать: CL | DM;
Вниз
Компонент для работы с COM портом работает в Me в XP не хочет Найти похожие ветки
← →
misyachniy © (2005-07-01 15:47) [0]Компонент для работы с COM портом работает в Me в XP не хочет.
Взял пример работы через WinApi.
Пакеты на отправляются а переводятся в ожидание "ERROR_IO_PENDING"
Кто чего подскажет?
Спасибо.
← →
Digitman © (2005-07-01 16:00) [1]
> Кто чего подскажет?
подсказываю - приводи код
← →
misyachniy © (2005-07-01 16:28) [2]Привожу:
function WriteComm(hComm : THandle; Buff : array of byte;
Count : integer;
var Writed : cardinal; Wait : boolean) : boolean;
var
Ovr : TOverlapped;
Code : DWord;
S : string;
p:pointer;
begin
p:=@Buff;
FillChar(Ovr,SizeOf(TOverlapped),0);
Ovr.hEvent := CreateEvent(nil,TRUE,FALSE,#0);
Result := WriteFile(hComm,P^,Count,Writed,@Ovr);
if not Result then begin
Code := GetLastError();
S := SysErrorMessage(Code);
if Code = ERROR_IO_PENDING
then Result := GetOverlappedResult(hComm,Ovr,Writed,Wait);
end;
CloseHandle(Ovr.hEvent);
end;
← →
Digitman © (2005-07-01 16:41) [3]флаг FILE_FLAG_OVERLAPPED, надеюсь, был указан при CreateFile() ?
> Пакеты на отправляются а переводятся в ожидание "ERROR_IO_PENDING"
и совершенно нормальная ситуация
ее не следует интерпретировать как отказ
GetOverlappedResult(hComm,Ovr, Writed, True) будет ждать завершения запущенной таким образом операции ввода/вывода, которая завершится либо полной успешной отправкой пакета (Result = True) либо отказом (Result = False), причину которого тут же можно узнать (SysErrorMessage(GetLastError))
← →
tesseract (2005-07-01 17:15) [4]Я так делаю - сильно экономит процессор
в инициализацию добавляется что-то вроде
fMask:=EV_RXCHAR and not EV_RING;
if not(SetCommMask(hCom,fMask)) then
begin
Status:=GetLastError;
Addlog("SetComMask Error" +fportName);
exit;
end;
// Ждём сообщения о чтении
WaitCommEvent(hCom,tMask,@READOL);
fSignaled:= WaitForSingleObject(ReadOl.hEvent,WaitInt);
if (fSignaled = WAIT_OBJECT_0) then
begin
// смотрим что у нас
fSignaled:= WaitForSingleObject(ReadOl.hEvent,WaitInt);
// Если событие произошло то
if (fSignaled = WAIT_OBJECT_0) then
begin
// Читаем
if GetOverlappedResult(hCom, REadOL, BytesTrans,false) then
begin
// Сравниваем произошедшее событие с прибытием символа
if (tMask and EV_RXCHAR)<>0 then
begin
AvBytes:=GetAvBytes; // Сколько байтов пришло
if AvBytes>=fScalePar.Size then
begin
//try
// Если пришло нужное кол-во то
//buf:="";
if ReadFile(hCom,buf^,AvBytes,ReadBytes,@ReadOL) then
begin
// Чистим буфер
PurgeComm(hCom,PURGE_RXCLEAR);
result:=true;
// Если прочитали нужное кол-во
if (ReadBytes>=fScalePAr.Size) then
begin
if not terminated
then
begin
fWeight:=ScaleRead;
// ChangeWeight;
State:="Данные разобраны";
end;
end;
end// if REadFile
else
begin
// Ошибка
fWait.setEvent;
Status:=GetLastError;
Addlog("Чтение невозможно");
end; // if REadFile
// end;
end; // if AvBytes
end; // if Fmask
end;// if GetOVerlappedResult
end; // if Signaled
// end;
end; // waitcommevent
← →
misyachniy © (2005-07-01 17:55) [5]В том то и вопрос, что под Me работает, а под XP не передает а висит несколько секунд или передает сразу.
Если "пошагово ходить" в DELPHI то работает.
Я так понимаю Thred которая обрабатывает событие передачи имеет не правильный приоритет.
← →
tesseract (2005-07-01 22:04) [6]Thread - фигня. Возможно слишком много событий. Код приведённый должен работать. Только создай Mutex или что-то в этом роде для того чтобы считывание/запись не перекрывались.
Ovr.hEvent := CreateEvent(nil,TRUE,FALSE,#0);
не надо в каждом цикле. Достаточно SetEvent/ResetEvent.
← →
misyachniy © (2005-07-04 10:29) [7]Я могу экспериметировать до бесконечности :-)
Я перепробовал несколько разных компонентов, ставил задержку на ожидание отсылки всего лишь трех байт до 10 секунд.
function SendArray(A:array of byte;S,R:dword;w:boolean):boolean;
var TheTime:dword;
c:dword;
begin
IndexB:=0; // внутренний приемный буфер очистили
c:=0;
p:= @A;
form1.Com.FlushBuffers(TRUE,TRUE); // очистить буфера
form1.com.SendData(p,S);
Delay(1);
if w and (r>0) then
begin
TheTime:=GetTickCount+TimeOutCommand;
while (IndexB<R)and(TheTime>GetTickCount) do
begin
Delay(1);
if c<>IndexB then // если байты еще идут ждем
begin
TheTime:=GetTickCount+TimeOutCommand;
c:=IndexB;
end;
end;
if IndexB<>R
then SendArray:=false
else SendArray:=true;
end
else SendArray:=true;
end;
Не работает :-(
На приемной стороне контроллер то не получает ни одного байта,
то получает посылку корректно.
По этому мне нужна конкретная ссылка на компонент работающий по Windows XP, или совет сталкивавшегося с таким вопросом.
Спасибо.
Страницы: 1 вся ветка
Текущий архив: 2005.08.21;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.052 c