news 2026/9/30 23:17:41

嵌入式开发必懂:hex、bin、axf文件格式区别与转换实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
嵌入式开发必懂:hex、bin、axf文件格式区别与转换实战

做过嵌入式开发的兄弟,应该都有过这样的困惑:Keil编译完,工程目录里冒出来一堆后缀各异的文件,hex、bin、axf到底有什么区别?为什么下载程序用hex,做OTA升级要bin,调试的时候又依赖axf?搞不清楚这几个文件的关系,轻则烧录之后程序跑飞找不到原因,重则批量生产时固件搞错变砖。

这篇文章把嵌入式开发中最常见的三种文件格式一次讲透,包括它们的格式原理、适用场景、互相转换的方法,以及我在实际项目中踩过的坑。不管你是在校学生准备入门,还是刚转岗来做嵌入式开发的工程师,搞清楚这些底层文件格式,对后续排查问题、理解编译链接流程都特别有帮助。


1. 三种文件的“出身”:从代码到芯片的完整链路

先说结论:axf是编译链接后生成的带调试信息的可执行文件,hex和bin都是从axf(或者说从axf背后的elf)派生出来的烧录镜像。这三者的关系,就像你写了一份Word文档,axf是带修订痕迹和批注的完整版,hex和bin是按照不同打印需求导出的PDF或纯文本版。

1.1 编译链接时的“源头文件”:axf从哪来

用Keil开发ARM芯片项目时,点击Build按钮后,编译器(armcc或armclang)把每一个.c文件编译成.o目标文件,然后链接器根据分散加载文件(sct文件)和链接脚本,把所有.o文件、库文件组织在一起,最终生成一个.axf文件。

axf是ARM eXtended Format的缩写,本质上是ELF(Executable and Linkable Format)格式的一种ARM变体。它内部包含的内容非常多:

  • 代码段(RO段):你的函数实现、常量数据
  • 数据段(RW段):初始化了的全局变量、静态变量
  • 零初始化段(ZI段):未初始化的全局变量,运行时置零
  • 调试信息:变量名、函数名、源码行号对应关系
  • 符号表:全局符号的地址映射

这些内容里,前三个是真正会烧录到Flash里的东西,后面两个是给调试器用的“附加服务”。axf文件之所以体积比hex和bin大很多,就是因为它塞进了调试信息。

1.2 烧录镜像的“两副面孔”:hex和bin的诞生

拿到axf之后,还不能直接烧录,因为调试信息和符号表芯片并不需要,芯片只需要纯机器码和数据。这时候就要从axf里提取出RO、RW、ZI段,整理成烧录镜像。

Hex文件是Intel公司制定的一种文本格式,本质上就是“地址+数据”的ASCII文本描述。Keil里的ARM从elf指令(fromelf)或者第三方工具链,能把axf里的每一条数据按地址排列,输出成hex文件。

Bin文件是最纯粹的二进制镜像,就是芯片Flash里的原始字节流,烧录到Flash哪个地址,那里的字节就变成什么。它不带地址信息,全靠烧录工具(或烧录算法)把它放到指定位置。

用一个生活化的类比:axf是装修设计图纸,标注了哪里放什么家具、用什么材质;hex是带坐标的施工图,“在坐标X放一张桌子”;bin是实际搬进屋的家具本体,没有坐标,你把它放哪儿它就呆在哪儿。

1.3 为什么Keil默认输出hex,生成bin还要额外配置

Keil默认配置下,编译结束只生成axf和hex,不生成bin。原因很简单:hex有地址信息,配套的下载算法(如ULINK、J-Link的Flash算法)可以直接解析并烧录,对开发者最方便。

但实际项目里,很多时候必须要bin。比如OTA升级,设备通过网络或蓝牙接收升级包,固件直接写入Flash的某个偏移地址,这时候升级程序接收的就是裸数据,根本没法用带地址的hex。再比如把固件交给生产车间烧录,用批量烧录器时,bin格式更直接可控。所以需要在Keil里加一条自定义命令,调用fromelf工具,从axf里生成bin文件。具体方法后面细说。


2. Hex文件格式深度拆解:从文本里看懂固件布局

2.1 Intel HEX的“一行一记录”结构

