web-dev-qa-db-ja.com

シリアル接続を介してファイルをコピーする

だから私が達成しようとしていることは非常に簡単に思えますが、外部ユーティリティを使用したり、事前にインストールされたライブラリを使用せずにそれを行う方法を見つけることができないようです。

Linuxを実行している組み込みシステムがあります(モデルによってはカーネル3.x)。その上で私はほとんどのGNUコアユーティリティ(cat、sed、ls、tarなど)にアクセスできます。
たとえばscreenを使用して、/dev/ttyUSBxを介してシェルセッションにアクセスできます。

screen /dev/ttyUSB0 9600 

画面を実行しているコンピューター(sourceと呼びましょう)は、インターネットにアクセスできるArchLinuxインストールです。
組み込みシステム(targetと呼びましょう)私がアクセスしようとしているのは、ネットワークアクセスのないLinuxマシンで、シリアルポートは/dev/ttyUSBxだけです。
バイナリファイルをターゲットの特定の場所にコピーする必要があります。これにより、cronジョブを介して一部のハードウェア(この場合はFPGA)を自動的にフラッシュできます。
targetにソフトウェアをインストールすることはできず、小さなシェルスクリプトを作成するだけです。
scpと同じ動作をするために使用できるPOSIXShellの方法を知っていますが、sshの代わりに/dev/ttyUSBxインターフェイスを使用しますか?

パイプとファイルリダイレクトを使用して次のことを考えました。
-catバイナリからsourceから/dev/ttyUSBxへ。
-そしてtargetで、ストリームをファイルにリダイレクトします。
どのように始めればよいのかまったくわかりません。これを使用する必要のあるプロジェクトは明日であり、今は迷っています。どんなアイデアでも歓迎します。シェルスクリプトから直接使用できる標準のPOSIXツールが非常に望ましいです。

ソリューションをコンパイルする必要がある場合に備えて、ターゲットのgccにアクセスできますが、targetでのコンパイルは非常に遅く、デプロイするのにより多くの労力が必要になるため、シェルソリューションを使用したいと思います。複数のマシンに。

私の目標は、このワークフローを自動化することです(ユーザーの操作を可能な限り減らす)。 targetファイルシステムをNFSとしてマウントするようなものでしょうか?

3
Soulthym

1つの可能性は、バイナリファイルをASCIIテキストとして、従来の encode または少し現代的なbase64を使用してエンコードすることです。プログラムuuencodeuudecodeはパッケージsharutilsによって提供され、base64coreutilsにあります。base64は、最近のGNU/Linuxディストリビューションにすでに存在しているようです。

バイナリファイルをエンコードすると、大量のテキストが生成されます。これは、原則として、ターミナル接続を介してtargetのデコーダーにコピー/貼り付けできます。大量のデータがある場合、クリップボードを使用するのは実際的ではありませんが、screenの機能を使用して、ファイルの内容をターミナルに貼り付けることができます。

  1. sourceで、base64 FILE > FILE.b64を実行します。
  2. screenに接続されているtargetセッションで、Ctrl-A :readreg p /path/to/FILE.b64と入力します。 (screenコントロールキーがCtrl-A以外の場合は、代わりにそれを入力します。)FILE.b64への完全なパスを指定する必要があるようです。 〜動作しません。画面は「26665052文字をバッファに丸呑み」のように報告するはずです。
  3. targetのコンソールで、base64 -d > FILEを実行します。
  4. Ctrl-A :paste pと入力します。
  5. Ctrl-Dを入力します。

この問題に対処するもう1つの長年の方法は、 ZModem です。これは、端末接続を介してファイルを転送するための由緒ある方法です。 ZModemのサポートは、lrzszパッケージがインストールされている限り、Konsoleなどの多くのターミナルエミュレータに組み込まれています。ただし、lrzszがインストールされていない可能性があるため、base64を使用することをお勧めします。

これらの方法はすべて、その時点でコンソールに使用しているシリアルリンクを介してファイルを転送する問題に対処します。コンソールが必要ない場合は、targetがリンクからファイルに何かをダンプするように調整する方が簡単です。しかし、シリアルコンソールがデバイスと対話する唯一の方法である場合、これは問題になります。

1
Nick Matteo

これまでの全員の回答に基づいて、targetにインストールされているユーティリティを検討したところ、sourceからのみスクリプトを実行することで機能する解決策が見つかりました。スクリプトは次のようになります。

dest="/dev/$(dmesg | grep "now attached to ttyUSB" | awk '{print$NF}' | tail -1)"
cat binfile | gzip | base64 > binfile.64.gz
md5=$(md5sum binfile | awk '{print $1}')
printf "\necho \"[ \\\$(md5sum <target-dir>/binfile | awk '{print \\\$1}') == %s ] &&\\ 
<flashing commands>\" > <target-dir>/flash.sh\n" \
    "$md5" \
    > "$dest"
printf " echo \"%s\" | base64 -d | gunzip > <target-dir>/binfile &&\\
/bin/sh <target-dir>/flash.sh
" "$(cat binfile.64.gz)" \
    > "$dest"

ソースとターゲットのbinfilesのチェックサムが同じかどうかをチェックする点滅プログラムを送信します
binfileを圧縮およびエンコードし、
送信します
そしてフラッシュプログラムを使用してカードをフラッシュします。エンコーディング/デコーディングで何かが壊れても、ターゲットをフラッシュしないでください。単純な再起動でシステムがデフォルトの状態に戻るため、他の問題が原因でシステムに問題が発生することはほとんどありません。

そのプロセスの完全な実装へのリンクは次のとおりです。
https://github.com/Soulthym/cycloneV-serial-flasher

1
Soulthym