OpenCores
URL https://opencores.org/ocsvn/tinyvliw8/tinyvliw8/trunk

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [tools/] [bin2hex/] [src/] [main.c] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 steckol
/**
2
 * \file   main.c
3
 * \author Oliver Stecklina <stecklina@ihp-microelectronics.com>
4
 * \date   25.07.2013
5
 *
6
 * \brief  Binary to hex copy program for the tinyVLIW8 processor.
7
 *
8
 * <p>
9
 *    Copyright (C) 2015 IHP GmbH, Frankfurt (Oder), Germany
10
 *
11
 * This code is free software. It is licensed under the EUPL, Version 1.1
12
 * or - as soon they will be approved by the European Commission - subsequent
13
 * versions of the EUPL (the "License").
14
 * You may redistribute this code and/or modify it under the terms of this
15
 * License.
16
 * You may not use this work except in compliance with the License.
17
 * You may obtain a copy of the License at:
18
 *
19
 * http://joinup.ec.europa.eu/software/page/eupl/licence-eupl
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" basis,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 * </p>
27
 */
28
 
29
#include <sys/types.h>
30
#include <sys/stat.h>
31
#include <fcntl.h>
32
#include <unistd.h>
33
#include <stdlib.h>
34
#include <stdio.h>
35
#include <string.h>
36
#include <errno.h>
37
 
38
typedef enum _mem_width_e {
39
        _mem_width_8bit = 0,
40
        _mem_width_16bit,
41
        _mem_width_32bit
42
} _mem_width_t;
43
 
44
static char         *_infile     = NULL;
45
static _mem_width_t  _mem_width  = _mem_width_32bit;
46
static unsigned int  _start_addr = 0x0000;
47
static char         *_outfile    = NULL;
48
static unsigned char _ascii      = 0;
49
 
50
static int _parse_args(int argc, char *argv[])
51
{
52
        int err, i;
53
 
54
        err = 0;
55
        for (i = 1; 0 == err && i < argc; i++) {
56
                if ('-' != *argv[i]) {
57
                        if ((i + 1) == argc) {
58
                                _infile = argv[i];
59
                                break;
60
                        }
61
 
62
                        fprintf(stderr, "\tERROR! bad option <%s>\n", argv[i]);
63
                        err = -EINVAL;
64
 
65
                        break;
66
                }
67
 
68
                switch (*(argv[i] + 1)) {
69
                case 'a':
70
                        _ascii = 1;
71
                        break;
72
                case 'o':
73
                        if ((i + 1) < argc) {
74
                                i++;
75
                                _outfile = argv[i];
76
 
77
                                break;
78
                        }
79
 
80
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
81
                                argv[i]);
82
                        err = -EINVAL;
83
 
84
                        break;
85
                case 's':
86
                        if ((i + 1) < argc) {
87
                                long num;
88
 
89
                                i++;
90
                                num = strtol(argv[i], NULL, 0);
91
                                if (0 <= num && 0x10000 > num) {
92
                                        _start_addr = num;
93
                                } else {
94
                                        fprintf(stderr, "\tERROR! bogus start address\n");
95
                                        err = -ERANGE;
96
                                }
97
 
98
                                break;
99
                        }
100
 
101
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
102
                                argv[i]);
103
                        err = -EINVAL;
104
 
105
                        break;
106
                case 'w':
107
                        if ((i + 1) < argc) {
108
                                long num;
109
 
110
                                i++;
111
                                num = strtol(argv[i], NULL, 0);
112
                                switch (num) {
113
                                case 8:
114
                                        _mem_width = _mem_width_8bit;
115
                                        break;
116
                                case 16:
117
                                        _mem_width = _mem_width_16bit;
118
                                        break;
119
                                case 32:
120
                                        _mem_width = _mem_width_32bit;
121
                                        break;
122
                                default:
123
                                        fprintf(stderr, "\tERROR! invalid memory width\n");
124
                                        err = -ERANGE;
125
                                }
126
 
127
                                break;
128
                        }
129
 
130
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
131
                                argv[i]);
132
                        err = -EINVAL;
133
 
134
                        break;
135
                case 'h':
