📄 hex2fdl
字号:
#! /usr/bin/perl# This script converts intel-hex data into fast flash download# binary format, for use with the PJRC MP3 player fast flash# firmware download.# Typical usages:# hex2fdl mp3player.hex > mp3player.fdl# hex2fdl mp3player.hex | xmit115200# Redhat8 now defaults to utf-8, so we need this for true binary outputbinmode STDOUT, ":bytes";$ascii_output = 0;$code_zero = 0x5A;$code_two_ff = 0x2D;$code_three_ff = 0x19;$code_escape_byte = 0x59;$code_address = 0x29;$code_115200_baud = 0x6A;$code_checksum = 0x3C;$code_end_of_data = 0x58;$code_undef_skip = 0x1D;$code_abort = 0x1B;$h = '[0-9A-F]';$addr_hi = 0;while (<>) { $addr_hi = 0x00000, next if /^:020000020000FC/; $addr_hi = 0x10000, next if /^:020000021000EC/; next unless /^:($h{2})/; #todo: this parsing is slow, can it be faster somehow? $len = hex($1) * 2; $hh = "$h\{$len\}"; next unless /^:($h{2})($h{4})00($hh)($h{2})/; $addr = hex($2) + $addr_hi; $data_text = $3; $sum = hex($4); #todo: check the checksum for ($i=0; $i<$len/2; $i++) { $data_text =~ /^($h{2})/; $data[$addr + $i] = hex($1); $data_text = $'; }}$cksum = 0;output_range(0x00000, 0x0FFFF);output_range(0x10000, 0x1FFFF);emit_byte($code_end_of_data);print "\n" if $ascii_output;sub output_range{ my $begin = shift; my $end = shift; my $addr; my $undef_count = 100000; my $ff_count = 0; my $data_count = 0; for ($addr=$begin; $addr<$end+1; $addr++) { if (!defined($data[$addr])) { if ($ff_count > 0) { emit_ff($ff_count); $ff_count = 0; } $undef_count++; } else { if ($undef_count > 0) { if ($undef_count < 120) { emit_undef_skip($undef_count); } else { emit_addr($addr); } $undef_count = 0; } if ($data[$addr] == 0xFF) { $ff_count++; } else { if ($ff_count > 0) { emit_ff($ff_count); $ff_count = 0; } emit_data($data[$addr]); $data_count++; if ($data_count > 400) { emit_cksum(); $data_count = 0; } } } } emit_ff($ff_count) if $ff_count > 0; emit_cksum() if $data_count > 0;}sub emit_addr{ my $addr = shift; my $byte; warn sprintf "Addr: %04X\n", $addr; emit_byte($code_address); $byte = ($addr & 0x7F) | 0x80; $cksum = ($cksum + (($byte ^ 0x6B) << 8)) & 0xFFFF; emit_byte($byte); $byte = (($addr >> 8) & 0x7F) | 0x80; $cksum = ($cksum + (($byte ^ 0x5A) << 8)) & 0xFFFF; emit_byte($byte); $byte = (($addr >> 7) & 1) | (($addr >> 14) & 6) | 0x80; $cksum = ($cksum + ($byte << 8)) & 0xFFFF; emit_byte($byte);}sub emit_cksum{ emit_byte($code_checksum); #warn("cksum: $cksum\n"); emit_byte(($cksum & 0x7F) | 0x80); emit_byte((($cksum >> 8) & 0x7F) | 0x80); $cksum = 0;}sub emit_undef_skip{ my $num = shift; my $byte; #warn("undef: $num\n"); emit_byte($code_undef_skip); $byte = $num | 0x80; $cksum = ($cksum + (($byte ^ 0x4E) << 8)) & 0xFFFF; emit_byte($byte);}sub emit_ff{ my $num = shift; while ($num >= 3) { #warn("Three FFs\n"); $cksum = ($cksum + 0x3C00) & 0xFFFF; emit_byte($code_three_ff); $num -= 3; } if ($num == 2) { #warn("Two FFs\n"); $cksum = ($cksum + 0x5D00) & 0xFFFF; emit_byte($code_two_ff); } if ($num == 1) { #warn("One FFs\n"); emit_data(0xFF); }}sub emit_data{ my $byte = shift; $cksum = ($cksum + $byte + (($byte ^ 0x56) << 8)) & 0xFFFF; if ($byte == 0) { emit_byte($code_zero); return; } if ($byte == $code_zero || $byte == $code_two_ff || $byte == $code_three_ff || $byte == $code_escape_byte || $byte == $code_address || $byte == $code_115200_baud || $byte == $code_checksum || $byte == $code_end_of_data || $byte == $code_undef_skip || $byte == $code_abort) { #warn("ESC: $byte\n"); emit_byte($code_escape_byte); emit_byte($byte | 0x80); return; } emit_byte($byte);}sub emit_byte{ my $byte = shift; if ($ascii_output) { printf("%02X ", $byte); print "\n" if ++$bytecount % 16 == 0; } else { print pack('C', $byte); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -