我正在为一个将二进制数据记录到一个2 2GB的micro-SD卡上的文件中的SparkFun custom V2编写自定义固件。数据文件大小从100 MB到1 GB。
随着电路板固件的发展,二进制数据的格式也在不断变化(它实际上在运行时是可动态重新配置的)。与其为固件/配置的每个版本创建和维护单独的解码器/转换器程序,我更愿意让数据文件自动转换为CSV格式,方法是在数据记录开始之前使用写入数据文件的Bash脚本启动数据文件。
我知道如何创建一个Here文档,但是我怀疑Bash无法快速解析和转换千兆字节的二进制数据,所以我想让脚本首先编译一些C代码(假设有GCC在path中),然后运行生成的程序,将二进制数据传递给标准输入,从而使这个过程运行得更快。
为了使问题更具体,假设固件将创建由4个16位整数值组成的二进制数据:一个时间戳(无符号)后跟3个加速度计轴(有符号)。记录之间没有分隔符(主要是因为我会使uSD卡的SPI卡接口饱和)。
因此,我认为我需要一个包含两个here文档的脚本:一个用于C代码(由扩展的Bash变量参数化),另一个用于二进制数据。到目前为止,我是这样做的:
#! env bash
# Produced by firmware version 0.0.0.0.0.1 alpha
# Configuration for this data run:
header_string = "Time, X, Y, Z"
column_count = 4
# Create the converter executable
# Use "<<-" to permit code to be indented for readability.
# Allow variable expansion/substitution.
gcc -xc /tmp/convertit - <<-THE_C_CODE
#include <stdio.h>
int main (int argc, char **argv) {
// Write ${header_string} to stdout
while (1) {
// Read $(column_count} shorts from stdin
// Break if EOF
// Write $(column_count} comma-delimited values to stdout
}
// Close stdout
return 0;
}
THE_C_CODE
# Pass the binary data to the converter
# Hard-quote the Here tag to prevent subsequent expansion/substitution
/tmp/convertit >./$1.csv <<'THE_BINARY_DATA'
...
... hundreds of megabytes of semi-random data ...
...
THE_BINARY_DATA
rm /tmp/convertit
exit 0这看起来是对的吗?我还没有一个真实的数据文件来测试这一点,但我想在进一步深入之前验证一下这个想法。
如果缺少结束行,Bash会抱怨吗?如果由于电击松开电池或uSD卡而导致数据捕获意外终止,则可能会发生这种情况。或者如果固件闪存。
有没有我应该考虑的更快或更好的方法?例如,我想知道Bash复制二进制数据的速度是否会太慢,因为C程序是否应该直接打开数据文件?
蒂娅
-BobC
发布于 2012-02-25 04:39:53
你可能想看看makeself。它允许您将任何.tar.gz归档文件更改为独立于平台的自解压文件(类似于包含here文档的shell脚本)。这将允许您轻松分发您的数据和解码器。它还允许您配置归档中包含的脚本,以便在运行容器脚本时运行。通过这种方式,您可以使用makeself进行打包,并且在归档中,您可以将您的数据文件和解码器放入C或bash或任何您认为合适的语言中。
虽然可以使用外壳工具(例如,使用od)解码二进制数据,但它非常繁琐且效率低下。我建议使用C程序或perl,这也可能在几乎任何机器上找到(请查看this page)。
https://stackoverflow.com/questions/9074577
复制相似问题