使用CSerial(C++)打开虚拟COM端口

3
我正在使用Ramon de Klein的CSerial库来打开和管理串口。我的硬件实现了一个带有FTDI芯片的串到USB转换器,因此我能够将串口连接到计算机上的USB插口。安装FTDI驱动程序后,“设备管理器”(Windows)会显示一个虚拟的COM端口。
如果我尝试打开它,它就能工作。但是现在我安装了一个USB转以太网服务器,比如这个,所以我安装它的驱动程序和软件,在将某些USB设备连接到它之后,它被检测到并添加为“设备管理器”窗口的一个虚拟串行端口。
但是当我尝试打开这个端口时,它无法工作。 如果我使用类似HyperTerminal的应用程序打开这个端口,它可以工作,就像普通的串口一样,但是在我的代码中却不行。 CSerial库的工作方式好像正在创建一个新文件,鉴于LastErrorCode是2:“找不到文件”。这是CSerial库的Open方法:
LONG CSerial::Open (LPCTSTR lpszDevice, DWORD dwInQueue, DWORD dwOutQueue, bool fOverlapped)
{
    // Reset error state
    m_lLastError = ERROR_SUCCESS;

    // Check if the port isn't already opened
    if (m_hFile)
    {
        m_lLastError = ERROR_ALREADY_INITIALIZED;
        _RPTF0(_CRT_WARN,"CSerial::Open - Port already opened\n");
        return m_lLastError;
    }

    // Open the device
    m_hFile = ::CreateFile(lpszDevice,
                           GENERIC_READ|GENERIC_WRITE,
                           0,
                           0,
                           OPEN_EXISTING,
                           fOverlapped?FILE_FLAG_OVERLAPPED:0,
                           0);
    if (m_hFile == INVALID_HANDLE_VALUE)
    {
        // Reset file handle
        m_hFile = 0;

        // Display error
        m_lLastError = ::GetLastError();
        _RPTF0(_CRT_WARN, "CSerial::Open - Unable to open port\n");
        return m_lLastError;
    }

#ifndef SERIAL_NO_OVERLAPPED
    // We cannot have an event handle yet
    _ASSERTE(m_hevtOverlapped == 0);

    // Create the event handle for internal overlapped operations (manual reset)
    if (fOverlapped)
    {
        m_hevtOverlapped = ::CreateEvent(0,true,false,0);
        if (m_hevtOverlapped == 0)
        {
            // Obtain the error information
            m_lLastError = ::GetLastError();
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to create event\n");

            // Close the port
            ::CloseHandle(m_hFile);
            m_hFile = 0;

            // Return the error
            return m_lLastError;
        }
    }
#else

    // Overlapped flag shouldn't be specified
    _ASSERTE(!fOverlapped);

#endif

    // Setup the COM-port
    if (dwInQueue || dwOutQueue)
    {
        // Make sure the queue-sizes are reasonable sized. Win9X systems crash
        // if the input queue-size is zero. Both queues need to be at least
        // 16 bytes large.
        _ASSERTE(dwInQueue >= 16);
        _ASSERTE(dwOutQueue >= 16);

        if (!::SetupComm(m_hFile,dwInQueue,dwOutQueue))
        {
            // Display a warning
            long lLastError = ::GetLastError();
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to setup the COM-port\n");

            // Close the port
            Close();

            // Save last error from SetupComm
            m_lLastError = lLastError;
            return m_lLastError;    
        }
    }

    // Setup the default communication mask
    SetMask();

    // Non-blocking reads is default
    SetupReadTimeouts(EReadTimeoutNonblocking);

    // Setup the device for default settings
    COMMCONFIG commConfig = {0};
    DWORD dwSize = sizeof(commConfig);
    commConfig.dwSize = dwSize;
    if (::GetDefaultCommConfig(lpszDevice,&commConfig,&dwSize))
    {
        // Set the default communication configuration
        if (!::SetCommConfig(m_hFile,&commConfig,dwSize))
        {
            // Display a warning
            _RPTF0(_CRT_WARN,"CSerial::Open - Unable to set default communication configuration.\n");
        }
    }
    else
    {
        // Display a warning
        _RPTF0(_CRT_WARN,"CSerial::Open - Unable to obtain default communication configuration.\n");
    }

    // Return successful
    return m_lLastError;
}

我不明白为什么它不能像直接将USB插入计算机一样工作:我一直认为,只要在“设备管理器”中列出COM,它就应该能够正常工作,无论它实际连接到哪里。
总的来说,数据传输的方式是:
RS232---> 转换为USB ---> USB CPU连接器 ---> 以COM端口的形式虚拟化为RS232
现在是这样的:
RS232---> 转换为USB ---> 通过“netUSB服务器”转换为以太网 ---> 在CPU上以Ethernet / WiFi的形式存在 ---> 以USB设备的形式虚拟化 ---> 以COM端口的形式虚拟化为RS232
需要帮助吗?

你的_CPU_ 上有一个USB连接器吗? - Some programmer dude
当然,我有一个带有RS232输出的硬件,一个RS232到USB转换器以及我的CPU上的USB连接器。这样就可以工作了。如果我添加一个“USB网络服务器”,数据传输的方式是RS323-->USB--->以太网-->虚拟化为USB--->虚拟化为RS232进入COM端口。 - Roman Rdgz
@Roman Rdgz:实际上,你所说的所有连接都连接到南桥,南桥再连接到北桥,最后连接到CPU。USB、RS232和以太网并不直接连接到CPU。 - In silico
@Insilico 这只是一种解释方式。重要的是,我有一个虚拟COM端口,但一旦将netUSB添加到网络中,我的代码就无法打开它,但是HyperTerminal可以打开它。 - Roman Rdgz
1个回答

1
问题出现并非由于硬件元素,而是由于分配给COM端口的编号。
当COM端口超过9时,CreateFile函数无法打开设备,并返回INVALID_HANDLE_VALUE。
已报告错误,并在此处报告解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接