从ComPort退出中恢复

时间:2015-12-26 22:58:42

标签: arduino serial-port delphi-5 tcomport

D5-PRO: 使用TurboPower APro以及带有USB Arduino Nano的ComPort和终端组件,用于非常基本的Comms终端。一切正常,直到我拔掉USB以模拟丢失端口。它只是挂起而不会在没有关闭和重新启动的情况下重新启动。

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

我也尝试过Dejan Crnila的TComPort和终端,它也不会优雅地停止。它实际上崩溃了,我必须使用TaskManager将它全部关闭。

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

1 个答案:

答案 0 :(得分: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. 将类似的代码添加到&#34; ProcessOutputEvent&#34;。

  4. 在新事件处理程序中分析I / O错误并关闭/重新打开端口。