1、 文档目标
解析MDK生成的HEX文件中的各个数据所代表的内容是什么,了解HEX文件中各个数据段的组成。并且通过计算校验和的结果确认hex文件是否正确。
2、 问题场景
在项目开发过程中通常会根据项目需求去生成对应工程的HEX文件进行使用。而通常情况下,工程师拿到Hex文件都是用于烧录或者调试使用的。那么其实对于Hex文件中各个数据段代表的意义都不太清楚(如图2-1),每个数据的得到方式也不清楚。

图 2-1
3、软硬件环境
1)、软件版本:Keil MDK 5.38a
2)、电脑环境:Windows 11
3)、外设硬件:无
4、解决方法
1)、首先,Intel HEX文件是一个ASCII文本文件,其中的文本行遵循Intel HEX文件格式。Intel 十六进制文件中的每一行包含一条十六进制记录。这些记录由表示机器语言代码和/或常量数据的十六进制数组成。Intel十六进制文件通常用于传输将存储在ROM或EPROM中的程序和数据。大多数EPROM程序员或模拟器可以使用Intel十六进制文件。
2)Hex文件的数据格式为:“:LLAAAATTDDDDDDDD...DDCC”
(1)“:”:表示开头,每一行数据都会用冒号进行开头,表示一个新的内存地址数据开头
(2)“LL”:表示数据长度,L是4位的十六进制,LL表示一个字节。
(3)“AAAA”:表示偏移量,基于起始地址的偏移量是多少
(4)“TT”:表示这一行数据类型或数据标识是什么。
a) 00:表示数据标识;
b) 01:表示文件结束标识,通常的hex文件的最后一行数据中;
c) 02:表示扩展段的地址;
d) 04:表示线性地址;
e) 05:表示线性起始地址
(5)“DDD.....DDD”:这里就表示数据。每一个数字都是占4位,2个数字就是一个字节。
(6)“CC”:表示校验码。校验码是通过下面的公式进行计算出来的。
CheckSum = 0x100 - (Sum & 0xFF)
其中Sum是由这一行的所有字节进行相加所得,Sum与上0xFF后即保留Sum的后8位数据,然后再减去0x100。
3)例子:
(1)、HEX文件的开头第一行(如图4-3-1):“:020000040040BA”
(a)、“:”:表示开头
(b)、“02”:表示数据长度,02是十六进制,单位的byte,即表示这一行的数据长度是2个字节。
(c)、“0000”:基于起始地址的偏移量是0x0000
(d)、“04”:表示这一行是线性地址
(e)、“0040”:这里就表示段地址信息。每一个数字都是占4位,这一行中4个数字,则16位即2bytes,和前面的第二部分的“10”进行对应。地址是0x0400000,是内存的起始地址即基地址
(f)、“BA”:表示校验码。校验和的计算过程如下:
Sum = 0x02+0x00+0x00+0x04+0x00+0x40=0x46
CheckSum = 0x100-0x46&0xFF=0x100-0x46=0xBA

4-3-1
(2)、HEX文件的中间的数据行(如图4-3-2):“:1000A0009B0340009B0340009B0340009B034000D8”
(a)、“:”:表示开头
(b)、“10”:表示数据长度,这一行的数据长度是16个字节。
(c)、“00A0”:基于起始地址的偏移量是0x00A0
(d)、“00”:表示这一行是数据
(e)、“9B03......4000”:这里就表示数据。每一个数字都是占4位,这一行中32个数字,则128位即16bytes,和前面的第二部分的“10”进行对应。
(f)、“D8”:表示校验码。校验和的计算过程如下:
Sum = 0x10+0x00+0xA0+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00=0x428
CheckSum = 0x100-0x428&0xFF=0x100-0x28=0xD8

图 4-3-2
(3)、Hex文件的倒数第二行数据(如图4-3-3-2):“:040000050040014175”
(a)、“:”:表示开头
(b)、“04”:表示数据长度,这一行的数据长度是4个字节。
(c)、“0000”:基于起始地址的偏移量是0x0000,这个偏移地址是无效数据,无需关注
(d)、“05”:表示这一行是线性起始地址
(e)、“00400141”:这里就表示线性起始地址。地址为0x00400141,是指令集执行的起始地址,这个地址指向的是__scatterload函数,该函数用于将程序代码和数据从链接文件中加载到内存中,是由编译器提供的。(如图4-3-3-1)

图4-3-3-1
(f)、“75”:表示校验码。校验和的计算过程如下:
Sum = 0x04+0x00+0x00+0x05+0x00+0x40+0x01+0x41= =0x8B
CheckSum = 0x100-0x428&0xFF=0x100-0x8B=0x75

图4-3-3-2
(4)、Hex文件的最后一行数据:“:00000001FF”
(a)、“:”:表示开头
(b)、“00”:表示数据长度。
(c)、“0000”:基于起始地址的偏移量是0x0000,这个偏移地址是无效数据,无需关注
(d)、“01”:表示文件结束标识
(e)、“FF”:校验和

图4-3-4