Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Last active February 7, 2024 02:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save snipsnipsnip/143569 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/143569 to your computer and use it in GitHub Desktop.
intel_hex_record.rb: intel hex record parser
:10006000000102030405060708090A0B0C0D0E0F18
:10007000101112131415161718191A1B1C1D1E1F08
:10008000202122000000000000000000000000000D
:100090000000000000000000000000000000000060
:1000A0000000000000000000000000000000000050
:1000B0000000000000000000000000000000000040
:1000C0000000000000000000000000000000000030
:1000D0000000000000000000000000000000002000
:00000001FF
require 'intel_hex_record'
def calc_dest_filename(name)
out = "#{name}.txt"
i = 1
while true
break out unless File.exist?(out)
out = "#{name}.#{i}.txt"
i += 1
end
end
def main
if ARGV.empty?
warn "usage: #{File.basename $0} records.hex [records.hex ..]"
warn ' writes to records.txt'
end
ARGV.each do |file|
records = IO.readlines(file).map {|x| x.strip!; IntelHexRecord.parse(x) if x[0] == ?: }
open(calc_dest_filename(file), 'w') do |f|
records.each do |r|
break if r.end?
raise "unexpected record type #{r.type}: #{r.inspect}" unless r.data?
f.printf '%08x ', r.offset
for c in r.data
f.printf '%02x ', c
end
f.puts
end
end
end
end
main if $0 == __FILE__
class IntelHexRecord
def self.parse(str)
Parser.new(str).parse
end
attr_reader :offset, :type, :data
include Enumerable
def initialize(offset, type, data)
@offset = offset
@type = type
@data = data
end
def data?
type == 0
end
def end?
type == 1
end
def size
data.size
end
def each(&blk)
data.each(&blk)
end
class Parser
def initialize(str)
@str = str
@i = 0
@sum = 0
end
def parse
char == ?: or raise 'expected colon'
size = byte
offset = word
type = byte
data = (1..size).map { byte }
checksum = byte
eof? or raise 'expected eof'
(@sum & 0xff) == 0 or raise "checksum doesn't match"
IntelRecord.new(offset, type, data)
end
def char
c = @str[@i]
@i += 1
@sum += c.chr.hex
c
end
def byte
b = @str[@i..@i+1].hex
@i += 2
@sum += b
b
end
def word
byte | (byte << 8)
end
def eof?
@i == @str.size
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment