当前位置: 首页 > article >正文

Hex文件解析

一、Hex文件简介

由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。一般用于MCU程序烧录,可以把hex文件理解为带有地址信息的bin数据的记录集合。(注:烧录时如果使用bin文件则需要指明对应首地址的位置,而使用hex文件则不需要,因为hex文件中包含了对应地址包含的数据内容)

二、Hex文件记录格式与解析

Hex文件记录格式:

  • RECORD MASK:HEX文件的起始格式,文件一开始应该是一个冒号作为起点
  • RECLEN:表示[INFO OR DATA]区域有多少字节的数据长度
  • LOAD OFFSET:表示数据偏移的地址(数据开始记录的偏移地址)
  • RECTYPE:表示该行的Hex文本的类型
    • 00 表示该行记录的是数据(可以理解为bin文件内容)
    • 01 表示该Hex文件结束,一般放在最末尾
    • 02 表示记录的是扩展段地址(数据地址段)
    • 03 表示记录的是开始段地址
    • 04 表示记录的是扩展线性地址
    • 05 表示记录的是起始线性地址(一般认为main函数入口地址)
  • INFO OR DATA:该行的数据或者地址信息
  • CHKSUM:该行的检验和 [该行所有16进制(除了checksum)的累加和S,然后(0x100 - S)& 0xFF]

注意:最常见的Recv type有00、01、04、05

(1)RECTYPE 00 数据标识

 04 2000 00 FECACEFA 4C

04 表示本行有4个字节数据

2000  表示偏移地址为0x2000

FECACEFA  表示本行数据

4C 为该行校验和计算如下:

  • 累加和S =(04 + 20 + 00 + FE + CA + CE + FA)= 0x3B4;
  • 校验和CHKSUM  = (0x100 - S)& 0xFF = 0x4C
(2)RECTYPE 01 文件结束标识

: 00 0000 01 FF

00 表示本行有0个字节数据

0000 表示偏移地址为 0x0000

01  表示Hex文件结束

FF 为该行校验和计算如下:

  • 累加和S =(00 + 00 + 00 + 01)= 0x01;
  • 校验和CHKSUM  = (0x100 - S)& 0xFF = 0xFF
(3)RECTYPE 02 扩展段标识

USBA:用于记录16位扩展段地址的段基址为位4—19(SBA),其中SBA的位0---3为0。位4—19称为上段基地址USBA,再加上LOAD OFFSET就可计算数据偏移量地址。

:02 0000 02 1200 EA  

02 表示本行有2个字节数据

0000 表示偏移地址为 0x0000

02 表示扩展段标识

1200 表示扩展段标识,对应的段地址为0x0001 2000

EA 为该行校验和计算如下:

  • 累加和S =(02 + 00 + 00 + 02 + 12 + 00)= 0x16;
  • 校验和CHKSUM  = (0x100 - S)& 0xFF = 0xEA
(4)RECTYPE 03 开始段地址

(5)RECTYPE 04 扩展线性地址标识

: 02 0000 04 0005 F5

02 表示本行有2个字节数据

0000 表示偏移地址为 0x0000

04 表示为拓展线性地址

0005 表示扩展线性地址的高16位为0x0005低16位在LOAD OFFSET中为 0x0000,即在下一个04出现前,后续数据记录的基址为 0x0005 0000

F5 为该行校验和计算如下:

  • 累加和S =(02 + 00 + 00 + 04 + 00 + 05)= 0x0B;
  • 校验和CHKSUM  = (0x100 - S)& 0xFF = 0xF5
(6)RECTYPE 05 起始线性地址标识

04 0000 05 00000411 E2

04 表示本行有4个字节数据

0000 表示偏移地址为 0x0000

05 表示起始线性地址标识

00000411 表示目标执行起始地址为0x0000 0411可以在对应map文件中找到

E2 为该行校验和计算如下:

  • 累加和S =(04 + 00 + 00 + 05 + 00 + 00 + 04 + 11)= 0x1E;
  • 校验和CHKSUM  = (0x100 - S)& 0xFF = 0xE2

示例:

:040000050000841162

(7)Recv type 04/00/05/01 简单示例

:020000040005F5
:04200000FECACEFA4C
:0400000500000411E2
:00000001FF

: 02 0000 04 0005 F5 :该行表示后续数据记录的扩展线性地址的基址为 0005 0000

04 2000 00 FECACEFA 4C:表示 0x0005 2000地址起始的数据为FECACEFA

04 0000 05 00000411 E2:表示0x0000 0411为main函数的入口地址

: 00 0000 01 FF:表示Hex文件末尾