Hex文件看起来是一堆十六进制文本,每一行都是一个记录(Record)。标准的Intel HEX记录格式如下:

: 1A 0000 00 547687960000000000000000000000000000000000000000 F2

逐段拆解这一行:

  • 冒号(:):每一行的起始标记
  • 1A:本行数据的字节数(这里26个字节)
  • 0000:本条数据的起始地址(16位)
  • 00:记录类型(00表示数据记录)
  • 5476...:真正的数据内容(十六进制ASCII)
  • F2:校验和

这里最容易懵的是地址。Intel HEX为了兼容老古董的16位地址空间,设置了多种记录类型,用类型字段区分:

记录类型名称作用
00数据记录(Data)存放实际数据
01文件结束记录(EOF)标记hex文件结束
02扩展段地址记录(Extended Segment Address)用段地址方式扩展高16位地址(少见)
04扩展线性地址记录(Extended Linear Address)指定高16位基地址(常用)
05启动地址记录(Start Linear Address)记录程序入口地址(可选)

网络上搜“hex start linear address record”,说的就是类型05这条记录。它一般出现在文件的末尾、EOF之前,表示程序入口地址。用J-Link或Keil烧录时,调试器会读取这个地址,用于设置PC指针的初值。没有这条记录也不影响烧录,但影响调试复位后的行为,比如你看不到程序停在main函数入口。

2.2 校验和算法:手工检查hex文件有没有被改坏

Hex每行最后两位是校验和,算法很简单:本行所有字节(从长度字节开始,到最后一个数据字节)求和,取低8位,然后取反加一(也就是求补码),使总和低8位等于0。

举个例子,刚才那行: 1A 0000 00 547687... F2,把1A + 00 + 00 + 00 + 数据字节逐个求和 + F2 = 0x100,低8位为0就是校验通过。

这个算法不复杂,但实际项目里很少有人手工去算,都是靠工具。我用过几个在线hex校验工具,都不太靠谱,下载文件后建议用Python写一段小脚本验一下,几十行代码就能搞定,对生产环节特别实用——批量烧录前先验hex校验和,能避免镜像文件损坏导致大规模烧录失败。

2.3 从hex里能读出哪些关键信息

拿到一个hex文件,除了烧录,还能做几件实用的事:

  • 查看固件入口地址:看05记录,知道程序启动后从哪里执行
  • 确认烧录起始地址:看第一条04记录和后面00记录的地址,比如04记录写着0x0800,数据地址从0000开始,那第一条数据地址就是0x08000000,对应STM32的Flash起始地址
  • 统计固件大小:把每条00记录的数据长度加起来就是总字节数,但要注意每条记录之间可能有地址空洞,真实占用Flash空间应该是“最后一条数据地址+长度-起始地址”

我经常遇到的情况是,编译完不知道固件到底多大,直接看bin文件属性,再对照芯片Flash容量,判断剩余空间够不够加功能。但hex文件因为带地址信息,想从hex推断实际占用Flash范围,需要写脚本解析,比较繁琐,不如直接看bin文件大小直接。


3. Bin文件:最朴素的固件,最容易被忽略的坑

3.1 Bin文件怎么来的:地址去哪了

Bin文件的生成逻辑非常简单:把axf/elf里的加载地址(LMA)对应的数据,按Flash地址从小到大的顺序,一字排开,输出成一个连续文件。它不记录任何地址信息,不知道放哪里,全靠烧录者把“这个文件应该烧到哪个基地址”告诉烧录工具。

使用J-Flash烧录bin时,必须手动填一个“Start address”(起始地址)。很多新手栽跟头就在这:默认起始地址是0x08000000,如果你的芯片是STM32F103,Flash基地址正好是这个,没问题;但如果用了带Boot区域的芯片,或者程序放在外部Flash、放在0x08004000这种偏移位置,就必须手动改,否则程序写进去也跑不起来。

3.2 Keil中生成bin文件的两种正确姿势

网上的教程教的是这两种方法:

方法一:在Keil的Options for Target → User选项卡,After Build/Rebuild栏勾选Run User Program After Build,填命令:

fromelf.exe --bin -o ./Output/项目名.bin ./Output/项目名.axf

其中fromelf.exe的完整路径一般在Keil安装目录的ARM/ARMCC/bin下,建议用绝对路径或者%KEXPATH%环境变量。

