srecLoad.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:4k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * srecLoad
  3.  *
  4.  * by Curt McDowell, 09-05-99
  5.  */
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "srecLoad.h"
  9. #if 0
  10. int test_me()
  11. {
  12. }
  13. int test_me1()
  14. {
  15. }
  16. #endif
  17. /*
  18.  * nextByte:
  19.  *
  20.  * Utility routine for srecLoad()
  21.  */
  22. static int nextByte(char **p)
  23. {
  24.     int d1, d2;
  25.     d1 = **p;
  26.     if (d1 >= '0' && d1 <= '9')
  27. d1 = d1 - '0';
  28.     else if (d1 >= 'A' && d1 <= 'F')
  29. d1 = d1 - 'A' + 10;
  30.     else
  31. return -1;
  32.     d1 *= 16;
  33.     (*p)++;
  34.     d2 = **p;
  35.     if (d2 >= '0' && d2 <= '9')
  36. d1 += d2 - '0';
  37.     else if (d2 >= 'A' && d2 <= 'F')
  38. d1 += d2 - 'A' + 10;
  39.     else
  40. return -1;
  41.     (*p)++;
  42.     return d1;
  43. }
  44. /*
  45.  * srecLoad:
  46.  *
  47.  * Routine to read an S-record format file into a fixed-size buffer.
  48.  *
  49.  * On success, returns number of bytes loaded.
  50.  * On failure, returns negative error code.
  51.  */
  52. int srecLoad(FILE *fp, char *buf, int bufLen, int *entry)
  53. {
  54.     static unsigned char addrLens[] = { 2, 2, 3, 4, 0, 2, 0, 4, 3, 2 };
  55.     char line[1 + 1 + 2 + 255*2 + 1];
  56.     char dataBytes[255], *p;
  57.     int dataLen, dataRecs;
  58.     char *s;
  59.     int type, x, addrLen, byteCount, byteTotal;
  60.     int addr;
  61.     unsigned char chkSum;
  62.     memset(buf, 0, bufLen);
  63.     *entry = 0;
  64.     dataRecs = 0;
  65.     byteTotal = 0;
  66.     while (fgets(line, sizeof (line), fp) != 0) {
  67. s = line;
  68. chkSum = 0;
  69. if (*s++ != 'S')
  70.     continue;
  71. type = *s++;
  72. if (type < '0' || type > '9')
  73.     return SREC_ERROR_FORMAT;
  74. addrLen = addrLens[type - '0'];
  75. if ((byteCount = nextByte(&s)) < 0)
  76.     return SREC_ERROR_FORMAT;
  77. chkSum = (unsigned char) byteCount;
  78. byteCount -= addrLen;
  79. if (byteCount < 1)
  80.     return SREC_ERROR_FORMAT; /* Need at least addr and checksum */
  81. addr = 0;
  82. while (addrLen--) {
  83.     if ((x = nextByte(&s)) < 0)
  84. return SREC_ERROR_TRUNC;
  85.     addr = addr << 8 | x;
  86.     chkSum += (unsigned char) x;
  87. }
  88. p = dataBytes;
  89. dataLen = byteCount - 1;
  90. while (byteCount-- > 1) {
  91.     if ((x = nextByte(&s)) < 0)
  92. return SREC_ERROR_TRUNC;
  93.     *p++ = (char) x;
  94.     chkSum += (unsigned char) x;
  95. }
  96. if ((x = nextByte(&s)) < 0)
  97.     return SREC_ERROR_TRUNC;
  98. chkSum += (unsigned char) x;
  99. if (chkSum != (unsigned char) 0xff)
  100.     return SREC_ERROR_CHECKSUM;
  101. switch (type) {
  102. case '0': /* Header record */
  103.     dataRecs = 0;
  104.     break;
  105. case '5': /* Record count */
  106.     if (addr != dataRecs)
  107. return SREC_ERROR_NRECORDS;
  108.     break; /* Ignore */
  109. case '1': /* 2-byte address with data */
  110. case '2': /* 3-byte address with data */
  111. case '3': /* 4-byte address with data */
  112.     if (addr < 0 || addr + dataLen > bufLen){
  113. printf("addr=0x%x, addr+dataLen=0x%x, bufLen=%dn",
  114.        addr, addr + dataLen, bufLen);
  115. return SREC_ERROR_ADDR;
  116.     }
  117.     memcpy(buf + addr, dataBytes, dataLen);
  118.     byteTotal += dataLen;
  119.     dataRecs++;
  120.     break;
  121. case '7': /* Termination with 4-byte address */
  122. case '8': /* Termination with 3-byte address */
  123. case '9': /* Termination with 2-byte address */
  124.     *entry = addr;
  125.     dataRecs = 0;
  126.     break;
  127. default:
  128.     return SREC_ERROR_FORMAT;
  129. }
  130.     }
  131.     return byteTotal;
  132. }
  133. char *srecErrmsg(int errcode)
  134. {
  135.     switch (errcode) {
  136.     case SREC_ERROR_NONE:
  137. return "Success";
  138.     case SREC_ERROR_FORMAT:
  139. return "File format error";
  140.     case SREC_ERROR_CHECKSUM:
  141. return "Checksum mismatch";
  142.     case SREC_ERROR_NRECORDS:
  143. return "Incorrect number of records";
  144.     case SREC_ERROR_TRUNC:
  145. return "Truncated line";
  146.     case SREC_ERROR_ADDR:
  147. return "Address out of range";
  148.     }
  149.     return "Unknown error";
  150. }
  151. #ifdef TEST_MAIN
  152. /*
  153.  * Test main program
  154.  */
  155. #define PROM_SIZE (512 * 1024)
  156. main(int argc, char **argv)
  157. {
  158.     FILE *fp;
  159.     char buf[PROM_SIZE];
  160.     int entry, r;
  161.     if (argc != 2) {
  162. fprintf(stderr, "Usage: srecLoad file.hex > file.binn");
  163. exit(1);
  164.     }
  165.     if ((fp = fopen(argv[1], "r")) == 0) {
  166. fprintf(stderr, "srecLoad: could not open %sn", argv[1]);
  167. exit(1);
  168.     }
  169.     if ((r = srecLoad(fp, buf, sizeof (buf), &entry)) < 0) {
  170. fprintf(stderr, "srecLoad: load error %dn", r);
  171. exit(1);
  172.     }
  173.     fclose(fp);
  174.     write(1, buf, sizeof (buf));
  175.     fprintf(stderr, "Entry address: 0x%08xn", (unsigned int) entry);
  176.     exit(0);
  177. }
  178. #endif /* TEST_MAIN */
  179. #if 0
  180. int test_me()
  181. {
  182. }
  183. int test_me1()
  184. {
  185. test_me();
  186. }
  187. #endif