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

手把手教你用Python解析Hex文件:自己写个简易烧录器脚本

Python实战:从零构建Hex文件解析器与Bin转换工具

在嵌入式开发中,Hex文件与Bin文件是两种最常见的固件格式。许多开发者习惯依赖现成的IDE工具进行格式转换,但当我们需要自动化流程或定制化处理时,理解其底层原理并手动实现转换工具就显得尤为重要。本文将带你用Python标准库一步步构建一个健壮的Hex文件解析器,并生成可直接烧录的Bin文件。

1. Hex文件格式深度解析

Hex文件(Intel HEX格式)是一种文本格式的十六进制编码文件,每行代表一条记录。每条记录由六个关键字段组成:

:BBAAAATTHHHH...HHCC

其中各字段含义如下:

字段符号名称字节数描述
:记录起始符1固定为冒号
BB数据长度1本记录中数据字节数
AAAA地址2数据存储的起始地址
TT记录类型1决定该记录的作用
HH...HH数据变长实际数据内容
CC校验和1用于验证记录完整性的校验值

记录类型(TT字段)主要有以下几种:

  • 0x00:数据记录(Data Record)
  • 0x01:文件结束记录(End Of File)
  • 0x04:扩展线性地址记录(Extended Linear Address)
  • 0x05:起始线性地址记录(Start Linear Address)

校验和的计算方法是:将记录起始符后的所有字节相加,取和的低8位补码。例如对于记录:10010000214601360121470136007EFE09D2190140

def calc_checksum(hex_str): bytes_data = bytes.fromhex(hex_str[1:]) return (0x100 - (sum(bytes_data) & 0xFF)) & 0xFF

2. 构建Python解析框架

我们首先创建一个HexParser类来处理文件解析:

import struct from collections import defaultdict class HexParser: def __init__(self): self.memory_map = defaultdict(lambda: 0xFF) self.current_address = 0 self.extended_linear_address = 0 def parse_line(self, line): line = line.strip() if not line.startswith(':'): raise ValueError("Invalid HEX line format") byte_count = int(line[1:3], 16) address = int(line[3:7], 16) record_type = int(line[7:9], 16) data = line[9:-2] checksum = int(line[-2:], 16) # 校验和验证 calculated_checksum = self._calculate_checksum(line[1:-2]) if calculated_checksum != checksum: raise ValueError(f"Checksum mismatch at line: {line}") return { 'byte_count': byte_count, 'address': address, 'record_type': record_type, 'data': data, 'checksum': checksum } def _calculate_checksum(self, hex_str): bytes_data = bytes.fromhex(hex_str) return (0x100 - (sum(bytes_data) & 0xFF)) & 0xFF

3. 处理扩展地址与数据拼接

Hex文件可能包含非连续地址数据,特别是当使用扩展线性地址记录(0x04类型)时。我们需要正确处理地址偏移:

def process_record(self, parsed_line): record_type = parsed_line['record_type'] data_bytes = bytes.fromhex(parsed_line['data']) if record_type == 0x00: # 数据记录 base_address = self.extended_linear_address + parsed_line['address'] for i, byte in enumerate(data_bytes): self.memory_map[base_address + i] = byte elif record_type == 0x04: # 扩展线性地址记录 self.extended_linear_address = (data_bytes[0] << 24 | data_bytes[1] << 16) elif record_type == 0x01: # 文件结束记录 return False return True

4. 生成Bin文件与地址间隙处理

Bin文件是连续的二进制数据,而Hex文件可能有地址间隙。我们需要填充这些间隙(通常用0xFF):

def generate_bin(self, output_path, fill_value=0xFF): if not self.memory_map: raise ValueError("No data parsed") min_addr = min(self.memory_map.keys()) max_addr = max(self.memory_map.keys()) bin_size = max_addr - min_addr + 1 # 创建并填充二进制缓冲区 bin_data = bytearray([fill_value] * bin_size) for addr, value in self.memory_map.items(): bin_data[addr - min_addr] = value # 写入文件 with open(output_path, 'wb') as f: f.write(bin_data) return bin_size

5. 完整实现与错误处理

将各部分组合成完整的解决方案:

def hex_to_bin(hex_path, bin_path): parser = HexParser() try: with open(hex_path, 'r') as f: for line in f: parsed = parser.parse_line(line) if not parser.process_record(parsed): break size = parser.generate_bin(bin_path) print(f"Successfully converted {hex_path} to {bin_path}") print(f"Output size: {size} bytes") return True except Exception as e: print(f"Error during conversion: {str(e)}") return False if __name__ == "__main__": import sys if len(sys.argv) != 3: print("Usage: python hex2bin.py <input.hex> <output.bin>") sys.exit(1) hex_to_bin(sys.argv[1], sys.argv[2])

6. 高级功能扩展

6.1 支持分段Bin文件生成

某些情况下,我们需要根据地址范围生成多个Bin文件:

