2回分まとめますが、まず、前回の疑問

> 「いつデータがくるかわからない」という状況ではない

は、よくあるパターンだと思って、私が相手のデバイスのマニ
ュアルを読まずに、perl のコーディングだけ見て書いてしまっ
たのが原因です。

open(), close() はハードウェアを初期化してしまいますから、
open() で行うたくさんの仕事がハードウェアで全て完了するま
で、接続相手のデバイスと正常なコンタクトができません。ま
た、相手側のデバイスが open() の後、一定時間しないとコマ
ンドを受け付けられる状態にならないケースもあります。

次に、今回の C のプログラムのほうは、

  tios.c_lflag |= ICANON;

でしたら、

  tios.c_cc[VEOL] = '\n';
  tios.c_cc[VMIN] = 0;
  tios.c_cc[VTIME] = 100;

とか、デリミタなどの待機終了条件を指定しておかないと、運任
せになります。

あと、相手のデバイスの仕様書を見ると、単純なコマンド・レス
ポンス方式ですから、本来 select() のような入出力多重化機構
は要らないわけで、素直に \n をデリミタにした canonical 入力
(ICANON) でタイミングを合わせるのが一番ではないでしょうか?

つまり、

  open();       // デリミタ LF の CANONICAL 入力
  sleep();      // 相手側で必要なら
  write();      // コマンド出力
  read();       // データ入力
  close();

の繰り返しになります。気圧計でしたら、プログラム中でのループ
でなく、cron からの起動になると思いますが。

平林 浩一

メールによる返信