BIN 转化为 S19 格式及 S19 格式解析_bin文件转s19文件-程序员宅基地

技术标签: TI C2000 DSP  

bin2srec.c

/*
	BIN2SREC  - Convert binary to Motorola S-Record file
	Copyright (C) 1998-2012  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 3 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, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include "common.h"

#define HEADER1 "\nBIN2SREC " SREC_VER " - Convert binary to Motorola S-Record file.\n"

char *filename;
FILE *infile;

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


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

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

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

void process(void)
{
	int i;
	uint32_t max_addr, address;
	int byte_count, this_line;
	unsigned char checksum;
	uint32_t 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   = %Xh\n", begin_addr);
		fprintf(stderr, "End address     = %Xh\n", end_addr);
		fprintf(stderr, "Address offset  = %Xh\n", addr_offset);
		fprintf(stderr, "Maximum address = %Xh\n", max_addr);
		fprintf(stderr, "Address bytes   = %d\n", addr_bytes);
	}

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

	address = addr_offset;

	for (;;)
	{
		if (verbose)
			fprintf(stderr, "Processing %08Xh\r", address);

		this_line = min(line_length, (max_addr - address) + 1);
		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++;

		/* check before adding to allow for finishing at 0xffffffff */
		if ((address - 1 + line_length) >= max_addr)
			break;

		address += line_length;
	}

	if (do_headers)
	{
		if (record_count > 0xffff)
		{
			checksum = 4 + (record_count & 0xff) + ((record_count >> 8) & 0xff) + ((record_count >> 16) & 0xff);
			printf("S604%06X%02X\n", record_count, 255 - checksum);
		}
		else
		{
			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;
	uint32_t size;
	int offset_specified = FALSE;
	int end_specified = FALSE;

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

		else if (!strcmp(argv[i], "-b"))
		{
			begin_addr = str_to_uint32(argv[++i]);
			continue;
		}

		else if (!strcmp(argv[i], "-e"))
		{
			end_addr = str_to_uint32(argv[++i]);
			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
		{
			filename = argv[i];
		}
	}

	if (filename == NULL)
	{
		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 %Xh is greater than file size %Xh\n", begin_addr, size);
			return(3);
		}

		if (end_addr < begin_addr)
		{
			fprintf(stderr, "End address %Xh is less than begin address %Xh\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);
	}
}

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

common.c

/*
	common.c - Common functions for both srec2bin and bin2srec
	Copyright (C) 1998-2012  Anthony Goffart

	This file is part of SREC2BIN and BIN2SREC

	BIN2SREC and SREC2BIN are free software: you can redistribute them
	and/or modify them under the terms of the GNU General Public License
	as published by the Free Software Foundation, either version 3
	of the License, or (at your option) any later version.

	BIN2SREC and SREC2BIN are distributed in the hope that they 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 BIN2SREC and SREC2BIN. If not, see <http://www.gnu.org/licenses/>.
*/

#include <sys/stat.h>
#include "common.h"

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

unsigned int char_to_uint(char c)
{
	int res = 0;

	if (c >= '0' && c <= '9')
		res = (c - '0');
	else if (c >= 'A' && c <= 'F')
		res = (c - 'A' + 10);
	else if (c >= 'a' && c <= 'f')
		res = (c - 'a' + 10);

	return(res);
}

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

uint32_t str_to_uint32(char *s)
{
	int i;
	char c;
	uint32_t res = 0;

	for (i = 0; (i < 8) && (s[i] != '\0'); i++)
	{
		c = s[i];
		res <<= 4;
		res += char_to_uint(c);
	}

	return(res);
}

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

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

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

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

common.h

#ifndef COMMON_H
#define COMMON_H

#define SREC_VER "1.43"

#define HEADER2 "Copyright (c) 2000-2014 Ant Goffart - http://www.s-record.com/\n\n"

#include <stdio.h>
#include <stdint.h>

#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (~FALSE)
#endif

#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))

unsigned int char_to_uint(char s);
uint32_t str_to_uint32(char *s);
uint32_t file_size(FILE *f);

#endif

Motorola S-records 16进制文件格式是嵌入式中除intel hex之外很常见的格式,下面是它的格式:
+-------------------//------------------//-----------------------+
| type(hex1) | count(hex 1) |  address | data | checksum(从count累加到checksum,总和为0xFF) |
+-------------------//------------------//-----------------------+
  S0    :标识记录,地址域长度为2个字节,并用0000填充,数据区记录了一些模块名称和版本之类的信息
  S1    :数据记录,地址域长度为2个字节,数据区域为数据内容。
  S2    :数据记录,地址域长度为3个字节,数据区域为数据内容。
  S3    :数据记录,地址域长度为4个字节,数据区域为数据内容。
  S5    :统计记录,地址域长度为2个字节,内容是之前数据记录(S1,S2,S3)的个数,数据区域空。
  S7    : 运行记录,地址域长度为4个字节,内容是程序启动的地址,数据域空。
  S8    :运行记录,地址域长度为3个字节,内容是程序启动的地址,数据域空。
  S9    :运行记录,地址域长度为2个字节,内容是程序启动的地址,数据域空。
下面是一个例子,大家看看:
S02B0000433A5C446F63756D656E747320616E642053657474696E67735C7A6F75642E4143434F554E54535C7D
S208010000FFFFFFFFFA
S30800020000000000F5
S5030002FA
S9030000FC
第一行:没什么,开个头而已。
第二行:地址0x10000有4个0xFF
第三行:地址0x20000有3个0x00
第四行:标明之前有两条数据记录
第五行:程序从0x0000地址开始运行
关于checksum的算法和intel hex不太一样,
checksum = 0xFF - (从count段开始所有字节的总和)。


更快学习的动力来源于适当的压力。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fz835304205/article/details/46710317

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签