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

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [tools/] [bin2hex/] [src/] [main.c] - Diff between revs 5 and 7

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 5 Rev 7
Line 1... Line 1...
/**
/**
 
 
 * \file   main.c
 * \file   main.c
 
 
 * \date   25.07.2013
 
 
 
 * \author Oliver Stecklina <stecklina@ihp-microelectronics.com>
 * \author Oliver Stecklina <stecklina@ihp-microelectronics.com>
 
 * \date   25.07.2013
 
 *
 
 * \brief  Binary to hex copy program for the tinyVLIW8 processor.
 
 *
 
 * <p>
 
 *    Copyright (C) 2015 IHP GmbH, Frankfurt (Oder), Germany
 
 *
 
 * This code is free software. It is licensed under the EUPL, Version 1.1
 
 * or - as soon they will be approved by the European Commission - subsequent
 
 * versions of the EUPL (the "License").
 
 * You may redistribute this code and/or modify it under the terms of this
 
 * License.
 
 * You may not use this work except in compliance with the License.
 
 * You may obtain a copy of the License at:
 
 *
 
 * http://joinup.ec.europa.eu/software/page/eupl/licence-eupl
 
 *
 
 * Unless required by applicable law or agreed to in writing, software
 
 * distributed under the License is distributed on an "AS IS" basis,
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 * See the License for the specific language governing permissions and
 
 * limitations under the License.
 
 * </p>
 */
 */
 
 
 
 
 
 
