0

D5-pro:将 TurboPower APro 和 ComPort 和终端组件与 USB Arduino Nano 一起用于非常基本的 Comms-Terminal。一切正常,直到我拔下 USB 以模拟丢失端口。这一切都只是挂起,不会在不关闭和重新启动的情况下重新启动。

我找不到正在监视端口状态的事件或进程,因此我可以优雅地关闭端口。如果端口不存在,我可以阻止它被打开,但是一旦打开并且数据流入,我似乎就失去了对它的所有访问权限。

我还尝试了 Dejan Crnila 的 TComPort 和 Terminal,它也没有优雅地停止。它实际上崩溃了,我必须使用 TaskManager 将其全部关闭。

有人可以用一些代码片段指导我,这些代码片段可能表明该端口已丢失。或者是否有更好的免费组件来执行此操作。

4

1 回答 1

0

需要对 AwUser 单元进行一些修改。

  1. 为 I/O 错误添加新事件。

    TPortIOErrorEvent = 对象的过程(CP:TObject;错误:Cardinal);属性 OnPortIOError:TPortIOErrorEvent 读取 FOnPortIOError 写入 FOnPortIOError;

  2. 修改 AwUser 单元中的 TComThread.Execute 方法。

          {Release time slice until we get a communications event}
      if not WaitComEvent(CurrentEvent, @ComOL) then begin
        if GetLastError = ERROR_IO_PENDING then begin
          if GetOverLappedResult(CidEx,
                                 ComOL,
                                 Junk,
                                 True) then begin
    
            {WIN32 bug workaround: Apro gets the modem status bits
            with a call (later) to GetCommModemStatus. Unfortunately,
            that routine never seems to return either RI or TERI.
            So, we note either EV_RING or EV_RINGTE here and later
            manually merge the TERI bit into ModemStatus.}
            if ((CurrentEvent and EV_RINGTE) <> 0) or
               ((CurrentEvent and EV_RING) <> 0) then
              RingFlag := True;
    
            {Read complete, reset event}
            ResetEvent(ComOL.hEvent);
          end else begin
            {Port closed or other fatal condition, just exit the thread}
            SetEvent(GeneralEvent);
            CloseHandle(ComOL.hEvent);
            H.ThreadGone(Self);
            Exit;
          end;
        end else begin
          Err := GetLastError; {!!! added code}
          { If we get an ERROR_INVALID_PARAMETER, we assume it's our }
          { use of ev_RingTe -- clear the flag and try again }
          if (GetLastError = ERROR_INVALID_PARAMETER) and
             (LastMask and EV_RINGTE <> 0) then begin
            LastMask := DefEventMask and not EV_RINGTE;
            SetCommMask(CidEx, LastMask);
          end;
          {!!! added code begin}
          if (Err <> ERROR_INVALID_PARAMETER) and (Err>0) and Assigned(FOnPortIOError) then
           FOnPortIOError(H.fOwner, Err)
          {!!! added code end}
        end;
      end;
    
  3. 将类似的代码添加到“ProcessOutputEvent”。

  4. 在新的事件处理程序中分析 I/O 错误并关闭/重新打开端口。
于 2015-12-27T07:03:59.300 回答