ダミーのIntel HEXデータを作る(その2)

その1の続きです。
今回はもう少しサイズのあるデータを作成します。perlで120バイトのバイナリを作成します。

~$ seq 120 | perl -ne 'print chr' > a.bin
~$ od -tx1 -Ax a.bin
000000 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
000010 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20
000020 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30
000030 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40
000040 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50
000050 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60
000060 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70
000070 71 72 73 74 75 76 77 78
000078
~$ 

ファイル名はa.binとしました。

チェックサムの計算をしやすいように10進ダンプに変換します。

~$ od -An -tu1 a.bin
   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32
  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48
  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64
  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80
  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96
  97  98  99 100 101 102 103 104 105 106 107 108 109 110 111 112
 113 114 115 116 117 118 119 120
~$ 

各行の合計を出してみましょう。

~$ od -An -tu1 a.bin | awk '{sum=0;for(i=1;i<=NF;i++){sum+=$i}print sum}'
136
392
648
904
1160
1416
1672
932
~$ 

16進にします。

~$ od -An -tu1 a.bin | awk '{sum=0;for(i=1;i<=NF;i++){sum+=$i}printf "%02X\n",sum%256}'
88
88
88
88
88
88
88
A4
~$ 

各データは、forで回すついでに、文字列を結合してしまえばよいです。

~$ od -An -tu1 a.bin | awk '{sum=0;s="";for(i=1;i<=NF;i++){sum+=$i;s = s sprintf("%02X",$i)}printf "%s %02X\n",s,sum%256}'
0102030405060708090A0B0C0D0E0F10 88
1112131415161718191A1B1C1D1E1F20 88
2122232425262728292A2B2C2D2E2F30 88
3132333435363738393A3B3C3D3E3F40 88
4142434445464748494A4B4C4D4E4F50 88
5152535455565758595A5B5C5D5E5F60 88
6162636465666768696A6B6C6D6E6F70 88
7172737475767778 A4
~$ 

先頭の:(コロン)を追加します。データ数は、NFそのものズバリとなります。

~$ od -An -tu1 a.bin | awk '{sum=0;s="";for(i=1;i<=NF;i++){sum+=$i;s = s sprintf("%02X",$i)}printf ":%02X %s %02X\n",NF,s,sum%256}'
:10 0102030405060708090A0B0C0D0E0F10 88
:10 1112131415161718191A1B1C1D1E1F20 88
:10 2122232425262728292A2B2C2D2E2F30 88
:10 3132333435363738393A3B3C3D3E3F40 88
:10 4142434445464748494A4B4C4D4E4F50 88
:10 5152535455565758595A5B5C5D5E5F60 88
:10 6162636465666768696A6B6C6D6E6F70 88
:08 7172737475767778 A4
~$ 

アドレスは、前行のデータ数分進める必要があります。

~$ od -An -tu1 a.bin | awk '{sum=0;s="";for(i=1;i<=NF;i++){sum+=$i;s = s sprintf("%02X",$i)}printf ":%02X %04X %s %02X\n",NF,addr,s,sum%256;addr+=NF}'
:10 0000 0102030405060708090A0B0C0D0E0F10 88
:10 0010 1112131415161718191A1B1C1D1E1F20 88
:10 0020 2122232425262728292A2B2C2D2E2F30 88
:10 0030 3132333435363738393A3B3C3D3E3F40 88
:10 0040 4142434445464748494A4B4C4D4E4F50 88
:10 0050 5152535455565758595A5B5C5D5E5F60 88
:10 0060 6162636465666768696A6B6C6D6E6F70 88
:08 0070 7172737475767778 A4
~$ 

チェックサムは、データ数+アドレス+00+各データの2の補数で算出します。レコードタイプも追加しました。

~$ od -An -tu1 a.bin | awk '{sum=0;s="";for(i=1;i<=NF;i++){sum+=$i;s = s sprintf("%02X",$i)}printf ":%02X %04X 00 %s %02X\n",NF,addr,s,(256-((NF+addr+sum)%256));addr+=NF}'
:10 0000 00 0102030405060708090A0B0C0D0E0F10 68
:10 0010 00 1112131415161718191A1B1C1D1E1F20 58
:10 0020 00 2122232425262728292A2B2C2D2E2F30 48
:10 0030 00 3132333435363738393A3B3C3D3E3F40 38
:10 0040 00 4142434445464748494A4B4C4D4E4F50 28
:10 0050 00 5152535455565758595A5B5C5D5E5F60 18
:10 0060 00 6162636465666768696A6B6C6D6E6F70 08
:08 0070 00 7172737475767778 E4
~$ 

最終的に、空白を除いて、EOFを追加すれば、Intel HEXファイルになります。
以下のようにスクリプトにしました。

~$ cat -n bin2hex.sh
     1	od -An -tu1 $1 | awk '{
     2		sum=0
     3		s=""
     4		for(i=1;i<=NF;i++){
     5			sum+=$i
     6			s = s sprintf("%02X",$i)
     7		}
     8		printf ":%02X%04X00%s%02X\n",NF,addr,s,(256-((NF+addr+sum)%256))
     9		addr+=NF
    10	}'
    11	printf ":00000001FF\n"
~$ 

使ってみましょう。

~$ . bin2hex.sh a.bin | tee a.hex
:100000000102030405060708090A0B0C0D0E0F1068
:100010001112131415161718191A1B1C1D1E1F2058
:100020002122232425262728292A2B2C2D2E2F3048
:100030003132333435363738393A3B3C3D3E3F4038
:100040004142434445464748494A4B4C4D4E4F5028
:100050005152535455565758595A5B5C5D5E5F6018
:100060006162636465666768696A6B6C6D6E6F7008
:080070007172737475767778E4
:00000001FF
~$ srec_info a.hex -intel
Format: Intel Hexadecimal (MCS-86)
Data:   0000 - 0077
~$ 

srec_infoでも正しく認識されたようです。

3 responses to “ダミーのIntel HEXデータを作る(その2)

  1. Pingback: Raspberry PiからAVR ATtiny85にIntel HEXを書き込む | コマンドの達人

  2. My hat is off to your astute command over this toaip-brcvo!

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA