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

Subversion Repositories tinyvliw8

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

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

Line No. Rev Author Line
1 5 steckol
/**
2
 
3
 * \file   main.c
4
 
5
 * \date   25.07.2013
6
 
7
 * \author Oliver Stecklina <stecklina@ihp-microelectronics.com>
8
 
9
 */
10
 
11
 
12
 
13
#include <sys/types.h>
14
 
15
#include <sys/stat.h>
16
 
17
#include <fcntl.h>
18
 
19
#include <unistd.h>
20
 
21
#include <stdlib.h>
22
 
23
#include <stdio.h>
24
 
25
#include <string.h>
26
 
27
#include <errno.h>
28
 
29
 
30
 
31
typedef enum _mem_width_e {
32
 
33
        _mem_width_8bit = 0,
34
 
35
        _mem_width_16bit,
36
 
37
        _mem_width_32bit
38
 
39
} _mem_width_t;
40
 
41
 
42
 
43
static char         *_infile     = NULL;
44
 
45
static _mem_width_t  _mem_width  = _mem_width_32bit;
46
 
47
static unsigned int  _start_addr = 0x0000;
48
 
49
static char         *_outfile    = NULL;
50
 
51
static unsigned char _ascii      = 0;
52
 
53
 
54
 
55
static int _parse_args(int argc, char *argv[])
56
 
57
{
58
 
59
        int err, i;
60
 
61
 
62
 
63
        err = 0;
64
 
65
        for (i = 1; 0 == err && i < argc; i++) {
66
 
67
                if ('-' != *argv[i]) {
68
 
69
                        if ((i + 1) == argc) {
70
 
71
                                _infile = argv[i];
72
 
73
                                break;
74
 
75
                        }
76
 
77
 
78
 
79
                        fprintf(stderr, "\tERROR! bad option <%s>\n", argv[i]);
80
 
81
                        err = -EINVAL;
82
 
83
 
84
 
85
                        break;
86
 
87
                }
88
 
89
 
90
 
91
                switch (*(argv[i] + 1)) {
92
 
93
                case 'a':
94
 
95
                        _ascii = 1;
96
 
97
                        break;
98
 
99
                case 'o':
100
 
101
                        if ((i + 1) < argc) {
102
 
103
                                i++;
104
 
105
                                _outfile = argv[i];
106
 
107
 
108
 
109
                                break;
110
 
111
                        }
112
 
113
 
114
 
115
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
116
 
117
                                argv[i]);
118
 
119
                        err = -EINVAL;
120
 
121
 
122
 
123
                        break;
124
 
125
                case 's':
126
 
127
                        if ((i + 1) < argc) {
128
 
129
                                long num;
130
 
131
 
132
 
133
                                i++;
134
 
135
                                num = strtol(argv[i], NULL, 0);
136
 
137
                                if (0 <= num && 0x10000 > num) {
138
 
139
                                        _start_addr = num;
140
 
141
                                } else {
142
 
143
                                        fprintf(stderr, "\tERROR! bogus start address\n");
144
 
145
                                        err = -ERANGE;
146
 
147
                                }
148
 
149
 
150
 
151
                                break;
152
 
153
                        }
154
 
155
 
156
 
157
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
158
 
159
                                argv[i]);
160
 
161
                        err = -EINVAL;
162
 
163
 
164
 
165
                        break;
166
 
167
                case 'w':
168
 
169
                        if ((i + 1) < argc) {
170
 
171
                                long num;
172
 
173
 
174
 
175
                                i++;
176
 
177
                                num = strtol(argv[i], NULL, 0);
178
 
179
                                switch (num) {
180
 
181
                                case 8:
182
 
183
                                        _mem_width = _mem_width_8bit;
184
 
185
                                        break;
186
 
187
                                case 16:
188
 
189
                                        _mem_width = _mem_width_16bit;
190
 
191
                                        break;
192
 
193
                                case 32:
194
 
195
                                        _mem_width = _mem_width_32bit;
196
 
197
                                        break;
198
 
199
                                default:
200
 
201
                                        fprintf(stderr, "\tERROR! invalid memory width\n");
202
 
203
                                        err = -ERANGE;
204
 
205
                                }
206
 
207
 
208
 
209
                                break;
210
 
211
                        }
212
 
213
 
214
 
215
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
216
 
217
                                argv[i]);