136
                        printf("%s [option] <input>\n", argv[0]);
137
                        printf("\t-a           ascii input\n");
138
                        printf("\t-o <file>    output filename (default: stdout)\n");
139
                        printf("\t-s <num>     start address (default: 0x0000)\n");
140
                        printf("\t-w [8|16|32] memory width in bit (default: 32)\n");
141
                        printf("\t-h           useful help\n");
142
 
143
                        exit(0);
144
                }
145
        }
146
 
147
        if (0 == err && NULL == _infile) {
148
                fprintf(stderr, "\tERROR! no input file given\n");
149
                err = -EINVAL;
150
        }
151
 
152
        return err;
153
}
154
 
155
static unsigned char _mem_width2byte(const _mem_width_t mwidth)
156
{
157
        unsigned char width;
158
 
159
        switch (mwidth) {
160
        case _mem_width_8bit:
161
                width = 1;
162
                break;
163
        case _mem_width_16bit:
164
                width = 2;
165
                break;
166
        case _mem_width_32bit:
167
                width = 4;
168
                break;
169
        }
170
 
171
        return width;
172
}
173
 
174
static char *_asci2bin(char *img, unsigned int *size_ptr)
175
{
176
        unsigned int i, j, k;
177
        unsigned char c;
178
        char *p;
179
 
180
        for (i = 0, j = 0, k = 7, c = 0; i < *size_ptr; i++) {
181
                switch (*(img + i)) {
182
                case '0':
183
                        break;
184
                case '1':
185
                        c |= 1 << k;
186
                        break;
187
                default:
188
                        /* ignore */
189
                        continue;
190
                }
191
 
192
                if (0 == k) {
193
                        /* move char to buffer */
194
                        *(img + j) = c;
195
 
196
                        /* reset bit pos and char */
197
                        k = 7;
198
                        c = 0;
199
 
200
                        /* increment pos in output buffer */
201
                        j++;
202
                } else
203
                        k--;
204
        }
205
 
206
        if (7 != k) {
207
                fprintf(stderr, "\tWARNING! input is not byte aligned.\n");
208
 
209
                *(img + j) = c;
210
                j++;
211
        }
212
 
213
        p = NULL;
214
        *size_ptr = j;
215
 
216
        if (0 < j) {
217
                p = malloc(j);
218
                if (NULL != p)
219
                        memcpy(p, img, j);
220
        }
221
 
222
        free(img);
223
 
224
        return p;
225
}
226
 
227
static char *_load_image(const char *filename, unsigned int *size_ptr,
228
                         const unsigned char ascii, const _mem_width_t mwidth)
229
{
230
        char *img;
231
        int err;
232
 
233
        img = NULL;
234
        err = open(filename, O_RDONLY);
235
        if (0 <= err) {
236
                struct stat s;
237
                int fd;
238
 
239
                fd = err;
240
 
241
                err = fstat(fd, &s);
242
                if (0 == err) {
243
                        img = malloc(s.st_size);
244
                        if (NULL != img) {
245
                                unsigned int done;
246
 
247
                                done = 0;
248
                                do {
249
                                        err = read(fd, img + done, s.st_size - done);
250
                                        if (0 > err) {
251
                                                err = -errno;
252
                                                if (-EINTR == err) {
253
                                                        err = 0;
254
                                                        continue;
255
                                                }
256
 
257
                                                break;
258
                                        }
259
 
260
                                        done += err;
261
                                        err = 0;
262
                                } while (0 == err && done < s.st_size);
263
 
264
                                if (0 == err) {
265
                                        unsigned int size;
266
 
267
                                        size = s.st_size;
268
                                        if (0 != ascii) {
269
                                                img = _asci2bin(img, &size);
270
                                        }
271
 
272
                                        if (0 != (s.st_size & (_mem_width2byte(mwidth) - 1))) {
273
                                                fprintf(stderr, "\tWARNING! input size does not match with memory width\n");
274
                                        }
275
 
276
                                        *size_ptr = size;
277
                                } else {
278
                                        free(img);
279
                                        img = NULL;
280
                                }
281
                        } else
282
                                err = -ENOMEM;
283
                } else
284
                        err = -errno;
285
 
286
                close(fd);
287
        } else
288
                err = -errno;
289
 
290
        if (0 != err)
291
                fprintf(stderr, "\tERROR! loading input file <%s>", filename);
292
 
293
        return img;
294
}
295
 