#include <sys/types.h>
#include <sys/types.h>
 
 
#include <sys/stat.h>
#include <sys/stat.h>
 
 
#include <fcntl.h>
#include <fcntl.h>
 
 
#include <unistd.h>
#include <unistd.h>
 
 
#include <stdlib.h>
#include <stdlib.h>
 
 
#include <stdio.h>
#include <stdio.h>
 
 
#include <string.h>
#include <string.h>
 
 
#include <errno.h>
#include <errno.h>
 
 
 
 
 
 
typedef enum _mem_width_e {
typedef enum _mem_width_e {
 
 
        _mem_width_8bit = 0,
        _mem_width_8bit = 0,
 
 
        _mem_width_16bit,
        _mem_width_16bit,
 
 
        _mem_width_32bit
        _mem_width_32bit
 
 
} _mem_width_t;
} _mem_width_t;
 
 
 
 
 
 
static char         *_infile     = NULL;
static char         *_infile     = NULL;
 
 
static _mem_width_t  _mem_width  = _mem_width_32bit;
static _mem_width_t  _mem_width  = _mem_width_32bit;
 
 
static unsigned int  _start_addr = 0x0000;
static unsigned int  _start_addr = 0x0000;
 
 
static char         *_outfile    = NULL;
static char         *_outfile    = NULL;
 
 
static unsigned char _ascii      = 0;
static unsigned char _ascii      = 0;
 
 
 
 
 
 
static int _parse_args(int argc, char *argv[])
static int _parse_args(int argc, char *argv[])
 
 
{
{
 
 
        int err, i;
        int err, i;
 
 
 
 
 
 
        err = 0;
        err = 0;
 
 
        for (i = 1; 0 == err && i < argc; i++) {
        for (i = 1; 0 == err && i < argc; i++) {
 
 
                if ('-' != *argv[i]) {
                if ('-' != *argv[i]) {
 
 
                        if ((i + 1) == argc) {
                        if ((i + 1) == argc) {
 
 
                                _infile = argv[i];
                                _infile = argv[i];
 
 
                                break;
                                break;
 
 
                        }
                        }
 
 
 
 
 
 
                        fprintf(stderr, "\tERROR! bad option <%s>\n", argv[i]);
                        fprintf(stderr, "\tERROR! bad option <%s>\n", argv[i]);
 
 
                        err = -EINVAL;
                        err = -EINVAL;
 
 
 
 
 
 
                        break;
                        break;
 
 
                }
                }
 
 
 
 
 
 
                switch (*(argv[i] + 1)) {
                switch (*(argv[i] + 1)) {
 
 
                case 'a':
                case 'a':
 
 
                        _ascii = 1;
                        _ascii = 1;
 
 
                        break;
                        break;
 
 
                case 'o':
                case 'o':
 
 
                        if ((i + 1) < argc) {
                        if ((i + 1) < argc) {
 
 
                                i++;
                                i++;
 
 
                                _outfile = argv[i];
                                _outfile = argv[i];
 
 
 
 
 
 
                                break;
                                break;
 
 
                        }
                        }
 
 
 
 
 
 
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
 
 
                                argv[i]);
                                argv[i]);
 
 
                        err = -EINVAL;
                        err = -EINVAL;
 
 
 
 
 
 
                        break;
                        break;
 
 
                case 's':
                case 's':
 
 
                        if ((i + 1) < argc) {
                        if ((i + 1) < argc) {
 
 
                                long num;
                                long num;
 
 
 
 
 
 
                                i++;
                                i++;
 
 
                                num = strtol(argv[i], NULL, 0);
                                num = strtol(argv[i], NULL, 0);
 
 
                                if (0 <= num && 0x10000 > num) {
                                if (0 <= num && 0x10000 > num) {
 
 
                                        _start_addr = num;
                                        _start_addr = num;
 
 
                                } else {
                                } else {
 
 
                                        fprintf(stderr, "\tERROR! bogus start address\n");
                                        fprintf(stderr, "\tERROR! bogus start address\n");
 
 
                                        err = -ERANGE;
                                        err = -ERANGE;
 
 
                                }
                                }
 
 
 
 
 
 
                                break;
                                break;
 
 
                        }
                        }
 
 
 
 
 
 
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
 
 
                                argv[i]);
                                argv[i]);
 
 
                        err = -EINVAL;
                        err = -EINVAL;
 
 
 
 
 
 
                        break;
                        break;
 
 
                case 'w':
                case 'w':
 
 
                        if ((i + 1) < argc) {
                        if ((i + 1) < argc) {
 
 
                                long num;
                                long num;
 
 
 
 
 
 
                                i++;
                                i++;
 
 
                                num = strtol(argv[i], NULL, 0);
                                num = strtol(argv[i], NULL, 0);
 
 
                                switch (num) {
                                switch (num) {
 
 
                                case 8:
                                case 8:
 
 
                                        _mem_width = _mem_width_8bit;
                                        _mem_width = _mem_width_8bit;
 
 
                                        break;
                                        break;
 
 
                                case 16:
                                case 16:
 
 
                                        _mem_width = _mem_width_16bit;
                                        _mem_width = _mem_width_16bit;
 
 
                                        break;
                                        break;
 
 
                                case 32:
                                case 32:
 
 
                                        _mem_width = _mem_width_32bit;
                                        _mem_width = _mem_width_32bit;
 
 
                                        break;
                                        break;
 
 
                                default:
                                default:
 
 
                                        fprintf(stderr, "\tERROR! invalid memory width\n");
                                        fprintf(stderr, "\tERROR! invalid memory width\n");
 
 
                                        err = -ERANGE;
                                        err = -ERANGE;
 
 
                                }
                                }
 
 
 
 
 
 
                                break;
                                break;
 
 
                        }
                        }
 
 
 
 
 
 
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
                        fprintf(stderr, "\tERROR! option <%s> requires an argument\n",
 
 
                                argv[i]);
                                argv[i]);
 
 
                        err = -EINVAL;
                        err = -EINVAL;
 
 
 
 
 
 
                        break;
                        break;
 
 
                case 'h':
                case 'h':
 
 
                        printf("%s [option] <input>\n", argv[0]);
                        printf("%s [option] <input>\n", argv[0]);
 
 
                        printf("\t-a           ascii input\n");
                        printf("\t-a           ascii input\n");
 
 
                        printf("\t-o <file>    output filename (default: stdout)\n");
                        printf("\t-o <file>    output filename (default: stdout)\n");
 
 
                        printf("\t-s <num>     start address (default: 0x0000)\n");
                        printf("\t-s <num>     start address (default: 0x0000)\n");
 
 
                        printf("\t-w [8|16|32] memory width in bit (default: 32)\n");
                        printf("\t-w [8|16|32] memory width in bit (default: 32)\n");
 
 
                        printf("\t-h           useful help\n");
                        printf("\t-h           useful help\n");
 
 
 
 
 
 
                        exit(0);
                        exit(0);
 
 
                }
                }
 
 
        }
        }
 
 
 
 
 
 
        if (0 == err && NULL == _infile) {
        if (0 == err && NULL == _infile) {
 
 
                fprintf(stderr, "\tERROR! no input file given\n");
                fprintf(stderr, "\tERROR! no input file given\n");
 
 
                err = -EINVAL;
                err = -EINVAL;
 
 
        }
        }
 
 
 
 
 
 
        return err;
        return err;
 
 
}
}
 
 
 
 
 
 
static unsigned char _mem_width2byte(const _mem_width_t mwidth)
static unsigned char _mem_width2byte(const _mem_width_t mwidth)
 
 
{
{
 
 
        unsigned char width;
        unsigned char width;
 
 
 
 
 
 
        switch (mwidth) {
        switch (mwidth) {
 
 
        case _mem_width_8bit:
        case _mem_width_8bit:
 
 
                width = 1;
                width = 1;
 
 
                break;
                break;
 
 
        case _mem_width_16bit:
        case _mem_width_16bit:
 
 
                width = 2;
                width = 2;
 
 
                break;
                break;
 
 
        case _mem_width_32bit:
        case _mem_width_32bit:
 
 
                width = 4;
                width = 4;
 
 
                break;
                break;
 
 
        }
        }
 
 
 
 
 
 
        return width;
        return width;
 
 
}
}
 
 
 
 
 
 
static char *_asci2bin(char *img, unsigned int *size_ptr)
static char *_asci2bin(char *img, unsigned int *size_ptr)
 
 
{
{
 
 
        unsigned int i, j, k;
        unsigned int i, j, k;
 
 
        unsigned char c;
        unsigned char c;
 
 
        char *p;
        char *p;
 
 
 
 
 
 
        for (i = 0, j = 0, k = 7, c = 0; i < *size_ptr; i++) {
        for (i = 0, j = 0, k = 7, c = 0; i < *size_ptr; i++) {
 
 
                switch (*(img + i)) {
                switch (*(img + i)) {
 
 
                case '0':
                case '0':
 
 
                        break;
                        break;
 
 
                case '1':
                case '1':
 
 
                        c |= 1 << k;
                        c |= 1 << k;
 
 
                        break;
                        break;
 
 
                default:
                default:
 
 
                        /* ignore */
                        /* ignore */
 
 
                        continue;
                        continue;
 
 
                }
                }
 
 
 
 
 
 
                if (0 == k) {
                if (0 == k) {
 
 
                        /* move char to buffer */
                        /* move char to buffer */
 
 
                        *(img + j) = c;
                        *(img + j) = c;
 
 
 
 
 
 
                        /* reset bit pos and char */
                        /* reset bit pos and char */
 
 
                        k = 7;
                        k = 7;
 
 
                        c = 0;
                        c = 0;
 
 
 
 
 
 
                        /* increment pos in output buffer */
                        /* increment pos in output buffer */
 
 
                        j++;
                        j++;
 
 
                } else
                } else
 
 
                        k--;
                        k--;
 
 
        }
        }
 
 
 
 
 
 
        if (7 != k) {
        if (7 != k) {
 
 
                fprintf(stderr, "\tWARNING! input is not byte aligned.\n");
                fprintf(stderr, "\tWARNING! input is not byte aligned.\n");
 
 
 
 
 
 
                *(img + j) = c;
                *(img + j) = c;
 
 
                j++;
                j++;
 
 
        }
        }
 
 
 
 
 
 
        p = NULL;
        p = NULL;
 
 
        *size_ptr = j;
        *size_ptr = j;
 
 
 
 
 
 
        if (0 < j) {
        if (0 < j) {
 
 
                p = malloc(j);
                p = malloc(j);
 
 
                if (NULL != p)
                if (NULL != p)
 
 
                        memcpy(p, img, j);
                        memcpy(p, img, j);
 
 
        }
        }
 
 
 
 
 
 
        free(img);
        free(img);
 
 
 
 
 
 
        return p;
        return p;
 
 
}
}
 
 
 
 
 
 
static char *_load_image(const char *filename, unsigned int *size_ptr,
static char *_load_image(const char *filename, unsigned int *size_ptr,
 
 
                         const unsigned char ascii, const _mem_width_t mwidth)
                         const unsigned char ascii, const _mem_width_t mwidth)
 
 
{
{
 
 
        char *img;
        char *img;
 
 
        int err;
        int err;
 
 
 
 
 
 
        img = NULL;
        img = NULL;
 
 
        err = open(filename, O_RDONLY);
        err = open(filename, O_RDONLY);
 
 
        if (0 <= err) {
        if (0 <= err) {
 
 
                struct stat s;
                struct stat s;
 
 
                int fd;
                int fd;
 
 
 
 
 
 
                fd = err;
                fd = err;
 
 
 
 
 
 
                err = fstat(fd, &s);
                err = fstat(fd, &s);
 
 
                if (0 == err) {
                if (0 == err) {
 
 
                        img = malloc(s.st_size);
                        img = malloc(s.st_size);
 
 
                        if (NULL != img) {
                        if (NULL != img) {
 
 
                                unsigned int done;
                                unsigned int done;
 
 
 
 
 
 
                                done = 0;
                                done = 0;
 
 
                                do {
                                do {
 
 
                                        err = read(fd, img + done, s.st_size - done);
                                        err = read(fd, img + done, s.st_size - done);
 
 
                                        if (0 > err) {
                                        if (0 > err) {
 
 
                                                err = -errno;
                                                err = -errno;
 
 
                                                if (-EINTR == err) {
                                                if (-EINTR == err) {
 
 
                                                        err = 0;
                                                        err = 0;
 
 
                                                        continue;
                                                        continue;
 
 
                                                }
                                                }
 
 
 
 
 
 
                                                break;
                                                break;
 
 
                                        }
                                        }
 
 
 
 
 
 
                                        done += err;
                                        done += err;
 
 
                                        err = 0;
                                        err = 0;
 
 
                                } while (0 == err && done < s.st_size);
                                } while (0 == err && done < s.st_size);
 
 
 
 
 
 
                                if (0 == err) {
                                if (0 == err) {
 
 
                                        unsigned int size;
                                        unsigned int size;
 
 
 
 
 
 
                                        size = s.st_size;
                                        size = s.st_size;
 
 
                                        if (0 != ascii) {
                                        if (0 != ascii) {
 
 
                                                img = _asci2bin(img, &size);
                                                img = _asci2bin(img, &size);
 
 
                                        }
                                        }
 
 
 
 
 
 
                                        if (0 != (s.st_size & (_mem_width2byte(mwidth) - 1))) {
                                        if (0 != (s.st_size & (_mem_width2byte(mwidth) - 1))) {
 
 
                                                fprintf(stderr, "\tWARNING! input size does not match with memory width\n");
                                                fprintf(stderr, "\tWARNING! input size does not match with memory width\n");
 
 
                                        }
                                        }
 
 
 
 
 
 
                                        *size_ptr = size;
                                        *size_ptr = size;
 
 
                                } else {
                                } else {
 
 
                                        free(img);
                                        free(img);
 
 
                                        img = NULL;
                                        img = NULL;
 
 
                                }
                                }
 
 
                        } else
                        } else
 
 
                                err = -ENOMEM;
                                err = -ENOMEM;
 
 
                } else
                } else
 
 
                        err = -errno;
                        err = -errno;
 
 
 
 
 
 
                close(fd);
                close(fd);
 
 
        } else
        } else
 
 
                err = -errno;
                err = -errno;
 
 
 
 
 
 
        if (0 != err)
        if (0 != err)
 
 
                fprintf(stderr, "\tERROR! loading input file <%s>", filename);
                fprintf(stderr, "\tERROR! loading input file <%s>", filename);
 
 
 
 
 
 
        return img;
        return img;
 
 
}
}
 
 
 
 
 
 
#define _BUFSIZ ((16 << 1) + 4 + 2 + 2 + 2 + 1 + 1 + 1)
#define _BUFSIZ ((16 << 1) + 4 + 2 + 2 + 2 + 1 + 1 + 1)
 
 
 
 
 
 
static int _ihex_out(const int fd, const unsigned short addr, const char *data,
static int _ihex_out(const int fd, const unsigned short addr, const char *data,
 
 
                     const unsigned int len)
                     const unsigned int len)
 
 
{
{
 
 
        unsigned int j, i;
        unsigned int j, i;
 
 
        char buf[_BUFSIZ];
        char buf[_BUFSIZ];
 
 
        int err;
        int err;
 
 
 
 
 
 
        if (0 < len) {
        if (0 < len) {
 
 
                unsigned char chksum;
                unsigned char chksum;
 
 
 
 
 
 
                chksum = 0;
                chksum = 0;
 
 
 
 
 
 
                i = snprintf(&buf[0], _BUFSIZ, ":%02x%04x00", len, addr);
                i = snprintf(&buf[0], _BUFSIZ, ":%02x%04x00", len, addr);
 
 
                if (_BUFSIZ < i)
                if (_BUFSIZ < i)
 
 
                        return -ENOSPC;
                        return -ENOSPC;
 
 
 
 
 
 
                for (j = 0; j < len; j++) {
                for (j = 0; j < len; j++) {
 
 
                        i += snprintf(&buf[i], _BUFSIZ - i, "%02x", (unsigned char) *(data + j));
                        i += snprintf(&buf[i], _BUFSIZ - i, "%02x", (unsigned char) *(data + j));
 
 
                        if (_BUFSIZ < i)
                        if (_BUFSIZ < i)
 
 
                                return -ENOSPC;
                                return -ENOSPC;
 
 
 
 
 
 
                        chksum += *(data + j);
                        chksum += *(data + j);
 
 
                }
                }
 
 
 
 
 
 
                chksum += len;
                chksum += len;
 
 
                chksum += addr & 0x00ff;
                chksum += addr & 0x00ff;
 
 
                chksum += addr >> 8;
                chksum += addr >> 8;
 
 
 
 
 
 
                chksum = (chksum ^ 0xff) + 0x01;
                chksum = (chksum ^ 0xff) + 0x01;
 
 
                i += snprintf(&buf[i], _BUFSIZ - i, "%02x\n", chksum);
                i += snprintf(&buf[i], _BUFSIZ - i, "%02x\n", chksum);
 
 
                if (_BUFSIZ < i)
                if (_BUFSIZ < i)
 
 
                        return -ENOSPC;
                        return -ENOSPC;
 
 
        } else
        } else
 
 
                i = snprintf(&buf[0], _BUFSIZ, ":00000001ff\n");
                i = snprintf(&buf[0], _BUFSIZ, ":00000001ff\n");
 
 
 
 
 
 
        j = 0;
        j = 0;
 
 
        do {
        do {
 
 
                err = write(fd, &buf[j], i - j);
                err = write(fd, &buf[j], i - j);
 
 
                if (0 > err) {
                if (0 > err) {
 
 
                        err = -errno;
                        err = -errno;
 
 
                        if (-EINTR == err) {
                        if (-EINTR == err) {
 
 
                                err = 0;
                                err = 0;
 
 
                                continue;
                                continue;
 
 
                        }
                        }
 
 
 
 
 
 
                        break;
                        break;
 
 
                }
                }
 
 
 
 
 
 
                j += err;
                j += err;
 
 
                err = 0;
                err = 0;
 
 
        } while (0 == err && j < i);
        } while (0 == err && j < i);
 
 
 
 
 
 
        return err;
        return err;
 
 
}
}
 
 
 
 
 
 
static int _out_image(const char *image, const unsigned int size,
static int _out_image(const char *image, const unsigned int size,
 
 
                      const _mem_width_t mwidth, const char *outfile)
                      const _mem_width_t mwidth, const char *outfile)
 
 
{
{
 
 
        int err;
        int err;
 
 
 
 
 
 
        if (NULL != outfile) {
        if (NULL != outfile) {
 
 
                err = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                err = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
 
 
                if (0 > err)
                if (0 > err)
 
 
                        err = -errno;
                        err = -errno;
 
 
        } else
        } else
 
 
                err = fileno(stdout);
                err = fileno(stdout);
 
 
 
 
 
 
        if (0 <= err) {
        if (0 <= err) {
 
 
                const unsigned int offset = _mem_width2byte(mwidth);
                const unsigned int offset = _mem_width2byte(mwidth);
 
 
 
 
 
 
                unsigned short addr;
                unsigned short addr;
 
 
                unsigned int i;
                unsigned int i;
 
 
                int fd;
                int fd;
 
 
 
 
 
 
                fd = err;
                fd = err;
 
 
 
 
 
 
                addr = _start_addr;
                addr = _start_addr;
 
 
                i = 0;
                i = 0;
 
 
                do {
                do {
 
 
                        char buf[4];
                        char buf[4];
 
 
 
 
 
 
                        memset(&buf[0], 0x00, offset);
                        memset(&buf[0], 0x00, offset);
 
 
                        memcpy(&buf[0], &image[i],
                        memcpy(&buf[0], &image[i],
 
 
                               ((size - i) < offset) ? (size - i) : offset);
                               ((size - i) < offset) ? (size - i) : offset);
 
 
 
 
 
 
                        err = _ihex_out(fd, addr, &image[i], offset);
                        err = _ihex_out(fd, addr, &image[i], offset);
 
 
 
 
 
 
                        i += offset;
                        i += offset;
 
 
                        addr += 1;
                        addr += 1;
 
 
                } while (0 == err && i < size);
                } while (0 == err && i < size);
 
 
 
 
 
 
                /* finish line */
                /* finish line */
 
 
                if (0 == err)
                if (0 == err)
 
 
                        err = _ihex_out(fd, 0x00, NULL, 0);
                        err = _ihex_out(fd, 0x00, NULL, 0);
 
 
 
 
 
 
                if (fd != fileno(stderr))
                if (fd != fileno(stderr))
 
 
                        close(fd);
                        close(fd);
 
 
        }
        }
 
 
 
 
 
 
        if (0 != err)
        if (0 != err)
 
 
                fprintf(stderr, "\tERROR! dump image failed\n");
                fprintf(stderr, "\tERROR! dump image failed\n");
 
 
 
 
 
 
        return err;
        return err;
 
 
}
}
 
 
 
 
 
 
int main(int argc, char *argv[])
int main(int argc, char *argv[])
 
 
{
{
 
 
        int err;
        int err;
 
 
 
 
 
 
        err = _parse_args(argc, argv);
        err = _parse_args(argc, argv);
 
 
        if (0 == err) {
        if (0 == err) {
 
 
                unsigned int size;
                unsigned int size;
 
 
                char *img;
                char *img;
 
 
 
 
 
 
                img = _load_image(_infile, &size, _ascii, _mem_width);
                img = _load_image(_infile, &size, _ascii, _mem_width);
 
 
                if (img) {
                if (img) {
 
 
                        err = _out_image(img, size, _mem_width, _outfile);
                        err = _out_image(img, size, _mem_width, _outfile);
 
 
 
 
 
 
                        free(img);
                        free(img);
 
 
                } else
                } else
 
 
                        err = -EIO;
                        err = -EIO;
 
 
        }
        }
 
 
 
 
 
 
        return err;
        return err;
 
 
}
}
 
 
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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