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

📄 srec.cpp

📁 用于开发Atmel的AVR系列单片机的GCC集成开发环境
💻 CPP
字号:
/**************************************************************************
Project: WinAVRIDE        Class: Read/Write Motorola SRecord File
Copyright (C) 2005  Philipp Schober

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

History
19.Feb 2005 - First Release (V1.0)
****************************************************************************/

#include "srec.h"

#define MAX_LINELEN 16
//---------------------------------------------------------------------------
int __fastcall TSRecord::ReadFile (AnsiString name, unsigned char *buf,
                                    int maxsize)
{
 unsigned char line[100];
 int address, count, i, temp, checksum, filesize = 0;
 bool finished = false, r;

 stream = new TFileStream(name, fmOpenRead);
 if (stream == NULL) return 0;
 while (!finished)
 {
  if (!ReadLine (line))
  {
   delete stream;
   return 0;
  }
  if (line[0] == 'S')
  {
   switch (line[1] - '0')
   {
    case 0: break; // Header
    case 1: r = HexToBin (line + 2, &count, 2);
            checksum = count;
            if (r) r = HexToBin (line + 4, &address, 4);
            checksum += address & 0xff;
            checksum += (address >> 8) & 0xff;
            if ((address + count - 3) > filesize) filesize = address + count - 3;
            if (filesize > maxsize)
            {
             ErrorMessage ("File exceeds Maximum Size");
             finished = true;
             filesize = 0;
             break;
            }
            for (i = 0;i < count - 3;i++)
            {
             if (r) r = HexToBin (line + 8 + (2 * i), &temp, 2);
             *(buf + address + i) = (unsigned char)temp;
             checksum += temp;
            }
            if (r) r = HexToBin (line + (2 * count) + 2, &temp, 2);
            checksum += temp;
            if (!r)
            {
             filesize = 0;
             finished = true;
             break;
            }
            if ((checksum & 0xff)!= 0xff)
            {
             ErrorMessage ("Checksum Error");
             finished = true;
             filesize = 0;
             break;
            }
            break;
    case 2: r = HexToBin (line + 2, &count, 2);
            checksum = count;
            if (r) r = HexToBin (line + 4, &address, 6);
            checksum += address & 0xff;
            checksum += (address >> 8) & 0xff;
            checksum += (address >> 16) & 0xff;
            if ((address + count - 4) > filesize) filesize = address + count - 4;
            if (filesize > maxsize)
            {
             ErrorMessage ("File exceeds Maximum Size");
             finished = true;
             filesize = 0;
             break;
            }
            for (i = 0;i < count - 4;i++)
            {
             if (r) r = HexToBin (line + 10 + (2 * i), &temp, 2);
             *(buf + address + i) = (unsigned char)temp;
             checksum += temp;
            }
            if (r) r = HexToBin (line + (2 * count) + 2, &temp, 2);
            checksum += temp;
            if (!r)
            {
             filesize = 0;
             finished = true;
             break;
            }
            if ((checksum & 0xff) != 0xff)
            {
             ErrorMessage ("Checksum Error");
             finished = true;
             filesize = 0;
             break;
            }
            break;
    case 3: r = HexToBin (line + 2, &count, 2);
            checksum = count;
            if (r) r = HexToBin (line + 4, &address, 8);
            checksum += address & 0xff;
            checksum += (address >> 8) & 0xff;
            checksum += (address >> 16) & 0xff;
            checksum += (address >> 24) & 0xff;
            if ((address + count - 5) > filesize) filesize = address + count - 5;
            if (filesize > maxsize)
            {
             ErrorMessage ("File exceeds Maximum Size");
             finished = true;
             filesize = 0;
             break;
            }
            for (i = 0;i < count - 5;i++)
            {
             if (r) r = HexToBin (line + 12 + (2 * i), &temp, 2);
             *(buf + address + i) = (unsigned char)temp;
             checksum += temp;
            }
            if (r) r = HexToBin (line + (2 * count) + 2, &temp, 2);
            checksum += temp;
            if (!r)
            {
             filesize = 0;
             finished = true;
             break;
            }
            if ((checksum & 0xff) != 0xff)
            {
             ErrorMessage ("Checksum Error");
             finished = true;
             filesize = 0;
             break;
            }
            break;
    case 5: break; // Count of records
    case 7: // Starting execution address
    case 8:
    case 9: finished = true;
   }
  }
  else
  {
   ErrorMessage ("Illegal Line found");
   finished = true;
   filesize = 0;
  }
 }
 delete stream;
 return filesize;
}
//---------------------------------------------------------------------------
bool __fastcall TSRecord::ReadLine (unsigned char *line)
{
 int i;
 long temppos;

 // Workaround for the missing ReadLine Method
 temppos = stream->Position;
 if (stream->Read (line, 100) < 1)
 {
  ErrorMessage ("File Read Operation Failed");
  return false;
 }
 for (i = 0;i < 100;i++)
 {
  if (*(line + i) == 10)
  {
   stream->Seek(temppos + i + 1, soFromBeginning);
   *(line + i + 1) = 0;
   break;
  }
 }

 return true;
}
//---------------------------------------------------------------------------
bool __fastcall TSRecord::HexToBin (unsigned char *in, int *out, int len)
{
 if (!isxdigit (*in) || !isxdigit (*(in + 1)))
 {
  ErrorMessage ("Illegal Char in File");
  return false;
 }
 *out = 0;
 while (len--)
 {
  *out *= 16;
  if (*in <= '9') *out += *in - '0';
  else if (*in >= 'A' && *in <= 'F') *out += *in -'A' + 10;
  else *out += *in - 'a' + 10;
  in++;
 }
 return true;
}
//---------------------------------------------------------------------------
bool __fastcall TSRecord::WriteFile (AnsiString name, unsigned char *buf,
        						     int size)
{
 unsigned char line[100];
 int type, i, count, address = 0, pos, checksum;
 bool emptyline;
 stream = new TFileStream(name, fmCreate);
 if (stream == NULL) return false;

 type = 1;
 if (size > 0xffff) type = 2;
 if (size > 0xffffff) type = 3;
 stream->Write ("S00600004844521B\r\n", 18); // Write Header
 while (size)
 {
  pos = 2;
  line[0] = 'S';
  line[1] = (unsigned char)(type + '0');
  if (size < MAX_LINELEN) count = size;
  else count = MAX_LINELEN;
  count += type + 1;
  checksum = count + 1;
  BinToHex (count + 1, line + pos, 2);
  pos += 2;
  BinToHex (address, line + pos, (type + 1) * 2);
  pos += (type + 1) * 2;
  checksum += address & 0xff;
  checksum += (address >> 8) & 0xff;
  checksum += (address >> 16) & 0xff;
  checksum += (address >> 24) & 0xff;
  emptyline = true;
  for (i = 0;i < (count - (type + 1));i++)
  {
   if (*(buf + i) != 0xff) emptyline = false;
  }
  for (i = 0;i < (count - (type + 1));i++)
  {
   checksum += *buf;
   BinToHex ((int)*(buf++), line + pos, 2);
   pos += 2;
  }
  BinToHex (0xff - (checksum & 0xff), line + pos, 2);
  pos += 2;
  *(line + pos++) = '\r';
  *(line + pos++) = '\n';
  if (!emptyline) stream->Write (line, pos);
  if (size >= MAX_LINELEN) size -= MAX_LINELEN;
  else size = 0;
  address += MAX_LINELEN;
 }
 if (type == 1) stream->Write ("S9030000FC\r\n", 12);
 else if (type == 2) stream->Write ("S804000000FB\r\n", 14);
 else stream->Write ("S70500000000FA\r\n", 16);
 delete stream;
 return true;
}
//---------------------------------------------------------------------------
void __fastcall TSRecord::BinToHex (int in, unsigned char *out, int len)
{
 unsigned char t;

 while (len--)
 {
  t = (unsigned char)(in % 16);
  in /= 16;
  if (t < 10) t += '0';
  else t = (unsigned char)(t - 10 + 'A');
  *(out + len) = t;
 }
}
//---------------------------------------------------------------------------
void __fastcall TSRecord::ErrorMessage (char *mess)
{
 Application->MessageBox (mess, "Error", MB_OK | MB_ICONERROR);
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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