C ++コードからシリアルポートを開いて管理するために、RamondeKleinのCSerialライブラリを使用しています。
私のハードウェアはFTDIチップを備えたシリアルtuUSBコンバーターを実装しているので、シリアルポートをCPUのUSBプラグに接続することができます。FTDIドライバーがインストールされると、仮想COMポートが「デバイスマネージャー」(Windows)に表示されます。
開こうとすると動作します。
しかし今、私はこのようなイーサネットサーバーにUSBをインストールしました。そこで、ドライバとソフトウェアをインストールし、USBデバイスを接続した後、検出され、仮想シリアルポートとして[デバイスマネージャ]ウィンドウに追加されます。
しかし、ポートを開こうとすると、機能しません。ハイパーターミナルのようなアプリケーションでポートを開くと、通常のシリアルポートであるかのように機能しますが、コードでは機能しません。
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が実際に接続されている場所とは関係なく、「デバイスマネージャ」にCOMが表示されていれば機能するはずだといつも思っていました。
全体として、データの送信方法は次のとおりです。
RS232--->USBに変換--->USBCPUコネクタ--->COMポートでRS232として仮想化
そして今は:
RS232--->USBに変換--->「netUSBサーバー」によってイーサネットに変換--->CPUでのイーサネット/WiFi--->USBデバイスとして仮想化--->COMでRS232として仮想化ポート
何か助けはありますか?