私は組み込みLinuxを実行しており、コマンドラインにconsole=/dev/ttyO0,...
このUARTに接続されたターミナルプログラムがあり、表示できます。すべてシステムによって生成されます。
これで、ライブを実行するときにこれらのすべての出力をファイルに保存したいと思います(メディアが接続されています)。しかしsyslogd
、とCo.を使用したすべての努力は私が望む結果を得ていませんでした。一部のメッセージは保存されましたが、一部は保存されませんでした。一般的に最も重要なメッセージですklogd
。logger
たとえば、次のように実行すると:
myapplication.sh | logger
echo
また、アプリケーションのコマンドsyslog
といくつかのドライバメッセージが表示されます。print
ただし、分割エラーが原因でアプリケーションがクラッシュした場合、この情報は記録されません。しかし、これが最も貴重なものです!
もしそうなら、あなたが一番いいと思うのは、ファイルttyO0
にリダイレクトすることです。しかし、どうすればいいですか?
次のおすすめを見つけました。
(stty raw; cat > received.txt) < /dev/ttyO0
しかし、これはうまくいきません。たとえば、コマンドを入力できますが、ifconfig
応答はファイルやコンソールには表示されません。ファイルが生成されなくても... :-(
ファイルとシリアルコンソールの両方を持つことができれば良いでしょう。ただし、ファイルの優先順位が高くなります。
助けてくれてありがとう!
修正する解決策を見つけて回答セクションに追加しました。
答え1
あなたはやや基本的な事実を見落としているようです。パイプライン可能なすべてのプログラムは、次の事実に依存します。サム標準ファイル記述子は、それを呼び出すプログラムに関係なく、事前に開かれています。パイプに関連するほとんどの場合、呼び出し側プログラムはコマンドシェルになります。
3つのファイル記述子は次のとおりです。
- ファイル記述子#0:標準入力ストリームまたは
stdin
簡単に説明します。 - ファイル記述子#1:標準出力ストリームまたは
stdout
単に。 - ファイル記述子#2:標準エラー出力ストリーミングするか、
stderr
単に。
プログラムがファイルの読み取り/書き込みにパイピングまたはリダイレクトしない場合、通常、3つのファイル記述子はすべて現在ログインセッションが実行されているTTYデバイスを指します。プログラムが意図的にデーモンまたはバックグラウンド/非対話型プロセスで開始された場合、これらすべてがファイル、/dev/null
または一種のロギングツールに渡される可能性があります。
エラーメッセージは、通常、stderr
パイプで接続されたデータ出力と混在しないようにストリームに出力されます。しかし、あなたと同じ場合は、キャプチャしたいときみんな出力の場合は、両方のストリームを取得するようにシステムに明示的に通知する必要があります。
すべての出力をパイプに渡すには、myapplication.sh
次のことを行う必要があります。
myapplication.sh 2>&1 | logger
「ファイル記述子#2を#1と同じ場所にリダイレクトする」とマークされた後、2つの2>&1
ファイルを同時にパイプできます。
次の小さなスクリプトを使用して直接テストできます。
#!/bin/sh
echo "this is stdout"
echo "this is stderr" >&2
>&2
「このコマンドの標準出力を取得し、標準エラーストリームに送信します」を意味します。これはおそらくstderr
スクリプトから出力を生成する最も簡単な方法です。
このスクリプトを実行して./test.sh | od -t x1z
16進ダンプ形式の出力を取得すると、次のような結果が得られます。
$ ./test.sh | od -t x1z
this is stderr
0000000 74 68 69 73 20 69 73 20 73 74 64 6f 75 74 0a >this is stdout.<
0000017
したがって、コマンドはstdout
出力のみを処理しますod
。
2>&1
両方のストリームをマージするために追加すると、次の結果が得られます。
$ ./test.sh 2>&1 | od -t x1z
0000000 74 68 69 73 20 69 73 20 73 74 64 6f 75 74 0a 74 >this is stdout.t<
0000020 68 69 73 20 69 73 20 73 74 64 65 72 72 0a >his is stderr.<
0000036
これで、両方の出力がパイプに送信されます。これは| logger
。
2番目のコマンドラインは、組み込みデバイスが端末に送信するのではなく、組み込みデバイスが端末プログラムから受け取るすべてをキャプチャします。
(stty raw; cat > received.txt) < /dev/ttyO0
カーネルパラメータを使用する組み込みシステムを開発していると言うと、console=/dev/ttyO0
本質的に/dev/console
グラフィックディスプレイ(組み込みデバイスには存在しない可能性があります)ではなくシリアルポートになります。
内蔵デバイスでこのコマンドを実行する場合、括弧内のコマンドは次のようになります。標準入力ストリーム(ファイル記述子#0またはstdin
単に)がに割り当てられます/dev/ttyO0
。ただし、に接続されているシリアルラインを介してコマンドを入力すると、デフォルトでこのようなttyO0
場合が発生する可能性があるため、この入力リダイレクトは状況をそのまま再適用できます。 。
この/dev/ttyO0
デバイスは、他のコンピュータの端末プログラムに接続されたUARTを直接表現したものです。読めば手に入る端末プログラムに入力した内容のみ:以前に送信された出力を再読み込みできません。ここに書かれているすべての内容は、シリアルケーブルの端にある端末プログラムに直接渡されます。
シリアルポートのUnixコマンドラインは通常次のとおりです。リモートエコー仕組み:ターミナルプログラムに書いた内容を表示するには、組み込みシステムのTTYドライバは、ユーザーが入力したすべての文字のコピーをターミナルプログラムに送り返す必要があります。この動作は非対称です。ターミナルプログラムは、シリアルポート接続を介して受信したコンテンツのコピーも再送信しません。
TTYドライバはUnixの伝統で多くのことを必要とするので複雑です。リモートエコー機能はそのうちの1つにすぎません。
を使用するとstty raw
効果的にTTYドライバの一般的に便利な機能をすべてオフにします。、リモートエコー機能付き。したがって、その時点から明示的に読み取ってすぐに書き換えない限り、/dev/ttyS0
端末プログラムに書かれた内容を見ることはできません。
stty raw
コマンドが終了した後、ターミナルプログラムのすべての入力はコマンドに入り、cat
引数なしで呼び出されると変更されずに標準出力に渡されます。ただし、標準出力は現在ファイルにリダイレクトされますreceived.txt
。ターミナルプログラムに入力した内容だけがファイルに書き込まれます。コマンドが終わるまでcat
- そしてファイルの終わり文字(通常Control+D)を取得したときにのみ可能です。
received.txt
(リダイレクトシェルで実行できるバッファリングのため、ファイルの終わり文字で入力を終了したり、複数行のテキストを入力しない限り、ファイルに何も出力されないことがあります。)
したがって、TTYドライバ機能をオフにする以外に、(stty raw; cat > received.txt) < /dev/ttyO0
組み込みシステムのTTYドライバは何もキャプチャしません。出力書き込み/dev/ttyO0
このコマンドは、問題を解決するときにのみ使用されます。シリアル接続: 端末プログラムが送信する文字を何らかの形で損なうと思われる場合は、端末プログラムが組み込みデバイスに送信するすべてを最も原始的な形式でキャプチャする方法です。
録音したい場合絶対にすべてたとえば、カーネルパニックメッセージを含むUART接続でこれが発生した場合、最良の方法は他のコンピュータのターミナルプログラムにすべてのトラフィックを記録するように指示することです。多くの端末プログラムにはこの機能が組み込まれています。
これは、カーネルに問題が発生すると、実際にはディスクファイルに何も書き込めなくなる可能性があるためです。 UARTがエラーメッセージのテキストを送信し、それを受け取る人がそれを発見すると信頼する方がはるかに簡単です。
答え2
まあ、答えを見つけたと思います。このように単純で必要なIMHO問題がこのように「不規則な」方法で解決されたという事実に非常に驚きました。しかし、人生も同じです... :-)
とにかく、telcoM
私に参照参照をくださった方に感謝します。より多くの参考資料を見つけて、ついに私がttyrpl
望んでいたバッグを見つけました。
パッケージのメンテナンスは約7〜10年前に中断され、Linuxディストリビューションと必須ライブラリに適用するのに少し時間がかかりましたが、うまくいきます!
それは私が望むものを正確に行います。 ttyS0/ttyO0の出力を収集してファイルに保存します。そして必ずしも必要ではありませんが、素晴らしいオプションもたくさんあります... :-)
答え3
console=/dev/ttyS0の代わりにpicocomを試してみてください。他のツールもありますが、picocomが最も簡単なようです。
これらのツールのいずれかを使用すると、出力にパイプとティーを使用できます。
picocom /dev/ttyS0 -b 115200 -l | tee my.log
答え4
努力するhttps://tio.github.io- ファイルのロギングをサポートします。たとえば、
tio /dev/ttyS0 --log --log-file my-log.txt
または
tio /dev/ttyS0 --log
自動的に生成されたファイル名を使用して、ファイルにシリアル出力を書き込みます。tio_ttyS0_2022-09-14T08:56:09.log