218
 
219
                        err = -EINVAL;
220
 
221
 
222
 
223
                        break;
224
 
225
                case 'h':
226
 
227
                        printf("%s [option] <input>\n", argv[0]);
228
 
229
                        printf("\t-a           ascii input\n");
230
 
231
                        printf("\t-o <file>    output filename (default: stdout)\n");
232
 
233
                        printf("\t-s <num>     start address (default: 0x0000)\n");
234
 
235
                        printf("\t-w [8|16|32] memory width in bit (default: 32)\n");
236
 
237
                        printf("\t-h           useful help\n");
238
 
239
 
240
 
241
                        exit(0);
242
 
243
                }
244
 
245
        }
246
 
247
 
248
 
249
        if (0 == err && NULL == _infile) {
250
 
251
                fprintf(stderr, "\tERROR! no input file given\n");
252
 
253
                err = -EINVAL;
254
 
255
        }
256
 
257
 
258
 
259
        return err;
260
 
261
}
262
 
263
 
264
 
265
static unsigned char _mem_width2byte(const _mem_width_t mwidth)
266
 
267
{
268
 
269
        unsigned char width;
270
 
271
 
272
 
273
        switch (mwidth) {
274
 
275
        case _mem_width_8bit:
276
 
277
                width = 1;
278
 
279
                break;
280
 
281
        case _mem_width_16bit:
282
 
283
                width = 2;
284
 
285
                break;
286
 
287
        case _mem_width_32bit:
288
 
289
                width = 4;
290
 
291
                break;
292
 
293
        }
294
 
295
 
296
 
297
        return width;
298
 
299
}
300
 
301
 
302
 
303
static char *_asci2bin(char *img, unsigned int *size_ptr)
304
 
305
{
306
 
307
        unsigned int i, j, k;
308
 
309
        unsigned char c;
310
 
311
        char *p;
312
 
313
 
314
 
315
        for (i = 0, j = 0, k = 7, c = 0; i < *size_ptr; i++) {
316
 
317
                switch (*(img + i)) {
318
 
319
                case '0':
320
 
321
                        break;
322
 
323
                case '1':
324
 
325
                        c |= 1 << k;
326
 
327
                        break;
328
 
329
                default:
330
 
331
                        /* ignore */
332
 
333
                        continue;
334
 
335
                }
336
 
337
 
338
 
339
                if (0 == k) {
340
 
341
                        /* move char to buffer */
342
 
343
                        *(img + j) = c;
344
 
345
 
346
 
347
                        /* reset bit pos and char */
348
 
349
                        k = 7;
350
 
351
                        c = 0;
352
 
353
 
354
 
355
                        /* increment pos in output buffer */
356
 
357
                        j++;
358
 
359
                } else
360
 
361
                        k--;
362
 
363
        }
364
 
365
 
366
 
367
        if (7 != k) {
368
 
369
                fprintf(stderr, "\tWARNING! input is not byte aligned.\n");
370
 
371
 
372
 
373
                *(img + j) = c;
374
 
375
                j++;
376
 
377
        }
378
 
379
 
380
 
381
        p = NULL;
382
 
383
        *size_ptr = j;
384
 
385
 
386
 
387
        if (0 < j) {
388
 
389
                p = malloc(j);
390
 
391
                if (NULL != p)
392
 
393
                        memcpy(p, img, j);
394
 
395
        }
396
 
397
 
398
 
399
        free(img);
400
 
401
 
402
 
403
        return p;
404
 
405
}
406
 
