目录
2.3 Text line terminators文本行终止符
优质博文推荐阅读(单击下方链接,即可跳转):
1 什么是Intel Hex
Intel Hex格式最初于1973年为Intel的Intellec Microcomputer Development Systems (MDS)设计,以便从纸带上加载和执行程序。它还被用于向Intel指定memory内容,以便生产ROM。1973年,Intel的“软件小组”仅由Bill Byerly和Ken Burget以及作为外部顾问的Gary Kildall组成。从1975年开始,该格式被MCS系列II ISIS-II系统所利用,使用文件扩展名HEX。后来许多PROM和EPROM编程设备接受了这种格式。
Intel Hex文件格式是一种以ASCII文本形式传达二进制的十六进制值信息的文件格式。它通常用于对Microcontroller微控制器、EPROM和其他类型的可编程逻辑器件和硬件仿真器进行编程。在一个典型的应用程序中,compiler编译器或assembler汇编器将程序的源代码(例如C或汇编语言)转换为machine code机器码,并将其输出到HEX文件中。有些人还将其用作容纳流数据包的容器格式。由此产生的文件常用的扩展名是.HEX或.H86。然后,programmer编程器读取HEX文件,以将机器码写入PROM中,或传输到目标系统进行加载和执行。
2 Intel Hex的格式
2.1 Intel Hex的Record结构
一个Intel Hex文件由一系列ASCII text record组成,一个record的长度将小于或等于92字符。这些record从左到右有以下结构:
: |
Byte Count |
Address |
Type |
Data |
Checksum |
举例:
1. Start code:一个ASCII冒号“:”(ASCII 0x3A)字符。在一条record中,这个符号之前的所有字符都应该被忽略。事实上,该规范的早期版本甚至要求在第一条record之前和最后一条record之后,至少25个NUL字符。然而,由于这是规范中鲜为人知的部分,并非所有编写的软件都能正确的处理这个问题。它允许在同一文件(甚至同一行)中存储其他相关信息,这是各种软件开发工具用来存储符号表或附加注释的设施,以及使用其他字符作为Start code的第三方扩展,如Keil的数字'0',Mostek的'$',或TDL的'!'、'@'、'#'、'\'、'&'和';'。按照惯例,“//”经常用于注释。这些扩展都不能包含任何“:”字符作为有效负载的一部分。
2. Byte count:两个十六进制数字(既,1个字节),表示Data段中的字节数。最大字节计数为255(0xFF)。8(0x08),16(0x10)和32(0x20)是常用的data byte数。
3. Address:四个十六进制数字(既,2个字节),表示Data段的16位起始memory地址偏移量。Data的物理地址是通过将此偏移量添加到先前建立的base address基址来计算的,从而允许memory寻址超过16位地址的64千字节限制。基址默认为零,可以通过各种类型的record进行更改。Base address和address offset始终表示为big endian大端值。
4. Record type(参见下文的record type):两个十六进制数字(既,1个字节),00到05,定义了Data段的含义。
5. Data:由2n个十六进制数字表示的数据组成的序列(既,n个字节)。某些record省略此Data段(n等于零)。data byte的含义和解释取决于应用程序。(4-bit data必须存储在字节的下半部分或上半部分,也就是说,一个字节只容纳一个可寻址的数据项)。
6. Checksum:两个十六进制数字(既,1个字节),一个计算值,可用于验证record是否有错误。一个record的checksum字节是checksum之前record中所有解码的字节值之和的least significant byte (LSB)的二进制补码(按位取反,再加1)。
2.1.1 “Record type记录类型”的说明
Intel HEX有六种标准record type:
Hex code |
Record type |
Description |
Example |
00 |
Data 数据 |
byte count规定了record中的data byte数量。本例有0B(11个)data byte。data的16位起始地址(本例中从0010起始的地址)和data(61,64,64,72,65,73,73,20,67,61,70)。 |
:0B0010006164647265737320676170A7 |
01 |
End Of File 文件的结束 |
必须在Hex文件的最后一条record中准确出现一次。byte count始终为00,address段为0000,data段被省略。 |
:00000001FF |
02 |
Extended Segment Address 扩展段地址 |
byte count始终为02,address段被忽略(通常为0000),data段包含一个16位段基地址。这个地址乘以16,然后加到每个后续的data record address上,形成数据的起始地址。这允许寻址到一兆字节(1048576字节)的地址空间。 |
:020000021200EA |
03 |
Start Segment Address 起始段地址 |
对于80x86处理器,指定起始执行地址。byte count始终为04,address段为0000,前两个data byte为CS值,后两个为IP值。执行应该从这个地址开始。 |
:0400000300003800C1 |
04 |
Extended Linear Address 扩展的线性地址 |
允许32位寻址(最高可达4GiB)。byte count始终为02,address段被忽略(通常为0000)。两个data byte(big endian)为所有后续的00型record指定32位绝对地址的上16位;这些上地址位适用于下一个04型record。00型record的绝对地址是由最近的04型record的高16位地址位和00型record的低16位地址位组合而成。如果一个00型record前面没有任何04型record,那么它的上16位地址位默认为0000。 |
:020000040800F2 |
05 |
Start Linear Address 起始线性地址 |
byte count始终为04,address段为0000。四个data byte代表一个32位的地址值(big-endian)。在支持它的CPU的情况下,这个32位地址是执行开始的地址。 |
:04000005000000CD2A |
其他record type已被用于变体,包括Wayne和Layne的06,BBC/Micro:bit Educational Foundation的0A、0B、0C、0D和0E,以及Digital Research的81、82、83、84、85、86、87和88。
2.1.2 “Record length记录长度”的说明
不同于Motorola S-record(S19/SREC/mot/SX)文件,Intel Hex文件中的record count仅用来表征Data段的长度,一个字节的record count最大为255,而8(0x08),16(0x10)和32(0x20)是常用的data byte数。
一个record的总长度最大为521个字符:
- Start code为1个ASCII字符(2个十六进制数字);
- Byte count为2个十六进制数字;
- Address为4个十六进制数字;
- Record type为2个十六进制数字;
- Data最大255*2个十六进制数字;
- Checksum为2个十六进制数字。
2.1.3 如何计算“Checksum校验和”
下面的record为例,来介绍Checksum的计算:
:208800000A3400090A34000A0A34000B0A34000C0A34000D0A34000E0A34000F0A34001004
Checksum计算过程:
1.对所有Byte count + Address + Record type +Data十六进制字节求和:
20 + 88 + 00 + 00 + 0A + 34 + 00 + 09 + 0A + 34 + 00 + 0A + 0A + 34 + 00 + 0B + 0A + 34 + 00 + 0C + 0A + 34 + 00 + 0D + 0A + 34 + 00 + 0E + 0A + 34 + 00 + 0F + 0A + 34 + 00 + 10 = 2FC。
2.保留最后一个LSB字节,即十六进制字节FC,其二进制为1111 1100。
3. LSB的二进制补码:取反为0000 0011,再加1后为0000 0100,即十六进制字节04。或checksum=FF - FC + 1= 04。
2.2 Record order记录顺序
当生成一个Hex文件时,需要按照一定的record order将数据和指令写入文件中。下面是Hex文件的record order:
1.扩展线性地址记录(Record type = 04 Extended Linear Address Record)
这是Hex文件的第一条record,用于设置程序的起始地址。该record的地址段必须设置为0,数据段包含扩展线性地址的高16位。这个record只有一个,并且是可选的。
2.扩展段地址记录(Record type = 02 Extended Segment Address Record)
这是Hex文件的第二条record,用于设置程序的起始地址。该record的地址段必须设置为0,数据段包含扩展段地址的高16位。这个record只有一个,并且是可选的。
3.数据记录(Record type = 00 Data Record)
数据记录包含程序的代码和数据。每个数据记录包含一个地址和一组数据。数据记录的地址必须按照从小到大的顺序排列。
4.结束记录(Record type = 01 End of File Record)
结束记录表示Hex文件的结束。该record的地址段必须设置为0,数据段为空。
在Hex文件中,扩展线性地址记录和扩展段地址记录是可选的,因为它们只在程序起始地址超过16位时才需要使用。数据记录是Hex文件中最常见的Record type,它包含程序的代码和数据。结束记录表示Hex文件的结束,并且必须出现在Hex文件的末尾。
需要注意的是,record order必须按照上述顺序进行,否则程序可能无法正常运行或数据丢失。因此,在生成Hex文件时,必须按照规定的record order将record写入文件中,以确保程序的正确性。
举例:
:0200000400E01A
:208800000A3400090A34000A0A34000B0A34000C0A34000D0A34000E0A34000F0A34001004
:208820000A3400110A3400120A3400130A3400140A3400150A3400160A3400170A340018A4
......
:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
:0200000400E119
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
......
:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
:0200000400E218
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
......
:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
:0200000400E317
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
......
:20FFC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41
:20FFE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21
:0200000400E416
......
......
:20BF600092FEE1872737CCFFFF6B82EE806CE018EDE0140E4B0115EE8834EE82EDE0143562
:20BF8000C60B874AB21BFE1B84044411EC803BC7874ABA56FE1B826C851827FF31EC851B66
:02BFA0008A0A0B
:00000001FF
2.3 Text line terminators文本行终止符
Intel HEX record通常由一个或多个ASCII行终止符分隔,以便每条record单独显示在一个文本行上。这可以直观地分隔record来增强可读性,同时也提供了record之间的填充,可以用来提高机器的解析效率。但是,line termination character行终止符是可选的,因为“:”用于检测record的开始。创建HEX record的程序通常使用符合其操作系统约定的行终止符。例如,Linux程序使用一个LF(换行,十六进制值为0A)字符来终止行,而Windows程序则使用一个CR(回车,十六进制值为0D),后面跟着一个LF。
Intel HEX由ASCII文本行组成,这些文本由line feed换行符和/或carriage return回车符分隔。每个文本行都包含编码多个二进制数的十六进制字符。二进制数可以表示data、memory address或其他值,具体取决于它们在行中的位置以及行的类型和长度。每个文本行称为一条record。
3 Hex文件的Variants变体
您可能会遇到以下几种类型的hex文件:
- Intel HEX文件:这是最常见的hex文件格式,由Intel公司推出,用于将二进制数据转换成文本格式。这种格式的hex文件通常用于嵌入式系统的程序下载、烧录和调试。
- Motorola HEX文件:这种格式的hex文件通常用于旧版本的嵌入式系统和一些老式的烧录器。它与Intel HEX文件格式有些不同,但基本上还是将二进制数据转换为文本格式。
Motorola HEX文件的格式如下:
:BBAAAATT[DDDDDDDD...]CC
其中:
::冒号是记录起始的标志。
BB:表示该记录中数据的长度,以十六进制表示。这个长度不包括起始地址、记录类型和校验和,只包括数据部分的长度。
AAAA:表示数据的起始地址,以十六进制表示。这个地址是一个16位地址,也就是说,可以表示64KB的内存。
TT:表示该记录的类型,以十六进制表示。记录类型有四种:
00:数据记录,表示该记录包含数据。
01:结束记录,表示该文件的结束。
02:扩展线性地址记录,表示该记录包含一个扩展线性地址,用于超过64KB的内存空间。
04:扩展段地址记录,表示该记录包含一个扩展段地址,用于超过64KB的内存空间。
DDDDDDDD...:表示该记录中的数据,以十六进制表示。数据的长度由BB指定。
CC:表示校验和,以十六进制表示。校验和是整个记录中除了冒号以外的所有数据的累加和的反码加1。
- TI-TXT文件:这种格式的文件由德州仪器公司开发,通常用于烧录 TI 微控制器和数字信号处理器(DSP)。
TI-TXT文件的格式如下:
HDR
<length> <address> <type>
<D0> <D1> <D2> ... <DN> <checksum>
<CR><LF>
其中:
HDR:是文件头,指示该行是一个数据记录。
<length>:是数据的长度,以十六进制表示。
<address>:是数据在内存中的地址,以十六进制表示。
<type>:是数据的类型,以十六进制表示。类型有以下几种:
00:数据记录。
01:文件结束记录。
02:扩展段地址记录。
03:起始段地址记录。
04:扩展线性地址记录。
05:起始线性地址记录。
<D0> <D1> <D2> ... <DN>:是数据,以十六进制表示。
<checksum>:是校验和,以十六进制表示。校验和是数据记录中所有字节的和取反加1。
<CR><LF>:表示一个回车换行符,用于分隔每一行数据记录。
- S-Record文件:这是一种通用的记录格式(S19/SREC/mot/SX),由Motorola公司推出,可以用于表示不同类型的二进制数据。S-Record文件通常用于嵌入式系统的程序下载和烧录。
无论是哪种类型的hex文件,它们都包含了可执行程序的二进制数据和相关的元数据信息。在程序下载和烧录过程中,这些文件可以帮助确保程序正确地加载到嵌入式系统中。
部分内容摘自:
Intel Hex - *https://en.wikipedia.org/wiki/Intel_HEX
结尾
获取更多“汽车电子资讯”和“工具链使用”,
请关注CSDN博客“汽车电子助手”,做您的好助手。