お使いの OS (Linux) は、シリアル ポートを処理する際に次のメカニズムを提供します。
シリアルポートを非標準モードに設定できます (構造体のICANON
フラグを設定解除することによりtermios
)。次に、MIN
パラメータTIME
inc_cc[]
が 0 の場合、read()
関数は、シリアル ポートの入力バッファに新しいデータがある場合にのみ戻ります (詳細についてはtermios
、man ページを参照してください)。したがって、着信シリアル データの取得を担当する別のスレッドを実行できます。
ssize_t count, bytesReceived = 0;
char myBuffer[1024];
while(1)
{
if (count = read(portFD,
myBuffer + bytesReceived,
sizeof(myBuffer)-bytesReceived) > 0)
{
/*
Here we check the arrived bytes. If they can be processed as a complete message,
you can alert other thread in a way you choose, put them to some kind of
queue etc. The details depend greatly on communication protocol being used.
If there is not enough bytes to process, you just store them in buffer
*/
bytesReceived += count;
if (MyProtocolMessageComplete(myBuffer, bytesReceived))
{
ProcessMyData(myBuffer, bytesReceived);
AlertOtherThread(); //emit your 'signal' here
bytesReceived = 0; //going to wait for next message
}
}
else
{
//process read() error
}
}
ここでの主なアイデアはread()
、新しいデータが到着したときにのみスレッド呼び出しがアクティブになるということです。残りの時間、OS はこのスレッドを待機状態に保ちます。したがって、CPU 時間を消費しません。実際のsignal
部分をどのように実装するかはあなた次第です。
上記の例では、通常のread
システム コールを使用してポートからデータを取得していますがboost
、同じ方法でクラスを使用できます。同期読み取り機能を使用するだけで、結果は同じになります。