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));
}