私は、ファイル記述子を介してアクセスできるいくつかのメモリを含む組み込みシステムで作業しています。 (何を言っているのかわかりません。間違っている場合は訂正してください。)
メモリは32kBで、0x00から0xFFFFFFFFまで埋めたいです。テキストファイルが次のようになることがわかります。
exec {fh} >> ./eeprom;
for i in {0..32767}; do echo $i >& $fh; done; $fh>&-;
これにより、ASCII文字0〜977が記録されます。
これにより、次のようなhexdump eeprop | head
結果が得られます。
0000000 0a30 0a31 0a32 0a33 0a34 0a35 0a36 0a37
0000010 0a38 0a39 3031 310a 0a31 3231 310a 0a33
0000020 3431 310a 0a35 3631 310a 0a37 3831 310a
0000030 0a39 3032 320a 0a31 3232 320a 0a33 3432
0000040 320a 0a35 3632 320a 0a37 3832 320a 0a39
0000050 3033 330a 0a31 3233 330a 0a33 3433 330a
0000060 0a35 3633 330a 0a37 3833 330a 0a39 3034
0000070 340a 0a31 3234 340a 0a33 3434 340a 0a35
0000080 3634 340a 0a37 3834 340a 0a39 3035 350a
0000090 0a31 3235 350a 0a33 3435 350a 0a35 3635
uint32
各アドレスをASCII表現ではなくアドレスで埋めるにはどうすればよいですか?
答え1
perl -e 'print pack "L*", 0..0x7fff' > file
ローカルシステムのバイト順で記録されます。
使用:
perl -e 'print pack "L>*", 0..0x7fff'
perl -e 'print pack "L<*", 0..0x7fff'
ローカルシステムの基本バイト順序に関係なく、それぞれビッグエンディアンまたはリトルエンディアンを強制します。
perldoc -f pack
詳細より。
具体的には、bashの組み込み機能を使用すると、必要なものを書くことができます。バイト値は次のとおりです。
printf '\123' # 123 in octal
printf '\xff' # ff in hexadecimal
したがって、次のようにuint32数値の各バイトを手動で作成するだけです。
for ((i = 0; i <= 32767; i++)); do
printf -v format '\\x%x' \
"$(( i & 0xff ))" \
"$(( (i >> 8) & 0xff ))" \
"$(( (i >> 16) & 0xff ))" \
"$(( (i >> 24) & 0xff ))"
printf "$format"
done
(ここではリトルエンディアン)。
とにかく32767は0x7fffではないことに注意してください。0xFFFFFFFF。 uint32数字0〜32767は32kbではなく128KiBを占めます。 0~0xFFFFFFFFは16GiBを占めます。
これらの16GiBを書くには、perl
コードを次のように変更する必要があります。
perl -e 'print pack "L", $_ for 0..0xffffffff'
そうしないと、対応する16GiBをメモリに割り当てようとし、失敗する可能性があります。私のシステムでは、perl
書き込み出力は約30MiB / sでbash
書き込みは約250KiB / sです(したがって完了するまでに数時間かかります)。
32kb(32000ビット、4000バイト、1000 uint32数値)uint32数値を書き込むには、0..999の範囲を使用できます。 32KiBは0..8191です。あるいは、L
(unsigned long)を(unsigned Short)に置き換えて、S
0..16383をuint16の数値として書き込むこともできます。
答え2
Cを使用してください。これはPerlよりわずかに高速です。
#include <unistd.h>
// in bytes, and MUST be sizeof(int) * somevalue
#define BSZ 4096
int main(void) {
// TWEAK how far to go up to (set below 0xFFFFFFFF to actually
// be testable on the 2009 macbook with a spinny metal drive and
// no main CPU fan. the other laptop is even older and slower)
// NOTE that max MUST fit exactly into a full buf
unsigned long max = 0xFFFFFF;
int buf[BSZ];
unsigned long buf_size = BSZ;
unsigned long buf_nint = BSZ / sizeof(int);
unsigned long total = 0;
while (total < max) {
unsigned long i = 0;
for (; i < buf_nint; i++) {
// TWEAK on little-endian you can htonl(3) this
// to get one of the other byte orders, if you
// need that. other byte orders on other systems
// will be more complicated
buf[i] = (int) (total + i);
}
write(STDOUT_FILENO, buf, buf_size);
total += i;
}
return 0;
}
Perlを使ってCが怖すぎないことを確認できます。
% perl -e 'print pack "L", $_ for 0..0xffffff' > p.out
% cc -O2 -std=c99 incrnumberfill.c -o incrnumberfill
% ./incrnumberfill > c.out
% cmp {p,c}.out
% echo $?
0
% repeat 3; time perl -e 'print pack "L", $_ for 0..0xffffff' > /dev/null
perl -e 'print pack "L", $_ for 0..0xffffff' > /dev/null 4.11s user 0.02s system 99% cpu 4.151 total
perl -e 'print pack "L", $_ for 0..0xffffff' > /dev/null 4.43s user 0.02s system 99% cpu 4.471 total
perl -e 'print pack "L", $_ for 0..0xffffff' > /dev/null 4.38s user 0.02s system 99% cpu 4.420 total
% repeat 3; time ./incrnumberfill > /dev/null
./incrnumberfill > /dev/null 0.02s user 0.01s system 88% cpu 0.035 total
./incrnumberfill > /dev/null 0.02s user 0.01s system 86% cpu 0.035 total
./incrnumberfill > /dev/null 0.02s user 0.01s system 88% cpu 0.034 total