407
 
408
 
409
static char *_load_image(const char *filename, unsigned int *size_ptr,
410
 
411
                         const unsigned char ascii, const _mem_width_t mwidth)
412
 
413
{
414
 
415
        char *img;
416
 
417
        int err;
418
 
419
 
420
 
421
        img = NULL;
422
 
423
        err = open(filename, O_RDONLY);
424
 
425
        if (0 <= err) {
426
 
427
                struct stat s;
428
 
429
                int fd;
430
 
431
 
432
 
433
                fd = err;
434
 
435
 
436
 
437
                err = fstat(fd, &s);
438
 
439
                if (0 == err) {
440
 
441
                        img = malloc(s.st_size);
442
 
443
                        if (NULL != img) {
444
 
445
                                unsigned int done;
446
 
447
 
448
 
449
                                done = 0;
450
 
451
                                do {
452
 
453
                                        err = read(fd, img + done, s.st_size - done);
454
 
455
                                        if (0 > err) {
456
 
457
                                                err = -errno;
458
 
459
                                                if (-EINTR == err) {
460
 
461
                                                        err = 0;
462
 
463
                                                        continue;
464
 
465
                                                }
466
 
467
 
468
 
469
                                                break;
470
 
471
                                        }
472
 
473
 
474
 
475
                                        done += err;
476
 
477
                                        err = 0;
478
 
479
                                } while (0 == err && done < s.st_size);
480
 
481
 
482
 
483
                                if (0 == err) {
484
 
485
                                        unsigned int size;
486
 
487
 
488
 
489
                                        size = s.st_size;
490
 
491
                                        if (0 != ascii) {
492
 
493
                                                img = _asci2bin(img, &size);
494
 
495
                                        }
496
 
497
 
498
 
499
                                        if (0 != (s.st_size & (_mem_width2byte(mwidth) - 1))) {
500
 
501
                                                fprintf(stderr, "\tWARNING! input size does not match with memory width\n");
502
 
503
                                        }
504
 
505
 
506
 
507
                                        *size_ptr = size;
508
 
509
                                } else {
510
 
511
                                        free(img);
512
 
513
                                        img = NULL;
514
 
515
                                }
516
 
517
                        } else
518
 
519
                                err = -ENOMEM;
520
 
521
                } else
522
 
523
                        err = -errno;
524
 
525
 
526
 
527
                close(fd);
528
 
529
        } else
530
 
531
                err = -errno;
532
 
533
 
534
 
535
        if (0 != err)
536
 
537
                fprintf(stderr, "\tERROR! loading input file <%s>", filename);
538
 
539
 
540
 
541
        return img;
542
 
543
}
544
 
545
 
546
 
547
#define _BUFSIZ ((16 << 1) + 4 + 2 + 2 + 2 + 1 + 1 + 1)
548
 
549
 
550
 
551
static int _ihex_out(const int fd, const unsigned short addr, const char *data,
552
 
553
                     const unsigned int len)
554
 