方法二:不修改工程,直接用命令行手动执行。打开Keil安装目录的ARM Compiler环境,执行同样的fromelf命令。

注意:fromelf命令一定要确保axf路径正确,而且axf必须是刚编译成功的最新版本。有几次我改了代码重新编译,但生成bin的命令路径指向了旧目录,结果bin文件还是老版本,烧进板子怎么调都不对,折腾半天才发现是bin文件没更新。

3.3 Bin文件的“地址漂移”问题

Bin文件最典型的坑是它只包含从链接脚本指定的起始地址开始的数据。如果你的工程里把程序链接到0x08008000(比如做了一个带Bootloader的App),那么bin文件烧录时起始地址就必须填0x08008000,而不是0x08000000。

更隐蔽的问题是:链接脚本里如果分散加载,代码段、数据段之间有大量未使用的空洞,bin文件并不会填充这些空洞,它是一段连续的数据流。比如Flash中函数放在0x08000000,常量池放在0x08010000,那么bin文件的字节范围就是0x08000000到0x08010000加上常量池的长度,中间0x08008000到0x0800FFFF这段哪怕没烧东西,bin文件也会用空白填上,导致bin文件比实际代码大很多。这时候就需要检查分散加载文件设置,尽量把可执行段放在连续区域。


4. Axf文件:调试利器,也是出问题的“背锅侠”

4.1 Axf和bin/hex的关系:调试信息到底有多大价值

Axf里最有价值的是调试信息。用Keil的Debugger连上ST-Link或J-Link后,之所以能实现打断点、看变量值、单步执行时高亮源码行,靠的就是axf里的调试信息把机器指令和源码建立映射。

在Release版本里,如果去掉调试信息,axf就退化成纯粹的ELF可执行文件,跟bin的内容几乎一样,只是多了ELF文件头和各段信息。很多人直接用WinHex打开axf,发现能看到“ELF”魔数和一堆段表,但对普通开发者来说,直接用bin更省事。

我个人的习惯是:调试阶段保留axf,量产阶段只保留hex和bin。axf文件在没优化的情况下可能比hex大十几倍,而且它包含源码的完整符号信息,对商业项目来说是敏感资产,不该随意外发。

4.2 Axf反汇编:看编译器到底做了什么

AxF非常实用的一个功能是反汇编。Keil的Debug模式下,你可以在Disassembly窗口直接看到每条C语句对应的汇编指令。这个能力在排查疑难bug时特别有用:

  • 检查优化后的代码流程:开了-O3优化之后,源码顺序和实际执行顺序完全不同,单步调试看到“乱跳”不要慌,打开反汇编看真实执行路径
  • 定位HardFault:程序跑飞进入HardFault后,查看PC指针和LR寄存器的值,在反汇编窗口搜索对应地址,能看到是哪个函数哪条指令出了问题
  • 验证volatile是否生效:一个变量明明改了值,但读出来没变化,反汇编看是不是编译器把这个变量优化成了寄存器变量,根本不写内存

网上搜“axf文件报错”,很多情况是在Keil调试时报错“cannot load driver”或者“axf file not found”。这种错误九成是因为:工程路径包含中文字符或空格,或者编译中途失败导致axf文件不完整。把工程放到纯英文路径下重新编译,立刻就好。

4.3 Axf文件损坏或丢失怎么办

有几次我把Keil工程拷到同事电脑上,打开后一编译就报错“file 'xxx.axf' not found”。排查后原因很统一:工程没有清理干净,obj目录下的axf是上次编译的残留,或者路径变了导致链接器没法覆盖写。

最简单的解决办法是:Project → Clean Targets,然后重新Build,强制全量编译,axf会重新生成。更稳妥的做法是定期把整个工程目录打包备份,axf跟obj文件一起删掉再重编,避免增量编译产生“伪成功”的axf文件。


5. 三者的关键区别与选型:什么时候用哪个

5.1 一张表说清核心差异