def generate_segmented_bin(self, output_dir, segment_size=0x10000): if not self.memory_map: raise ValueError("No data parsed") min_addr = min(self.memory_map.keys()) max_addr = max(self.memory_map.keys()) segment_start = min_addr & ~(segment_size - 1) segment_end = (max_addr + segment_size - 1) & ~(segment_size - 1) for segment_base in range(segment_start, segment_end, segment_size): segment_data = bytearray([0xFF] * segment_size) segment_min = segment_base segment_max = segment_base + segment_size - 1 for addr, value in self.memory_map.items(): if segment_min <= addr <= segment_max: segment_data[addr - segment_base] = value output_path = f"{output_dir}/segment_{segment_base:08x}.bin" with open(output_path, 'wb') as f: f.write(segment_data)

6.2 添加CRC校验

为生成的Bin文件添加CRC校验:

import zlib def add_crc_to_bin(bin_path): with open(bin_path, 'rb') as f: data = f.read() crc32 = zlib.crc32(data) & 0xFFFFFFFF with open(bin_path + '.crc', 'w') as f: f.write(f"CRC32: {crc32:08X}\n") return crc32

7. 实际应用场景

这个脚本可以集成到各种自动化流程中:

  1. CI/CD流水线:在固件构建后自动转换格式
  2. 批量处理:一次性处理多个Hex文件
  3. 自定义烧录工具:作为底层转换模块
  4. 固件分析:解析Hex文件内容进行安全检查
# 示例:批量处理目录下所有Hex文件 import glob import os def batch_convert(input_dir, output_dir): os.makedirs(output_dir, exist_ok=True) for hex_file in glob.glob(os.path.join(input_dir, '*.hex')): bin_file = os.path.join( output_dir, os.path.basename(hex_file).replace('.hex', '.bin') ) hex_to_bin(hex_file, bin_file)

这个Python实现的Hex解析器不仅完整实现了基本功能,还包含了许多实用扩展。相比现成工具,它具有以下优势:

  • 完全透明可控:每个处理步骤都可自定义
  • 轻量无依赖:仅使用Python标准库
  • 易于集成:可作为模块嵌入其他系统
  • 跨平台:在Linux、Windows、Mac上均可运行

在实际项目中,我曾用类似方案解决了IDE生成Hex文件与生产烧录工具不兼容的问题,通过自定义地址映射规则,完美实现了格式转换。这种深入理解文件格式并自主实现处理工具的能力,往往是区分普通开发者与技术专家的关键。

http://www.jsqmd.com/news/954024/

相关文章:

  • 3步解锁CPU性能:Universal x86 Tuning Utility终极硬件优化指南
  • 2026年最新巴中市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • NLP情报简报:工程师的技术雷达与落地避坑指南
  • MuleSoft企业级AI编排:LLM与ERP/CRM安全集成实战
  • Python包管理实战:PyPI、pip与虚拟环境全解析
  • 苏州传统零售私域直播系统怎么选?我会先看门店能不能接得住
  • 响应面驱动的复杂黑箱模型优化算法【附代码】
  • 实战应用:在快马ai中设计并仿真mos管h桥电机驱动电路
  • Agent Runtime 范式革命:会话即持久化事件日志
  • 原创:S905L/L3麻雀云arm通刷固件,已经测试UNT402A CM211-1通过
  • 2026年最新白城市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • 手机号定位神器:3秒查询陌生来电归属地,地图精准定位位置终极指南
  • Vision Transformer核心原理与PyTorch手撕实现
  • 探果AI(Tengo AI)办公AI实战:5分钟搞定复杂环境,避坑指南在此
  • Anthropic API架构变革:上下文编排层归零与客户端适配指南
  • 2026年最新白山市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • Claude 提示缓存机制深度解析:自动缓存、显式断点与 20 块回顾窗口
  • 零代码YouTube数据自动化:Google Sheets+Tableau可视化方案
  • Umi-OCR终极指南:免费开源离线文字识别软件,3分钟快速上手
  • 别再乱搜了!ESP8266-01S AT固件烧录,安信可官方固件+Flash下载工具最稳配置分享
  • 2026年最新白银市黄金回收白银回收铂金回收彩金回收TOP5靠谱门店甄选 识店+辨价+安全交易指南及联系方式推荐 - 前途无量YY
  • 毕业论文开题全攻略:从选题焦虑到顺利通关的实战经验
  • 手机号定位神器:3秒查询号码归属地,地图精准定位位置
  • 在macos python中安装dlib
  • 2026年泰州装修公司|泰州装修设计公司实力排行 - 奔跑123
  • Python if-else 不是语法糖,而是工程级决策引擎
  • LangChain+OpenAI构建技术文档精准问答系统
  • 软件协议整理
  • DBC文件避坑指南:从通讯协议到CANdb++编辑,手把手教你检查信号起始位与Value Table
  • 黄小宇GEO实验:大模型可见度监控系统设计与Python实现