296
#define _BUFSIZ ((16 << 1) + 4 + 2 + 2 + 2 + 1 + 1 + 1)
297
 
298
static int _ihex_out(const int fd, const unsigned short addr, const char *data,
299
                     const unsigned int len)
300
{
301
        unsigned int j, i;
302
        char buf[_BUFSIZ];
303
        int err;
304
 
305
        if (0 < len) {
306
                unsigned char chksum;
307
 
308
                chksum = 0;
309
 
310
                i = snprintf(&buf[0], _BUFSIZ, ":%02x%04x00", len, addr);
311
                if (_BUFSIZ < i)
312
                        return -ENOSPC;
313
 
314
                for (j = 0; j < len; j++) {
315
                        i += snprintf(&buf[i], _BUFSIZ - i, "%02x", (unsigned char) *(data + j));
316
                        if (_BUFSIZ < i)
317
                                return -ENOSPC;
318
 
319
                        chksum += *(data + j);
320
                }
321
 
322
                chksum += len;
323
                chksum += addr & 0x00ff;
324
                chksum += addr >> 8;
325
 
326
                chksum = (chksum ^ 0xff) + 0x01;
327
                i += snprintf(&buf[i], _BUFSIZ - i, "%02x\n", chksum);
328
                if (_BUFSIZ < i)
329
                        return -ENOSPC;
330
        } else
331
                i = snprintf(&buf[0], _BUFSIZ, ":00000001ff\n");
332
 
333
        j = 0;
334
        do {
335
                err = write(fd, &buf[j], i - j);
336
                if (0 > err) {
337
                        err = -errno;
338
                        if (-EINTR == err) {
339
                                err = 0;
340
                                continue;
341
                        }
342
 
343
                        break;
344
                }
345
 
346
                j += err;
347
                err = 0;
348
        } while (0 == err && j < i);
349
 
350
        return err;
351
}
352
 
353
static int _out_image(const char *image, const unsigned int size,
354
                      const _mem_width_t mwidth, const char *outfile)
355
{
356
        int err;
357
 
358
        if (NULL != outfile) {
359
                err = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
360
                if (0 > err)
361
                        err = -errno;
362
        } else
363
                err = fileno(stdout);
364
 
365
        if (0 <= err) {
366
                const unsigned int offset = _mem_width2byte(mwidth);
367
 
368
                unsigned short addr;
369
                unsigned int i;
370
                int fd;
371
 
372
                fd = err;
373
 
374
                addr = _start_addr;
375
                i = 0;
376
                do {
377
                        char buf[4];
378
 
379
                        memset(&buf[0], 0x00, offset);
380
                        memcpy(&buf[0], &image[i],
381
                               ((size - i) < offset) ? (size - i) : offset);
382
 
383
                        err = _ihex_out(fd, addr, &image[i], offset);
384
 
385
                        i += offset;
386
                        addr += 1;
387
                } while (0 == err && i < size);
388
 
389
                /* finish line */
390
                if (0 == err)
391
                        err = _ihex_out(fd, 0x00, NULL, 0);
392
 
393
                if (fd != fileno(stderr))
394
                        close(fd);
395
        }
396
 
397
        if (0 != err)
398
                fprintf(stderr, "\tERROR! dump image failed\n");
399
 
400
        return err;
401
}
402
 
403
int main(int argc, char *argv[])
404
{
405
        int err;
406
 
407
        err = _parse_args(argc, argv);
408
        if (0 == err) {
409
                unsigned int size;
410
                char *img;
411
 
412
                img = _load_image(_infile, &size, _ascii, _mem_width);
413
                if (img) {
414
                        err = _out_image(img, size, _mem_width, _outfile);
415
 
416
                        free(img);
417
                } else
418
                        err = -EIO;
419
        }
420
 
421
        return err;
422
}
423
 

powered by: WebSVN 2.1.0

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