#!/usr/bin/env tclsh # Changed to byte array per file with index struct for mega version # wc, 2014-01-13 # Generate a C include file from one or more Intel HEX files (avr-gcc output) # jcw, 2010-04-18 # Examples: # ./hex2c.tcl Blink.cpp.hex ATmegaBOOT_168_atmega328.hex >data_blink.h # ./hex2c.tcl RF12demo.cpp.hex ATmegaBOOT_168_atmega328.hex >data_rf12demo.h # ./hex2c.tcl Blink.cpp.hex optiboot_atmega328.hex >opti_blink.h # ./hex2c.tcl RF12demo.cpp.hex optiboot_atmega328.hex >opti_rf12demo.h if {$argv eq ""} { puts stderr "Usage: [info script] infile.hex ?...? >outfile.h" exit 1 } set bytes {} set psi 0 foreach a $argv { set start [llength $bytes] set mtime [clock format [file mtime $a] -format "%Y-%m-%d"] puts stderr $a: set fd [open $a] while {[gets $fd line] > 0} { if {[scan $line {:%2x%4x%2x%s} count addr type data]} { if {$type == 0} { if {![info exists next]} { set first [format 0x%04X $addr] set next $addr } while {$next < $addr} { lappend bytes 255 ;# pad with unset bytes if there is a gap incr next } if {$next != $addr} { puts stderr "non-contiguous data ($next vs $addr)" } incr next $count foreach {x y} [split [string range $data 0 end-2] ""] { lappend bytes [scan $x$y %x] } } } } incr next -$first set f [format %-30s [file tail $a]] lappend sections "\"$f\",\"$mtime\",progdata_$psi,$first,$start,$next" #lappend sections "\"$mtime $f ${next}b @ $first\",$first,$start,$next" unset next close $fd lappend byte_sections $bytes set bytes {} incr psi } puts "// This file was generated by hex2c.tcl on [clock format [clock seconds]]" puts "" puts "" set pgi 0 foreach bs $byte_sections { puts "const unsigned char progdata_$pgi\[] PROGMEM = {" set out " " foreach x $bs { if {[string length $out$x,] > 80} { puts $out set out " " } append out $x , } puts $out puts "};" incr pgi } puts "" puts "mega_flash_data_struct sections\[] = {" foreach x $sections { puts " {$x}," } puts "};" puts ""