(8)Recv type 04/02/00 简单示例
  1. :020000040108F1

  2. :020000021200EA 

  3. :0401000090FFAA556D 

 

:02 0000 04 0108 F1:该行表示后续数据记录的扩展线性地址的基址为   0108 0000

:02 0000 02 1200 EA:该行表示后续数据记录的扩展段地址的基址为 0001 2000                

:04 0100 00 90FFAA55 6D:该行表示0x0108 0000 +   0x0001 2000 + 0x0100 的起始地址数据为90FFAA55

实际物理地址=扩展线性地址 + 扩展段地址 + 数据偏移地址 = 0x0108 0000 +   0x0001 2000 + 0x0100 = 0x0109 2100

三、Hex文件解析Python代码示例

Hex文件的内容行解析python代码示例:

def _line_analyse(self, line:str):# string fliterline = line.strip()  # 去除开头与结尾的空格或换行符# Hex file formatrecord_mask    = line[0]data_len       = int(line[1:3], 16)load_offset    = int(line[3:7], 16)recv_type      = int(line[7:9], 16)checksum       = int(line[-2:], 16)# Hex file info string disposeDATA_START_INDEX = 9DATA_STR_LENGTH  = data_len * 2if (record_mask == ":") and (self.is_finished_analyse == False):# 数据记录类型if (recv_type == 0x00):     base_addr = self.address_info_list[-1]address = base_addr + load_offsetdata_hex_list = []for i in range(0, DATA_STR_LENGTH, 2):data_hex = int(line[DATA_START_INDEX + i : DATA_START_INDEX + i + 2], 16)data_hex_list.append(data_hex)# checksum 校验和检测# 该行所有16进制累加和S, 然后0x100 - Schecksum_temp = 0for i in range(1, len(line) - 2, 2):checksum_temp += int(line[i : i+2], 16)checksum_temp = (0x100 - checksum_temp) & 0xFF# 数据保存if checksum_temp == checksum:self.data_dict[address] = data_hex_listelse:print("checksum_temp:0x{:2x}, checksum:0x{:2x}, line:{:s}".format(checksum_temp, checksum, line))# 文件结束类型elif(recv_type == 0x01):    self.is_finished_analyse = True# 标识拓展段地址 (Hex86)elif(recv_type == 0x02):     pass# 标识开始段地址 (Hex86)elif(recv_type == 0x03):pass# 标识扩展线性地址elif(recv_type == 0x04):address_high_half_word = int(line[DATA_START_INDEX : DATA_START_INDEX + DATA_STR_LENGTH], 16)address_low_half_word = load_offsetaddress = ((address_high_half_word << 16) | (address_low_half_word)) & 0xFFFFFFFF# 补充地址信息self.address_info_list.append(address)# 标识开始线性地址 (main函数入口地址)elif(recv_type == 0x05):eip_address = int(line[DATA_START_INDEX : DATA_START_INDEX + DATA_STR_LENGTH], 16) + load_offsetself.main_address = eip_addresselse:pass

http://www.lryc.cn/news/2415093.html

相关文章:

  • 超详细一文到底!软件测试基本流程
  • 富文本编辑器汇总
  • 一篇了解使用springSecurity
  • jar包的概念及作用(二)运行jar包、查看jar包内容
  • 推荐开源项目:NSFW Filter — 图片安全性智能检测库
  • 【机器学习】SGD,SGDM,NAG,Adagard,AdaDelta,RMSpro,Adam原理
  • 【Python/绘图】python绘图
  • [计算机效率] 文件搜索工具:Listary(附详细使用教程)
  • IO的详细介绍
  • CPP/C++学习笔记01
  • Evaluation中Percision和Recall的理解
  • Animation 开源项目教程
  • SonarQube代码质量检查平台
  • 深入理解异或运算 xor 的含义——再探不使用加减乘除实现加法运算、不使用额外空间交换两个变量的值
  • 面试官灵魂三问:什么是SOA?什么是微服务?SOA和微服务有什么区别?
  • Dev-C++/Cpp使用入门详解
  • Angular简介(大神可略过)
  • Linux shell编程学习笔记69: curl 命令行网络数据传输工具 选项数量雷人(中)...
  • gateWay网关组件及工作原理
  • 一次性搞定!思源字体安装、使用及常见问题解答
  • WEBGL原理
  • Java中Synchronized的用法
  • jav常用类-时间处理相关类
  • Homebrew你了解吗?
  • MinGW下载和安装以及环境配置详细步骤
  • 一(一)、keil常见问题和解决方法常用操作
  • DOM 基础知识
  • flex布局(详解)
  • 第4章 探究 Composer 加载原理
  • Altium Designer 小白入门教程