在嵌入式开发时,很多时候我们需要将嵌入式编译链生成的hex文件转换成bin格式,然后再用bootload下载到板子上,方便在线升级,可以生成一个小工具软件在下载的脚本里先转换格式再下载bin文件到板子上
//将两个字符转化为一个字节量
void CharToByte(char* pChar,BYTE* pByte)
{
char h,l;
h=pChar[0];//高位
l=pChar[1];//低位
if(l>='0'&&l<='9')
l=l-'0';
else if(l>='a' && l<='f')
l=l-'a'+0xa;
else if(l>='A' && l<='F')
l=l-'A'+0xa;
if(h>='0'&&h<='9')
h=h-'0';
else if(h>='a' && h<='f')
h=h-'a'+0xa;
else if(h>='A' &&h <='F')
h=h-'A'+0xa;
*pByte=(BYTE)((h<<4)+l);
}
bool validateHexFile(FILE* hexfile)
{
char data[2];
BYTE dataLen;
BYTE nData;
int i;
BYTE Checksum;
if(hexfile==NULL) return false;
while (!feof(hexfile))
{
//:号表示一行的开始
if (fgetc(hexfile) == ':')
{
//一行的头两个字符表示该行包含的数据长度
Checksum = 0;
data[0] = fgetc(hexfile);
data[1] = fgetc(hexfile);
CharToByte(data,&dataLen);
Checksum+=dataLen;
for(i = 0 ;i<dataLen+ 4;i++)
{
data[0] = fgetc(hexfile);
data[1] = fgetc(hexfile);
CharToByte(data,&nData);
Checksum+=nData;
}
if((Checksum & 0xFF)!=0)
{
fclose(hexfile);
return false;
}
}
}
rewind(hexfile);
return true;
}
#define BUFFERLEN 512*1024
int main(int argc, char* argv[])
{
char fileName[200];
char data[2];
BYTE *outBuf;
FILE *myFile;
unsigned int len;
unsigned int i;
unsigned int LineAddrHigh,OutAddr,LineAddr;
BYTE adressHigh;
BYTE adressLow;
BYTE dataLen;
BYTE dataType;
BYTE byteData;
unsigned int gPeakAddr=0;
unsigned int totalLen;
totalLen = 0;
len = 0;
adressHigh = 0;
adressLow = 0;
dataLen = 0;
dataType = 0;
if(argc<3)
{
printf("hex2bin myhexfile.hex mybinfile.bin\r\n");
return 0;
}
//printf("请输入HEX格式文件名:");
//scanf("%s",fileName);
sprintf(fileName,"%s",argv[1]);//"D:\\JiuYuSoftware\\下载工具\\hex2bin\\pp.hex");
printf("\n");
myFile=fopen(fileName,"r");
if (myFile==NULL)
{
printf("打开文件%s失败!",fileName);
return 0;
}
//将文件长度计算出来用于申请存储数据的缓冲区
/*
while (!feof(myFile))
{
++len;
fgetc(myFile);
}
rewind(myFile);
*/
if(!validateHexFile(myFile))
{
printf("Hex文件效验错,请检查完整性\r\n");
return 0;
}
//512k
outBuf = (BYTE*)malloc(BUFFERLEN);
memset(outBuf,0xff,BUFFERLEN);
while (!feof(myFile))
{
//:号表示一行的开始
if (fgetc(myFile) == ':')
{
//一行的头两个字符表示该行包含的数据长度
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&dataLen);
//一行的第、个字符表示数据存储起始地址的高位
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&adressHigh);
//一行的第、个字符表示数据存储起始地址的低位
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&adressLow);
LineAddr=adressHigh;
LineAddr=((LineAddr<<8)+adressLow+65536)&65535;
//一行的第、个字符表示数据类型
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&dataType);
//当数据类型为时,表示本行包含的是普通数据记录
if (dataType == 0x00)
{
if( (LineAddrHigh >= 0x1D00)&&(LineAddrHigh <= 0x1D08))
{
OutAddr = (LineAddrHigh * 65536) + (LineAddr & 65535);
for (i=0;i<dataLen;i++)
{
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&byteData);
/*
if(byteData==0x0D)
{
printf("find 0x0d");
}
else if(byteData==0x0A)
{
printf("find 0x0A");
}
*/
outBuf[OutAddr - 0x1D000000 + i]=byteData;
//outBuf[adressHigh*256+adressLow+i] = byteData;
}
OutAddr = OutAddr + dataLen;
if(OutAddr > gPeakAddr)
gPeakAddr = OutAddr;
//totalLen += dataLen;
}
}
//当数据类型为时,表示到了最后一行
if (dataType == 0x01)
{
printf("文件结束记录!");
}
//当数据类型为时,表示本行包含的是扩展段地址记录
if (dataType == 0x02)
{
printf("不支持扩展段地址记录!");
return 0;
}
//当数据类型为时,表示本行包含的是扩展线性地址记录
if (dataType == 0x04)
{
//printf("不支持扩展线性地址记录!");
//return 0;
//LineAddrHigh = (Val("&H1" & Mid(FileLine, 10, 4)) And 65535)
BYTE hiByte,lowByte;
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&hiByte);
LineAddrHigh=hiByte;
data[0] = fgetc(myFile);
data[1] = fgetc(myFile);
CharToByte(data,&lowByte);
LineAddrHigh=((LineAddrHigh<<8)+lowByte+65536)&65535;
}
}
}
fclose(myFile);
//printf("请输入保存的BIN格式文件名:");
//scanf("%s",fileName);
sprintf(fileName,"%s",argv[2]);//"D:\\JiuYuSoftware\\下载工具\\hex2bin\\pp.bin");
myFile=fopen(fileName,"wb");
if (myFile== NULL)
{
printf("打开文件%s失败!",fileName);
return 0;
}
totalLen = ((gPeakAddr - 0x1D000000) & (~3)) + 4;
printf("totalLen 0x%x\r\n",totalLen);
/*
for (i=0;i<totalLen;i++)
{
if(outBuf[i]==0x0d)
{
printf("i:0x%x 0x%x 0x%x\r\n",i,outBuf[i],outBuf[i+1]);
}
fputc(outBuf[i],myFile);
}
*/
fwrite(outBuf,totalLen,1,myFile);
free(outBuf);
fclose(myFile);
return 0;
}