二进值bin文件转mcs文件的小工具

INTEL的.HEX文件只能表示小于64K字节的文件,XILINX 的.MCS文件在此基础上,每64K字节加入了一个起始地址,就能表示高达64K*64K的文件了。

 下面代码是生成的代码:

    static void show_a_seg(){
	unsigned char b[] = { 0x02,0x00,0x00,0x04,0x00,0x00,0x00 };
	static unsigned char b4 = 0 ,b5 = 0 ;
	unsigned char b6;int i , sum  = 0 ;
	for(i=0;i<4;++i) sum += b[i] ;sum += b4 ;sum += b5 ;b6 = 1+ (~sum) ;
	fprintf(fout,":%02X%02X%02X%02X%02X%02X%02X\n",b[0],b[1],b[2],b[3],b4,b5,b6);
	printf(":%02X%02X%02X%02X%02X%02X%02X\n",b[0],b[1],b[2],b[3],b4,b5,b6);
	if (b5==0xff) b4++;  b5++;
	if (b5==2 ) exit(1);
	}
	



#include <windows.h>
#include <stdio.h>
#include <conio.h>

		 
		 
		 


///

/* ----------------------------------------------------------------------
 * Individual file format routines appear here:
 *	Each file format must define the following routines:
 *		open()	- Called ONCE before any of the others.
 *			It is passed with a filename and a format
 *			specific argument.
 *
 *		close() - Called ONCE when no more emit_byte()
 *			function calls will be made.
 *
 *		addr() - Called when ever a new address has been set
 *			in the assembler (ie. .org, .skip).
 *			This routine is also called once when the
 *			location counter is set to 0 at the very start of
 *			assembling.
 * 
 *		byte() - Called with each byte to be outputed.
 *
 */

static unsigned long addr;
static FILE *fout=NULL;
static long int offset;
static int newaddr;
static int pos=-666;
static unsigned char bytes[160];

#define mesg_f printf
/*-----------------------------------------------------------------------
 * "hex" format.  Intel HEX format expected by many EPROM programmers
 */


void hexdump(void)     /* dumps one line into file */
{
	int i, sum;

	if (fout == NULL) return;
	fprintf(fout,":%02X%04lX00", pos, addr & 0xFFFF);
	sum = pos + ((addr>>8)&0xff) + (addr&0xff) ;
	for (i=0; i < pos; i++) {
		fprintf(fout,"%02X", bytes[i] & 0xFF );
		sum += bytes[i]&0xff;
	}
	fprintf(fout, "%02X\n", 1+(~sum)&0xff);
	addr += pos;///4; /// 2009-11-14 by liwei
	pos = 0;
}
 
    static void show_a_seg(){
	unsigned char b[] = { 0x02,0x00,0x00,0x04,0x00,0x00,0x00 };
	static unsigned char b4 = 0 ,b5 = 0 ;
	unsigned char b6;int i , sum  = 0 ;
	for(i=0;i<4;++i) sum += b[i] ;sum += b4 ;sum += b5 ;b6 = 1+ (~sum) ;
	fprintf(fout,":%02X%02X%02X%02X%02X%02X%02X\n",b[0],b[1],b[2],b[3],b4,b5,b6);
	printf(":%02X%02X%02X%02X%02X%02X%02X\n",b[0],b[1],b[2],b[3],b4,b5,b6);
	if (b5==0xff) b4++;  b5++;
	if (b5==2 ) exit(1);
	}
	
static int open_hex(const char *file)
{
	fout = fopen(file, "a");
	if( fout == NULL ) {
		mesg_f("Cannot open %s for writing.\n", file);
		return 0;
	}
	show_a_seg(); 
	printf("show a seg\n");
	pos = 0;
	return 1;
}


static void pause_hex(void)
{
	if (fout == NULL) return;
	if ( pos > 0 ) hexdump();
	printf("pause hex \n");
	fclose(fout);
}

static void close_hex(void)
{
	if (fout == NULL) return;
	if ( pos > 0 ) hexdump();
	printf("close hex \n");
	fprintf(fout, ":00000001FF\n");  /* end of file marker */
	fclose(fout);
}

static void addr_hex(unsigned long a)
{
	if ( pos > 0 ) hexdump();
	addr = a;
}


static void byte_hex(unsigned char b)
{
	bytes[pos] = b;
	pos += 1;
	if ( pos == 16) hexdump();
}


