\0x0A をエコーするときに \x0D を追加します。

\0x0A をエコーするときに \x0D を追加します。

ttyポートに16進値を送信しようとしています/dev/ttyS2。私が使用するときechoまたはでprintf \x0A動作します。\x0D\x0A

i=1 
a=$(printf "\xAA\xEE\x0A\x%02x" $i)
echo -ne   "$a"  > /dev/ttyS2

私はこれをターミナル/シリアルポートから取得します - 追加の0Dに注意してください。どうすれば削除できますか?

ここに画像の説明を入力してください。

答え1

シリアル接続を介して双方向にバイトをそのまま転送するには、システムからttyラインルールを切り離すか、次を実行して端末デバイスとして使用されないことをシステムに通知する必要があります。

stty raw -echo < /dev/ttyS2

あなたの場合、onlcr出力からLFをCRLFに変換することは、ttyデバイスでデフォルトで有効になっている属性です。無効にできます。みんな出力処理ocrnlにはが含まれますが、stty -opostこれによりデータへのすべての入力処理が異なる方向に送信されます。

echoどのシェルまたは実装を使用しているかは表示されませんが、オプションは標準ではなく、引数printfに含まれる項目や時期に対する動作が指定されていません。-n-eprintfecho\x

printf型パラメータのいくつかの実装は、\xHH値が0xHHのバイトに拡張されます。

その中で

printf "\xAA\xEE\x0A\x%02x" $i

\xAAはバイト0xAAに拡張され、forは文字通りまたは欠落している16進数について文句を言い、\xバイト0に拡張されます。\xたとえば、あなたはinで終わります<0xaa><0xee><LF>\x01$a

一部echoの実装では\xHHシーケンスを解釈することもあります(一部はオプションを渡すときのみ-e)。

ここで移植性が必要な場合は、次のようにします。

a=$(printf '\\252\\356\\012\\%03o' "$i")
printf "$a" > /dev/ttyS2

または:

a=$(printf '\\0252\\0356\\0012\\0%03o' "$i")
printf %b "$a" > /dev/ttyS2

(標準は、フォーマットの8進数シーケンスだけでなく、一部の実装で使用または使用されない可能性がある拡張タイプをエミュレートするように設計されたフォーマットをサポートし、printf8進数シーケンスはで表されます。)\ooo%becho-e\0ooo

また、最初の項目がNULバイトを印刷していないことを確認したいと思いますprintf。なぜなら、シェルはそれ以外の変数にNULバイトを格納できないからです(例えば、zshそうしないでください)。a=$(printf '\0 or \x00 or \u0000')

そしてzsh

bytes=(0xaa 0xee 0x0a $i)
set +o multibyte
printf %s ${(#)bytes} > /dev/ttyS2

このデータは、次のいずれかの方法で変数に保存できます。

printf -v data %s ${(#)bytes}

または

data=${(#j[])bytes}

しかし、より一般的には、任意のバイト値でデータを操作するには、おそらく適切なプログラミング言語を使用する必要がありますperlpython

xxd別の方法は、バイナリ形式とテキストの16進ダンプの間を前後に変換するための同様のツールを使用することです。

printf aaee0a%02d "$i" | xxd -p -r > /dev/ttyS1

答え2

改行変換を無効にする必要があります。

stty -F /dev/ttyS2 -onlcr

または厳格なPOSIXの場合stty:

stty -onlcr < /dev/ttyS2

関連情報