1 |
25 |
alirezamon |
/*
|
2 |
|
|
* kk_ihex.h: A simple library for reading and writing the Intel HEX
|
3 |
|
|
* or IHEX format. Intended mainly for embedded systems, and thus
|
4 |
|
|
* somewhat optimised for size at the expense of error handling and
|
5 |
|
|
* generality.
|
6 |
|
|
*
|
7 |
|
|
* USAGE
|
8 |
|
|
* -----
|
9 |
|
|
*
|
10 |
|
|
* The library has been split into read and write parts, which use a
|
11 |
|
|
* common data structure (`struct ihex_state`), but each can be used
|
12 |
|
|
* independently. Include the header `kk_ihex_read.h` for reading, and/or
|
13 |
|
|
* the header `kk_ihex_write.h` for writing (and link with their respective
|
14 |
|
|
* object files). Both can be used simultaneously - this header defines
|
15 |
|
|
* the shared data structures and definitions.
|
16 |
|
|
*
|
17 |
|
|
*
|
18 |
|
|
* READING INTEL HEX DATA
|
19 |
|
|
* ----------------------
|
20 |
|
|
*
|
21 |
|
|
* To read data in the Intel HEX format, you must perform the actual reading
|
22 |
|
|
* of bytes using other means (e.g., stdio). The bytes read must then be
|
23 |
|
|
* passed to `ihex_read_byte` and/or `ihex_read_bytes`. The reading functions
|
24 |
|
|
* will then call `ihex_data_read`, at which stage the `struct ihex_state`
|
25 |
|
|
* structure will contain the data along with its address. See the header
|
26 |
|
|
* `kk_ihex_read.h` for details and example implementation of `ihex_data_read`.
|
27 |
|
|
*
|
28 |
|
|
* The sequence to read data in IHEX format is:
|
29 |
|
|
* struct ihex_state ihex;
|
30 |
|
|
* ihex_begin_read(&ihex);
|
31 |
|
|
* ihex_read_bytes(&ihex, my_input_bytes, length_of_my_input_bytes);
|
32 |
|
|
* ihex_end_read(&ihex);
|
33 |
|
|
*
|
34 |
|
|
*
|
35 |
|
|
* WRITING BINARY DATA AS INTEL HEX
|
36 |
|
|
* --------------------------------
|
37 |
|
|
*
|
38 |
|
|
* In order to write out data, the `ihex_write_at_address` or
|
39 |
|
|
* `ihex_write_at_segment` functions are used to set the data location,
|
40 |
|
|
* and then the binary bytes are written with `ihex_write_byte` and/or
|
41 |
|
|
* `ihex_write_bytes`. The writing functions will then call the function
|
42 |
|
|
* `ihex_flush_buffer` whenever the internal write buffer needs to be
|
43 |
|
|
* cleared - it is up to the caller to provide an implementation of
|
44 |
|
|
* `ihex_flush_buffer` to do the actual writing. See the header
|
45 |
|
|
* `kk_ihex_write.h` for details and an example implementation.
|
46 |
|
|
*
|
47 |
|
|
* See the declaration further down for an example implementation.
|
48 |
|
|
*
|
49 |
|
|
* The sequence to write data in IHEX format is:
|
50 |
|
|
* struct ihex_state ihex;
|
51 |
|
|
* ihex_init(&ihex);
|
52 |
|
|
* ihex_write_at_address(&ihex, 0);
|
53 |
|
|
* ihex_write_bytes(&ihex, my_data, length_of_my_data);
|
54 |
|
|
* ihex_end_write(&ihex);
|
55 |
|
|
*
|
56 |
|
|
* For outputs larger than 64KiB, 32-bit linear addresses are output. Normally
|
57 |
|
|
* the initial linear extended address record of zero is NOT written - it can
|
58 |
|
|
* be forced by setting `ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW` before
|
59 |
|
|
* writing the first byte.
|
60 |
|
|
*
|
61 |
|
|
* Gaps in the data may be created by calling `ihex_write_at_address` with the
|
62 |
|
|
* new starting address without calling `ihex_end_write` in between.
|
63 |
|
|
*
|
64 |
|
|
*
|
65 |
|
|
* The same `struct ihex_state` may be used either for reading or writing,
|
66 |
|
|
* but NOT both at the same time. Furthermore, a global output buffer is
|
67 |
|
|
* used for writing, i.e., multiple threads must not write simultaneously
|
68 |
|
|
* (but multiple writes may be interleaved).
|
69 |
|
|
*
|
70 |
|
|
*
|
71 |
|
|
* CONSERVING MEMORY
|
72 |
|
|
* -----------------
|
73 |
|
|
*
|
74 |
|
|
* For memory-critical use, you can save additional memory by defining
|
75 |
|
|
* `IHEX_LINE_MAX_LENGTH` as something less than 255. Note, however, that
|
76 |
|
|
* this limit affects both reading and writing, so the resulting library
|
77 |
|
|
* will be unable to read lines with more than this number of data bytes.
|
78 |
|
|
* That said, I haven't encountered any IHEX files with more than 32
|
79 |
|
|
* data bytes per line. For write only there is no reason to define the
|
80 |
|
|
* maximum as greater than the line length you'll actually be writing,
|
81 |
|
|
* e.g., 32 or 16.
|
82 |
|
|
*
|
83 |
|
|
* If the write functionality is only occasionally used, you can provide
|
84 |
|
|
* your own buffer for the duration by defining `IHEX_EXTERNAL_WRITE_BUFFER`
|
85 |
|
|
* and providing a `char *ihex_write_buffer` which points to valid storage
|
86 |
|
|
* for at least `IHEX_WRITE_BUFFER_LENGTH` characters from before the first
|
87 |
|
|
* call to any IHEX write function to until after the last.
|
88 |
|
|
*
|
89 |
|
|
* If you are doing both reading and writing, you can define the maximum
|
90 |
|
|
* output length separately as `IHEX_MAX_OUTPUT_LINE_LENGTH` - this will
|
91 |
|
|
* decrease the write buffer size, but `struct ihex_state` will still
|
92 |
|
|
* use the larger `IHEX_LINE_MAX_LENGTH` for its data storage.
|
93 |
|
|
*
|
94 |
|
|
* You can also save a few additional bytes by disabling support for
|
95 |
|
|
* segmented addresses, by defining `IHEX_DISABLE_SEGMENTS`. Both the
|
96 |
|
|
* read and write modules need to be build with the same option, as the
|
97 |
|
|
* resulting data structures will not be compatible otherwise. To be honest,
|
98 |
|
|
* this is a fairly pointless optimisation.
|
99 |
|
|
*
|
100 |
|
|
*
|
101 |
|
|
* Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/
|
102 |
|
|
* Provided with absolutely no warranty, use at your own risk only.
|
103 |
|
|
* Use and distribute freely, mark modified copies as such.
|
104 |
|
|
*/
|
105 |
|
|
|
106 |
|
|
#ifndef KK_IHEX_H
|
107 |
|
|
#define KK_IHEX_H
|
108 |
|
|
|
109 |
|
|
#define KK_IHEX_VERSION "2016-07-11"
|
110 |
|
|
|
111 |
|
|
#include <stdint.h>
|
112 |
|
|
|
113 |
|
|
#ifdef IHEX_USE_STDBOOL
|
114 |
|
|
#include <stdbool.h>
|
115 |
|
|
typedef bool ihex_bool_t;
|
116 |
|
|
#else
|
117 |
|
|
typedef uint_fast8_t ihex_bool_t;
|
118 |
|
|
#endif
|
119 |
|
|
|
120 |
|
|
typedef uint_least32_t ihex_address_t;
|
121 |
|
|
typedef uint_least16_t ihex_segment_t;
|
122 |
|
|
typedef int ihex_count_t;
|
123 |
|
|
|
124 |
|
|
// Maximum number of data bytes per line (applies to both reading and
|
125 |
|
|
// writing!); specify 255 to support reading all possible lengths. Less
|
126 |
|
|
// can be used to limit memory footprint on embedded systems, e.g.,
|
127 |
|
|
// most programs with IHEX output use 32.
|
128 |
|
|
#ifndef IHEX_LINE_MAX_LENGTH
|
129 |
|
|
#define IHEX_LINE_MAX_LENGTH 255
|
130 |
|
|
#endif
|
131 |
|
|
|
132 |
|
|
enum ihex_flags {
|
133 |
|
|
IHEX_FLAG_ADDRESS_OVERFLOW = 0x80 // 16-bit address overflow
|
134 |
|
|
};
|
135 |
|
|
typedef uint8_t ihex_flags_t;
|
136 |
|
|
|
137 |
|
|
typedef struct ihex_state {
|
138 |
|
|
ihex_address_t address;
|
139 |
|
|
#ifndef IHEX_DISABLE_SEGMENTS
|
140 |
|
|
ihex_segment_t segment;
|
141 |
|
|
#endif
|
142 |
|
|
ihex_flags_t flags;
|
143 |
|
|
uint8_t line_length;
|
144 |
|
|
uint8_t length;
|
145 |
|
|
uint8_t data[IHEX_LINE_MAX_LENGTH + 1];
|
146 |
|
|
} kk_ihex_t;
|
147 |
|
|
|
148 |
|
|
enum ihex_record_type {
|
149 |
|
|
IHEX_DATA_RECORD,
|
150 |
|
|
IHEX_END_OF_FILE_RECORD,
|
151 |
|
|
IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD,
|
152 |
|
|
IHEX_START_SEGMENT_ADDRESS_RECORD,
|
153 |
|
|
IHEX_EXTENDED_LINEAR_ADDRESS_RECORD,
|
154 |
|
|
IHEX_START_LINEAR_ADDRESS_RECORD
|
155 |
|
|
};
|
156 |
|
|
typedef uint8_t ihex_record_type_t;
|
157 |
|
|
|
158 |
|
|
#ifndef IHEX_DISABLE_SEGMENTS
|
159 |
|
|
|
160 |
|
|
// Resolve segmented address (if any). It is the author's recommendation that
|
161 |
|
|
// segmented addressing not be used (and indeed the write function of this
|
162 |
|
|
// library uses linear 32-bit addressing unless manually overridden).
|
163 |
|
|
//
|
164 |
|
|
#define IHEX_LINEAR_ADDRESS(ihex) ((ihex)->address + (((ihex_address_t)((ihex)->segment)) << 4))
|
165 |
|
|
//
|
166 |
|
|
// Note that segmented addressing with the above macro is not strictly adherent
|
167 |
|
|
// to the IHEX specification, which mandates that the lowest 16 bits of the
|
168 |
|
|
// address and the index of the data byte must be added modulo 64K (i.e.,
|
169 |
|
|
// at 16 bits precision with wraparound) and the segment address only added
|
170 |
|
|
// afterwards.
|
171 |
|
|
//
|
172 |
|
|
// To implement fully correct segmented addressing, compute the address
|
173 |
|
|
// of _each byte_ with its index in `data` as follows:
|
174 |
|
|
//
|
175 |
|
|
#define IHEX_BYTE_ADDRESS(ihex, byte_index) ((((ihex)->address + (byte_index)) & 0xFFFFU) + (((ihex_address_t)((ihex)->segment)) << 4))
|
176 |
|
|
|
177 |
|
|
#else // IHEX_DISABLE_SEGMENTS:
|
178 |
|
|
|
179 |
|
|
#define IHEX_LINEAR_ADDRESS(ihex) ((ihex)->address)
|
180 |
|
|
#define IHEX_BYTE_ADDRESS(ihex, byte_index) ((ihex)->address + (byte_index))
|
181 |
|
|
|
182 |
|
|
#endif
|
183 |
|
|
|
184 |
|
|
// The newline string (appended to every output line, e.g., "\r\n")
|
185 |
|
|
#ifndef IHEX_NEWLINE_STRING
|
186 |
|
|
#define IHEX_NEWLINE_STRING "\n"
|
187 |
|
|
#endif
|
188 |
|
|
|
189 |
|
|
// See kk_ihex_read.h and kk_ihex_write.h for function declarations!
|
190 |
|
|
|
191 |
|
|
#endif // !KK_IHEX_H
|