Конференция "WinAPI" » Ошибка функции ReadFile при работе с COM-портом [D7, WinXP]
 
  • Armature_Current (29.07.09 08:02) [0]
    Уважаемые коллеги, прошу Вас помочь. Разрабатываю приложение для работы с COM - портом, не используя уже готовые компоненты. В основном потоке открываю порт, настраиваю DCB, очищаю очередь приема/передачи и завершаю все находящиеся в ожидании запросы ввода/вывода и устанавливаю маску на EV_RXCHAR.

    В другом потоке организую чтение порта слудющим образом:
    procedure TReadThread.Execute;
    var
    ComStat: TComStat;
    dwMask, dwError: DWORD;
    OverRead: TOverlapped;
    Buf: array[0..$FF] of Byte;
    dwRead: DWORD;
    begin
    OverRead.hEvent := CreateEvent(nil, True, False, nil);
    if OverRead.hEvent = Null then
    raise Exception.Create('Error creating read event');

    FreeOnTerminate := True;

    while not Terminated do
    begin
    if not WaitCommEvent(hPort, dwMask, @OverRead) then
    begin
    if GetLastError = ERROR_IO_PENDING then
    WaitForSingleObject(OverRead.hEvent, INFINITE)
    else
    raise Exception.Create('Error waiting port event');
    end;

    if not ClearCommError(hPort, dwError, @ComStat) then
    raise Exception.Create('Error clearing port');

    dwRead := ComStat.cbInQue;

    if dwRead > 0 then
    begin
    if not ReadFile(hPort, Buf, dwRead, dwRead, @OverRead) then
    raise Exception.Create('Error reading port');
    //Последнее условие выдает ошибку 998: ERROR_NOACCESS,
    //как я понимаю, это ошибка доступа при чтении порта.
    //
    end;
    end;
    end;


    Так вот эта ошибка и не дает стянуть данные с внешнего устройства, а они от туда поступают постоянно. Подскажите, что не так?
  • Сергей М. © (29.07.09 08:51) [1]
    Зачем тебе понадобились overlapped-операции  в доп.потоке ?
  • Armature_Current (29.07.09 09:30) [2]
    Вызываемый поток приложения принимает данные, основной поток параллельно с первым передает данные. В последствии принятые данные хочу обрабатывать в основном потоке
  • Сергей М. © (29.07.09 10:01) [3]
    В момент, когда ф-ция ReadFile завершается с ошибкой, основной поток осуществляет обращения к hPort ?
  • Armature_Current (29.07.09 10:30) [4]
    нет, в основном потоке только инициализируется порт, а отправка данных осуществляется по нажатию совсем другого баттона.
    Вот инициализация

    hPort:=CreateFile(ComPort,GENERIC_READ or GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

    if hCom=INVALID_HANDLE_VALUE then
      raise Exception.Create('Error');

    SetupComm(hPort,1600,1600);// назначение этих параметров мне не очень
    //понятно

    if not GetCommState(hPort, DCB) then begin
    raise Exception.Create('Error');
    exit;
    end;

    with DCB do begin
       BaudRate:=BRate;
       ByteSize:=D_Bits;
       Parity:=P_Control;
       StopBits:=S_Bits;
    end;

    if not SetCommState(hPort,DCB) then
       raise Exception.Create('Error');

    if not PurgeComm(hPort, PURGE_TXCLEAR or PURGE_RXCLEAR) then begin
    raise Exception.Create('Error');
    exit;
    end;

    if not SetCommMask(hPort, EV_RXCHAR) then
    raise Exception.Create('Error setting port mask');


    На этом основной поток перестает обращаться к hPort.

    На всякий случай еще одно условие: кабель содержит только Rx,Tx ну и земля (хотя мне кажется что по умолчанию прогамме и не нужны другие...).
  • Armature_Current (29.07.09 10:35) [5]

    > SetupComm(hPort,1600,1600);// назначение этих параметров
    > мне не очень //понятно

    все, понял.
  • Сергей М. © (29.07.09 12:52) [6]
    Win32Check(ReadFile(hPort, Buf, dwRead, dwRead, @OverRead));

    Какое сообщение при этом видишь дословно ?
  • Armature_Current (29.07.09 14:11) [7]
    Неверная попытка доступа к адрессу памяти: 998
  • Armature_Current (29.07.09 14:14) [8]
    Project RS232COM.exe raised exception class EOSError with message 'System Error. Code: 998.
    Неверная попытка доступа к адресу памяти'
    . Process stopped. Use Step or Run to continue.

  • Anatoly Podgoretsky © (29.07.09 16:27) [9]
    > Armature_Current  (29.07.2009 14:14:08)  [8]

    Какой то дурдом, половина по русски, половина по английски. И где адрес?
  • Сергей М. © (29.07.09 16:34) [10]
    Т.е. в осн.потоке сразу после SetCommMask() вызывается конструктор TReadThread.Create ?
  • Сергей М. © (29.07.09 16:36) [11]

    > И где адрес?


    Откуда адресу взяться ?
    Автор утверждает, что EOSError, а не EAccessViolation ..
  • Armature_Current (30.07.09 07:30) [12]

    > Win32Check(ReadFile(hPort, Buf, dwRead, dwRead, @OverRead));

    Как попросили, так и сделал. Текст сообщения ошибки дословный. Могу на почту выслать принтскрин)

    > Т.е. в осн.потоке сразу после SetCommMask() вызывается конструктор
    > TReadThread.Create ?

    Да, так и делаю, после SetCommMask вызываю доп.поток следующим образом:
    new := TReadThread.create(true);
    new.freeonterminate := true;
    new.priority := tplowest;
    new.resume;

  • Сергей М. © (30.07.09 08:42) [13]

    > Buf: array[0..$FF] of Byte;


    Почему именно $FF ? От балды взято ?


    > if dwRead > 0 then


    А если dwRead окажется > $FF ?
  • Armature_Current (30.07.09 08:59) [14]

    > Почему именно $FF ? От балды взято ?

    Огромное спасибо Вам, Сергей М.!!!
    проверял раньше что выдает dwRead. Выдавал 4096. Почему то не сообразил что к чему. Поэтому и взял от балды. Сейчас расширил массив, побежали битики))
    Еще раз спасибо!!!
 
Конференция "WinAPI" » Ошибка функции ReadFile при работе с COM-портом [D7, WinXP]
Есть новые Нет новых   [134434   +28][b:0][p:0.002]