1 |
25 |
alirezamon |
/*
|
2 |
|
|
* kk_ihex_write.h: A simple library for writing Intel HEX data.
|
3 |
|
|
* See the accompanying kk_ihex_read.h for read support, and the
|
4 |
|
|
* main header kk_ihex.h for the shared parts.
|
5 |
|
|
*
|
6 |
|
|
*
|
7 |
|
|
* WRITING BINARY DATA AS INTEL HEX
|
8 |
|
|
* --------------------------------
|
9 |
|
|
*
|
10 |
|
|
* In order to write out data, the `ihex_write_at_address` or
|
11 |
|
|
* `ihex_write_at_segment` functions are used to set the data location,
|
12 |
|
|
* and then the binary bytes are written with `ihex_write_byte` and/or
|
13 |
|
|
* `ihex_write_bytes`. The writing functions will then call the function
|
14 |
|
|
* `ihex_flush_buffer` whenever the internal write buffer needs to be
|
15 |
|
|
* cleared - it is up to the caller to provide an implementation of
|
16 |
|
|
* `ihex_flush_buffer` to do the actual writing. See below for details
|
17 |
|
|
* and an example implementation.
|
18 |
|
|
*
|
19 |
|
|
* See the declaration further down for an example implementation.
|
20 |
|
|
*
|
21 |
|
|
* The sequence to write data in IHEX format is:
|
22 |
|
|
* struct ihex_state ihex;
|
23 |
|
|
* ihex_init(&ihex);
|
24 |
|
|
* ihex_write_at_address(&ihex, 0);
|
25 |
|
|
* ihex_write_bytes(&ihex, my_data, length_of_my_data);
|
26 |
|
|
* ihex_end_write(&ihex);
|
27 |
|
|
*
|
28 |
|
|
* For outputs larger than 64KiB, 32-bit linear addresses are output. Normally
|
29 |
|
|
* the initial linear extended address record of zero is NOT written - it can
|
30 |
|
|
* be forced by setting `ihex->flags |= IHEX_FLAG_ADDRESS_OVERFLOW` before
|
31 |
|
|
* writing the first byte.
|
32 |
|
|
*
|
33 |
|
|
* Gaps in the data may be created by calling `ihex_write_at_address` with the
|
34 |
|
|
* new starting address without calling `ihex_end_write` in between.
|
35 |
|
|
*
|
36 |
|
|
*
|
37 |
|
|
* The same `struct ihex_state` may be used either for reading or writing,
|
38 |
|
|
* but NOT both at the same time. Furthermore, a global output buffer is
|
39 |
|
|
* used for writing, i.e., multiple threads must not write simultaneously
|
40 |
|
|
* (but multiple writes may be interleaved).
|
41 |
|
|
*
|
42 |
|
|
*
|
43 |
|
|
* CONSERVING MEMORY
|
44 |
|
|
* -----------------
|
45 |
|
|
*
|
46 |
|
|
* If you are using only the write support, you should define
|
47 |
|
|
* `IHEX_LINE_MAX_LENGTH` as the length of your output line. This makes
|
48 |
|
|
* both the `struct ihex_state' and the internal write buffer smaller.
|
49 |
|
|
* For example, 32 or even 16 can be used instead of the default 255.
|
50 |
|
|
*
|
51 |
|
|
* If the write functionality is not used all the time and can thus
|
52 |
|
|
* share its write buffer memory with something else that is inactive
|
53 |
|
|
* during writing IHEX, you can define `IHEX_EXTERNAL_WRITE_BUFFER` and
|
54 |
|
|
* provide the buffer as `char *ihex_write_buffer`. The size of the
|
55 |
|
|
* buffer must be at least `IHEX_WRITE_BUFFER_LENGTH` bytes and it must
|
56 |
|
|
* be valid for the entire duration from the first call to a write function
|
57 |
|
|
* until after the last call to `ihex_end_write`. Note that there is
|
58 |
|
|
* no advantage to this unless something else, mutually exclusive with
|
59 |
|
|
* IHEX writing, can share the memory.
|
60 |
|
|
*
|
61 |
|
|
* If you are reading IHEX as well, then you'll end up limiting the
|
62 |
|
|
* maximum length of line that can be read. In that case you may wish to
|
63 |
|
|
* define `IHEX_MAX_OUTPUT_LINE_LENGTH` as smaller to decrease the
|
64 |
|
|
* write buffer size, but keep `IHEX_LINE_MAX_LENGTH` at 255 to support
|
65 |
|
|
* reading any IHEX file.
|
66 |
|
|
*
|
67 |
|
|
*
|
68 |
|
|
* Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/
|
69 |
|
|
* Provided with absolutely no warranty, use at your own risk only.
|
70 |
|
|
* Use and distribute freely, mark modified copies as such.
|
71 |
|
|
*/
|
72 |
|
|
|
73 |
|
|
#ifndef KK_IHEX_WRITE_H
|
74 |
|
|
#define KK_IHEX_WRITE_H
|
75 |
|
|
#ifdef __cplusplus
|
76 |
|
|
extern "C" {
|
77 |
|
|
#endif
|
78 |
|
|
|
79 |
|
|
#include "kk_ihex.h"
|
80 |
|
|
|
81 |
|
|
// Default number of data bytes written per line
|
82 |
|
|
#if IHEX_LINE_MAX_LENGTH >= 32
|
83 |
|
|
#define IHEX_DEFAULT_OUTPUT_LINE_LENGTH 32
|
84 |
|
|
#else
|
85 |
|
|
#define IHEX_DEFAULT_OUTPUT_LINE_LENGTH IHEX_LINE_MAX_LENGTH
|
86 |
|
|
#endif
|
87 |
|
|
|
88 |
|
|
#ifndef IHEX_MAX_OUTPUT_LINE_LENGTH
|
89 |
|
|
#define IHEX_MAX_OUTPUT_LINE_LENGTH IHEX_LINE_MAX_LENGTH
|
90 |
|
|
#endif
|
91 |
|
|
|
92 |
|
|
// Length of the write buffer required
|
93 |
|
|
#define IHEX_WRITE_BUFFER_LENGTH (1+2+4+2+(IHEX_MAX_OUTPUT_LINE_LENGTH*2)+2+sizeof(IHEX_NEWLINE_STRING))
|
94 |
|
|
|
95 |
|
|
#ifdef IHEX_EXTERNAL_WRITE_BUFFER
|
96 |
|
|
// Define `IHEX_EXTERNAL_WRITE_BUFFER` to provide an external write buffer,
|
97 |
|
|
// as `char *ihex_write_buffer`, which must point to a valid storage for
|
98 |
|
|
// at least `IHEX_WRITE_BUFFER_LENGTH` characters whenever any of the
|
99 |
|
|
// write functionality is used (see above under "CONSERVING MEMORY").
|
100 |
|
|
extern char *ihex_write_buffer;
|
101 |
|
|
#endif
|
102 |
|
|
|
103 |
|
|
// Initialise the structure `ihex` for writing
|
104 |
|
|
void ihex_init(struct ihex_state *ihex);
|
105 |
|
|
|
106 |
|
|
// Begin writing at the given 32-bit `address` after writing any
|
107 |
|
|
// pending data at the current address.
|
108 |
|
|
//
|
109 |
|
|
// This can also be used to skip to a new address without calling
|
110 |
|
|
// `ihex_end_write`; this allows writing sparse output.
|
111 |
|
|
//
|
112 |
|
|
void ihex_write_at_address(struct ihex_state *ihex, ihex_address_t address);
|
113 |
|
|
|
114 |
|
|
// Write a single byte
|
115 |
|
|
void ihex_write_byte(struct ihex_state *ihex, int b);
|
116 |
|
|
|
117 |
|
|
// Write `count` bytes from `data`
|
118 |
|
|
void ihex_write_bytes(struct ihex_state * restrict ihex,
|
119 |
|
|
const void * restrict data,
|
120 |
|
|
ihex_count_t count);
|
121 |
|
|
|
122 |
|
|
// End writing (flush buffers, write end of file record)
|
123 |
|
|
void ihex_end_write(struct ihex_state *ihex);
|
124 |
|
|
|
125 |
|
|
// Called whenever the global, internal write buffer needs to be flushed by
|
126 |
|
|
// the write functions. The implementation is NOT provided by this library;
|
127 |
|
|
// this must be implemented to perform the actual output, i.e., write out
|
128 |
|
|
// `(eptr - buffer)` bytes from `buffer` (which is not NUL-terminated, but
|
129 |
|
|
// may be modified to make it thus).
|
130 |
|
|
//
|
131 |
|
|
// Example implementation:
|
132 |
|
|
//
|
133 |
|
|
// void ihex_flush_buffer(struct ihex_state *ihex,
|
134 |
|
|
// char *buffer, char *eptr) {
|
135 |
|
|
// *eptr = '\0';
|
136 |
|
|
// (void) fputs(buffer, stdout);
|
137 |
|
|
// }
|
138 |
|
|
//
|
139 |
|
|
// Note that the contents of `buffer` can become invalid immediately after
|
140 |
|
|
// this function returns - the data must be copied if it needs to be preserved!
|
141 |
|
|
//
|
142 |
|
|
extern void ihex_flush_buffer(struct ihex_state *ihex,
|
143 |
|
|
char *buffer, char *eptr);
|
144 |
|
|
|
145 |
|
|
// As `ihex_write_at_address`, but specify a segment selector. Note that
|
146 |
|
|
// segments are not automatically incremented when the 16-bit address
|
147 |
|
|
// overflows (the default is to use 32-bit linear addressing). For segmented
|
148 |
|
|
// 20-bit addressing you must manually ensure that a write does not overflow
|
149 |
|
|
// the segment boundary, and call `ihex_write_at_segment` every time the
|
150 |
|
|
// segment needs to be changed.
|
151 |
|
|
//
|
152 |
|
|
#ifndef IHEX_DISABLE_SEGMENTS
|
153 |
|
|
void ihex_write_at_segment(struct ihex_state *ihex,
|
154 |
|
|
ihex_segment_t segment,
|
155 |
|
|
ihex_address_t address);
|
156 |
|
|
#endif
|
157 |
|
|
|
158 |
|
|
// Set the output line length to `length` - may be safely called only right
|
159 |
|
|
// after `ihex_write_at_address` or `ihex_write_at_segment`. The maximum
|
160 |
|
|
// is IHEX_LINE_MAX_LENGTH (which may be changed at compile time).
|
161 |
|
|
void ihex_set_output_line_length(struct ihex_state *ihex, uint8_t line_length);
|
162 |
|
|
|
163 |
|
|
#ifdef __cplusplus
|
164 |
|
|
}
|
165 |
|
|
#endif
|
166 |
|
|
#endif // !KK_IHEX_WRITE_H
|