⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comport.cpp

📁 这个是补充啊!!!!!!!!!!!!!!!!!!! 大家要支持一下
💻 CPP
字号:
/*
 * $Id: comport.cpp,v 1.3 2007/02/06 11:53:33 vfrolov Exp $
 *
 * Copyright (c) 2006-2007 Vyacheslav Frolov
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * $Log: comport.cpp,v $
 * Revision 1.3  2007/02/06 11:53:33  vfrolov
 * Added options --odsr, --ox, --ix and --idsr
 * Added communications error reporting
 *
 * Revision 1.2  2007/02/05 09:33:20  vfrolov
 * Implemented internal flow control
 *
 * Revision 1.1  2007/01/23 09:13:10  vfrolov
 * Initial revision
 *
 *
 */

#include "precomp.h"
#include "comport.h"
#include "comhub.h"
#include "comio.h"
#include "comparams.h"

///////////////////////////////////////////////////////////////
ComPort::ComPort(ComHub &_hub)
  : handle(INVALID_HANDLE_VALUE),
    hub(_hub),
    countReadOverlapped(0),
    countXoff(0),
    filterX(FALSE),
    writeQueueLimit(256),
    writeQueued(0),
    writeLostTotal(0)
{
}

BOOL ComPort::Open(const char *pPath, const ComParams &comParams)
{
  if (handle != INVALID_HANDLE_VALUE)
    return FALSE;

  while (writeQueued) {
    if (SleepEx(5000, TRUE) != WAIT_IO_COMPLETION)
      return FALSE;
  }

  writeLost = 0;
  filterX = comParams.InX();

  string path(pPath);

  name = path.substr(path.rfind('\\') + 1);

  handle = ::OpenComPort(pPath, comParams);

  return handle != INVALID_HANDLE_VALUE;
}

BOOL ComPort::Start()
{
  if (!StartRead())
    return FALSE;

  cout << "Started " << name << endl;

  return TRUE;
}

BOOL ComPort::StartRead()
{
  if (countReadOverlapped)
    return TRUE;

  if (handle == INVALID_HANDLE_VALUE)
    return FALSE;

  ReadOverlapped *pOverlapped;

  pOverlapped = new ReadOverlapped(*this);

  if (!pOverlapped)
    return FALSE;

  if (!pOverlapped->StartRead()) {
    delete pOverlapped;
    return FALSE;
  }

  countReadOverlapped++;

  //cout << "Started Read " << name << " " << countReadOverlapped << endl;

  return TRUE;
}

BOOL ComPort::Write(LPCVOID pData, DWORD len)
{
  if (handle == INVALID_HANDLE_VALUE) {
    writeLost += len;
    return FALSE;
  }

  WriteOverlapped *pOverlapped;

  pOverlapped = new WriteOverlapped(*this, pData, len);

  if (!pOverlapped)
    return FALSE;

  if (filterX) {
    len = pOverlapped->FilterX();

    if (!len) {
      delete pOverlapped;
      return TRUE;
    }
  }

  if (writeQueued > writeQueueLimit)
    PurgeComm(handle, PURGE_TXABORT|PURGE_TXCLEAR);

  if (!pOverlapped->StartWrite()) {
    writeLost += len;
    delete pOverlapped;
    return FALSE;
  }

  if (writeQueued <= writeQueueLimit/2 && (writeQueued + len) > writeQueueLimit/2)
    hub.AddXoff(this, 1);

  writeQueued += len;

  //cout << "Started Write " << name << " " << len << " " << writeQueued << endl;

  return TRUE;
}

void ComPort::OnWrite(WriteOverlapped *pOverlapped, DWORD len, DWORD done)
{
  delete pOverlapped;

  if (len > done)
    writeLost += len - done;

  if (writeQueued > writeQueueLimit/2 && (writeQueued - len) <= writeQueueLimit/2)
    hub.AddXoff(this, -1);

  writeQueued -= len;
}

void ComPort::OnRead(ReadOverlapped *pOverlapped, LPCVOID pBuf, DWORD done)
{
  if (done)
    hub.Write(this, pBuf, done);

  if (countXoff > 0 || !pOverlapped->StartRead()) {
    delete pOverlapped;
    countReadOverlapped--;

    //cout << "Stopped Read " << name << " " << countReadOverlapped << endl;
  }
}

void ComPort::AddXoff(int count)
{
  countXoff += count;

  if (countXoff <= 0)
    StartRead();
}

void ComPort::LostReport()
{
  if (writeLost) {
    writeLostTotal += writeLost;
    cout << "Write lost " << name << ": " << writeLost << ", total " << writeLostTotal << endl;
    writeLost = 0;
  }

  DWORD errors;

  if (ClearCommError(handle, &errors, NULL) && errors) {
    cout << "Error " << name << ":";

    if (errors & CE_RXOVER) { cout << " RXOVER"; }
    if (errors & CE_OVERRUN) { cout << " OVERRUN"; }
    if (errors & CE_RXPARITY) { cout << " RXPARITY"; }
    if (errors & CE_FRAME) { cout << " FRAME"; }

    #define IOCTL_SERIAL_GET_STATS CTL_CODE(FILE_DEVICE_SERIAL_PORT,35,METHOD_BUFFERED,FILE_ANY_ACCESS)

    typedef struct _SERIALPERF_STATS {
      ULONG ReceivedCount;
      ULONG TransmittedCount;
      ULONG FrameErrorCount;
      ULONG SerialOverrunErrorCount;
      ULONG BufferOverrunErrorCount;
      ULONG ParityErrorCount;
    } SERIALPERF_STATS, *PSERIALPERF_STATS;

    SERIALPERF_STATS stats;
    DWORD size;

    if (DeviceIoControl(handle, IOCTL_SERIAL_GET_STATS, NULL, 0, &stats, sizeof(stats), &size, NULL)) {
      cout << ", total"
        << " RXOVER=" << stats.BufferOverrunErrorCount
        << " OVERRUN=" << stats.SerialOverrunErrorCount
        << " RXPARITY=" << stats.ParityErrorCount
        << " FRAME=" << stats.FrameErrorCount;
    }

    cout << endl;
  }
}
///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -