Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

mkimg.c

Go to the documentation of this file.
00001 /*
00002  *  mkimg.c
00003  *
00004  *  A program to make an image .c file given an s-record file.
00005  *
00006  *  Compile with: cc mkimg.c srec.c -o mkimg
00007  *
00008  *  The contents of this file are subject to the Mozilla Public License
00009  *  Version 1.0 (the "License"); you may not use this file except in
00010  *  compliance with the License. You may obtain a copy of the License at
00011  *  http://www.mozilla.org/MPL/
00012  *
00013  *  Software distributed under the License is distributed on an "AS IS"
00014  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00015  *  License for the specific language governing rights and limitations
00016  *  under the License.
00017  *
00018  *  The Original Code is Firmdl code, released October 3, 1998.
00019  *
00020  *  The Initial Developer of the Original Code is Kekoa Proudfoot.
00021  *  Portions created by Kekoa Proudfoot are Copyright (C) 1998, 1999
00022  *  Kekoa Proudfoot. All Rights Reserved.
00023  *
00024  *  Contributor(s): Kekoa Proudfoot <kekoa@graphics.stanford.edu>
00025  */
00026 
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <stdio.h>
00030 #include <ctype.h>
00031 
00032 #include "srec.h"
00033 
00034 #define IMAGE_START     0x8000
00035 #define IMAGE_MAXLEN    0x4000
00036 
00037 /* Stripping zeros is not entirely legal if firmware expects trailing zeros */
00038 /* Define FORCE_ZERO_STRIPPING to force zero stripping for all files */
00039 /* Normally you do not want to do this */
00040 /* Possibly useful only if you explicitly zero pad for OCX compatiblity */
00041 /* Since zero stripping is okay for Firm0309.lgo, that is done automatically */
00042 
00043 #if 0
00044 #define FORCE_ZERO_STRIPPING
00045 #endif
00046 
00047 /* Functions */
00048 
00049 int srec_load (char *name, unsigned char *image, int maxlen, unsigned short *start)
00050 {
00051     FILE *file;
00052     char buf[256];
00053     srec_t srec;
00054     int line = 0;
00055     int length = 0;
00056     int strip = 0;
00057 
00058     /* Initialize starting address */
00059     *start = IMAGE_START;
00060 
00061     /* Open file */
00062     if ((file = fopen(name, "r")) == NULL) {
00063         fprintf(stderr, "%s: failed to open\n", name);
00064         exit(1);
00065     }
00066 
00067     /* Clear image to zero */
00068     memset(image, 0, maxlen);
00069 
00070     /* Read image file */
00071     while (fgets(buf, sizeof(buf), file)) {
00072         int error, i;
00073         line++;
00074         /* Skip blank lines */
00075         for (i = 0; buf[i]; i++)
00076             if (!isspace(buf[i]))
00077                 break;
00078         if (!buf[i])
00079             continue;
00080         /* Decode line */
00081         if ((error = srec_decode(&srec, buf)) < 0) {
00082             if (error != SREC_INVALID_CKSUM) {
00083                 fprintf(stderr, "%s: %s on line %d\n",
00084                         name, srec_strerror(error), line);
00085                 exit(1);
00086             }
00087         }
00088         /* Detect Firm0309.lgo header, set strip=1 if found */
00089         if (srec.type == 0) {
00090             if (srec.count == 16)
00091                 if (!strncmp(srec.data, "?LIB_VERSION_L00", 16))
00092                     strip = 1;
00093         }
00094         /* Process s-record data */
00095         else if (srec.type == 1) {
00096             if (srec.addr < IMAGE_START ||
00097                 srec.addr + srec.count > IMAGE_START + maxlen) {
00098                 fprintf(stderr, "%s: address out of bounds on line %d\n",
00099                         name, line);
00100                 exit(1);
00101             }
00102             if (srec.addr + srec.count - IMAGE_START > length)
00103                 length = srec.addr + srec.count - IMAGE_START;
00104             memcpy(&image[srec.addr - IMAGE_START], &srec.data, srec.count);
00105         }
00106         /* Process image starting address */
00107         else if (srec.type == 9) {
00108             if (srec.addr < IMAGE_START ||
00109                 srec.addr > IMAGE_START + maxlen) {
00110                 fprintf(stderr, "%s: address out of bounds on line %d\n",
00111                         name, line);
00112                 exit(1);
00113             }
00114             *start = srec.addr;
00115         }
00116     }
00117 
00118     /* Strip zeros */
00119 #ifdef FORCE_ZERO_STRIPPING
00120     strip = 1;
00121 #endif
00122 
00123     if (strip) {
00124         int pos;
00125         for (pos = IMAGE_MAXLEN - 1; pos >= 0 && image[pos] == 0; pos--);
00126         length = pos + 1;
00127     }
00128 
00129     /* Check length */
00130     if (length == 0) {
00131         fprintf(stderr, "%s: image contains no data\n", name);
00132         exit(1);
00133     }
00134 
00135     return length;
00136 }
00137 
00138 char *basename (char *path)
00139 {
00140     char *last = strrchr(path, '/');
00141     return (last) ? last + 1 : path;
00142 }
00143 
00144 char *build_image_name (char *dst, char *src)
00145 {
00146     char *base = basename(src);
00147     while (*base) {
00148         if ((*base >= 'a' && *base <= 'z') || (*base >= 'A' && *base <= 'A') ||
00149             (*base >= '0' && *base <= '9') || *base == '_')
00150             *dst++ = *base;
00151         else if (*base == '.')
00152             break;
00153         else
00154             *dst++ = '_';
00155         base++;
00156     }
00157     *dst++ = '\0';
00158 
00159     return dst;
00160 }
00161 
00162 int main (int argc, char **argv)
00163 {
00164     unsigned char image_name[64];
00165     unsigned char image[IMAGE_MAXLEN];
00166     unsigned short image_start;
00167     unsigned int image_len;
00168     int i;
00169 
00170     argv[0] = basename(argv[0]);
00171 
00172     if (argc != 2) {
00173         fprintf(stderr, "usage: %s filename\n", argv[0]);
00174         exit(1);
00175     }
00176 
00177     build_image_name(image_name, argv[1]);
00178 
00179     /* Load the s-record file */
00180 
00181     image_len = srec_load(argv[1], image, IMAGE_MAXLEN, &image_start);
00182 
00183     /* Dump a .c file */
00184 
00185     printf("/* Image file generated from %s by %s. */\n", argv[1],  argv[0]);
00186     printf("/* See source for %s for license info. */\n", argv[1]);
00187     printf("\n");
00188     printf("int %s_len = %d;\n", image_name, image_len);
00189     printf("unsigned char %s_image[] = {", image_name);
00190     for (i = 0; i < image_len; i++) {
00191         if (i % 16 == 0)
00192             printf("\n    ");
00193         printf("%3d,", image[i]);
00194     }
00195     printf("\n");
00196     printf("};\n");
00197     printf("unsigned short %s_start = 0x%04x;\n", image_name, image_start);
00198 
00199     return 0;
00200 }
00201 
00202 
00203 
00204 

Generated on Fri Feb 25 08:02:40 2005 for brickos by  doxygen 1.3.9.1