转自:http://blog.csdn.net/spdian/article/details/52963467
HEX文件和BIN文件是我们经常碰到的2种文件格式。因为自己也是新手,所以一直对这两个文件懵懵懂懂,不甚了解,最近在做STM32单片机的IAP更新,其中要考虑HEX文件和BIN文件,所以需要学习下这两种文件。下面是最近的我的了解,如有不对地方还请指正。
1. HEX文件是包括地址信息的,而BIN文件格式只包括了数据本身
在烧写或下载HEX文件的时候,一般都不需要用户指定地址,因为HEX文件内部的信息已经包括了地址。而烧写BIN文件的时候,用户是一定需要指定地址信息的。
2. HEX文件格式
HEX文件都是由记录(RECORD)组成的。在HEX文件里面,每一行代表一个记录。以下为记录(Record)的具体格式:
A record (line of text) consists of six fields (parts) that appear in order from left to right:
3. BIN文件格式
对二进制文件而言,其实没有”格式”。文件只是包括了纯粹的二进制数据。
4. HEX文件是用ASCII来表示二进制的数值。例如一般8-BIT的二进制数值0x3F,用ASCII来表示就需要分别表示字符'3'和字符'F',每个字符需要一个BYTE,所以HEX文件需要 > 2倍的空间。
对一个BIN文件而言,你查看文件的大小就可以知道文件包括的数据的实际大小。而对HEX文件而言,你看到的文件 大小并不是实际的数据的大小。一是因为HEX文件是用ASCII来表示数据,二是因为HEX文件本身还包括别的附加信息。
1.分析一下hex文件
HEX格式文件以行为单位,每行由“:”(16进制为:0x3a)开始,以回车键结束(16进制为:0x0d,0x0a)。行内的数据都是由两个字符表示一个16进制字节,比如”01”就表示数0x01;”0a”,就表示0x0a。对于16位的地址,则高位在前低位在后,比如地址0x010a,在HEX格式文件中就表示为字符串”010a”。
下面为HEX文件中的一行,分析一下:
:10000000FF0462FF051EFF0A93FF0572FF0A93FF
“:” 表示一行的开始。
“:” 后的第1,2个字符“10”表示本行包含的数据的长度,这里就是0x10即16个。
第3,4,5,6个字符“0000”表示数据存储的起始地址,这里表示从0x0000地址开始存储16个数据,其中高位地址在前,低位地址在后。
第7,8个字符“00”表示数据的类型。该类型总共有以下几种:
00 ----数据记录
01 ----文件结束记录
02 ----扩展段地址记录
04 ----扩展线性地址记录
这里就是0x00即为普通数据记录。
自后的32个字符FF0462FF051EFF0A93FF0572FF0A93FF就是本行包含的数据,每两个字符表示一个字节数据,总共有16个字节数据跟行首的记录的长度相一致。
最后两个字符BC表示校验码。
再分析一个实际编译出来的hex文件:
第一行为:020000040000FA
“:” 表示一行的开始。
“:” 后的第1,2个字符“02”表示本行包含的数据的长度,这里就是0x02即2个。
第3,4,5,6个字符“0000”表示数据存储的起始地址,这里表示从0x0000地址开始存储2个数据,其中高位地址在前,低位地址在后。
第7,8个字符“04”表示数据的类型。该类型总共有以下几种:
00 ----数据记录
01 ----文件结束记录
02 ----扩展段地址记录
04 ----扩展线性地址记录
这里就是0x04即为扩展线性地址记录。
自后的4个字符0000就是本行包含的数据,每两个字符表示一个字节数据,总共有2个字节数据跟行首的记录的长度相一致。
最后两个字符FA 表示校验码。
每个HEX格式的最后一行都是固定为:
:00000001FF
01表示文件结束记录
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 |
记录类型包括:
'00' Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录
'01' End of FileRecord: 用来标识文件结束,放在文件的最后,标识HEX文件的结尾
'02' Extended Segment Address Record: 用来标识扩展段地址的记录
'04' Extended LinearAddress Record: 用来标识扩展线性地址的记录
4: HEX文件和BIN文件大小有区别, HEX文件是用ASCII来表示二进制的数值。例如一般8-BIT的二进制数值0x3F,用ASCII来表示就需要分别表示字符'3'和字符'F',每个字符需要一个BYTE,所以HEX文件需要> 2倍BIN文件的空间。对一个BIN文件而言,你查看文件的大小就可以知道文件包括的数据的实际大小。而对HEX文件而言,你看到的文件大小并不是实际的数据的大小。一是因为HEX文件是用ASCII来表示数据,二是因为HEX文件本身还包括别的附加信息(:,长度,)。
Bin文件是最纯粹的二进制机器代码,或者说是"顺序格式"。按照assemblycode顺序翻译成binarymachine code,内部没有地址标记。Bin是直接的内存映象表示,二进制文件大小即为文件所包含的数据的实际大小。
举个实际的例子,比如源代码中的字符串“MCU start”,对应在bin文件中就是:
二进制对应的就是:4D 43 55 20 73 74 61 72 74 20 ,用记事本打开显示为MCU start,因为记事本显示的是ASCII码字符。
对应的hex文件为:
比如原来的M 对应二进制是4D,对应到hex中就用34 44 来表示,记事本打开显示为4D
HEX文件转化为BIN文件源程序
Intel HEX文件是记录文本行的ASCII文本文件,在Intel HEX文件中,每一行是一个HEX记录,由十六进制数组成的机器码或者数据常量。Intel HEX文件经常被用于将程序或数据传输存储到ROM、EPROM,大多数编程器和模拟器使用Intel HEX文件。
很多编译器的支持生成HEX格式的烧录文件,尤其是Keil c。但是编程器能够下载的往往是BIN格式,因此HEX转BIN是每个编程器都必须支持的功能。
HEX格式文件以行为单位,每行由“:”(0x3a)开始,以回车键结束(0x0d,0x0a)。行内的数据都是由两个字符表示一个16进制字节,比如”01”就表示数0x01;”0a”,就表示0x0a。对于16位的地址,则高位在前低位在后,比如地址0x010a,在HEX格式文件中就表示为字符串”010a”。下面为HEX文件中的一行:
:10000000FF0462FF051EFF0A93FF0572FF0A93FFBC
“:”表示一行的开始。
“:”后的第1,2个字符“10”表示本行包含的数据的长度,这里就是0x10即16个。
第3,4,5,6个字符“0000”表示数据存储的起始地址,这里表示从0x0000地址开始存储16个数据,其中高位地址在前,低位地址在后。
第7,8个字符“00”表示数据的类型。该类型总共有以下几种:
00 ----数据记录
01 ----文件结束记录
02 ----扩展段地址记录
04 ----扩展线性地址记录
这里就是0x00即为普通数据记录。
自后的32个字符就是本行包含的数据,每两个字符表示一个字节数据,总共有16个字节数据跟行首的记录的长度相一致。
最后两个字符表示校验码。
每个HEX格式的最后一行都是固定为:
:00000001FF
以上的信息其实就足够进行HEX转BIN格式的程序的编写。首先我们只处理数据类型为0x00及0x01的情况。0x02表示对应的存储地址超过了64K,由于我的编程器只针对64K以下的单片机,因此在次不处理,0x04也是如此。
我的编程思路是从文件中一个一个读出字符,根据“:”判断一行的开始,然后每两个字符转换成一个字节,并解释其对应的意义。然后将数据从该行中剥离出来保存到缓冲区中,并最终输出到文件中。
具体程序如下,该程序在VC2005下采用控制台项目编译,需要在release下编译,在debug模式中会提示一个dll文件无法找到,这可能是VC自身的错误。
// hextobin.cpp : 定义控制台应用程序的入口点。
//
一、HEX
Hex文件,一般是指Intel标准的十六进制文件。Intelhex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般编程器均支持生成此种格式文件。如,KEIL下可通过配置相关选项来生成HEX目标文件。
HEX文件由记录(RECORD)组成。在HEX文件里面,每一行代表一个记录。
形如
:BBAAAATTHHHH...HHHHCC
BB:字节个数。
AAAA:数据记录的开始地址,高位在前,低位在后。
TT: Type
00数据记录,用来记录数据。
01记录结束,放在文件末尾,用来标识文件结束。
02用来标识扩展段地址的记录
04扩展地址记录(表示32位地址的前缀)
HHHH:一个字(Word)的数据记录,高字节在前,低字节在后。TT之后共有 BB/2 个字的数据 。
CC: 占据一个Byte的CheckSum
举例分析:
:020000040000FA
:10000400FF00A0E314209FE5001092E5011092E5A3
:00000001FF
第1条记录长度为0x02,LOAD OFFSET为0000,RECTYPE为04,说明该记录为扩展段地址记录。数据为0000,校验和为FA。从这个记录的长度和数据,我们可以计算出基地址为0X0000。后面的数据记录都以此地址为基地址。
第2条记录长度为0x10(16),LOAD OFFSET为0004,RECTYPE为00,说明该记录为数据记录。数据为FF00A0E314209FE5001092E5011092E5,共16个字节,记录的校验和为A3。此时的基地址为0X0000,加上OFFSET,这个记录里的16BYTE的数据的起始地址就是0x0000 + 0x0004 = 0x0004. 其实际的数据只有16个BYTE:FF00A0E314209FE5001092E5011092E5。
第3条记录的长度为00,LOAD OFFSET为0000,TYPE= 01,校验和为FF。类型为01,说明这个是一个END OF FILE RECORD,标识文件的结尾。HEX结束符一般以:00000001FF结尾。
二、BIN
Bin文件是最纯粹的二进制机器代码, 或者说是"顺序格式"。按照assembly code顺序翻译成binary machine code,内部没有地址标记。Bin是直接的内存映象表示,二进制文件大小即为文件所包含的数据的实际大小。
简单总结一下这2种文件格式的区别:
1、HEX文件包含地址信息而BIN文件只包含数据本身,烧写或下载HEX文件时,一般不需要用户指定地址,因为HEX文件内部已经包含了地址信息。烧写BIN文件时则需要用户指定烧录的地址信息。
2、HEX文件是用ASCII码来表示二进制的数值。例如8-BIT的二进制数值0x4E,用ASCII来表示就需要分别表示字符‘4’和字符‘E’,每个字符均需要一个字节,因此HEX文件至少需要2倍BIN文件的空间。
三、Axf
Axf文件由ARM编译器产生,除了包含bin的内容之外,还附加其他调试信息,这些调试信息加在可执行的二进制数据之前。调试时这些调试信息不会下载到RAM中,真正下载到RAM中的信息仅仅是可执行代码。因此,如果ram的大小小于axf文件的大小,程序是完全有可能在ram中调试的,只要axf除去调试信息后文件大小小于ram的大小即可。
调试信息有以下功用:
1、 可将源代码包括注释夹在反汇编代码中,这样我们可随时切换到源代码中进行调试。
2、 我们还可以对程序中的函数调用情况进行跟踪(通过Watch & Call Stack Window查看)。
3、对变量进行跟踪(利用Watch & Call Stack Window)。
调试信息虽然有用,但程序功能实现后,在目标文件和库中减少调试信息却是非常有益的。减少调试信息可减少目标文件和库大小、加快链接速度、减小最终镜象代码。以下几种方法可用来减少每个源文件产生的调试信息:
1、避免在头文件中条件性使用#define,链接器不能移除共用的调试部分,除非这些部分是完全一样的。
2、更改C/C++源文件,使#included包含的所有头文件有相同顺序。
3、尽量使用数量较多的小头文件而不是较大的单一头文件,这有利于链接器获取更多的通用块。
4、程序中最好只包含必须用到的头文件。避免重复包含头文件,可使用编译器选项--remarks来产生警告信息;
5、使用编译命令行选项--no_debug_macros,从调试表中丢弃预处理宏定义。
四、ELF
ELF(Executableand linking format)文件是x86 Linux系统下的一种常用目标文件(objectfile)格式,有三种主要类型:
(1)适于连接的可重定位文件(relocatablefile),可与其它目标文件一起创建可执行文件和共享目标文件。
(2)适于执行的可执行文件(executable file),用于提供程序的进程映像,加载到内存执行。
(3)共享目标文件(shared object file),连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。
ELF文件格式比较复杂。
小结:可由elf文件转化为hex和bin两种文件,hex也可以直接转换为bin文件,但是bin要转化为hex文件必须要给定一个基地址。而hex和bin不能转化为elf文件,因为elf的信息量要大。Axf文件可以转化为bin文件,KEIL下可用以下命令fromelf -nodebug xx.axf -bin xx.bin即可。