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