对比项hexbinaxf
文件格式ASCII文本纯二进制ELF二进制(含调试信息)
是否带地址带(每条记录都有地址)不带带(段地址)
烧录方式调试器解析地址→烧录手动指定起始地址→烧录调试器直接加载调试
典型用途J-Link/ST-Link下载调试OTA升级、量产烧录Keil调试、反汇编分析
肉眼可读性可用文本编辑器打开必须十六进制工具需要专用工具
典型大小中等(ASCII会膨胀)最小最大(含调试信息)
主要缺点文本解析慢、不适合大固件没地址,易烧错位置太大、不适合分发

5.2 线上升级为什么必须用bin

这是很多做IOT和嵌入式产品的人必须想明白的问题:OTA升级用的升级包,标准答案就是bin。原因有几个:

第一,hex是文本格式,同样数据比bin大1倍以上(字节变ASCII占两个字符),对流量敏感的产品来说不可接受。

第二,hex带地址信息,如果App在设备上有多个可运行区域(比如A/B分区升级),你没法简单地把hex中的地址改掉;bin是纯数据,接收端想放哪段Flash就放哪段,灵活得多。

第三,升级包的校验大多用CRC32或SHA256,直接对整个bin文件计算,简单可靠;hex还要先解析出数据段再算,多了一步且容易出错。

5.3 生产烧录选hex还是bin,看你的工具链

量产烧录现在主流有两种:用J-Flash批量烧录,或者用专门的烧录器配合离线文件。

如果用的是J-Flash,强烈建议用hex。因为J-Flash能自动解析hex里的地址,你不用手动设置烧录起始地址,减少人为错误。而bin文件还需要你对照工程里的链接地址手动填,填错了就是整批板子变砖的问题。

如果是厂商提供的专用烧录软件(比如STM32CubeProgrammer、NXP的Flash Tools),都支持hex和bin,但同样,hex更省心。我见过太多工厂里的技术员把bin烧错地址的情况,所以量产文件我从来只发hex,不解释原因,省事。


6. 工具实操:hex、bin、axf转换与排查手册

6.1 环境准备与基础转换命令

环境准备:安装Keil MDK(自带fromelf),或者安装ARM Development Studio。也可以用开源的GNU Arm Embedded Toolchain,里面的arm-none-eabi-objcopy和arm-none-eabi-objdump也能干同样的活。

Hex转Bin(用fromelf,从axf直接出两种文件):

fromelf.exe --bin -o output.bin input.axf fromelf.exe --i32 -o output.hex input.axf

Bin转Hex(用J-Flash或者Python脚本):实际项目中,我遇到过客户只给bin文件,需要转成hex灌进烧录器。J-Flash操作如下:

  1. 打开J-Flash,File → Open data file,选择bin文件
  2. 弹窗里填起始地址(比如0x08000000)
  3. File → Save data file,选Intel Hex格式保存

S19文件转Hex:飞思卡尔/NXP芯片的工程经常产出S19文件,跟hex一样是带地址的文本,但记录类型不同。可以用srec_cat这个开源工具(SRecord工具包里的瑞士军刀),一行命令转换:

srec_cat input.s19 -o output.hex -Intel

Hex转Bin的脚本方案(通用):如果手头只有hex文件又没法跑Keil,写个Python小脚本解析Intel HEX。流程很简单:逐行判断类型、解析地址和数据、按地址写入字节数组、最后输出bin。核心代码如下:

def hex_to_bin(hex_path, bin_path): data = {} base_addr = 0 with open(hex_path, 'r') as f: for line in f: line = line.strip() if not line.startswith(':'): continue byte_len = int(line[1:3], 16) addr = int(line[3:7], 16) rectype = int(line[7:9], 16) payload = bytes.fromhex(line[9:9 + byte_len * 2]) if rectype == 0x04: base_addr = int.from_bytes(payload, 'big') << 16 elif rectype == 0x00: full_addr = base_addr + addr data[full_addr] = payload elif rectype == 0x01: break if not data: raise ValueError("no data records") start = min(data.keys()) end = max(data.keys()) + len(data[max(data.keys())]) buf = bytearray(end - start) for addr, payload in data.items(): off = addr - start buf[off:off + len(payload)] = payload with open(bin_path, 'wb') as f: f.write(buf)

这段代码把每个地址上的数据都填到对应偏移位置,缺的洞补0x00(注意:hex文件不会主动补洞,这里补的是预设的默认值,实际如果链接脚本有空洞,bin里对应区域就是FF还是00取决于hex里有没有数据,严谨做法是先全填0xFF再覆盖有数据的部分)。

