这几天在写STM32的ISP烧录工具,因此有涉及到输入hex文件或bin文件进行烧录的问题,所以对hex文件和bin文件进行了些总结。
1 hex介绍
Hex 全称 (Intel HEX)文件是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。Intel HEX文件通常用于传输将被存于ROM或者EPROM中的程序和数据。大多数EPROM编程器或模拟器使用Intel HEX文件。
2 hex与bin的区别
1 HEX文件是包括地址信息的,而BIN文件格式只包括了数据本身,在烧写或下载HEX文件的时候,一般都不需要用户指定地址,因为HEX文件内部的信息已经包括了地址。而烧写BIN文件的时候,用户是一定需要指定地址信息的。
2 BIN文件格式,对二进制文件而言,其实没有”格式”。文件只是包括了纯粹的二进制数据。
3 HEX文件格式
HEX文件都是由记录(RECORD)组成的。在HEX文件里面,每一行代表一个记录。记录的基本格式为:
+---------------------------------------------------------------+
|RECORD| RECLEN |LOAD|RECTYPE | INFO or DATA | CHKSUM |
|MARK ':'| | OFFSET | | | |
+---------------------------------------------------------------+
|1-byte| 1-byte | 2-byte | 1-byte| n-byte | 1-byte |
+---------------------------------------------------------------+
记录类型包括:
'00' DataRrecord:用来记录数据,HEX文件的大部分记录都是数据记录
'01' End of File Record:用来标识文件结束,放在文件的最后,标识HEX文件的结尾
'02' Extended SegmentAddress Record: 用来标识扩展段地址的记录
'03' Start Segment Address Record
'04' Extended Linear AddressRecord: 用来标识扩展线性地址的记录
'05' Start Linear Address Record
在上面的后2种记录,都是用来提供地址信息的。每次碰到这2个记录的时候,都可以根据记录计算出一个“基”地址。
对于后面的数据记录,计算地址的时候,都是以这些“基”地址为基础的。
数据记录的具体格式:
+---------------------------------------------------------------+
|RECORD| RECLEN |LOAD|RECTYPE | INFO or DATA | CHKSUM |
|MARK ':'| | OFFSET|'00' | | |
+---------------------------------------------------------------+
|1-byte| 1-byte | 2-byte | 1-byte| n-byte | 1-byte |
+---------------------------------------------------------------+
看个例子:
:020000040000FA
:10000400FF00A0E314209FE5001092E5011092E5A3
:00000001FF
对上面的HEX文件进行分析:
第1条记录的长度为02,LOADOFFSET为0000,RECTYPE为04,说明该记录为扩展段地址记录。数据为0000,校验和为
FA。从这个记录的长度和数据,我们可以计算出一个基地址,这个地址为0X0000。后面的数据记录都以这个地址为基
地址。
第2条记录的长度为10(16),LOADOFFSET为0004,RECTYPE为00,说明该记录为数据记录。
数据为FF00A0E314209FE5001092E5011092E5,共16个BYTE。这个记录的校验和为A3。此时的基地址为0X0000,加上OFFSET,
这个记录里的16BYTE的数据的起始地址就是0x0000+ 0x0004 = 0x0004.
第3条记录的长度为00,LOADOFFSET为0000,TYPE = 01,校验和为FF。说明这个是一个END OF FILE RECORD,标识
文件的结尾。
在上面这个例子里,实际的数据只有16个BYTE:FF00A0E314209FE5001092E5011092E5,其起始地址为0x4
4 HEX文件和BIN文件大小有区别
HEX文件是用ASCII来表示二进制的数值。例如一般8-BIT的二进制数值0x3F,用ASCII来表示就需要分别表示字符'3'
和字符'F',每个字符需要一个BYTE,所以HEX文件需要 > 2倍的空间。
对一个BIN文件而言,你查看文件的大小就可以知道文件包括的数据的实际大小。而对HEX文件而言,你看到的文件
大小并不是实际的数据的大小。一是因为HEX文件是用ASCII来表示数据,二是因为HEX文件本身还包括别的附加信息。
要想详细了解HEX文件格式, 请参见INTEL HEX PDF文档
3 hex文件流转bin文件流
hex.h:
#ifndef __HEX_H_
#define __HEX_H_
typedef struct{
int len; //bin文件大小
UINT startAddress; //刷写的起始地址
BYTE *pContent; //转化后的内容
}HexToBinData;
typedef struct{
BYTE data[16];//数据
BYTE len; //数据长度
UINT pos; //偏移地址
BYTE type; //类型
}HexLinData;
int ConvertHexToBin(const char *str,HexToBinData *pData);
#endif
hex.cpp:
//#include "StdAfx.h"
#include "hex.h"
static BYTE HexCharToByte(char c)
{
if(c>='0' && c<='9')
return c -'0';
else if(c>='a' && c<='f')
return c-'a'+0x0a;
else if(c>='A' && c <='F')
return c-'A'+0x0a;
return -1;
}
static BYTE GetFirstByte(const char *str)
{
ASSERT(str !=NULL);
BYTE tmp =0;
tmp =HexCharToByte(str[0]);
tmp <<=4;
tmp +=HexCharToByte(str[1]);
return tmp;
}
//从字符串中获取一行
static int GetLine(const char *str,char *pBuf)
{
ASSERT(str !=NULL);
ASSERT(pBuf !=NULL);
char *start =strchr((char *)str,':');
if(NULL ==start){
return -1;
}
char *end =strstr(start,"\r\n");
char *p =start;
char *p2 =pBuf;
int len=0;
for (;p<end+2;p++,p2++)
{
if(*p =='\0')
break;
*p2 =*p;
len ++;
}
*p2 ='\0';
return len;
}
//获取一行的数据
static int GetHexLineData(const char *line,HexLinData *pData)
{
ASSERT(line !=NULL);
ASSERT(pData !=NULL);
if(line[0] !=':')
return -1;
int i=1;
pData->len =GetFirstByte(&line[i]);
i +=2;
pData->pos =GetFirstByte(&line[i]);
i +=2;
pData->pos <<=8;
pData->pos +=GetFirstByte(&line[i]);
i +=2;
pData->type =GetFirstByte(&line[i]);
i +=2;
for(int j=0;j<pData->len;i+=2,j++){
pData->data[j] =GetFirstByte(&line[i]);
}
return 0;
}
//获取第一行指定类型的数据
static int GetFirstDataLine(const char *str,BYTE type,HexLinData *pData)
{
ASSERT(str !=NULL);
ASSERT(pData !=NULL);
char *p =(char *)str;
char line[128];
HexLinData data ={0};
int len =strlen(str);
int dataLen =0;
for(;p<str+len;p+=dataLen){
memset(line,0,128);
dataLen =GetLine(p,line);
if(dataLen <0)
return -1;
memset(&data,0x00,sizeof(HexLinData));
if(0 !=GetHexLineData(line,&data))
return -1;
if(data.type ==type){
memcpy(pData,&data,sizeof(HexLinData));
return 0;
}
}
return -1;
}
static int GetStartAddress(const char *str,UINT *pStartAddress)
{
HexLinData data ={0};
UINT basePos=0;
UINT pos;
if(0 !=GetFirstDataLine(str,4,&data))
return -1;
for(int i=0;i<data.len;i++){
basePos <<=8;
basePos +=data.data[i];
}
memset(&data,0x00,sizeof(HexLinData));
if(0 !=GetFirstDataLine(str,0,&data))
return -1;
pos =data.pos;
*pStartAddress =(basePos<<16) +pos;
return 0;
}
int ConvertHexToBin(const char *str,HexToBinData *pData)
{
ASSERT(str !=NULL);
ASSERT(pData !=NULL);
UINT startAddress =0;
char line[128] ={0};
HexLinData data={0};
if(0 !=GetStartAddress(str,&startAddress))
return -1;
pData->startAddress =startAddress;
char *p =(char *)str;
int binLen =0;
int len =0;
int size =strlen(str);
/*FILE *file =fopen("test.hex","wb+");
fseek(file,0,SEEK_SET);
FILE *file1 =fopen("test.bin","wb+");
fseek(file1,0,SEEK_SET);*/
for(binLen=0;p<str+size;p +=len){
memset(line,0,128);
len =GetLine(p,line);
if(len <0)
break;
/*fwrite(line,1,len,file);*/
memset(&data,0x00,sizeof(HexLinData));
if(0 !=GetHexLineData(line,&data))
return -1;
if(data.type ==0){
binLen +=data.len;
/*fwrite(data.data,1,data.len,file1);*/
}
}
/*fclose(file);
fclose(file1);*/
pData->len =binLen;
pData->pContent =(BYTE *)malloc(pData->len+1);
if(pData->pContent ==NULL)
return -1;
p =(char *)str;
binLen =0;
len =0;
for(binLen=0;p<str+size;p +=len){
memset(line,0,128);
len =GetLine(p,line);
if(len <0)
break;
memset(&data,0x00,sizeof(HexLinData));
if(0 !=GetHexLineData(line,&data))
return -1;
if(data.type ==0){
memcpy(pData->pContent+binLen,data.data,data.len);
binLen +=data.len;
}
}
return 0;
}
只有一个接口函数:
int ConvertHexToBin(const char *str,HexToBinData *pData);
它的作用是将hex文件流str直接转化为bin文件流,并存储到HexToBinData结构体中,若成功则返回0,失败则返回非0.
分享到:
相关推荐
hex文件与bin文件互相转换工具,hex文件合并工具,hex2bin.py源码
Python实现Keil生成的Hex文件转Bin文件
hex文件转bin文件,包含源代码,将.hex文件拖到hex2bin.exe上即可生成bin文件
C#-hex文件转bin文件
2.hex转换成bin文件使用方法直接把hex文件拖到HEX2BIN.EXE软件上自动生成bin文件 HEX 转 BIN 程序,弄过单片机的人可能都知道,很多编译器都会编译出一种叫HEX 的文件,这好像是Intel定的一个格式,就是把二进制的...
hex文件分析+Qt5制作Hex文件转Bin文件的工具(含源码+工具下载),参考博客:https://blog.csdn.net/weixin_42653531/article/details/103915629
用VS2015编写,可以将HEX文件转成BIN文件,并对地址空缺部分用0xff补齐。
虽然bin转hex功能没加上去,但是可以参看hex文件合并的代码自行处理,对于hex文件读取转换单独的写的一个文件,现在hex文件合并是先把两个hex文件转为bin文件,再把bin文件转为hex文件,所以bin转hex的函数已经提供...
Hex文件转Bin文件的QT程序,简单易用,上传hex文件和上传bin文件路径可见,方便查找 Hex文件不超过256K
C语言实现hex文件转bin文件的函数,增加了空地址补填0xFF功能,增加了bin文件后拼接CRC校验字的功能函数
把HEX2BIN.EXE 复制到c盘根目录下,hex转换成bin文件使用方法直接把hex文件拖到HEX2BIN.EXE软件上自动生成bin文件
压缩文件里是hex格式文件转bin文件的源码,用c语言实现将将hex格式的文件转换成Bin文件。
注意:BIN文件是编程器兼容最好的数据格式,如有HEX软件数据转换保存后的BIN软件数据为0 KB,则源数据本身是BIN文件,只需将源数据扩展名由HEX改为BIN即可,不需本软件转换,如源数据“8M10.hex”导入保存后数据...
可对单片机的bin文件和hex文件等,进行反编辑。
win+R→cmd回车→直接执行hex2bin应用程序。可以将hex文件转换为bin文件。
软件介绍: hex文件转bin文件工具使用非常简单,将.hex文件拖到hex2bin.exe上即可生成bin文件。主程序在bin\Debug目录下,里面有一个测试有的hex文件,使用前可以用来进行测试。
1.C#winform写的小工具,运行需要.NET4.5框架 2.Hex文件转Bin文件
提供两个exe软件 一个国内的一个国外的 国外的使用方法:在命令行中输入 软件名 需要转换文件名 转换后文件名
HEX和BIN文件的区别
1、支持目前的Hex86、Hex386等数据格式到bin文件的转换。 2、支持可选的CRC校验或BCC校验算法。 3、支持无效字符的填充(用以实现在嵌入式系统中的冗余技术,从而保证代码的健壮性)。 4、支持可选的BIN代码空间大小...