2012-03-13 17 views
3

これはシリアル通信の一般的なエラー状態でなければならないと感じていますが、私はまだ良い解決策を見ています。タイムアウトのためのLinuxのブロック、ソリューションのシリアル書き込み?

シリアルポートを非ブロックに設定し、フロー制御を無効にしました。次にSelectを使用してポートを書き込むことができるかどうかを判断します。私は大きなバッファ(ページサイズよりも大きい、4k、私はポートに与えられたソフトウェアのバッファリングの量だと思う)を書き込もうとしています。書き込みの最初の部分は終了しますが、シリアル接続が切断されたり、エンドコンシューマの電源が切れたり再起動されたりすると、残りの書き込みをブロックしようとしています。私はデータの小さな塊を書くことを考えましたが、最終的に私はバッファを埋めるように感じ、このケースに再び入ります。書き込む前に使用可能なバッファをクエリする方法はありますか?カーネルを再コンパイルせずにバッファサイズを変更する方法は?

私の目標は、失敗した書き込みをタイムアウトさせてユーザーに通知して通知する方法です。私は、デバイスが復帰したときに、失敗したメッセージの末尾が正しく通過することを望んでいません。シリアル設定(ボー、ストップビットなど)も時間の経過と共に変化している可能性がありますが、書き換えをしている間は変更したくありません。

私はスレッドにsigusr1シグナルを送ることができると判断しました。これは進行中の書き込みをキャンセルしますが、これはすべてうまくいくようです。おそらくこれが好ましい方法ですか?また、私はaio_writeの使用方法を検討しましたが、これまで使用したことはありませんでした。

誰かが失敗した書き込みをタイムアウトするための良い解決策を持っているなら、私はそれらのヒアリングに興味があるでしょう。ありがとう。

編集:私はより多くの調査を行い、私の質問は完全ではありませんでした。私は擬似シリアルポートを使用していて、実際のシリアルポートとは異なる動作をしていました。質問は、ハードウェアフロー制御が有効になっているか、擬似シリアルポートを使用する必要があるかどうかに関係します。

+0

を非ブロッキングにシリアルポートを設定することにより、あなたはあなたが設定した意味ですか私の記憶が正しければ、これは私が過去(pesudoコード)で行われてきたものですファイル記述子をfcntl()やopen()のO_NONBLOCKフラグを使ってノンブロッキングにする? – nos

+0

私はそれをopenの呼び出しで設定します。 fcntlで設定すると別の結果につながると思いますか? – john

+0

ファイル記述子が適切にブロックされていて、他のすべてが正しく行われていれば、これはカーネルのバグのように聞こえます。ノンブロッキングの 'write'は何らかの理由でブロックされるべきではありません。 – Kaz

答えて

1

スレッドにシグナルを送信するのが最良の方法ですが、私がやることはtimerを使ってタイムアウトを設定することです。

timer_create(); 
int value = write(fd, buffer, buff_len); 
if(value < 0 && errno == EINTR) { 
    /* We were interrupted by a signal - write failed. */ 
}else if(value < 0){ 
    timer_delete(); 
    /* other error */ 
}else if(value != buff_len){ 
    timer_delete(); 
    /* did not write out entire buffer */ 
}else{ 
    timer_delete(); 
    /* Write should be good */ 
} 

項目:http://pubs.opengroup.org/onlinepubs/009604499/functions/timer_create.html

+0

上記の私の編集を参照してください。これは、ハードウェアフロー制御を使用した書き込みに適したソリューションです。別のスレッドで一時的にフロー制御を無効にして、バイトを排出させることもできます。 – john

関連する問題