ihex: Intel HEX files
| (require ihex) | package: ihex |
The "ihex" package reads and writes Intel HEX files — the record-oriented firmware image format used by toolchains for 8051, MCS-96, ARM and countless other targets. Everything is implemented in pure Racket: no FFI, no system dependency.
The writer is validated byte-for-byte against the Python bincopy library (its outputs ship as golden fixtures), and the parser accepts everything bincopy produces. The image writer goes one step further than bincopy: data records never cross a 64K address window (a record’s address field is only 16 bits, so a straddling record would be unrepresentable) — an extended-linear record is inserted at every window change.
1 Quick start
> (define image (bytes 222 173 190 239))
> (define text (bytes->ihex image #:base-address 4096 #:start-address 4096)) > (display text)
:04100000DEADBEEFB4
:0400000500001000E7
:00000001FF
> (ihex->bytes text) #"\336\255\276\357"
> (ihex-start-address text) 4096
2 Records
A record line is :<length><address><type><data><checksum>, all hexadecimal, with a two’s-complement checksum over length, address, type and data — ihex-checksum. Record types: 00 data, 01 end-of-file, 02 extended segment address (segment × 16 + offset), 03 start segment address, 04 extended linear address (upper 16 bits of a 32-bit address) and 05 start linear address (a 32-bit entry point).
struct
(struct ihex-record (kind address data))
kind :
(or/c 'data 'eof 'extended-segment 'start-segment 'extended-linear 'start-linear) address : exact-nonnegative-integer? data : bytes?
procedure
(parse-ihex text) → (listof ihex-record?)
text : string?
procedure
(parse-ihex-line line line-no) → ihex-record?
line : string? line-no : exact-nonnegative-integer?
3 Writing
procedure
(write-ihex-record rec) → string?
rec : ihex-record?
procedure
(bytes->ihex bs [ #:base-address base #:data-bytes-per-line per-line #:start-address start #:trailing-newline? trailing-newline?]) → string? bs : bytes? base : exact-nonnegative-integer? = 0 per-line : (integer-in 1 255) = 16 start : (or/c exact-nonnegative-integer? #f) = #f trailing-newline? : boolean? = #t
4 Images
procedure
(ihex->bytes text [#:fill fill]) → bytes?
text : string? fill : (integer-in 0 255) = 255
procedure
(ihex-start-address text)
→ (or/c exact-nonnegative-integer? #f) text : string?
5 License
MIT.