Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #! /usr/bin/perl -w |
| 2 | |
| 3 | |
| 4 | # convert an Intel HEX file into a set of C records usable by the firmware |
| 5 | # loading code in usb-serial.c (or others) |
| 6 | |
| 7 | # accepts the .hex file(s) on stdin, a basename (to name the initialized |
| 8 | # array) as an argument, and prints the .h file to stdout. Typical usage: |
| 9 | # perl ezusb_convert.pl foo <foo.hex >fw_foo.h |
| 10 | |
| 11 | |
| 12 | my $basename = $ARGV[0]; |
| 13 | die "no base name specified" unless $basename; |
| 14 | |
| 15 | while (<STDIN>) { |
| 16 | # ':' <len> <addr> <type> <len-data> <crc> '\r' |
| 17 | # len, type, crc are 2-char hex, addr is 4-char hex. type is 00 for |
| 18 | # normal records, 01 for EOF |
| 19 | my($lenstring, $addrstring, $typestring, $reststring, $doscrap) = |
| 20 | /^:(\w\w)(\w\w\w\w)(\w\w)(\w+)(\r?)$/; |
| 21 | die "malformed line: $_" unless $reststring; |
| 22 | last if $typestring eq '01'; |
| 23 | my($len) = hex($lenstring); |
| 24 | my($addr) = hex($addrstring); |
| 25 | my(@bytes) = unpack("C*", pack("H".(2*$len), $reststring)); |
| 26 | #pop(@bytes); # last byte is a CRC |
| 27 | push(@records, [$addr, \@bytes]); |
| 28 | } |
| 29 | |
| 30 | @sorted_records = sort { $a->[0] <=> $b->[0] } @records; |
| 31 | |
| 32 | print <<"EOF"; |
| 33 | /* |
| 34 | * ${basename}_fw.h |
| 35 | * |
| 36 | * Generated from ${basename}.s by ezusb_convert.pl |
| 37 | * This file is presumed to be under the same copyright as the source file |
| 38 | * from which it was derived. |
| 39 | */ |
| 40 | |
| 41 | EOF |
| 42 | |
| 43 | print "static const struct ezusb_hex_record ${basename}_firmware[] = {\n"; |
| 44 | foreach $r (@sorted_records) { |
| 45 | printf("{ 0x%04x,\t%d,\t{", $r->[0], scalar(@{$r->[1]})); |
| 46 | print join(", ", map {sprintf('0x%02x', $_);} @{$r->[1]}); |
| 47 | print "} },\n"; |
| 48 | } |
| 49 | print "{ 0xffff,\t0,\t{0x00} }\n"; |
| 50 | print "};\n"; |