2

オリエンテーションコントローラーを開発しています。I2C を介してセンサー (コンパス) と通信する開発ボードがあります。ボードはかなり制限されているため (OS なし)、次のようなものを受け取る簡単なプログラムを開発しました。(1) 'get 0' でセンサーのレジスタ 0 を読み取ります。(2) センサーのレジスタ 0 を値 10 に設定するための「set 0 10」。(レジスタ 0 の値は 10); (2) '完了'; (3) エラーの場合は「error: ...」。これで、センサーを理解してコントローラーを開発するために、コマンドを送信してデータを取得するシェル スクリプト (bash) を開発しようとしています。

私の問題は、次のコードにあります。

# read device output in the background.
head -n 1 /dev/ttyUSB0 &
head=$!

# (#1): without the following stmt I get:
#   head: cannot open `/dev/ttyUSB0' for reading: : Protocol error
sleep 0.1

# send command to the device.
echo "get 0" > /dev/ttyUSB0

# (#2) wait for head.
while kill -0 $head 2>/dev/null ; do : ; done

(#1) は「head」と「echo」の間の読み取り/書き込みの競合が原因だと思いますが、その理由はわかりませんし、解決方法もわかりません。

別の問題は、タイムアウトを使用したい (#2) にあります。私は次のようなことを試しました:

timeout 1 bash -c "while kill -0 $head 2>/dev/null ; do : ; done"

しかし、私は次のようになります:Timeout: aborting command ``bash'' with signal 9そして、プログラムが動かなくなります。

ところで、上記のコードを実行する前に、シリアル ポートを次のように初期化します。

stty -F /dev/ttyUSB0 9600 cs8 -cstopb

編集: 対話型端末は必要ありません。必要に応じてこのルーチンを使用したいと思います。このルーチンは、後でボードに実装されるコントローラー (読み取り/書き込みセンサーのレジスター) の必要な基盤です。

4

1 に答える 1

0

(#1) を解決するために、fd を使用するようにルーチンを変更しました。

# $1: the device filename, eg. /dev/ttyS0
# $2: number of lines to read before exit.

exec 3<>$1

head -n "$2" 0<&3 &
wait_pid=$!

cat - 1>&3

wait $wait_pid

exec 3>&-

編集: (#2) を解決するには、ルーチンにタイムアウトのサポートを提供する代わりに、その責任を呼び出し元に委任します。ただし、タイムアウトの場合はクリーンアップする必要があります。そのために、 の後に次を追加しましたwait_pid=$!

trap="if kill -0 $wait_pid ; then kill -TERM $wait_pid ; fi"
trap "$trap" SIGINT SIGKILL SIGTERM
于 2012-06-27T07:34:58.743 に答える