c++如何解析Intel HEX文件格式_嵌入式固件数据提取【实战】

陌伟酱_3589

陌伟酱_3589

2026-04-10

234人浏览

原创

Intel HEX 文件每行以:开头,含字节数、地址、记录类型、数据和校验和;地址可16/32位,校验和为所有字段字节和的8位补码;仅类型00为有效数据,需处理04扩展地址,用substr切片解析,建议稀疏存储。

c++如何解析intel hex文件格式_嵌入式固件数据提取【实战】

Intel HEX 文件的结构到底长什么样

Intel HEX 不是文本协议,而是带校验的 ASCII 编码二进制数据表示法。每一行以 : 开头,后面紧接固定字段:字节数、地址、记录类型、数据、校验和。比如 :10010000214601360121470136007EFE09D2190140 这一行里,10 是数据长度(16 字节),0100 是地址(0x0100),00 是数据记录类型,最后两个字节 40 是校验和。

关键点在于:地址是 16 位或 32 位,取决于是否出现 04(扩展线性地址)或 05(开始线性地址)记录;校验和不是 CRC,而是所有字节(不含起始冒号和自身)取反加 1 后的低 8 位——但实际只需累加所有字节再取低 8 位的补码(即 ~(sum & 0xFF) & 0xFF)。

用 C++ 逐行解析并提取有效数据块

别用正则匹配整行,直接按字符位置切片更稳。每行至少 11 个字符(:020000040000FA 是最短的有效扩展地址行),先跳过空格和换行,再检查首字符是否为 :。

  • 用 std::string::substr() 提取字段:第 1–2 字符转为字节数(len),第 3–6 为地址(注意高低位顺序),第 7–8 为记录类型
  • 记录类型为 00 才是真实数据;01 是文件结束;04 要更新当前 32 位基地址(取其后 4 字符左移 16 位)
  • 数据段从第 9 位开始,每 2 字符一组,用 std::stoi(x, nullptr, 16) 转为 uint8_t
  • 校验和在末尾 2 字符,必须与前面所有字节(含 len/addr/type/data)的累加和校验一致,否则整行丢弃

地址重叠、空洞与写入缓冲区的处理逻辑

HEX 文件常有不连续地址(例如只烧录 Flash 的某几段),不能假设地址递增。解析时应把每段 00 记录视为独立内存块,存成 {base_addr, std::vector data} 结构。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

常见坑:

  • 没处理 04 记录就直接拼地址,导致高位全零(如 0x00010000 变成 0x00000100)
  • 多个记录写入同一地址范围,后写覆盖前写——除非你明确需要“最后定义优先”,否则应检测重叠并报错
  • 申请缓冲区时按最大地址 + 数据长度分配,但嵌入式场景往往只关心非零区域,建议用 std::map 稀疏存储,避免浪费内存

如何验证解析结果是否正确

最简单的办法是把解析出的数据重新打包成 HEX 行,再用开源工具(如 srec_cat 或 objcopy -I ihex -O binary)转成 bin 对比 SHA256。但更实用的是运行时校验:

  • 对每个 00 记录,手动重算校验和并与原值比对,不等就立刻 std::cerr
  • 解析完所有行后,遍历所有数据块,检查是否有未闭合的 01(文件结束标记缺失),或出现非法记录类型(如 06)
  • 如果目标是固件烧录,务必确认最高地址块是否包含复位向量(ARM 是 0x00000004 处的初始 SP 值),否则解析没错,但芯片根本跑不起来

地址计算和校验和逻辑最容易手滑写错,建议这两处单独抽成函数并加单元测试,哪怕只测 3 行典型样本(标准数据行、扩展地址行、文件结束行)。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7479

3

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

7479

3

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

2025.09.03

2152

14

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

730

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

343

7

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.17

553

20

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.27

323

6

常见的编码方式
常见的编码方式

常见的编码方式有ASCII编码、Unicode编码、UTF-8编码、UTF-16编码、GBK编码等。想了解更多编码方式相关内容,可以阅读本专题下面的文章。

2023.10.24

1548

7

a和A对应的ASCII码数值
a和A对应的ASCII码数值

a的ascii码是65,a的ascii码是97;ascii码表中,一个字母的大小写数值相差32,一般知道大写字母的ascii码数值,其对应的小写字母的ascii码数值就算出来了,是大写字母的ascii码数值“+32”。想了解更多相关的内容,可阅读本专题下面的相关文章。

2024.10.24

5727

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习