1 |
25 |
alirezamon |
/*
|
2 |
|
|
* kk_ihex_read.h: A simple library for reading Intel HEX data. See
|
3 |
|
|
* the accompanying kk_ihex_write.h for IHEX write support.
|
4 |
|
|
*
|
5 |
|
|
*
|
6 |
|
|
* READING INTEL HEX DATA
|
7 |
|
|
* ----------------------
|
8 |
|
|
*
|
9 |
|
|
* To read data in the Intel HEX format, you must perform the actual reading
|
10 |
|
|
* of bytes using other means (e.g., stdio). The bytes read must then be
|
11 |
|
|
* passed to `ihex_read_byte` and/or `ihex_read_bytes`. The reading functions
|
12 |
|
|
* will then call `ihex_data_read`, at which stage the `struct ihex_state`
|
13 |
|
|
* structure will contain the data along with its address. See below for
|
14 |
|
|
* details and example implementation of `ihex_data_read`.
|
15 |
|
|
*
|
16 |
|
|
* The sequence to read data in IHEX format is:
|
17 |
|
|
* struct ihex_state ihex;
|
18 |
|
|
* ihex_begin_read(&ihex);
|
19 |
|
|
* ihex_read_bytes(&ihex, my_input_bytes, length_of_my_input_bytes);
|
20 |
|
|
* ihex_end_read(&ihex);
|
21 |
|
|
*
|
22 |
|
|
*
|
23 |
|
|
* CONSERVING MEMORY
|
24 |
|
|
* -----------------
|
25 |
|
|
*
|
26 |
|
|
* For memory-critical use, you can save additional memory by defining
|
27 |
|
|
* `IHEX_LINE_MAX_LENGTH` as something less than 255. Note, however, that
|
28 |
|
|
* this limit affects both reading and writing, so the resulting library
|
29 |
|
|
* will be unable to read lines with more than this number of data bytes.
|
30 |
|
|
* That said, I haven't encountered any IHEX files with more than 32
|
31 |
|
|
* data bytes per line.
|
32 |
|
|
*
|
33 |
|
|
*
|
34 |
|
|
* Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com/
|
35 |
|
|
* Provided with absolutely no warranty, use at your own risk only.
|
36 |
|
|
* Use and distribute freely, mark modified copies as such.
|
37 |
|
|
*/
|
38 |
|
|
|
39 |
|
|
#ifndef KK_IHEX_READ_H
|
40 |
|
|
#define KK_IHEX_READ_H
|
41 |
|
|
#ifdef __cplusplus
|
42 |
|
|
extern "C" {
|
43 |
|
|
#endif
|
44 |
|
|
|
45 |
|
|
#include "kk_ihex.h"
|
46 |
|
|
|
47 |
|
|
// Begin reading at address 0
|
48 |
|
|
void ihex_begin_read(struct ihex_state *ihex);
|
49 |
|
|
|
50 |
|
|
// Begin reading at `address` (the lowest 16 bits of which will be ignored);
|
51 |
|
|
// this is required only if the high bytes of the 32-bit starting address
|
52 |
|
|
// are not specified in the input data and they are non-zero
|
53 |
|
|
void ihex_read_at_address(struct ihex_state *ihex,
|
54 |
|
|
ihex_address_t address);
|
55 |
|
|
|
56 |
|
|
// Read a single character
|
57 |
|
|
void ihex_read_byte(struct ihex_state *ihex, char chr);
|
58 |
|
|
|
59 |
|
|
// Read `count` bytes from `data`
|
60 |
|
|
void ihex_read_bytes(struct ihex_state * restrict ihex,
|
61 |
|
|
const char * restrict data,
|
62 |
|
|
ihex_count_t count);
|
63 |
|
|
|
64 |
|
|
// End reading (may call `ihex_data_read` if there is data waiting)
|
65 |
|
|
void ihex_end_read(struct ihex_state *ihex);
|
66 |
|
|
|
67 |
|
|
// Called when a complete line has been read, the record type of which is
|
68 |
|
|
// passed as `type`. The `ihex` structure will have its fields `data`,
|
69 |
|
|
// `line_length`, `address`, and `segment` set appropriately. In case
|
70 |
|
|
// of reading an `IHEX_EXTENDED_LINEAR_ADDRESS_RECORD` or an
|
71 |
|
|
// `IHEX_EXTENDED_SEGMENT_ADDRESS_RECORD` the record's data is not
|
72 |
|
|
// yet parsed - it will be parsed into the `address` or `segment` field
|
73 |
|
|
// only if `ihex_data_read` returns `true`. This allows manual handling
|
74 |
|
|
// of extended addresses by parsing the `ihex->data` bytes.
|
75 |
|
|
//
|
76 |
|
|
// Possible error cases include checksum mismatch (which is indicated
|
77 |
|
|
// as an argument), and excessive line length (in case this has been
|
78 |
|
|
// compiled with `IHEX_LINE_MAX_LENGTH` less than 255) which is indicated
|
79 |
|
|
// by `line_length` greater than `length`. Unknown record types and
|
80 |
|
|
// other erroneous data is usually silently ignored by this minimalistic
|
81 |
|
|
// parser. (It is recommended to compute a hash over the complete data
|
82 |
|
|
// once received and verify that against the source.)
|
83 |
|
|
//
|
84 |
|
|
// Example implementation:
|
85 |
|
|
//
|
86 |
|
|
// ihex_bool_t ihex_data_read(struct ihex_state *ihex,
|
87 |
|
|
// ihex_record_type_t type,
|
88 |
|
|
// ihex_bool_t error) {
|
89 |
|
|
// error = error || (ihex->length < ihex->line_length);
|
90 |
|
|
// if (type == IHEX_DATA_RECORD && !error) {
|
91 |
|
|
// (void) fseek(outfile, IHEX_LINEAR_ADDRESS(ihex), SEEK_SET);
|
92 |
|
|
// (void) fwrite(ihex->data, 1, ihex->length, outfile);
|
93 |
|
|
// } else if (type == IHEX_END_OF_FILE_RECORD) {
|
94 |
|
|
// (void) fclose(outfile);
|
95 |
|
|
// }
|
96 |
|
|
// return !error;
|
97 |
|
|
// }
|
98 |
|
|
//
|
99 |
|
|
extern ihex_bool_t ihex_data_read(struct ihex_state *ihex,
|
100 |
|
|
ihex_record_type_t type,
|
101 |
|
|
ihex_bool_t checksum_mismatch);
|
102 |
|
|
|
103 |
|
|
// Begin reading at `segment`; this is required only if the initial segment
|
104 |
|
|
// is not specified in the input data and it is non-zero.
|
105 |
|
|
//
|
106 |
|
|
#ifndef IHEX_DISABLE_SEGMENTS
|
107 |
|
|
void ihex_read_at_segment(struct ihex_state *ihex, ihex_segment_t segment);
|
108 |
|
|
#endif
|
109 |
|
|
|
110 |
|
|
#ifdef __cplusplus
|
111 |
|
|
}
|
112 |
|
|
#endif
|
113 |
|
|
#endif // !KK_IHEX_READ_H
|