OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_c/] [ihex2bin/] [ihex2bin.c] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 alirezamon
/*
2
 * ihex2bin.c: Read Intel HEX format, write binary data.
3
 *
4
 * By default reads from stdin and writes to stdout. The command-line
5
 * options `-i` and `-o` can be used to specify the input and output
6
 * file, respectively. Specifying an output file allows sparse writes.
7
 *
8
 * NOTE: Many Intel HEX files produced by compilers/etc have data
9
 * beginning at an address greater than zero, potentially causing very
10
 * unnecessarily large files to be created. The command-line option
11
 * `-a` can be used to specify the start address of the output file,
12
 * i.e., the value will be subtracted from the IHEX addresses (the
13
 * result must not be negative).
14
 *
15
 * Alternatively, the command-line option `-A` sets the address offset
16
 * to the first address that would be written (i.e., first byte of
17
 * data written will be at address 0).
18
 *
19
 * Copyright (c) 2013-2015 Kimmo Kulovesi, http://arkku.com
20
 * Provided with absolutely no warranty, use at your own risk only.
21
 * Distribute freely, mark modified copies as such.
22
 */
23
 
24
#include "kk_ihex_read.h"
25
#include <stdbool.h>
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <errno.h>
30
 
31
#define AUTODETECT_ADDRESS (~0UL)
32
 
33
static FILE *outfile;
34
static unsigned long line_number = 1L;
35
static unsigned long file_position = 0L;
36
static unsigned long address_offset = 0UL;
37
static bool debug_enabled = 0;
38
 
39
int
40
main (int argc, char *argv[]) {
41
    struct ihex_state ihex;
42
    FILE *infile = stdin;
43
    ihex_count_t count;
44
    char buf[256];
45
 
46
    outfile = stdout;
47
 
48
    while (--argc) {
49
        char *arg = *(++argv);
50
        if (arg[0] == '-' && arg[1] && arg[2] == '\0') {
51
            switch (arg[1]) {
52
            case 'a':
53
                if (--argc == 0) {
54
                    goto invalid_argument;
55
                }
56
                ++argv;
57
                errno = 0;
58
                address_offset = strtoul(*argv, &arg, 0);
59
                if (errno || arg == *argv) {
60
                    errno = errno ? errno : EINVAL;
61
                    goto argument_error;
62
                }
63
                break;
64
            case 'A':
65
                address_offset = AUTODETECT_ADDRESS;
66
                break;
67
            case 'i':
68
                if (--argc == 0) {
69
                    goto invalid_argument;
70
                }
71
                ++argv;
72
                if (!(infile = fopen(*argv, "r"))) {
73
                    goto argument_error;
74
                }
75
                break;
76
            case 'o':
77
                if (--argc == 0) {
78
                    goto invalid_argument;
79
                }
80
                ++argv;
81
                if (!(outfile = fopen(*argv, "wb"))) {
82
                    goto argument_error;
83
                }
84
                break;
85
            case 'v':
86
                debug_enabled = 1;
87
                break;
88
            case 'h':
89
            case '?':
90
                arg = NULL;
91
                goto usage;
92
            default:
93
                goto invalid_argument;
94
            }
95
            continue;
96
        }
97
invalid_argument:
98
        (void) fprintf(stderr, "Invalid argument: %s\n", arg);
99
usage:
100
        (void) fprintf(stderr, "kk_ihex " KK_IHEX_VERSION
101
                               " - Copyright (c) 2013-2015 Kimmo Kulovesi\n");
102
        (void) fprintf(stderr, "Usage: ihex2bin ([-a <address_offset>]|[-A])"
103
                                " [-o <out.bin>] [-i <in.hex>] [-v]\n");
104
        return arg ? EXIT_FAILURE : EXIT_SUCCESS;
105
argument_error:
106
        perror(*argv);
107
        return EXIT_FAILURE;
108
    }
109
 
110
    ihex_read_at_address(&ihex, (address_offset != AUTODETECT_ADDRESS) ?
111
                                (ihex_address_t) address_offset :
112
                                0);
113
    while (fgets(buf, sizeof(buf), infile)) {
114
        count = (ihex_count_t) strlen(buf);
115
        ihex_read_bytes(&ihex, buf, count);
116
        line_number += (count && buf[count - 1] == '\n');
117
    }
118
    ihex_end_read(&ihex);
119
 
120
    if (infile != stdin) {
121
        (void) fclose(infile);
122
    }
123
 
124
    return EXIT_SUCCESS;
125
}
126
 
127
ihex_bool_t
128
ihex_data_read (struct ihex_state *ihex,
129
                ihex_record_type_t type,
130
                ihex_bool_t error) {
131
    if (error) {
132
        (void) fprintf(stderr, "Checksum error on line %lu\n", line_number);
133
        exit(EXIT_FAILURE);
134
    }
135
    if ((error = (ihex->length < ihex->line_length))) {
136
        (void) fprintf(stderr, "Line length error on line %lu\n", line_number);
137
        exit(EXIT_FAILURE);
138
    }
139
    if (!outfile) {
140
        (void) fprintf(stderr, "Excess data after end of file record\n");
141
        exit(EXIT_FAILURE);
142
    }
143
    if (type == IHEX_DATA_RECORD) {
144
        unsigned long address = (unsigned long) IHEX_LINEAR_ADDRESS(ihex);
145
        if (address < address_offset) {
146
            if (address_offset == AUTODETECT_ADDRESS) {
147
                // autodetect initial address
148
                address_offset = address;
149
                if (debug_enabled) {
150
                    (void) fprintf(stderr, "Address offset: 0x%lx\n",
151
                            address_offset);
152
                }
153
            } else {
154
                (void) fprintf(stderr, "Address underflow on line %lu\n",
155
                        line_number);
156
                exit(EXIT_FAILURE);
157
            }
158
        }
159
        address -= address_offset;
160
        if (address != file_position) {
161
            if (debug_enabled) {
162
                (void) fprintf(stderr,
163
                        "Seeking from 0x%lx to 0x%lx on line %lu\n",
164
                        file_position, address, line_number);
165
            }
166
            if (outfile == stdout || fseek(outfile, (long) address, SEEK_SET)) {
167
                if (file_position < address) {
168
                    // "seek" forward in stdout by writing NUL bytes
169
                    do {
170
                        (void) fputc('\0', outfile);
171
                    } while (++file_position < address);
172
                } else {
173
                    perror("fseek");
174
                    exit(EXIT_FAILURE);
175
                }
176
            }
177
            file_position = address;
178
        }
179
        if (!fwrite(ihex->data, ihex->length, 1, outfile)) {
180
            perror("fwrite");
181
            exit(EXIT_FAILURE);
182
        }
183
        file_position += ihex->length;
184
    } else if (type == IHEX_END_OF_FILE_RECORD) {
185
        if (debug_enabled) {
186
            (void) fprintf(stderr, "%lu bytes written\n", file_position);
187
        }
188
        if (outfile != stdout) {
189
            (void) fclose(outfile);
190
        }
191
        outfile = NULL;
192
    }
193
    return true;
194
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.