STIMA  3
kk_ihex.h
1 /*
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-2019 Kimmo Kulovesi, https://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 "2019-08-07"
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
Definition: kk_ihex.h:137