⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bin2srec.c

📁 并口程序串行发送
💻 C
字号:
/*

BIN2SREC  - Convert binary to Motorola S-Record file
Copyright (c) 2002  Anthony Goffart

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>

#define HEADER1 "\nBIN2SREC V1.11 - Convert binary to Motorola S-Record file.\n"
#define HEADER2 "Copyright (c) 2002 Ant Goffart - http://www.s-record.com/\n\n"

#define TRUE -1
#define FALSE 0

typedef unsigned long int dword;
typedef unsigned int word;

char filename[256] = "";
FILE *infile;

dword addr_offset = 0;
dword begin_addr;
dword end_addr;
int   addr_bytes = 2;
int   do_headers = TRUE;
int   verbose = TRUE;
int   line_length = 32;

/***************************************************************************/

dword atoh(char *s)
{
   int i;
   char c;
   dword res = 0;

   strupr(s);

   for (i = 0; i < strlen(s); i++)
   {
      c = s[i];
      res <<= 4;
      if (c >= '0' && c <= '9')
         res += (c - '0');
      else if (c >= 'A' && c <= 'F')
         res += (c - 'A' + 10);
   }
   return(res);
}

/***************************************************************************/

dword file_size(FILE *f)
{
   struct stat info;

   if (!fstat(fileno(f), &info))
      return(info.st_size);
   else
      return(0);
}

/***************************************************************************/

void syntax(void)
{
   printf(HEADER1);
   printf(HEADER2);
   printf("Syntax: BIN2SREC <options> INFILE > OUTFILE\n\n");
   printf("-help            Show this help.\n");
   printf("-b <begin>       Address to begin at in binary file (hex), default = 0.\n");
   printf("-e <end>         Address to end at in binary file (hex), default = end of file.\n");
   printf("-o <offset>      Generated address offset (hex), default = begin address.\n");
   printf("-a <addrsize>    Number of bytes used for address (2-4),\n");
   printf("                  default = minimum needed for maximum address.\n");
   printf("-l <linelength>  Number of bytes per line (8-32), default = 32.\n");
   printf("-s               Supress header and footer records.\n");
   printf("-q               Quiet mode - no output except S-Record.\n");
}

/***************************************************************************/

void process(void)
{
   int i;
   dword max_addr, address;
   int byte_count, this_line;
   unsigned char checksum;
   dword c;
   int record_count = 0;

   unsigned char buf[32];

   max_addr = addr_offset + (end_addr - begin_addr);

   fseek(infile, begin_addr, SEEK_SET);

   if ((max_addr > 0xffffl) && (addr_bytes < 3))
      addr_bytes = 3;

   if ((max_addr > 0xffffffl) && (addr_bytes < 4))
      addr_bytes = 4;

   if (verbose)
   {
      fprintf(stderr, HEADER1);
      fprintf(stderr, HEADER2);
      fprintf(stderr, "Input binary file: %s\n", filename);
      fprintf(stderr, "Begin address   = %lXh\n", begin_addr);
      fprintf(stderr, "End address     = %lXh\n", end_addr);
      fprintf(stderr, "Address offset  = %lXh\n", addr_offset);
      fprintf(stderr, "Maximum address = %lXh\n", max_addr);
      fprintf(stderr, "Address bytes   = %d\n", addr_bytes);
   }

   if (do_headers)
      printf("S00600004844521B\n");     /* Header record */

   for (address = addr_offset; address <= max_addr; address += line_length)
   {
      if (verbose)
         fprintf(stderr, "Processing %08lXh\r", address);

      this_line = min(line_length, 1 + max_addr - address);
      byte_count = (addr_bytes + this_line + 1);
      printf("S%d%02X", addr_bytes - 1, byte_count);

      checksum = byte_count;

      for (i = addr_bytes - 1; i >= 0; i--)
      {
         c = (address >> (i << 3)) & 0xff;
         printf("%02X", c);
         checksum += c;
      }

      fread(buf, 1, this_line, infile);

      for (i = 0; i < this_line; i++)
      {
         printf("%02X", buf[i]);
         checksum += buf[i];
      }

      printf("%02X\n", 255 - checksum);

      record_count++;
   }

   if (do_headers)
   {
      checksum = 3 + (record_count & 0xff) + ((record_count >> 8) & 0xff);
      printf("S503%04X%02X\n", record_count, 255 - checksum);

      byte_count = (addr_bytes + 1);
      printf("S%d%02X", 11 - addr_bytes, byte_count);

      checksum = byte_count;

      for (i = addr_bytes - 1; i >= 0; i--)
      {
         c = (addr_offset >> (i << 3)) & 0xff;
         printf("%02X", c);
         checksum += c;
      }
      printf("%02X\n", 255 - checksum);
   }

   if (verbose)
      fprintf(stderr, "Processing complete \n");
}

/***************************************************************************/

int main(int argc, char *argv[])
{
   int i;
   dword size;
   int offset_specified = FALSE;
   int end_specified = FALSE;
   char saddr[16] = "";

   for (i = 1; i < argc; i++)
   {
      if(!strcmp(argv[i], "-o"))
      {
         sscanf(argv[++i], "%s", saddr);
         addr_offset = atoh(saddr);
         offset_specified = TRUE;
         continue;
      }

      else if(!strcmp(argv[i], "-b"))
      {
         sscanf(argv[++i], "%s", saddr);
         begin_addr = atoh(saddr);
         continue;
      }

      else if(!strcmp(argv[i], "-e"))
      {
         sscanf(argv[++i], "%s", saddr);
         end_addr = atoh(saddr);
         end_specified = TRUE;
         continue;
      }

      else if(!strcmp(argv[i], "-a"))
      {
         sscanf(argv[++i], "%d", &addr_bytes);
         addr_bytes = max(2, addr_bytes);
         addr_bytes = min(4, addr_bytes);
         continue;
      }

      else if(!strcmp(argv[i], "-l"))
      {
         sscanf(argv[++i], "%d", &line_length);
         line_length = max(8, line_length);
         line_length = min(32, line_length);
         continue;
      }

      else if(!strcmp(argv[i], "-s"))
      {
         do_headers = FALSE;
         continue;
      }

      else if(!strcmp(argv[i], "-q"))
      {
         verbose = FALSE;
         continue;
      }

      else if(!strncmp(argv[i], "-h", 2))       /* -h or -help */
      {
         syntax();
         return(0);
      }

      else
      {
         sscanf(argv[i], "%s", filename);
         strupr(filename);
      }
   }

   if(!strcmp(filename, ""))
   {
      syntax();
      fprintf(stderr, "\n** No input filename specified\n");
      return(1);
   }

   if((infile = fopen(filename, "rb")) != NULL)
   {
      size = file_size(infile) - 1;

      if (end_specified)
         end_addr = min(size, end_addr);
      else
         end_addr = size;

      if (begin_addr > size)
      {
          fprintf(stderr, "Begin address %lXh is greater than file size %lXh\n", begin_addr, size);
          return(3);
      }

      if (end_addr < begin_addr)
      {
          fprintf(stderr, "End address %lXh is less than begin address %lXh\n", end_addr, begin_addr);
          return(3);
      }

      if (!offset_specified)
          addr_offset = begin_addr;

      process();
      fclose(infile);
      return(0);
   }
   else
   {
      fprintf(stderr, "Input file %s not found\n", filename);
      return(2);
   }
}

/***************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -