深入解析Intel HEX文件格式

Intel HEX文件格式是一种用于表示二进制数据的ASCII文本格式,广泛应用于嵌入式系统的固件存储和传输。

1. Intel HEX文件格式简介

Intel HEX文件格式是一种将二进制数据转换为ASCII文本的格式,适用于8位、16位和32位微处理器。它的主要优点是可以将二进制数据存储在非二进制介质(如纸带、穿孔卡片)上,并且可以通过CRT终端或行式打印机显示。

  • ASCII表示:每个字节的二进制值被转换为两个ASCII字符。例如,二进制值00111111(十六进制3F)被表示为ASCII字符'3''F'
  • 记录结构:HEX文件由多个记录组成,每个记录包含记录类型、长度、地址、数据和校验和。

2. HEX文件记录格式

每个HEX记录由以下字段组成:

字段名长度描述
RECORD MARK1字节记录起始标志,固定为ASCII字符':'(十六进制03AH)。
RECLEN1字节数据字段的长度(以字节为单位),最大值为FF(255)。
LOAD OFFSET2字节数据加载的起始偏移地址,仅用于数据记录。
RECTYP1字节记录类型,用于解释记录的内容。
INFO/DATA可变长度数据字段,包含实际的数据字节。
CHKSUM1字节校验和,用于验证记录的有效性。

3. 记录类型

Intel HEX文件定义了六种记录类型:

  1. 数据记录(00

    • 包含实际的数据字节。
    • 用于将数据加载到内存中。
  2. 文件结束记录(01

    • 表示HEX文件的结束。
    • 必须出现在文件的最后。
  3. 扩展段地址记录(02

    • 用于16位或32位格式,定义段基地址的高16位。
    • 影响后续数据记录的地址计算。
  4. 起始段地址记录(03

    • 用于16位或32位格式,定义代码的起始执行地址(CS和IP寄存器)。
  5. 扩展线性地址记录(04

    • 仅用于32位格式,定义线性基地址的高16位。
    • 影响后续数据记录的地址计算。
  6. 起始线性地址记录(05

    • 仅用于32位格式,定义代码的起始执行地址(EIP寄存器)。

4. 地址计算

  • 线性地址(32位格式)

    • 绝对地址 = 线性基地址(LBA) + 数据记录的偏移地址(DRLO) + 数据字节索引(DRI)。
    • 线性基地址由扩展线性地址记录定义。
  • 段地址(16位格式)

    • 绝对地址 = 段基地址(SBA) + (数据记录的偏移地址(DRLO) + 数据字节索引(DRI)) MOD 64K。
    • 段基地址由扩展段地址记录定义。

地址计算示例

在Intel HEX文件中,地址计算可以分为线性地址和段地址两种格式。以下是几个示例,帮助读者理解如何计算绝对地址。

示例1:线性地址(32位格式)

假设我们有以下Intel HEX文件记录:

:020000040001F9
:10000000112233445566778899AABBCCDDEEFF00F0
  1. 扩展线性地址记录:

    :020000040001F9
    
    • 字节数:02(2字节)
    • 地址:0000
    • 记录类型:04(扩展线性地址记录)
    • 数据:0001(线性基地址)
    • 校验和:F9

    线性基地址(LBA) = 0x0001 << 16 = 0x00010000

  2. 数据记录:

    :10000000112233445566778899AABBCCDDEEFF00F0
    
    • 字节数:10(16字节)
    • 地址:0000
    • 记录类型:00(数据记录)
    • 数据:112233445566778899AABBCCDDEEFF00
    • 校验和:F0

    绝对地址计算:

    • 数据字节索引(DRI) = 0, 1, 2, …, 15
    • 绝对地址 = 线性基地址(LBA) + 数据记录的偏移地址(DRLO) + 数据字节索引(DRI)
    • 绝对地址 = 0x00010000 + 0x0000 + DRI

    具体地址和数据:

    0x00010000: 11
    0x00010001: 22
    0x00010002: 33
    0x00010003: 44
    0x00010004: 55
    0x00010005: 66
    0x00010006: 77
    0x00010007: 88
    0x00010008: 99
    0x00010009: AA
    0x0001000A: BB
    0x0001000B: CC
    0x0001000C: DD
    0x0001000D: EE
    0x0001000E: FF
    0x0001000F: 00
    
示例2:段地址(16位格式)

假设我们有以下Intel HEX文件记录:

:020000021000EC
:10000000112233445566778899AABBCCDDEEFF00F0
  1. 扩展段地址记录:

    :020000021000EC
    
    • 字节数:02(2字节)
    • 地址:0000
    • 记录类型:02(扩展段地址记录)
    • 数据:1000(段基地址)
    • 校验和:EC

    段基地址(SBA) = 0x1000 << 4 = 0x10000

  2. 数据记录:

    :10000000112233445566778899AABBCCDDEEFF00F0
    
    • 字节数:10(16字节)
    • 地址:0000
    • 记录类型:00(数据记录)
    • 数据:112233445566778899AABBCCDDEEFF00
    • 校验和:F0

    绝对地址计算:

    • 数据字节索引(DRI) = 0, 1, 2, …, 15
    • 绝对地址 = 段基地址(SBA) + (数据记录的偏移地址(DRLO) + 数据字节索引(DRI)) MOD 64K
    • 绝对地址 = 0x10000 + (0x0000 + DRI) MOD 64K

    具体地址和数据:

    0x10000: 11
    0x10001: 22
    0x10002: 33
    0x10003: 44
    0x10004: 55
    0x10005: 66
    0x10006: 77
    0x10007: 88
    0x10008: 99
    0x10009: AA
    0x1000A: BB
    0x1000B: CC
    0x1000C: DD
    0x1000D: EE
    0x1000E: FF
    0x1000F: 00
    

通过上述示例,我们可以看到如何计算Intel HEX文件中线性地址和段地址的绝对地址。希望这些示例能够帮助读者更好地理解Intel HEX文件的地址计算方法。

5. 校验和计算

每个记录的校验和是记录中所有字节(从RECLENINFO/DATA字段)的二进制和的补码。校验和的计算公式如下:

校验和 = 0xFF - (所有字节的和 MOD 0xFF)

校验和字段的值应使得整个记录的所有字节(包括校验和)的和为0

6. 示例解析

以下是一个简单的HEX文件示例:

:10010000214601360121470136007EFE09D2190140
:00000001FF
  • 第一条记录

    • RECORD MARK:
    • RECLEN10(16字节)。
    • LOAD OFFSET0100
    • RECTYP00(数据记录)。
    • DATA214601360121470136007EFE09D21901
    • CHKSUM40
  • 第二条记录

    • RECORD MARK:
    • RECLEN00
    • LOAD OFFSET0000
    • RECTYP01(文件结束记录)。
    • CHKSUMFF

Intel HEX文件的用途

Intel HEX文件广泛应用于嵌入式系统开发中,主要用于以下几个方面:

  1. 程序代码加载:将编译后的程序代码存储在Intel HEX文件中,通过编程器或其他工具将代码加载到微控制器或嵌入式设备中。
  2. 配置数据存储:将设备的配置数据存储在Intel HEX文件中,方便设备初始化和配置。
  3. 固件升级:通过Intel HEX文件进行固件升级,将新版本的固件加载到设备中。

生成和解析Intel HEX文件

生成Intel HEX文件

在嵌入式系统开发中,编译器通常会提供生成Intel HEX文件的选项。例如,使用GCC编译器可以通过以下命令生成Intel HEX文件:

avr-gcc -mmcu=atmega328p -o main.elf main.c
avr-objcopy -O ihex main.elf main.hex

解析Intel HEX文件

解析Intel HEX文件可以使用多种编程语言实现,以下是一个使用Python解析Intel HEX文件的示例:

def parse_hex_line(line):
    if line[0] != ':':
        raise ValueError("Invalid start code")
    
    byte_count = int(line[1:3], 16)
    address = int(line[3:7], 16)
    record_type = int(line[7:9], 16)
    data = line[9:9 + byte_count * 2]
    checksum = int(line[9 + byte_count * 2:11 + byte_count * 2], 16)
    
    return byte_count, address, record_type, data, checksum

def verify_checksum(line):
    total = 0
    for i in range(1, len(line) - 2, 2):
        total += int(line[i:i + 2], 16)
    total = (total & 0xFF) ^ 0xFF
    return total == int(line[-2:], 16)

def parse_hex_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            line = line.strip()
            if not verify_checksum(line):
                raise ValueError("Checksum error")
            byte_count, address, record_type, data, checksum = parse_hex_line(line)
            print(f"Byte Count: {byte_count}, Address: {address:04X}, Record Type: {record_type}, Data: {data}, Checksum: {checksum:02X}")

# 示例使用
parse_hex_file('example.hex')

通过上述代码,我们可以解析Intel HEX文件的每一行记录,并验证校验和的正确性。

总结

Intel HEX文件是一种常见的文件格式,用于存储和传输二进制数据。它广泛应用于嵌入式系统开发中,用于程序代码加载、配置数据存储和固件升级等场景。本文详细讲解了Intel HEX文件的结构和用途,并结合实例深入分析了如何生成和解析Intel HEX文件。希望本文的讲解和实例分析能够帮助读者深入理解Intel HEX文件格式,并在实际开发中灵活运用。

参考

  • Intel Hexadecimal Object File Format Specification(本文翻译自该文档)。
  • 相关嵌入式系统开发文档和工具手册。

希望本文能帮助你更好地理解Intel HEX文件格式!如果你有任何问题或建议,欢迎在评论区留言。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

v0.8.0: 去掉“直接Hex文件编辑”功能的128K字节限制(其他功能仍然有128KB限制) v0.7.0: 一些小的调整 V0.6.1: 调整另存对话框,去掉无效选项 V0.6.0: 加入文件拖放功能。 V0.5.5:修正建立新的配置文件时,保存失败的Bug。 V0.5.4:修正数制计算器中输入A-F时的bug,增加源数据存储类型选择。 0.5.3:修改图标,部分界面。 0.5.2: About 界面修改,添加更新网址。 0.5.1:修正块另存时新建文件保存失败的Bug。 0.5:新增文件内、文件间块移动、复制、交换、另存等功能 0.4:新增转换为二进制后比较功能 本人继MCUTool以后的另外一个单片机开发实用工具软件,用于单片机调试过程中简单的参量修改,省略修改源代码、再编译的过程,直接修改目标文件。尤其是对eeprom数据的修改、调整更为方便实用。 本软件编写的目的是用来编辑存放于单片机 Flash 或 EEPROM 中的数据,支持 Intel Hex 格式以及 Motorola S 格式的数据文件,也可以编辑二进制的内存映射文件。数据的编辑可以通过常量定义的方式,也可以通过内存映射的方式进行。 同时可以在两种16进制格式文件之间相互转换。格式转换以行数据为单位,以确保转换前后数据不会改变。 另外提供十进制、十六进制转换器,转换结果可以作为普通显示或作为内存映射,作内存映射时可以选择多字节数据的存储方式。 二进制比较功能,通过不同工具生成的Hex文件可能因为格式而无法进行文本方式比较,本工具可以首先转换为二进制数据再进行比较,免去自行转换的麻烦。 单文件内/双文件间的块操作,包括复制、移动、交换、另存等等,方便实验数据提取、复制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值