6.2 Keil里一步生成hex+bin+axf的完整配置

以MDK 5.38为例,完整配置流程如下:

第一步:配置Output选项卡。Options for Target → Output,勾选Creates HEX File,这样编译后自动产出hex。axf是默认就有的,不需要配置。

第二步:配置User选项卡。Options for Target → User,在After Build/Rebuild栏,勾选Run User Program After Build,点击右侧“...”按钮选择fromelf.exe路径,然后在后面追加参数:

--bin -o ./obj/App.bin ./obj/App.axf

第三步:验证输出。编译完成后打开工程目录的obj文件夹,正常情况应该有App.axf、App.hex、App.bin三个文件,比对三者生成时间是否一致。

提示:fromelf路径含空格时,Keil的User命令解析可能出问题。稳妥做法是给fromelf.exe加双引号,但双引号后面的参数不能也加双引号,否则会当成路径的一部分。比如:"C:\Keil_v5\ARM\ARMCLANG\bin\fromelf.exe" --bin -o ./obj/App.bin ./obj/App.axf,注意fromelf后面的参数不带引号,但路径本身带引号没问题。

实际操作中,很多人在这一步卡住,因为Keil的User命令窗口边框很小,复制粘贴长命令容易出错,建议直接在命令行窗口先测试一遍fromelf命令能跑通,再贴进Keil配置界面。

6.3 实用工具清单与适用场景

这些年折腾hex、bin、axf,我攒了一套顺手的工具箱,拿出来共享:

  • Keil MDK自带的fromelf:最趁手的转换工具,不用额外装环境,axf转hex/bin一步到位
  • J-Flash:烧录必备,还能做bin转hex、hex转bin,也会显示flash校验结果
  • STM32CubeProgrammer:ST官方工具,界面友好,支持带地址解析烧录,还能查看Flash内容
  • SRecord(srec_cat/srec_info):处理s19、hex、bin转换的命令行神器,批量处理场景效率极高
  • VSCode加Hex Editor插件:偶尔需要直接改二进制时用,比如验证bin文件里某个字节对不对
  • Beyond Compare:固件对比神器,两个bin文件做二进制比对,支持十六进制视图,排查“代码改了但bin没变”这类问题非常高效

7. 常见文件报错与排查实录

7.1 Keil报“axf文件找不到”的处理流程

这个报错我至少遇到十几次,核心排查顺序记牢:

  1. 看编译输出窗:往下翻,找到第一次出现error的地方,很多情况是之前的编译就失败了,axf文件压根没生成
  2. 检查工程路径:中文路径、空格、过长路径是经典杀手,把工程移到D:\proj\test下再试
  3. 清理重建:Project → Clean Targets,然后重新Build
  4. 检查杀毒软件:公司电脑装了360或McAfee,经常拦截axf写入,在杀毒软件里加目录白名单

7.2 Hex烧录后程序跑飞,大概率是地址配置问题

症状:程序烧录成功,但上电不是白屏就是复位循环。 排查思路:

  • 先看hex的04记录:如果第四条记录的地址不是芯片Flash基地址(比如STM32F1是0x08000000),说明你的分散加载文件有问题,或者下载算法选错芯片
  • 再看05记录:如果没有启动地址记录,有些烧录器默认PC从0开始,程序直接跑飞
  • 最后看bin的起始地址:如果烧的是bin,99%是起始地址没填对,检查你填的地址是否等于链接脚本里的RO Base

7.3 Bin文件烧录成功但程序不运行,排查步骤

这种情况比烧录失败更恶心,因为看起来一切正常,但板子没反应。我总结的排查顺序:

  1. 检查起始地址:你烧录时填的地址,和工程的linker脚本里指定的地址要一致
  2. 先烧一次全擦除再烧bin:有些芯片的Flash里还留着旧Bootloader或旧代码,bin没覆盖到的区域跑的还是老代码,互相干扰
  3. 确认bin文件大小:用编辑器打开bin文件,检查末尾有没有意外截断,我有一次U盘拷贝bin文件出差错,文件被截断成原来一半,烧进去程序不跑,对比文件大小才发现
  4. 用J-Flash校验:烧录完成后做个verify,看Flash内容和bin是否完全一致