unsigned char  gen_hex_file_64k(  char *filename,unsigned char *buff , int len)
{
int i;
open_hex(filename);
for(i=0;i<len;i++)byte_hex(buff[i]);
}


unsigned char  gen_hex_file(  char *filename,unsigned char *buff , int len)
{
int i ;
int offset = 0  ; 
	fout = fopen(filename, "w"); //re create this file 
	fclose(fout) ; 
while(len > 65536 ){
          gen_hex_file_64k(filename,buff+offset,65536);
          offset += 65536;
          len -= 65536;
          if (len==0)close_hex();else  pause_hex();
}
if (len)   { gen_hex_file_64k(filename,buff+offset,len); close_hex(); }
}


///
/*

记录格式
一个Intel HEX文件可以包含任意多的十六进制记录,每条记录有五个域,下面是一个记录的格式.
:llaaaatt[dd...]cc
每一组字母是独立的一域,每一个字母是一个十六进制数字,每一域至少由两个十六进制数字组成,下面是字节的描述.
:冒号     是每一条Intel HEX记录的开始
ll 是这条记录的长度域,他表示数据(dd)的字节数目.
aaaa 是地址域,他表示数据的起始地址
<如果是数据记录,这表示将要烧录的这条记录中的数据在EPROM中的偏移地址,
对于不支持扩展段地址和扩展线性地址的,如89C51,这就是此条记录的起始地址>
tt 这个域表示这条HEX记录的类型,他有可能是下面这几种类型
00 ----数据记录
01 ----文件结束记录
02 ----扩展段地址记录
04 ----扩展线性地址记录
dd   是数据域,表示一个字节的数据,一个记录可能有多个数据字节,字节数目可以
查看ll域的说明
cc   是效验和域,表示记录的效验和,计算方法是将本条记录冒号开始的所有字母对
<不包括本效验字和冒号> 所表示的十六进制数字
<一对字母表示一个十六进制数,这样的一个十六进制数为一个字节>
都加起来然后模除256得到的余数最后求出余数的补码即是本效验字节cc.
<例如:
:0300000002005E9D
cc=0x01+NOT((0x03+0x00+0x00+0x00+0x02+0x00+0x5E)%0x100)=0x01+0x9C=0x9D
C语言描述:
UCHAR cc;
cc=(UCHAR)~(0x03+0x00+0x00+0x00+0x02+0x00+0x5E);
cc++;
*/




unsigned char byte_swap(unsigned char hi ){
     unsigned char r = 0 ;
     if ( hi & 128 ) r += 1   ; 
     if ( hi & 64 )  r += 2 ; 
     if ( hi & 32 ) r += 4 ; 
     if ( hi & 16 ) r += 8  ; 
     if ( hi & 8 )  r += 16 ; 
     if ( hi & 4 )  r += 32; 
     if ( hi & 2 ) r += 64; 
     if ( hi & 1 ) r += 128 ; 
     return r ;
}

unsigned char byte_swap2(unsigned char hi ){
     unsigned char r = 0 ;
     if ( hi & 128 ) r += 16   ; 
     if ( hi & 64 )  r += 32 ; 
     if ( hi & 32 ) r += 64 ; 
     if ( hi & 16 ) r += 128  ; 
     
     if ( hi & 8 )  r += 1 ; 
     if ( hi & 4 )  r += 2; 
     if ( hi & 2 ) r += 4; 
     if ( hi & 1 ) r += 8 ; 
	 return r ;
}



int  file2buff (char * fn, unsigned char *buff ,int buff_len ){	
   int size ;   FILE *fp; 
   fp = fopen( fn , "rb");
   if (fp==NULL)  {	printf("can not read file \n");getchar();}
   size = fread (buff,1, buff_len, fp);
   fclose (fp);
   return size ;	
} 

#define BUFF_SIZE 1024*1024*128  
unsigned char  s[BUFF_SIZE]  ;
 
void main()
{
unsigned 	int i,len;
len = file2buff("aaa.bin",s,BUFF_SIZE) ;
printf("file len = %d ",len);
 //for(i=0;i<len ;i+=1) s[i] =      byte_swap2 (s[i]); 
fout = fopen("aaa.mcs", "w");
fclose(fout) ; 
gen_hex_file("aaa.mcs",s,sizeof(s));
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值