質問
イベント/割り込みを使用してシリアルから読み書きしたい。 現在、whileループ内にあり、シリアルを介して継続的に読み取りと書き込みを行います。シリアルポートから何かが来たときだけ読むようにしたい。これをC ++で実装するにはどうすればよいですか?
これは私の現在のコードです:
while(true) { //read if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)){ //error occurred. Report to user. } //write if(!WriteFile(hSerial, szBuff, n, &dwBytesRead, NULL)){ //error occurred. Report to user. } //print what you are reading printf("%s\n", szBuff); }
解決
select
ステートメントを使用します。これにより、ブロックせずに読み取りバッファと書き込みバッファをチェックし、ステータスを返すため、ポートにデータがあることがわかっている場合にのみ読み取るか、ポートにデータがあることがわかっている場合に書き込む必要があります出力バッファ内のスペース。
http://www.developerweb.net/forumの3番目の例/showthread.php?t=2933 および関連するコメントが役立つ場合があります。
編集: selectのmanページの最後に、よりシンプルで完全な例があります。 http://linux.die.net/man/2/selectにあります。 a> man 2 select
がシステムで機能しない場合。
注:マスター select()
を使用すると、シリアルポートとソケットの両方で作業できます。多くのネットワーククライアントとサーバーの中心にあります。
他のヒント
Windows環境の場合、よりネイティブなアプローチは非同期I / O 。このモードでは、引き続きReadFileとWriteFileの呼び出しを使用しますが、ブロックする代わりに、操作の完了時に呼び出されるコールバック関数を渡します。
すべての詳細を正しく取得するのはかなり難しいです。
こちらは、c / C ++で公開された記事のコピーです。数年前のユーザージャーナル。 Win32 APIについて詳しく説明します。
ここで、Windowsの割り込みを使用してシリアル着信データを読み取るコード 待機中の中断時間の経過時間を確認できます
int pollComport(int comport_number, LPBYTE buffer, int size)
{
BYTE Byte;
DWORD dwBytesTransferred;
DWORD dwCommModemStatus;
int n;
double TimeA,TimeB;
// Specify a set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR );
while (m_comPortHandle[comport_number] != INVALID_HANDLE_VALUE)
{
// Wait for an event to occur for the port.
TimeA = clock();
WaitCommEvent (m_comPortHandle[comport_number], &dwCommModemStatus, 0);
TimeB = clock();
if(TimeB-TimeA>0)
cout <<" ok "<<TimeB-TimeA<<endl;
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR);
if (dwCommModemStatus & EV_RXCHAR)
{
// Loop for waiting for the data.
do
{
ReadFile(m_comPortHandle[comport_number], buffer, size, (LPDWORD)((void *)&n), NULL);
// Display the data read.
if (n>0)
cout << buffer <<endl;
} while (n > 0);
}
return(0);
}
}