从Hex到Bin嵌入式开发者必须掌握的烧录文件实战指南第一次在Keil中点击Build按钮时看到输出目录里突然冒出的.hex、.bin、.axf文件我盯着它们发了五分钟呆——该选哪个烧录到板子里这个问题困扰过每个嵌入式新手。就像面对快递柜里形状各异的包裹明明知道芯片就在那里等着程序注入却不确定该拆哪个包装。1. 烧录文件的本质差异从快递包装到裸机直投想象你要给朋友寄送一块珍贵的电路板。Hex文件就像精心包装的快递每个部件都有泡沫棉包裹贴满物流标签甚至附带签收单。而Bin文件则是直接把电路板塞进对方口袋——简单粗暴但需要双方事先约定好交接细节。Hex文件的智能之处在于它的自描述性。打开一个STM32生成的.hex文件你会看到类似这样的内容:1000000000040020D1000008B5000008B9000008B3 :10001000BD000008C1000008C50000080000000064每行记录都像快递面单包含起始标记冒号相当于快递单号数据长度告诉你包裹里有多少物品内存地址是精确的送货地址记录类型区分普通数据、扩展地址或文件结束校验和确保运输过程没有丢件相比之下Bin文件就是纯粹的二进制流。用hexdump查看一个.bin文件00000000 00 04 00 20 d1 00 00 08 b5 00 00 08 b9 00 00 08 00000010 bd 00 00 08 c1 00 00 08 c5 00 00 08 00 00 00 00这就是为什么烧录工具普遍支持Hex它能自动解析地址信息某些场景必须用Bin比如OTA升级时文件大小敏感调试阶段多用Hex方便定位问题地址量产阶段倾向Bin节省存储空间2. 主流IDE中的文件生成配置实战2.1 Keil MDK老牌IDE的精细控制在Options for Target → Output选项卡中关键配置项包括配置项Hex文件影响Bin文件影响Create HEX File控制是否生成无直接影响Browse Information增加调试信息无影响Name of Executable决定输出文件名影响转换源文件生成Bin文件需要额外步骤在User选项卡添加Post-build命令使用Keil自带的fromelf工具fromelf --bin --outputL.bin !L常见坑点地址偏移设置错误会导致Bin文件错位未勾选Use Memory Layout可能生成无效Hex2.2 IAR Embedded Workbench高度集成的解决方案工程选项 → Output Converter 提供更直观的配置界面// 典型配置示例 define symbol __ICFEDIT_region_ROM_start__ 0x08000000; define symbol __ICFEDIT_region_ROM_end__ 0x0807FFFF;实用技巧启用generate additional output可同时输出多种格式output file override允许自定义内存布局2.3 STM32CubeIDE图形化配置的现代选择在Properties → C/C Build → Settings中Hex文件生成勾选Create Flash Image选择Intel Hex格式Bin文件生成 添加自定义构建步骤arm-none-eabi-objcopy -O binary ${BuildArtifactFileName} ${BuildArtifactFileBaseName}.bin对比实验 使用同一工程在三种IDE中生成文件结果差异指标KeilIARSTM32CubeIDEHex文件大小48KB47KB49KBBin文件大小32KB31KB33KB生成速度2.1s1.8s3.4s3. 烧录工具链中的文件选择策略3.1 调试器专用工具ST-Link Utility典型工作流连接开发板点击Open file选择Hex或Bin注意这两个关键区别Hex文件会自动识别烧录地址Bin文件需要手动指定起始地址J-Flash的特殊处理支持分段Hex文件Bin文件需要配套.elf文件提供地址信息3.2 开源工具链方案使用OpenOCD时烧录命令差异明显# Hex文件烧录 openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c program test.hex verify reset exit # Bin文件烧录必须指定地址 openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c program test.bin 0x08000000 verify reset exit3.3 生产环境批量烧录量产烧录器通常更青睐Bin文件因为文件体积更小节省传输时间无需解析直接写入速度更快容易做文件校验(MD5/SHA)但要注意必须严格确认烧录地址多区域烧录时需要合并Bin文件4. 高级技巧格式转换与自定义处理4.1 命令行转换工具实战objcopy是转换利器# Hex转Bin arm-none-eabi-objcopy -I ihex -O binary input.hex output.bin # 反向转换需要地址参数 arm-none-eabi-objcopy -I binary -O ihex --change-addresses 0x08000000 input.bin output.hexsrec_cat功能更强大# 合并多个Hex文件 srec_cat file1.hex -Intel file2.hex -Intel -o merged.hex -Intel # 提取特定地址段 srec_cat full.hex -Intel -crop 0x08000000 0x0800FFFF -o section.hex -Intel4.2 自定义校验与修补有时需要手动处理Bin文件# Python二进制修补示例 with open(firmware.bin, rb) as f: # 在0x200偏移处写入版本号 f.seek(0x200) f.write(bFW_VER_1.2) # 计算CRC32并写入文件末尾 f.seek(0, 2) file_size f.tell() f.seek(0) crc binascii.crc32(f.read(file_size)) f.write(crc.to_bytes(4, little))4.3 逆向解析Hex文件理解Hex格式后可以自己写解析器// 简化的Hex解析结构体 typedef struct { uint8_t byte_count; uint16_t address; uint8_t record_type; uint8_t data[256]; uint8_t checksum; } HEX_RECORD; bool validate_checksum(HEX_RECORD *rec) { uint8_t sum rec-byte_count (rec-address 8) (rec-address 0xFF) rec-record_type; for(int i0; irec-byte_count; i) { sum rec-data[i]; } return (sum rec-checksum) 0; }在ESP32项目中遇到过一个典型问题PlatformIO生成的Bin文件必须配合分区表使用而直接烧录Hex文件会导致启动失败。这时候就需要理解Hex虽然方便但不是万能的——某些芯片的引导流程对二进制布局有特殊要求。
从Hex到Bin:一份给嵌入式新手的‘烧录文件’避坑指南(Keil/IAR/STM32CubeIDE)
发布时间:2026/6/5 21:37:15
从Hex到Bin嵌入式开发者必须掌握的烧录文件实战指南第一次在Keil中点击Build按钮时看到输出目录里突然冒出的.hex、.bin、.axf文件我盯着它们发了五分钟呆——该选哪个烧录到板子里这个问题困扰过每个嵌入式新手。就像面对快递柜里形状各异的包裹明明知道芯片就在那里等着程序注入却不确定该拆哪个包装。1. 烧录文件的本质差异从快递包装到裸机直投想象你要给朋友寄送一块珍贵的电路板。Hex文件就像精心包装的快递每个部件都有泡沫棉包裹贴满物流标签甚至附带签收单。而Bin文件则是直接把电路板塞进对方口袋——简单粗暴但需要双方事先约定好交接细节。Hex文件的智能之处在于它的自描述性。打开一个STM32生成的.hex文件你会看到类似这样的内容:1000000000040020D1000008B5000008B9000008B3 :10001000BD000008C1000008C50000080000000064每行记录都像快递面单包含起始标记冒号相当于快递单号数据长度告诉你包裹里有多少物品内存地址是精确的送货地址记录类型区分普通数据、扩展地址或文件结束校验和确保运输过程没有丢件相比之下Bin文件就是纯粹的二进制流。用hexdump查看一个.bin文件00000000 00 04 00 20 d1 00 00 08 b5 00 00 08 b9 00 00 08 00000010 bd 00 00 08 c1 00 00 08 c5 00 00 08 00 00 00 00这就是为什么烧录工具普遍支持Hex它能自动解析地址信息某些场景必须用Bin比如OTA升级时文件大小敏感调试阶段多用Hex方便定位问题地址量产阶段倾向Bin节省存储空间2. 主流IDE中的文件生成配置实战2.1 Keil MDK老牌IDE的精细控制在Options for Target → Output选项卡中关键配置项包括配置项Hex文件影响Bin文件影响Create HEX File控制是否生成无直接影响Browse Information增加调试信息无影响Name of Executable决定输出文件名影响转换源文件生成Bin文件需要额外步骤在User选项卡添加Post-build命令使用Keil自带的fromelf工具fromelf --bin --outputL.bin !L常见坑点地址偏移设置错误会导致Bin文件错位未勾选Use Memory Layout可能生成无效Hex2.2 IAR Embedded Workbench高度集成的解决方案工程选项 → Output Converter 提供更直观的配置界面// 典型配置示例 define symbol __ICFEDIT_region_ROM_start__ 0x08000000; define symbol __ICFEDIT_region_ROM_end__ 0x0807FFFF;实用技巧启用generate additional output可同时输出多种格式output file override允许自定义内存布局2.3 STM32CubeIDE图形化配置的现代选择在Properties → C/C Build → Settings中Hex文件生成勾选Create Flash Image选择Intel Hex格式Bin文件生成 添加自定义构建步骤arm-none-eabi-objcopy -O binary ${BuildArtifactFileName} ${BuildArtifactFileBaseName}.bin对比实验 使用同一工程在三种IDE中生成文件结果差异指标KeilIARSTM32CubeIDEHex文件大小48KB47KB49KBBin文件大小32KB31KB33KB生成速度2.1s1.8s3.4s3. 烧录工具链中的文件选择策略3.1 调试器专用工具ST-Link Utility典型工作流连接开发板点击Open file选择Hex或Bin注意这两个关键区别Hex文件会自动识别烧录地址Bin文件需要手动指定起始地址J-Flash的特殊处理支持分段Hex文件Bin文件需要配套.elf文件提供地址信息3.2 开源工具链方案使用OpenOCD时烧录命令差异明显# Hex文件烧录 openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c program test.hex verify reset exit # Bin文件烧录必须指定地址 openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c program test.bin 0x08000000 verify reset exit3.3 生产环境批量烧录量产烧录器通常更青睐Bin文件因为文件体积更小节省传输时间无需解析直接写入速度更快容易做文件校验(MD5/SHA)但要注意必须严格确认烧录地址多区域烧录时需要合并Bin文件4. 高级技巧格式转换与自定义处理4.1 命令行转换工具实战objcopy是转换利器# Hex转Bin arm-none-eabi-objcopy -I ihex -O binary input.hex output.bin # 反向转换需要地址参数 arm-none-eabi-objcopy -I binary -O ihex --change-addresses 0x08000000 input.bin output.hexsrec_cat功能更强大# 合并多个Hex文件 srec_cat file1.hex -Intel file2.hex -Intel -o merged.hex -Intel # 提取特定地址段 srec_cat full.hex -Intel -crop 0x08000000 0x0800FFFF -o section.hex -Intel4.2 自定义校验与修补有时需要手动处理Bin文件# Python二进制修补示例 with open(firmware.bin, rb) as f: # 在0x200偏移处写入版本号 f.seek(0x200) f.write(bFW_VER_1.2) # 计算CRC32并写入文件末尾 f.seek(0, 2) file_size f.tell() f.seek(0) crc binascii.crc32(f.read(file_size)) f.write(crc.to_bytes(4, little))4.3 逆向解析Hex文件理解Hex格式后可以自己写解析器// 简化的Hex解析结构体 typedef struct { uint8_t byte_count; uint16_t address; uint8_t record_type; uint8_t data[256]; uint8_t checksum; } HEX_RECORD; bool validate_checksum(HEX_RECORD *rec) { uint8_t sum rec-byte_count (rec-address 8) (rec-address 0xFF) rec-record_type; for(int i0; irec-byte_count; i) { sum rec-data[i]; } return (sum rec-checksum) 0; }在ESP32项目中遇到过一个典型问题PlatformIO生成的Bin文件必须配合分区表使用而直接烧录Hex文件会导致启动失败。这时候就需要理解Hex虽然方便但不是万能的——某些芯片的引导流程对二进制布局有特殊要求。