質問: read(fd,&buffer,16); if(len > 0) { printf("[read_serial]buffer=%s\n", buffer); } else { printf("[read_serial]null\n"); } } ``` 変数定義などは省略しています。 前置きが長くなりましたが、質問は以下3点です。 1.前述の通り、これで"AT\r\n"の固定値送出に対して、"OK"が返ってくるのですが、 例えばそれを確認する為のread_serialの結果、write_serialにて送出した"AT"まで一緒にreadされてしまいます。 flush等の操作が必要なのではないかと思っていますが、うまく行かず、"AT"が表示されてしまいます。 このあたりの作法はLinuxとそう変わらないと考えていますが、 本来この様にシリアル通信を行う場合、どの様な作法で行うのが正しいのでしょうか? 2.1.と本質的には同じ質問なのですが、特に、この後loop処理の中で定期的に 別口のUSBシリアル(ttyS0)からの入力もprintfで表示させています。 この時、read_serial()に対してttyS0のファイルディスクリプタを渡すと、 何かが入力されるまでread関数から抜けられていない様な動作となっているのですが、 これを避けて、"もし何か入力された場合のみ表示させ、それ以外の場合はスルー" としたい場合は別タスクを作るのが正しいやり方でしょうか?他にやり方があるのでしょうか? 3.理想としては、USBシリアルのコンソール上にて"AT"等のコマンドを入力し、 Enter押下の時点でttyS0にそのコマンドを送りたいのですが、 現状では1文字ずつの入力でread_serial()を抜けてしまっています。 理想の形を実現する為にはどの様な設定(canonical等?)で実装するのが良いのでしょうか? 二度目の質問投稿でして、お見苦しい点や流儀に沿っていない部分がありましたら申し訳ありませんが、ご指摘下さい。 よろしくお願い致します。
回答: `read_serial()` において、コマンド入力(Enterを押下するまで)を受けるためには下記のような、 `while` ループを実装し `\n` ないし `\r\n` をreadするまで文字列を蓄積するように変更が必要です。 ``` while(1) { c = read(); if (c == '\n') { /* 文字列の終端に '\0' を追加する処理を入れます。 */ break; } /* 文字列にreadしたcを追加する処理をここにいれます */ } ``` 基本的に `read()` は呼ばれたタイミングで保持しているBufferを返すので、コマンド入力などのプログラムを作成するためにはそのような対応が必要になります。