Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зацикливание при чтение из COM порта 
:(
    Опции темы
cemick
Дата 1.11.2011, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 416
Регистрация: 6.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 6



Вообщем делаю чтение в overlapped режиме из последовательного порта в отдельном потоке. Но регулярно происходит зацикливание получения данных после нескольких десятков считываний из COM порта, даже если данных на вход перестали поступать. Выглядит как будто событие  TOverlapped.hEvent никогда не сбрасывается в не сигнальное состояние и в строчке с WaitForSingleObject(FOverlap.hEvent, INFINITE); не происходит остановки, а  Stat.cbInQue возвращает 0 байт. И так по кругу, пока в порт не поступят данные.
Если данные снова начинают записываться в порт, то считывания их выполняется успешно. Зацикливание легко прервать, если поставить где нибудь в теле цикла потока брекпоин, то на следующем витке выполнение успешно  застывает на  WaitForSingleObject(FOverlap.hEvent, INFINITE); до поступления данных, либо если поставить Sleep(50);. 
Такое ощущения что тогда что то успевает отработать и сбросить FOverlap.hEvent событие. Может кто то сталкивался с таким зацикливанием, или есть какие либо идеи.
 Вот код:

Код

procedure TbtkSerialPortReaderThread.Execute;
var
  dwMask, dwTemp: DWORD;
  signal : Cardinal;
  r: integer;
begin
  FillChar(FOverlap,SizeOf(TOverlapped),0);
  try
    FOverlap.hEvent := CreateEvent(nil, true, true, nil);
    if FOverlap.hEvent = 0 then
      raise EComPortException.Create('Îøèáêà ñîçäàíèÿ ñîáûòèÿ íà ÷òåíèå èç COM ïîðòà', FComPort.PortName);

    r := integer(SetCommMask(FComPort.FPortHandle, EV_RXCHAR or EV_BREAK)); //
    if r = 0 then
      RaiseLastWin32Error;

    ClearCommBreak(FComPort.FPortHandle);
    PurgeComm(FComPort.FPortHandle, PURGE_RXABORT or PURGE_RXCLEAR);

    while not Terminated do
    begin
       if not WaitCommEvent(FComPort.FPortHandle, dwMask, @FOverlap) then
      begin
       if GetLastError <> ERROR_IO_PENDING then
          raise Exception.Create('Error waiting port event');
      end;
      signal := WaitForSingleObject(FOverlap.hEvent, INFINITE); \\ Не задерживается
      if (signal = WAIT_OBJECT_0) and not Terminated then
      begin
        if GetOverlappedResult(FComPort.FPortHandle, FOverlap, dwTemp, true)then
        begin
          if((dwMask and EV_RXCHAR)<> 0)    then
          begin
             FComPort.PortData := FComPort.ReadPort(FOverlap);
             DataReadedEvent;
             WaitForSingleObject(FEvent, INFINITE);
             ResetEvent(FEvent);
          end;
        end;
      end;
    end;
  except
    FException := ExceptObject as Exception;
    ProcessException;
  end;
end;

function TbtkSerialPort.ReadPort(var AOverlapped: TOverlapped): string;
var
  byteCount, Errs: DWORD;
  stat: TComStat;
  p: PChar;
  Buff: array of byte;
begin

  ClearCommError(FPortHandle,errs,@stat);
  if errs <> 0 then
     RaiseLastWin32Error;
  byteCount := Stat.cbInQue;   //0
  // 1 - место под символ конца строки
  SetLength(Buff, byteCount+1);
  try
    FillChar(Buff[0], byteCount+1, #0);
    ReadFile(FPortHandle, Buff[0], byteCount, byteCount, @AOverlapped);
    if ByteCount > 0 then //÷òî-òî ïðèøëî
      Result := String(Buff)
    else
      Result := '';
  finally
    SetLength(Buff, 0);
  end;
end;


Порт открыт в overlapped режиме:
    
Код

 FPortHandle := CreateFile(PChar(PortName),
                   GENERIC_READ or GENERIC_WRITE,
                   0,
                   nil,
                   OPEN_EXISTING,
//                   0,
                   FILE_FLAG_OVERLAPPED,
                   0);

PM MAIL WWW   Вверх
northener
Дата 1.11.2011, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: нет
Всего: 20



Цитата(cemick @  1.11.2011,  15:26 Найти цитируемый пост)
Вообщем делаю чтение в overlapped режиме из последовательного порта в отдельном потоке.

Так вы Доктор Франкенштейн?


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0631 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.