所以我想要实现的目标似乎很简单,但我似乎无法找到一种方法来做到这一点,而不使用外部实用程序或不预安装的库。
我有一个运行 Linux 的嵌入式系统(内核 3.x,具体取决于型号)。在它上我可以访问大多数 GNU 核心实用程序(如 cat、sed、ls、tar 等)。
我可以通过它访问 shell 会话/dev/ttyUSBx
,例如使用 screen :
screen /dev/ttyUSB0 9600
我运行 screen 的计算机(我们称之为source
)安装了 ArchLinux,可以访问互联网。我试图访问的
嵌入式系统(我们称之为)是一台 Linux 机器,没有任何网络访问权限,只有一个串行端口。 我需要将二进制文件复制到目标上的特定位置,然后能够通过 cron 作业自动刷新某些硬件(在本例中为 FPGA)。 我无法真正在 上安装软件,只能制作小型 shell 脚本。 你知道我可以使用任何 POSIX shell 方式来实现与 scp 相同的行为,但通过接口而不是 ssh 吗?target
/dev/ttyUSBx
target
/dev/ttyUSBx
我想到使用管道和文件重定向到:
-cat
将二进制文件/dev/ttyUSBx
从source
.
- 在 上target
,将流重定向到文件。
我什至不知道如何开始。我需要使用它的项目将于明天到期,但我现在迷失了方向,欢迎任何想法,最好是我可以直接从 shell 脚本使用的标准 POSIX 工具。
我确实可以在目标上访问 gcc,以防需要编译解决方案,但我仍然更喜欢 shell 解决方案,因为编译速度target
非常慢,并且需要更多的努力才能部署到多台计算机。
我的目标是自动化此工作流程(尽可能减少用户交互)。也许像将target
文件系统挂载为 NFS 之类的东西?
答案1
一种可能性是将二进制文件编码为 ASCII 文本,或者使用传统的uu编码,或者稍微现代一点的base64
。程序由软件包uuencode
提供uudecode
沙鲁蒂斯,并且base64
位于核心工具。它似乎base64
更有可能已经出现在现代 GNU/Linux 发行版上。
编码二进制文件的结果是大量文本,原则上可以通过终端连接将其复制/粘贴到 上的解码器中target
。对于大量数据,使用剪贴板可能不切实际,但我们可以使用工具 inscreen
将文件内容粘贴到终端中。
- 上
source
,跑base64 FILE > FILE.b64
。 - 在
screen
连接到 的会话中target
,键入 Ctrl-A:readreg p /path/to/FILE.b64
。 (如果您的screen
控制键不是 Ctrl-A,请键入该键。)看来您必须提供 FILE.b64 的完整路径; 〜不起作用。屏幕应该报告类似“将 26665052 个字符放入缓冲区”之类的信息。 - 在控制台上
target
,运行base64 -d > FILE
. - 输入 Ctrl-A
:paste p
。 - 键入 Ctrl-D。
解决这个问题的另一个长期的方法是调制解调器,一种通过终端连接传输文件的古老方法。许多终端仿真器都内置了对 ZModem 的支持,例如 Konsole,只要lrzsz
安装了该软件包即可。然而,很可能 lrzsz 没有安装,所以使用 base64 会更好。
这些方法都解决了通过您当时用于控制台的串行链路传输文件的问题。如果您不需要控制台,那么安排将target
链接中的任何内容转储到文件中应该更简单;但如果串行控制台是您与设备交互的唯一方式,那就会出现问题!
答案2
根据到目前为止每个人的反应,并考虑到 上已安装的实用程序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"
它发送一个刷新程序,检查源和目标的 bin 文件的校验和是否相同,对
bin 文件进行压缩和编码,
发送它,
并使用刷新程序来刷新卡。如果编码/解码中出现任何中断,则不应闪烁目标。任何其他问题都不太可能对系统造成问题,因为简单的重新启动即可将其恢复到默认状态。
这是我完整实施该流程的链接:
https://github.com/Soulthym/cycloneV-serial-flasher