Documentation
¶
Overview ¶
Package ihex implements access to Intel HEX files.
IHEX files consist of records representing instructions for a PROM programmer to write data to memory locations (hereby referred to as "the address space") and set certain registers ("the start address"), along with record types this package only handles internally (EOF and extended addressing). As these records may appear in a file in any order and are defined to have peculiar corner cases, this package only presents the user with a simplified view of the address space, losing details of a particular representation on input and generating conservative output.
IHEX files come in three formats. The format termed "8-bit" or "I8HEX" has, naturally, contiguous 16-bit address space (64KB), "16-bit"/"I16HEX" has crazy Intel-segmeted 20-bit address space (1MB), and "32-bit"/"I32HEX" has 32-bit (4GB) addressing which is contiguous but the high 16 bits of the address are still set separately.
Input ¶
The parser uses bufio.Scanner, and thus may overread from the underlying reader. It reads the whole file at once until an End of File record is encountered, resulting in the address space looking as described under (*ChunkList).Normalize.
The parser rejects records of RECTYP that is unknown or invalid for the given format, and records of RECTYP other than Data with non-zero LOAD OFFSET.
The parser uses one Base Address, whose value and type is set by the most recent Extended Segment Address or Extended Linear Address record. The initial zero base is a Segment Base Address with 16-bit input and Linear otherwise. When the base is Segment, Data records spanning segment boundaries are wrapped around at the end of the segment to the beginning thereof. Data past the end of the address space are wrapped around to zero.
A Start Linear Address record sets the start address to its value. Start Segment Address sets it to the absolute value, losing the detail of the segmentation. The original segmented representation is available via IHex.StartSegment or (*Reader).ReadStartSegment; for Linear addresses it is set to zero.
Output ¶
The writer never generates Data records crossing addresses divisible by the given data record length, which must be a power of two and defaults to 16. Writes are buffered until such address boundary is reached or a Writer method other than Write is called, causing the write buffer to be flushed. (*IHex).WriteTo calls (*Writer).Seek before writing each Chunk.
Segment addresses are generated with the segment/offset split at 64 KB boundaries, with the bottom 12 bits of the segment set to zero. IHex.StartSegment and (*Writer).WriteStartSegment set the start segment address, preserving segmentation. In all other cases Linear addresses are used in 32-bit format.
Index ¶
Constants ¶
const ( FormatAuto = iota // I32HEX; (*IHex).ReadFrom: detect format Format8Bit // I8HEX format, 16-bit address space Format16Bit // I16HEX format, 20-bit address space Format32Bit // I32HEX format, 32-bit address space )
IHEX file formats
Variables ¶
var ( ErrArgs = errors.New("ihex: invalid arguments") ErrChecksum = errors.New("ihex: checksum error") ErrClosed = errors.New("ihex: writer is closed") ErrFormat = errors.New("ihex: invalid record for format") ErrRange = errors.New("ihex: address out of range") ErrRecord = errors.New("ihex: unknown record type") ErrStart = errors.New("ihex: invalid start address") ErrSyntax = errors.New("ihex: invalid syntax") )
Functions ¶
This section is empty.
Types ¶
type ChunkList ¶
type ChunkList []Chunk
ChunkList is a slice of Chunks.
func (*ChunkList) Normalize ¶
func (cl *ChunkList) Normalize()
Normalize turns cl into a sorted list of nonadjacent non-zero-legth Chunks representing the address space as it would look after the data in cl is written to it sequentially. Subsequent writes to a location already written to overwrite whole bytes.
Normalize may mutate data in place.
type IHex ¶
type IHex struct { // Format sets the file format. Legal formats are FormatAuto, // Format8Bit, Format16Bit and Format32Bit. FormatAuto is // equivalent to Format32Bit, but InFormat is used. Format byte // InFormat is used if Format is FormatAuto. ReadFrom sets // InFormat to Format16Bit or Format32Bit if input contains // records specific to those formats. WriteTo uses InFormat // as the output format. InFormat byte // DataRecLen is the maximum number of bytes in a Data // record length generated by WriteTo. Must be a power // of two or 0. In the latter case the default length of // 16 is used. DataRecLen byte // Start is the linear start address. If the active format is // Format32Bit, Start represents the contents of EIP on 80386. // If it is Format16Bit, WriteTo will segment Start on a 64 KB // boundary; the top 12 bits must be zero. Start uint32 // StartSegment is the segmented start address, representing // the pair of registers CS:IP on 8086. StartSegment uint32 // StartSet indicates that Start has been set by // ReadFrom, or should be written by WriteTo even if it's // zero. StartSet bool // Chunks are the data written to the address space. Chunks ChunkList }
IHex represents the contents of an IHEX file.
func (*IHex) ReadFrom ¶
ReadFrom reads an IHEX file from r into ix. ReadFrom returns nil on success, ErrArgs if ix.Format is invalid, an error from r on read errors or a SyntaxError on invalid input. ReadFrom may overread r.
ReadFrom adds the data from r to ix.Chunks, setting it to a list of programmed data areas as described under (*ChunkList).Normalize. Any data in the byte arrays underlying Chunks may be overwritten. If ix.Format is FormatAuto (zero value), ix.InFormat is set to Format16Bit or Format32Bit if records specific to those formats appear in the input file.
When a Start Segment Address or Start Linear Address record is encountered, ix.StartSet is set to true. In the former case ix.StartSegment is set to the value and ix.Start to its 20 bit linear representation, in the latter ix.Start is set to the value and ix.StartSegment to zero.
func (*IHex) WriteTo ¶
WriteTo writes data from ix to an IHEX file, using a Writer with parameters specified by ix.Format/ix.InFormat and ix.DataRecLength. ix.Chunks are written in order, flushing the write buffer between Chunks. If ix.Start or ix.StartSegment is not zero or ix.StartSet is true, WriteTo sets the start address. To set Start Segment Address in a 32-bit file, ix.Start must be zero and ix.StartSegment non-zero.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader provides a simple interface for reading an IHEX file from an underlying reader. It reads the whole file at the first Read, ReadStart, ReadStartSegment or Seek call.
Reader's Read method reads from a contiguous address space spanning from address 0 to the end address, which is normally the address immediately after the topmost byte written by the programmer, with gaps between written memory filled with zeros. For readers created by NewPadReader, the end address is set to padTo if the latter is higher, and the filler byte is set to gapFill.
func NewPadReader ¶
NewPadReader returns a Reader reading from r. The returned Reader has its address space padded to at least padTo, with any gaps filled with gapFill.
func NewReader ¶
NewReader returns a Reader reading from r. format must be one of FormatAuto, Format8Bit, Format16Bit or Format32Bit.
func (*Reader) Read ¶
Read reads from the address space represented by r. Read returns io.EOF at the end of address space or ErrRange out of the address space.
func (*Reader) ReadStart ¶
ReadStart returns the start address, or zero if it has not been set. If the start address is segmented, it's converted to linear.
func (*Reader) ReadStartSegment ¶ added in v1.3.0
ReadStartSegment returns the start segment address, or zero if it has not been set.
type SyntaxError ¶ added in v1.1.0
type SyntaxError struct { Err error // ErrChecksum, ErrFormat, ErrRecord or ErrSyntax Format byte // Active IHEX format Line int // input line number, or 0 for missing EOF record Record string // input line, or "" for missing EOF record }
func (SyntaxError) Error ¶ added in v1.1.0
func (e SyntaxError) Error() string
Error returns the error formatted as one of:
"ihex: <invalid syntax/invalid record type/checksum error> on line <n>" "ihex: invalid record for <unspecified/I8HEX/I16HEX/I32HEX> format on line <n>" "ihex: missing EOF record"
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer writes an IHEX file to an underlying writer. Records are written in the order in which Writer's methods are called. After all data are written to the Writer, Close must be called.
func NewWriter ¶
NewWriter returns a new Writer writing to w. format defines the IHEX file format. dataRecLen is the maximum number of bytes in a Data record generated, which must be a power of two or 0. In the latter case the default length of 16 is used. If any argument is invalid, ErrArgs is returned as error.
func (*Writer) Close ¶
Close flushes the data buffer and writes an EOF record to the underlying writer. After Close is called, further calls to Close will return nil, and calls to other methods of w will return ErrClosed as error.
func (*Writer) Seek ¶
Seek causes the next Write to write data to the specified address in the address space. Seek flushes the data buffer, but otherwise does not generate any records. Seek implements the io.Seeker interface.
func (*Writer) WriteStart ¶
WriteStart sets the start linear address in 32-bit files or start segment address in 16-bit files. WriteStart returns ErrFormat if the format is Format8Bit, and ErrStart if the format is Format16Bit and addr is wider than 20 bit.
func (*Writer) WriteStartSegment ¶ added in v1.3.0
WriteStartSegment sets the start segment address to addr.