Hex文件分析

本文介绍了Intel HEX和Motorola SREC两种不同的十六进制文件格式。Intel HEX文件由ASCII文本组成,每行包含数据记录、地址、类型等信息,主要用于存储ROM或EPROM中的程序和数据。SREC(S-record)由摩托罗拉创建,同样用于微控制器编程,其结构包括记录类型、字节数、地址、数据和校验域。两种格式在编程和数据传输中发挥着重要作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hex格式文件有两种,一种是Intel的Intel HEX,另一种是Motorola(摩托罗拉)的SREC(又称MOT)。

Intel HEX

IntelHEX文件是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个ASCII HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。Intel HEX文件通常用于传输将被存于ROM或者EPROM中的程序和数据。

//Intel HEX格式

//行数据

:   10   0000  00  C2020000C2020000C2020000C2020000  E0


iHex文件一行为单位,分为6个部分。

第一部分是iHEX文件的起始格式,文件一开始应该是一个冒号作为起点;

第二部分的两码所代表的是该行总共具备多少个字节的数据,是第五部分包含多少字节的数据;以本行为例,应该有16个字节,因为10H换算成十进制应该是16;

第三部分的四码所代表的地址域是放置数据的开始位置,本行的数据应该是放置在0000H~000FH 这段地址中;

第四部分的两码是检查码,所代表的是该行数据类型。数据类型有:0x00、0x01、0x02、0x03、0x04、0x05。

'00'Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录

'01'End of File Record:用来标识文件结束,放在文件的最后,标识HEX文件的结尾

'02'Extended Segment Address Record:用来标识扩展段地址的记录

'03'Start Segment Address Record:开始段地址记录

'04'Extended Linear Address Record:用来标识扩展线性地址的记录

'05'Start Linear Address Record:开始线性地址记录

 其中:

'02'类型数据区的地址信息需要左移4位得到'基'地址。

'03'类型数据区的地址信息就是'基'地址。

'04'类型数据区的地址信息需要左移16位得到'基'地址。

         :  02   0000   04  0060    9A

         '基'地址是(0x0060<<16)=0x00600000,后面的数据记录都以这个地址为基地址,知道下一个扩展线性地址。

'05'类型数据区的地址信息就是'基'地址。

对于后面的数据记录,计算地址的时候,都是以这些“基”地址为基础的。

 

(扩展线性地址记录也叫32位地址记录或HEX386记录。这些记录包含数据地址的高16位)

(扩展段地址记录也叫HEX86记录,它包括4-19位数据地址段)

 

第五部分则为数据存放区,本行总共32码16个字节

第六部分为校验值,校验值是一种标准的校验码,把它加在每一行的最后,可以使每一行所有的十六进制值(两个为一组),加总后所得到最后两位十六进制码应为00H。

每个HEX格式的最后一行都是固定为::00000001FF

 

Elf文件可以使用命令“objcopy -O ihex Test.elf Test.ihex”转换成Intel Hex文件。


 SREC

SREC全称Motorola S-record,一种文件格式,由摩托罗拉创建的,该文件使用ASCII HEX文件格式表达二进制信息。这种格式也叫做SRECORD, SREC, S19, S28, S37。通常用于微控制器编程,EPROMs和其他可编程的逻辑器件。在通常的应用中,编译器或汇编器将程序的源代码(如C语言或汇编语言)转换成机器代码,并将其输出到一个HEX文件。然后这个HEX文件被程序员烧写到ROM中,或者转移到目标系统用于装载和执行。

//SREC格式

//第一行数据

S0  0F  0000     636B3631302D6C2E73686578          0C

//行数据

S2  08  010000   FFFFFFFF                          FA

S3  15  08640000 6C0264086C0264086C0264086C026408  16

S5  03  0002                                        FA

S7  05  08640214                                     78


SREC文件一行为单位,分为5个部分。分别是记录类型域、字节数域、地址域、数据域、校验域。

第一部分类型域是SREC文件的起始标志,代表该行的类型,必须已S开始,值可以是从S0到S9;

类型

作用

(Record Purpose)

地址域范围

(AddressField)