555
{
556
 
557
        unsigned int j, i;
558
 
559
        char buf[_BUFSIZ];
560
 
561
        int err;
562
 
563
 
564
 
565
        if (0 < len) {
566
 
567
                unsigned char chksum;
568
 
569
 
570
 
571
                chksum = 0;
572
 
573
 
574
 
575
                i = snprintf(&buf[0], _BUFSIZ, ":%02x%04x00", len, addr);
576
 
577
                if (_BUFSIZ < i)
578
 
579
                        return -ENOSPC;
580
 
581
 
582
 
583
                for (j = 0; j < len; j++) {
584
 
585
                        i += snprintf(&buf[i], _BUFSIZ - i, "%02x", (unsigned char) *(data + j));
586
 
587
                        if (_BUFSIZ < i)
588
 
589
                                return -ENOSPC;
590
 
591
 
592
 
593
                        chksum += *(data + j);
594
 
595
                }
596
 
597
 
598
 
599
                chksum += len;
600
 
601
                chksum += addr & 0x00ff;
602
 
603
                chksum += addr >> 8;
604
 
605
 
606
 
607
                chksum = (chksum ^ 0xff) + 0x01;
608
 
609
                i += snprintf(&buf[i], _BUFSIZ - i, "%02x\n", chksum);
610
 
611
                if (_BUFSIZ < i)
612
 
613
                        return -ENOSPC;
614
 
615
        } else
616
 
617
                i = snprintf(&buf[0], _BUFSIZ, ":00000001ff\n");
618
 
619
 
620
 
621
        j = 0;
622
 
623
        do {
624
 
625
                err = write(fd, &buf[j], i - j);
626
 
627
                if (0 > err) {
628
 
629
                        err = -errno;
630
 
631
                        if (-EINTR == err) {
632
 
633
                                err = 0;
634
 
635
                                continue;
636
 
637
                        }
638
 
639
 
640
 
641
                        break;
642
 
643
                }
644
 
645
 
646
 
647
                j += err;
648
 
649
                err = 0;
650
 
651
        } while (0 == err && j < i);
652
 
653
 
654
 
655
        return err;
656
 
657
}
658
 
659
 
660
 
661
static int _out_image(const char *image, const unsigned int size,
662
 
663
                      const _mem_width_t mwidth, const char *outfile)
664
 
665
{
666
 
667
        int err;
668
 
669
 
670
 
671
        if (NULL != outfile) {
672
 
673
                err = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
674
 
675
                if (0 > err)
676
 
677
                        err = -errno;
678
 
679
        } else
680
 
681
                err = fileno(stdout);
682
 
683
 
684
 
685
        if (0 <= err) {
686
 
687
                const unsigned int offset = _mem_width2byte(mwidth);
688
 
689
 
690
 
691
                unsigned short addr;
692
 
693
                unsigned int i;
694
 
695
                int fd;
696
 
697
 
698
 
699
                fd = err;
700
 
701
 
702
 
703
                addr = _start_addr;
704
 
705
                i = 0;
706
 
707
                do {
708
 
709
                        char buf[4];
710
 
711
 
712
 
713
                        memset(&buf[0], 0x00, offset);
714
 
715
                        memcpy(&buf[0], &image[i],
716
 
717
                               ((size - i) < offset) ? (size - i) : offset);
718
 
719
 
720
 
721
                        err = _ihex_out(fd, addr, &image[i], offset);
722
 
723
 
724
 
725
                        i += offset;
726
 
727
                        addr += 1;
728
 
729
                } while (0 == err && i < size);
730
 
731
 
732
 
733
                /* finish line */
734
 
735
                if (0 == err)
736
 
737
                        err = _ihex_out(fd, 0x00, NULL, 0);
738
 
739
 
740
 
741
                if (fd != fileno(stderr))
742
 
743
                        close(fd);
744
 
745
        }
746
 
747
 
748
 
749
        if (0 != err)
750
 
751
                fprintf(stderr, "\tERROR! dump image failed\n");
752
 
753
 
754
 
755
        return err;
756
 
757
}
758
 
759
 
760
 
761
int main(int argc, char *argv[])
762
 
763
{
764
 
765
        int err;
766
 
767
 
768
 
769
        err = _parse_args(argc, argv);
770
 
771
        if (0 == err) {
772
 
773
                unsigned int size;
774
 
775
                char *img;
776
 
777
 
778
 
779
                img = _load_image(_infile, &size, _ascii, _mem_width);
780
 
781
                if (img) {
782
 
783
                        err = _out_image(img, size, _mem_width, _outfile);
784
 
785
 
786
 
787
                        free(img);
788
 
789
                } else
790
 
791
                        err = -EIO;
792
 
793
        }
794
 
795
 
796
 
797
        return err;
798
 
799
}
800
 
801
 
802
 

powered by: WebSVN 2.1.0

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