7.4 Keil下载时报“Error: Flash Download failed - Target DLL has been cancelled”

这种报错其实跟文件格式无关,但经常被误以为是hex/axf问题。实际原因是调试器的RTT或SWO功能占用了下载通道,或者芯片没进入Debug模式。解决方法是:Options for Target → Debug → Settings,把Port改成SW或JTAG,Reset and Run前确认Reset模式是Normal。另外确认板子供电正常、复位引脚没被拉死。

7.5 Hex反编译成C语言:能还是不能

网上搜“hex文件反编译成C语言”,先给个明确结论:hex文件里只有机器码,没有符号信息,想反编译成可读的C语言基本不可能。你能做的最多是反汇编成汇编代码,工具可以用:

  • Keil自带的ARM Disassembler
  • Ghidra(开源,支持ARM,对新手友好)
  • IDA Pro(老牌,但正版贵,学习成本高)

但如果项目里有对应的axf文件,那情况完全不同。Axf里有完整的调试信息和符号表,反编译之后能恢复出大部分函数名、变量名,代码逻辑可读性高了很多。所以如果有人拿个hex文件找你“帮忙看下这段逻辑”,先问他有没有axf,没有的话基本只能看汇编硬啃。


8. 进阶拓展:从hex/bin反推Flash布局

8.1 用hex文件直接画出Flash占用图

在排查“为什么编译器报Flash溢出”的时候,有一个直观操作:写脚本解析hex,把每条记录的地址区间画出来,就能清楚地看到代码段、数据段分别占了多少Flash。虽然Keil的Build Output窗口也会report Program Size,但那个显示的是Code+RO+RW总大小,不展示布局。

我写的脚本逻辑很简单:遍历00记录,把地址和长度登记到一个区间列表,最后合并重叠区间,输出各个区间起始地址、长度、总占用。这样能发现一个常见问题:分散加载文件配置不合理,导致代码段里有巨大空洞,hex文件看着大小正常,但bin却大得离谱,因为空洞被补0了。

8.2 从bin文件反推链接脚本参数

这是排查问题时最实用的一招。手里只有一个bin文件,不知道它烧到哪个地址,怎么做?

用十六进制工具打开bin文件,看前32个字节。ARM Cortex-M芯片的中断向量表开头是初始SP值和复位向量,复位向量是第2个字(偏移4字节处)。比如一个bin文件的前8字节是00 00 00 20 09 00 00 08,那么SP初值是0x20000000,复位向量是0x08000009(bit0是Thumb标志,实际地址是0x08000008)。从这个值能反推出链接脚本的Flash基地址是0x08000000附近。

这个方法在拿到陌生固件、或者忘了工程配置的时候,能快速定位固件烧录地址,配合调试器直接干分析。我在给客户做逆向兼容的时候,靠这个办法反推出了好几块板子的固件起始地址。

8.3 生成带版本号的bin固件

实际产线上经常遇到一个痛点:固件更新了,但车间里的文件还是老版本,烧完板子才发现不对。我的做法是写一个自动化脚本,在编译前自动生成一个包含版本号信息的结构体,编译进固件。

具体做法是在代码里定义一张版本表存到固定Flash地址(比如0x08080000),然后写个脚本在bin文件生成后,把版本号、编译时间、Git提交哈希写进去。这样拿任何bin文件出来,打开都能直接看到是什么时候编译的哪个版本。网上搜“bin文件打补丁”也是类似思路,在固定偏移位置修改特定字节。

实际操作中,记得在分散加载文件里为版本信息预留空间,并且主程序启动时主动读取校验,防止版本信息被意外覆盖。


9. 踩坑实录与个人总结

写了这么多,最后说说我自己在这个话题上掉过的坑,你们参考的时候能少走几步弯路。

第一个坑是混淆hex和bin的适用范围。刚入行时做OTA升级,想当然地给设备推送hex文件,结果接收端解析hex里的冒号和地址信息,处理逻辑复杂到爆,还不支持断点续传。后来统一改成bin文件,接收端直接按块写入Flash,代码量立马减少一大半。

