目次
前
次
HEXファイル生成(AWK)
ラベルを使ったデータファイルから、HEXファイルを生成する
必要に迫られたので、AWKを使ったフィルタを作成しました。
データファイルは、次のフォーマットでテキストファイルで
用意します。
NONE ALL_BLACK NONE
NONE ALL_WHITE NONE
NONE LEFT_WHITE NONE
NONE RIGHT_WHITE NONE
NONE CENTER NONE
NONE HARD_RIGHT NONE
NONE RIGHT NONE
NONE TINY_RIGHT NONE
NONE TINY_LEFT NONE
NONE LEFT NONE
NONE HARD_LEFT NONE
NONE BOTH_WHITE NONE
CRANK ALL_BLACK CRANK
CRANK ALL_WHITE CRANK
CRANK LEFT_WHITE LEFT_ROTATE
CRANK RIGHT_WHITE RIGHT_ROTATE
CRANK CENTER CRANK
CRANK HARD_RIGHT CRANK
CRANK RIGHT CRANK
CRANK TINY_RIGHT CRANK
CRANK TINY_LEFT CRANK
CRANK LEFT CRANK
CRANK HARD_LEFT CRANK
CRANK BOTH_WHITE CRANK
RIGHT_ROTATE ALL_BLACK RIGHT_ROTATE
RIGHT_ROTATE ALL_WHITE RIGHT_ROTATE
RIGHT_ROTATE LEFT_WHITE RIGHT_ROTATE
RIGHT_ROTATE RIGHT_WHITE RIGHT_ROTATE
RIGHT_ROTATE CENTER NORMAL
RIGHT_ROTATE HARD_RIGHT RIGHT_ROTATE
RIGHT_ROTATE RIGHT RIGHT_ROTATE
RIGHT_ROTATE TINY_RIGHT RIGHT_ROTATE
RIGHT_ROTATE TINY_LEFT RIGHT_ROTATE
RIGHT_ROTATE LEFT RIGHT_ROTATE
RIGHT_ROTATE HARD_LEFT RIGHT_ROTATE
RIGHT_ROTATE BOTH_WHITE RIGHT_ROTATE
LEFT_ROTATE ALL_BLACK LEFT_ROTATE
LEFT_ROTATE ALL_WHITE LEFT_ROTATE
LEFT_ROTATE LEFT_WHITE LEFT_ROTATE
LEFT_ROTATE RIGHT_WHITE LEFT_ROTATE
LEFT_ROTATE CENTER NORMAL
LEFT_ROTATE HARD_RIGHT LEFT_ROTATE
LEFT_ROTATE RIGHT LEFT_ROTATE
LEFT_ROTATE TINY_RIGHT LEFT_ROTATE
LEFT_ROTATE TINY_LEFT LEFT_ROTATE
LEFT_ROTATE LEFT LEFT_ROTATE
LEFT_ROTATE HARD_LEFT LEFT_ROTATE
LEFT_ROTATE BOTH_WHITE LEFT_ROTATE
LANE_LEFT ALL_BLACK LANE_LEFT_BLIND
LANE_LEFT ALL_WHITE LANE_LEFT
LANE_LEFT LEFT_WHITE LANE_LEFT
LANE_LEFT RIGHT_WHITE LANE_LEFT
LANE_LEFT CENTER LANE_LEFT
LANE_LEFT HARD_RIGHT LANE_LEFT
LANE_LEFT RIGHT LANE_LEFT
LANE_LEFT TINY_RIGHT LANE_LEFT
LANE_LEFT TINY_LEFT LANE_LEFT
LANE_LEFT LEFT LANE_LEFT
LANE_LEFT HARD_LEFT LANE_LEFT
LANE_LEFT BOTH_WHITE LANE_LEFT
LANE_LEFT_BLIND ALL_BLACK LANE_LEFT_BLIND
LANE_LEFT_BLIND ALL_WHITE LANE_LEFT_BLIND
LANE_LEFT_BLIND LEFT_WHITE LANE_LEFT_BLIND
LANE_LEFT_BLIND RIGHT_WHITE LANE_LEFT_BLIND
LANE_LEFT_BLIND CENTER LANE_LEFTX
LANE_LEFT_BLIND HARD_RIGHT LANE_LEFT_BLIND
LANE_LEFT_BLIND RIGHT LANE_LEFT_BLIND
LANE_LEFT_BLIND TINY_RIGHT LANE_LEFT_BLIND
LANE_LEFT_BLIND TINY_LEFT LANE_LEFT_BLIND
LANE_LEFT_BLIND LEFT LANE_LEFT_BLIND
LANE_LEFT_BLIND HARD_LEFT LANE_LEFT_BLIND
LANE_LEFT_BLIND BOTH_WHITE LANE_LEFT_BLIND
LANE_LEFTX ALL_BLACK LANE_LEFTX
LANE_LEFTX ALL_WHITE LANE_LEFTX
LANE_LEFTX LEFT_WHITE LANE_LEFTX
LANE_LEFTX RIGHT_WHITE LANE_LEFTX
LANE_LEFTX CENTER NORMAL
LANE_LEFTX HARD_RIGHT LANE_LEFTX
LANE_LEFTX RIGHT LANE_LEFTX
LANE_LEFTX TINY_RIGHT LANE_LEFTX
LANE_LEFTX TINY_LEFT LANE_LEFTX
LANE_LEFTX LEFT LANE_LEFTX
LANE_LEFTX HARD_LEFT LANE_LEFTX
LANE_LEFTX BOTH_WHITE LANE_LEFTX
LANE_RIGHT ALL_BLACK LANE_RIGHT_BLIND
LANE_RIGHT ALL_WHITE LANE_RIGHT
LANE_RIGHT LEFT_WHITE LANE_RIGHT
LANE_RIGHT RIGHT_WHITE LANE_RIGHT
LANE_RIGHT CENTER LANE_RIGHT
LANE_RIGHT HARD_RIGHT LANE_RIGHT
LANE_RIGHT RIGHT LANE_RIGHT
LANE_RIGHT TINY_RIGHT LANE_RIGHT
LANE_RIGHT TINY_LEFT LANE_RIGHT
LANE_RIGHT LEFT LANE_RIGHT
LANE_RIGHT HARD_LEFT LANE_RIGHT
LANE_RIGHT BOTH_WHITE LANE_RIGHT
LANE_RIGHT_BLIND ALL_BLACK LANE_RIGHT_BLIND
LANE_RIGHT_BLIND ALL_WHITE LANE_RIGHT_BLIND
LANE_RIGHT_BLIND LEFT_WHITE LANE_RIGHT_BLIND
LANE_RIGHT_BLIND RIGHT_WHITE LANE_RIGHT_BLIND
LANE_RIGHT_BLIND CENTER LANE_RIGHTX
LANE_RIGHT_BLIND HARD_RIGHT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND RIGHT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND TINY_RIGHT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND TINY_LEFT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND LEFT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND HARD_LEFT LANE_RIGHT_BLIND
LANE_RIGHT_BLIND BOTH_WHITE LANE_RIGHT_BLIND
LANE_RIGHTX ALL_BLACK LANE_RIGHTX
LANE_RIGHTX ALL_WHITE LANE_RIGHTX
LANE_RIGHTX LEFT_WHITE LANE_RIGHTX
LANE_RIGHTX RIGHT_WHITE LANE_RIGHTX
LANE_RIGHTX CENTER NORMAL
LANE_RIGHTX HARD_RIGHT LANE_RIGHTX
LANE_RIGHTX RIGHT LANE_RIGHTX
LANE_RIGHTX TINY_RIGHT LANE_RIGHTX
LANE_RIGHTX TINY_LEFT LANE_RIGHTX
LANE_RIGHTX LEFT LANE_RIGHTX
LANE_RIGHTX HARD_LEFT LANE_RIGHTX
LANE_RIGHTX BOTH_WHITE LANE_RIGHTX
NORMAL ALL_BLACK NORMAL
NORMAL ALL_WHITE CRANK
NORMAL LEFT_WHITE LANE_LEFT
NORMAL RIGHT_WHITE LANE_RIGHT
NORMAL CENTER NORMAL
NORMAL HARD_RIGHT NORMAL
NORMAL RIGHT NORMAL
NORMAL TINY_RIGHT NORMAL
NORMAL TINY_LEFT NORMAL
NORMAL LEFT NORMAL
NORMAL HARD_LEFT NORMAL
NORMAL BOTH_WHITE NORMAL
HEXファイルは、数値を並べたテキストファイルなので
ラベルから数値に変換するスクリプトを作成します。
{
# mode
if ( $1 == "NONE" ) { res0 = 0 }
if ( $1 == "CRANK" ) { res0 = 1 }
if ( $1 == "RIGHT_ROTATE" ) { res0 = 2 }
if ( $1 == "LEFT_ROTATE" ) { res0 = 3 }
if ( $1 == "LANE_LEFT" ) { res0 = 8 }
if ( $1 == "LANE_LEFT_BLIND" ) { res0 = 9 }
if ( $1 == "LANE_LEFTX" ) { res0 = 10 }
if ( $1 == "LANE_RIGHT" ) { res0 = 12 }
if ( $1 == "LANE_RIGHT_BLIND" ) { res0 = 13 }
if ( $1 == "LANE_RIGHTX" ) { res0 = 14 }
if ( $1 == "NORMAL" ) { res0 = 15 }
# sensor
if ( $2 == "ALL_BLACK" ) { res1 = 0 }
if ( $2 == "ALL_WHITE" ) { res1 = 1 }
if ( $2 == "LEFT_WHITE" ) { res1 = 2 }
if ( $2 == "RIGHT_WHITE" ) { res1 = 3 }
if ( $2 == "CENTER" ) { res1 = 4 }
if ( $2 == "HARD_RIGHT" ) { res1 = 5 }
if ( $2 == "RIGHT" ) { res1 = 6 }
if ( $2 == "TINY_RIGHT" ) { res1 = 7 }
if ( $2 == "TINY_LEFT" ) { res1 = 8 }
if ( $2 == "LEFT" ) { res1 = 9 }
if ( $2 == "HARD_LEFT" ) { res1 = 10 }
if ( $2 == "BOTH_WHITE" ) { res1 = 11 }
# mode
if ( $3 == "NONE" ) { res2 = 0 }
if ( $3 == "CRANK" ) { res2 = 1 }
if ( $3 == "RIGHT_ROTATE" ) { res2 = 2 }
if ( $3 == "LEFT_ROTATE" ) { res2 = 3 }
if ( $3 == "LANE_LEFT" ) { res2 = 8 }
if ( $3 == "LANE_LEFT_BLIND" ) { res2 = 9 }
if ( $3 == "LANE_LEFTX" ) { res2 = 10 }
if ( $3 == "LANE_RIGHT" ) { res2 = 12 }
if ( $3 == "LANE_RIGHT_BLIND" ) { res2 = 13 }
if ( $3 == "LANE_RIGHTX" ) { res2 = 14 }
if ( $3 == "NORMAL" ) { res2 = 15 }
# show
printf("%d %d 0 %d\n",res0,res1,res2)
}
ラベルで記述した内容は、以下の操作でテキストファイルに
変換されます。
I/Oリダイレクトでファイルに落とした内容は、以下。
0 0 0 0
0 1 0 0
0 2 0 0
0 3 0 0
0 4 0 0
0 5 0 0
0 6 0 0
0 7 0 0
0 8 0 0
0 9 0 0
0 10 0 0
0 11 0 0
1 0 0 1
1 1 0 1
1 2 0 3
1 3 0 2
1 4 0 1
1 5 0 1
1 6 0 1
1 7 0 1
1 8 0 1
1 9 0 1
1 10 0 1
1 11 0 1
2 0 0 2
2 1 0 2
2 2 0 2
2 3 0 2
2 4 0 15
2 5 0 2
2 6 0 2
2 7 0 2
2 8 0 2
2 9 0 2
2 10 0 2
2 11 0 2
3 0 0 3
3 1 0 3
3 2 0 3
3 3 0 3
3 4 0 15
3 5 0 3
3 6 0 3
3 7 0 3
3 8 0 3
3 9 0 3
3 10 0 3
3 11 0 3
8 0 0 9
8 1 0 8
8 2 0 8
8 3 0 8
8 4 0 8
8 5 0 8
8 6 0 8
8 7 0 8
8 8 0 8
8 9 0 8
8 10 0 8
8 11 0 8
9 0 0 9
9 1 0 9
9 2 0 9
9 3 0 9
9 4 0 10
9 5 0 9
9 6 0 9
9 7 0 9
9 8 0 9
9 9 0 9
9 10 0 9
9 11 0 9
10 0 0 10
10 1 0 10
10 2 0 10
10 3 0 10
10 4 0 15
10 5 0 10
10 6 0 10
10 7 0 10
10 8 0 10
10 9 0 10
10 10 0 10
10 11 0 10
12 0 0 13
12 1 0 12
12 2 0 12
12 3 0 12
12 4 0 12
12 5 0 12
12 6 0 12
12 7 0 12
12 8 0 12
12 9 0 12
12 10 0 12
12 11 0 12
13 0 0 13
13 1 0 13
13 2 0 13
13 3 0 13
13 4 0 14
13 5 0 13
13 6 0 13
13 7 0 13
13 8 0 13
13 9 0 13
13 10 0 13
13 11 0 13
14 0 0 14
14 1 0 14
14 2 0 14
14 3 0 14
14 4 0 15
14 5 0 14
14 6 0 14
14 7 0 14
14 8 0 14
14 9 0 14
14 10 0 14
14 11 0 14
15 0 0 15
15 1 0 15
15 2 0 8
15 3 0 12
15 4 0 15
15 5 0 15
15 6 0 15
15 7 0 15
15 8 0 15
15 9 0 15
15 10 0 15
15 11 0 15
フィールドを4個として、次のAWKスクリプトを使うため
テキストファイルのデータに追加をしておきます。
# bit inverse
function xinverse(x) {
# default
result = 0
# judge
if ( x == 0 ) { result = 1 }
return result
}
# 1's compliment
function bnot(x) {
# copy
tmpx = x
# separate
x0 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x1 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x2 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x3 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x4 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x5 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x6 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x7 = int( tmpx % 2 ) ;
# inverse
x0 = xinverse(x0) ; x1 = xinverse(x1)
x2 = xinverse(x2) ; x3 = xinverse(x3)
x4 = xinverse(x4) ; x5 = xinverse(x5)
x6 = xinverse(x6) ; x7 = xinverse(x7)
# calculate
result = 0 ;
result = result * 2 + x7 ; result = result * 2 + x6
result = result * 2 + x5 ; result = result * 2 + x4
result = result * 2 + x3 ; result = result * 2 + x2
result = result * 2 + x1 ; result = result * 2 + x0
return result
}
BEGIN {
res = 0
}
{
adr = ($1 * 16 + $2) * 2
ln = NR - 1
r = ln % 8
# show address
if ( r == 0 ) {
# data size
res = res + 16
# address
res = res + (adr / 256) + (adr % 256)
# 2 data
res = res + $3 + $4
# show
printf(":10%04X00%02X%02X",adr,$3,$4)
}
# add check sum
if ( r == 7 ) {
# add
res = res + $3 + $4
# calculate check sum
result = bnot(res % 256) + 1
# show
printf("%02X%02X%02X\n",$3,$4,result)
# prepare next
res = 0
}
# others
if ( r != 0 && r != 7 ) {
# add
res = res + $3 + $4
# show
printf("%02X%02X",$3,$4)
}
}
END {
printf(":00000001FF\n")
}
4個のフィールドのうち、左の2個のフィールドに入れた
データから8ビットのアドレスを生成します。
8ビットアドレスの上位、下位に分けていますが
下位は0から15にしなければならないのに、11で
終わっているので、不足分を追加しました。
不足分を追加すると、以下。
0 0 0 0
0 1 0 0
0 2 0 0
0 3 0 0
0 4 0 0
0 5 0 0
0 6 0 0
0 7 0 0
0 8 0 0
0 9 0 0
0 10 0 0
0 11 0 0
0 12 0 0
0 13 0 0
0 14 0 0
0 15 0 0
1 0 0 1
1 1 0 1
1 2 0 3
1 3 0 2
1 4 0 1
1 5 0 1
1 6 0 1
1 7 0 1
1 8 0 1
1 9 0 1
1 10 0 1
1 11 0 1
1 12 0 1
1 13 0 1
1 14 0 1
1 15 0 1
2 0 0 2
2 1 0 2
2 2 0 2
2 3 0 2
2 4 0 15
2 5 0 2
2 6 0 2
2 7 0 2
2 8 0 2
2 9 0 2
2 10 0 2
2 11 0 2
2 12 0 2
2 13 0 2
2 14 0 2
2 15 0 2
3 0 0 3
3 1 0 3
3 2 0 3
3 3 0 3
3 4 0 15
3 5 0 3
3 6 0 3
3 7 0 3
3 8 0 3
3 9 0 3
3 10 0 3
3 11 0 3
3 12 0 3
3 13 0 3
3 14 0 3
3 15 0 3
8 0 0 9
8 1 0 8
8 2 0 8
8 3 0 8
8 4 0 8
8 5 0 8
8 6 0 8
8 7 0 8
8 8 0 8
8 9 0 8
8 10 0 8
8 11 0 8
8 12 0 8
8 13 0 8
8 14 0 8
8 15 0 8
9 0 0 9
9 1 0 9
9 2 0 9
9 3 0 9
9 4 0 10
9 5 0 9
9 6 0 9
9 7 0 9
9 8 0 9
9 9 0 9
9 10 0 9
9 11 0 9
9 12 0 9
9 13 0 9
9 14 0 9
9 15 0 9
10 0 0 10
10 1 0 10
10 2 0 10
10 3 0 10
10 4 0 15
10 5 0 10
10 6 0 10
10 7 0 10
10 8 0 10
10 9 0 10
10 10 0 10
10 11 0 10
10 12 0 10
10 13 0 10
10 14 0 10
10 15 0 10
12 0 0 13
12 1 0 12
12 2 0 12
12 3 0 12
12 4 0 12
12 5 0 12
12 6 0 12
12 7 0 12
12 8 0 12
12 9 0 12
12 10 0 12
12 11 0 12
12 12 0 12
12 13 0 12
12 14 0 12
12 15 0 12
13 0 0 13
13 1 0 13
13 2 0 13
13 3 0 13
13 4 0 14
13 5 0 13
13 6 0 13
13 7 0 13
13 8 0 13
13 9 0 13
13 10 0 13
13 11 0 13
13 12 0 13
13 13 0 13
13 14 0 13
13 15 0 13
14 0 0 14
14 1 0 14
14 2 0 14
14 3 0 14
14 4 0 15
14 5 0 14
14 6 0 14
14 7 0 14
14 8 0 14
14 9 0 14
14 10 0 14
14 11 0 14
14 12 0 14
14 13 0 14
14 14 0 14
14 15 0 14
15 0 0 15
15 1 0 15
15 2 0 8
15 3 0 12
15 4 0 15
15 5 0 15
15 6 0 15
15 7 0 15
15 8 0 15
15 9 0 15
15 10 0 15
15 11 0 15
15 12 0 15
15 13 0 15
15 14 0 15
15 15 0 15
4個のフィールドの左の2個で、8ビットのアドレスを
生成できるようになったので、次の操作でHEXファイル
を生成。
できあがったHEXファイルの内容は、以下。
:1000000000000000000000000000000000000000F0
:1000100000000000000000000000000000000000E0
:1000200000010001000300020001000100010001C5
:1000300000010001000100010001000100010001B8
:100040000002000200020002000F00020002000293
:100050000002000200020002000200020002000290
:100060000003000300030003000F0003000300036C
:100070000003000300030003000300030003000368
:1001000000090008000800080008000800080008AE
:10011000000800080008000800080008000800089F
:100120000009000900090009000A00090009000986
:100130000009000900090009000900090009000977
:10014000000A000A000A000A000F000A000A000A5A
:10015000000A000A000A000A000A000A000A000A4F
:10018000000D000C000C000C000C000C000C000C0E
:10019000000C000C000C000C000C000C000C000CFF
:1001A000000D000D000D000D000E000D000D000DE6
:1001B000000D000D000D000D000D000D000D000DD7
:1001C000000E000E000E000E000F000E000E000EBE
:1001D000000E000E000E000E000E000E000E000EAF
:1001E000000F000F0008000C000F000F000F000FA1
:1001F000000F000F000F000F000F000F000F000F87
:00000001FF
ラベルを使うと、人間にはわかりやすいですが
デジタル回路やマイコンでは扱えません。
ラベルから数値へと変換するために、スクリプト
言語を利用するのが、ミスなく短時間で済ませる
極意と言えるでしょう。
1行にアドレスとニブルデータを並べた次のような
データを考えてみます。
0 1 0
1 2 1
2 3 2
3 4 4
4 0 8
5 15 15
6 15 15
7 15 15
8 15 15
9 15 15
10 15 15
11 15 15
12 15 15
13 15 15
14 15 15
15 15 15
第1フィールドがアドレス、続く2フィールドに
4ビットでデータが入っているので、計算に利用
する一時変数を用意して対応すれば充分でしょう。
スクリプトは、以下。
# bit inverse
function xinverse(x) {
# default
result = 0
# judge
if ( x == 0 ) { result = 1 }
return result
}
# 1's compliment
function bnot(x) {
# copy
tmpx = x
# separate
x0 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x1 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x2 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x3 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x4 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x5 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x6 = int( tmpx % 2 ) ; tmpx = tmpx / 2 ;
x7 = int( tmpx % 2 ) ;
# inverse
x0 = xinverse(x0) ; x1 = xinverse(x1)
x2 = xinverse(x2) ; x3 = xinverse(x3)
x4 = xinverse(x4) ; x5 = xinverse(x5)
x6 = xinverse(x6) ; x7 = xinverse(x7)
# calculate
result = 0 ;
result = result * 2 + x7 ; result = result * 2 + x6
result = result * 2 + x5 ; result = result * 2 + x4
result = result * 2 + x3 ; result = result * 2 + x2
result = result * 2 + x1 ; result = result * 2 + x0
return result
}
BEGIN {
res = 0
}
{
adr = $1
ln = NR - 1
r = ln % 8
# show address
if ( r == 0 ) {
# data size
res = res + 8
# address
res = res + (adr / 256) + (adr % 256)
# data
tmp = $2 * 16 + $3
# 1 data
res = res + tmp
# show
printf(":08%04X00%02X",adr,tmp)
}
# add check sum
if ( r == 7 ) {
# data
tmp = $2 * 16 + $3
# add
res = res + tmp
# calculate check sum
result = bnot(res % 256) + 1
# show
printf("%02X%02X\n",tmp,result)
# prepare next
res = 0
}
# others
if ( r != 0 && r != 7 ) {
# data
tmp = $2 * 16 + $3
# add
res = res + tmp
# show
printf("%02X",tmp)
}
}
END {
printf(":00000001FF\n")
}
このスクリプトでHEXファイルを作成してみると以下。
:080000001021324408FFFFFF4C
:08000800FFFFFFFFFFFFFFFFF8
:00000001FF
目次
前
次