是否有数据域

描述

S0

文件头标识记录

16-bit,地址域必须是“0000”

此记录包含表示为一系列的十六进制数字对供应商特定的ASCII文本。可以是以下信息的混合:文件/模块名称,版本/版本号,日期/时间,产品名称,供应商名称,PCB上的内存标志,版权声明。

S1

数据记录

16-bit

该记录的地址域16-bit,数据域=字节数域的值-3

S2

数据记录

24-bit

该记录的地址域24-bit,数据域=字节数域的值-4

S3

数据记录

32-bit

该记录的地址域32-bit,数据域=字节数域的值-5

S4

保留

S5

统计数据个数的记录

16-bit

该记录用于统计之前的数据记录(S1、S2、S3)的个数。最大值为0xFFFF,超过了使用S6

S6

统计数据个数的记录

24-bit

该记录用于统计之前的数据记录(S1、S2、S3)的个数。最大值为0xFFFFFF,小于0xFFFF使用S5。该值目前还不确定是否正式的。

S7

运行记录

32-bit

该记录用于记录程序启动的位置

S8

运行记录

24bit

该记录用于记录程序启动的位置

S9

运行记录

16bit

该记录用于记录程序启动的位置

PS:HEX文件每行是ASCII HEX,因此一个字符占4-bit。

 

第二部分字节数域是每行记录的长度,地址域、数据域、校验域三个域的长度,单位为字节数。

第三部分地址域,该域的长度取决于第一部分类型域。

第四部分数据域,该自动长度=字节数域的值-地址域长度-1(校验域长度)

第五部分校验域,该域长度为1byte(16-bit),校验方法是:除了类型域的值其他十六进制值每两个一组相加结果末两位为0xFF。

 

Elf文件可以使用命令“objcopy -O srec Test.elf Test.srec”转换成SREC Hex文件。




### 解析 Hex 文件的方法与工具 #### 工具介绍 Hex 文件解析可以通过多种方式进行,具体取决于需求场景以及使用的开发环境。以下是几种常见的工具及其功能: 1. **Hexview** Hexview 是一款强大的工具,专门设计用于处理不同格式的二进制文件,包括 hex、srec bin 等[^2]。它不仅提供图形化界面(GUI),还支持命令行操作,方便开发者集成到自动化脚本中。通过 Hexview,用户可以轻松实现以下目标: - 查看编辑 hex 文件的内容。 - 将 hex 文件转换为其他格式(如 bin 或 s19)。 - 提取特定地址范围的数据。 2. **CAPL 编程语言** CAPL(Communication Access Programming Language)是一种嵌入式系统的编程语言,常用于 CANoe 软件环境中。如果需要在 CAN 总线通信上下文中解析 hex 文件,则可以利用 CAPL 实现自定义逻辑[^1]。例如,读取 Intel HEX 文件并将其内容加载到内存映射区域中以便进一步分析或执行。 #### 手动解析流程 对于不依赖第三方软件的情况,手动编写代码来解析 hex 文件也是一种可行方案。以下是基于 Python 的简单示例,展示如何解析标准 Intel HEX 格式的文件: ```python def parse_hex_file(file_path): with open(file_path, 'r') as file: lines = file.readlines() result = [] for line in lines: if not line.startswith(':'): continue # 非法行跳过 byte_count = int(line[1:3], 16) # 字节数 address = int(line[3:7], 16) # 地址 record_type = int(line[7:9], 16) # 记录类型 (00=数据, 01=EOF) if record_type != 0: # 只关心数据记录 break data = [int(line[i:i+2], 16) for i in range(9, 9 + 2 * byte_count, 2)] # 数据部分提取 checksum = sum([byte_count] + [(address >> 8), (address & 0xFF), [record_type]] + data) % 256 # 校验计算 expected_checksum = int(line[-3:-1], 16) # 获取期望校验值 if checksum != expected_checksum: # 校验失败提示错误 raise ValueError(f"Checksum error at {line}") result.extend(data) return result ``` 此函数实现了基本的 Intel HEX 文件解析逻辑,并验证每条记录的有效性[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值