第二个坑是Keil里生成bin文件的路径问题。有段时间我用的工程名带“V2”后缀,fromelf命令里的输出文件名写死了旧名字,导致每次生成bin都是旧版本,排障排了一整天。现在我的习惯是工程目录下建一个build文件夹,输出文件名用固定的app.bin,不跟工程名绑定,省心很多。

第三个坑是调试时依赖axf,但分发固件时忘记剥离调试信息。给客户发升级包之前,一定要确认发的是hex或bin,而不是axf。axf里除了源码信息,还带有完整的符号表,对商业固件来说是严重的泄露风险。我现在只要做对外发布,一律只发bin,并在发布脚本里自动丢弃axf。

最后再分享一个实用小技巧:改完代码编译后,先看bin文件的修改时间,再看文件大小,如果大小没变但时间更新了,十有八九是优化选项变了或者代码改动只涉及数据段。这时候别急着烧录,反汇编确认一下改动是否真的进去了,才能避免“改了没生效”的错觉。

嵌入式开发里hex、bin、axf是天天打交道的三兄弟,花半小时把它们的格式原理、转换方法和排查思路理清楚,后面做开发、调bug、量产、升级的时候,能省下的时间远远不止半小时。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 23:16:19

工业级配电开关设备选型必看:电气参数、公差范围与机械寿命

上周去一个工厂做配电柜改造回访&#xff0c;电气负责人翻着设备台账问我&#xff1a;工业级配电开关控制设备的参数表到底该看哪几个数&#xff1f;这问题我几乎每年都会遇到几回。低压框架断路器、塑壳断路器、中压真空断路器、交流接触器这些设备&#xff0c;选型时不能只看…

作者头像 李华
网站建设 2026/9/30 23:08:55

Python09:核心语法-数据存储与运算-字面量

Python核心语法&#xff1a;数据存储与运算数据的逻辑处理数据存储容器函数面向对象基础数据存储与运算&#xff1a;字面量与变量常见数据类型输入与输出运算符一、字面量字面量决定数据在代码中怎么写&#xff08;编写方式&#xff09;&#xff1b;变量决定数据在代码中如何存…

作者头像 李华
网站建设 2026/9/30 23:03:41

重磅消息:鸿蒙 7 正式版已推送!

据华为官方消息&#xff0c;Mate 80 系列、Pura 90 系列、nova16 系列等机型现支持升级鸿蒙 7 正式版了&#xff01;自 7 月 28 日花粉 Beta 版招募启动以来&#xff0c;历经两个月的快速迭代与海量场景打磨&#xff0c;鸿蒙 7 终于迎来了这一更稳定、更完善、体验更优的正式版…

作者头像 李华
网站建设 2026/9/30 23:03:14

电竞酒店多机位并发渲染的带宽与编解码选型实践 —— 从链路估算到NVENC/QSV参数落地

电竞酒店多机位并发渲染的带宽与编解码选型实践 —— 从链路估算到NVENC/QSV参数落地电竞酒店多机位并发渲染的核心矛盾不是单路画质&#xff0c;而是多路视频流叠加后的上行带宽、编码延迟与终端解码兼容性之间的平衡。 本文基于公开编码器参数与常见串流架构&#xff0c;拆解…

作者头像 李华
网站建设 2026/9/30 23:03:09

通达信黄钻必杀擒涨停指标公式

个股:EMA(100*(C-LLV(LOW,34))/(HHV(H,34)-LLV(LOW,34)),3),COLOR1010FF; 大盘:EMA(100*(INDEXC-LLV(INDEXL,34))/(HHV(INDEXH,34)-LLV(INDEXL,34)),3),COLORE67010,LINETHICK2; STICKLINE(个股>大盘,个股,大盘,1,0),COLORRED; STICKLINE(个股<大盘,个股,大盘,1,0),COLOR…

作者头像 李华
网站建设 2026/9/30 23:03:03

数据库核心八股终极典藏版:索引、事务与高可用面试全解析

腾讯技术面&#xff1a;数据库核心八股终极典藏版这两天后台好多读者在准备腾讯的技术面试&#xff0c;都在问数据库到底要看哪些内容。说实话&#xff0c;腾讯这种体量的公司&#xff0c;数据库考察早已不是“背几个概念就过关”的阶段了。面试官通常会在你回答完一个八股后连…

作者头像 李华