ihex

package module
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2024 License: ISC Imports: 6 Imported by: 1

README

ihex is a Go package implementing access to Intel HEX files.

Copyright (c) 2014-2015, 2020-2023 Vadim Vygonets <vadik@vygo.net>
Licensed under ISC License.

Installing:
go get github.com/unixdj/ihex 

Documentation:
http://godoc.org/github.com/unixdj/ihex

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

View Source
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

View Source
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 Chunk

type Chunk struct {
	Addr uint32
	Data []byte
}

Chunk represents a contiguous area in the IHEX address space.

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.

func (ChunkList) WriteTo added in v1.3.0

func (cl ChunkList) WriteTo(w io.WriteSeeker) error

WriteTo writes data from cl to w in order.

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

func (ix *IHex) ReadFrom(r io.Reader) error

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

func (ix *IHex) WriteTo(w io.Writer) error

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

func NewPadReader(r io.Reader, format byte, padTo int64, gapFill byte) (*Reader, error)

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

func NewReader(r io.Reader, format byte) (*Reader, error)

NewReader returns a Reader reading from r. format must be one of FormatAuto, Format8Bit, Format16Bit or Format32Bit.

func (*Reader) Read

func (r *Reader) Read(buf []byte) (int, error)

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

func (r *Reader) ReadStart() (uint32, error)

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

func (r *Reader) ReadStartSegment() (uint32, error)

ReadStartSegment returns the start segment address, or zero if it has not been set.

func (*Reader) Seek

func (r *Reader) Seek(offset int64, whence int) (int64, error)

Seek causes the next Read to return data from the specified address. Seek implements the io.Seeker interface.

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

func NewWriter(w io.Writer, format byte, dataRecLen byte) (*Writer, error)

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

func (w *Writer) Close() error

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

func (w *Writer) Seek(offset int64, whence int) (int64, error)

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) Write

func (w *Writer) Write(buf []byte) (int, error)

Write writes data from buf to r. Writes are buffered as needed.

func (*Writer) WriteStart

func (w *Writer) WriteStart(addr uint32) error

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

func (w *Writer) WriteStartSegment(addr uint32) error

WriteStartSegment sets the start segment address to addr.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL