☰
Zynq程序固化全流程:从BOOT.bin生成到Flash烧录与排错指南
2026/9/28 12:58:54 网站建设 项目流程

做FPGA开发,尤其是Zynq这种带ARM核的SoC平台,“程序固化”几乎是每个人都要过的一关。很多朋友用Vivado做仿真、跑SDK调试都挺顺利,一碰到要把程序烧到Flash里,就开始对着报错日志发懵。这篇文章专门解决这个问题,从SDK配置到Flash烧录,把整个流程掰开揉碎讲清楚,适合刚接触Zynq开发板的同学,也适合被“flash download failed - target dll has been cancelled”这类错误折磨到抓狂的工程师。全程没有跳步,按顺序操作就能跑通。

1. 固化前先看懂:Zynq启动流程与固化本质

1.1 为什么程序非要固化,不能一直靠JTAG下载

很多初学者有一个疑问:我用JTAG把bitstream下载进去,程序不也能跑吗?为什么非要固化?这里面的核心差别在于存储介质。FPGA的配置数据存放在SRAM或者BRAM里,这类存储器是易失性的,也就是掉电即丢。JTAG调试时workspace里加载的程序只存在于当前上电状态,一旦断电,芯片内部干干净净,一切从头来过。

固化的本质,就是把需要加载的程序写进非易失性存储器里,比如QSPI Flash、SD卡、NAND Flash这类掉电不丢数据的介质。Zynq上电之后,片内的BootROM会自动从你选定的启动介质中读取启动镜像,完成加载,整个过程不需要电脑、不需要调试器。对产品来说,这是唯一能交付的运行方式。板子在客户那儿不可能每台都连着一根JTAG线。

在实际项目里,固化还有一个隐含需求:把PL侧的bitstream和PS侧的裸机程序或操作系统镜像打包在一起。因为Zynq是一个SoC,PS(处理器系统)和PL(可编程逻辑)要协同工作,固化的产物不是单一文件,而是一个包含多段内容的启动镜像,这也是很多人觉得固化比纯FPGA麻烦的真正原因。

1.2 一条启动链看懂BootROM、FSBL、bitstream和应用程序的关系

要理解Vivado和SDK里那堆文件到底在干什么,得先搞清楚Zynq的启动链路。整个启动过程分阶段推进,每一段代码只负责做一件事,然后把手里的活儿交给下一段。很多人固化失败,就是因为只关注了某一个文件,忽略了整条链的完整性。

第一个阶段是BootROM。这是芯片出厂时固化在ROM里的代码,上电就执行,CPU复位后第一条指令就来自这里。BootROM会根据启动模式引脚MIO[5:0]的电平,判断是从QSPI、SD卡还是NAND启动,然后把存储介质前特定偏移处的启动头读出来,加载FSBL。

第二个阶段是FSBL(First Stage Boot Loader)。它由Xilinx官方提供模板代码,本质是一个引导加载程序,负责初始化DDR内存、配置PS端的MIO引脚复用和时钟,然后去加载PL侧的bitstream。如果启动镜像里还有SSBL(比如U-Boot)或者用户的应用程序,FSBL也会把它们从Flash搬到DDR里,最后跳转执行。

第三个阶段才是用户真正的程序,可能是裸机C工程,也可能是嵌入式Linux的U-Boot、内核和设备树。这样一拆就清楚了:BootROM相当于电脑里的主板固件,FSBL相当于引导扇区,bitstream相当于PL侧的配置流文件,应用程序相当于操作系统。四者缺一不可,任何一段加载失败,启动过程就卡死在空中,表现就是串口无输出、程序不运行。

1.3 项目里用哪种启动介质,QSPI还是SD卡

固化方案的选型直接影响后续烧录流程。Zynq常见启动介质有QSPI Flash、SD卡、NAND Flash、NOR Flash四种,但实际项目中绝大多数用QSPI Flash和SD卡这两类。

QSPI Flash是目前最主流的固化介质。它占用引脚少,板级布线简单,容量一般在16MB到512MB之间,对大多数裸机程序和中等规模嵌入式Linux镜像都够用。它的读取速度快,支持XIP(片上执行),性价比很高。xilinx官方开发板很多都板载了QSPI Flash,从16MB到64MB不等。

SD卡启动多用于嵌入式Linux系统,因为Linux文件系统通常需要数百MB甚至GB级别的空间,QSPI Flash容量不够。但SD卡方案依赖SDIO接口,启动速度比QSPI慢,而且SD卡座和卡本身在工业环境中的可靠性不如Flash芯片稳定。NAND Flash容量大、成本低,但控制器复杂,需要软件处理ECC校验和坏块管理,对新手来说调试难度偏高。NOR Flash则因为引脚多、容量小,在Zynq平台已经很少作为独立启动介质使用。

我的建议很简单:如果只是裸机程序或者轻量级Linux系统,无脑选QSPI Flash固化。这篇教程后续默认使用QSPI Flash演示。

2. 动手前准备:软件环境、硬件连接与Flash型号确认

2.1 Vivado与SDK版本怎么选,装错了很麻烦

做固化流程,软件版本直接影响操作界面和工具链行为。Vivado和SDK(Software Development Kit)的版本必须严格对应,不能混用。2019.2及之前的版本,SDK作为一个独立组件集成在Vivado安装器里,安装时勾选SDK选项即可,装好后在Vivado里可以直接Launch SDK。从2020.1版本开始,Xilinx把SDK换成了Vitis,界面变化较大,操作入口不同,但底层流程依然保留。

如果你手里是新买的开发板,厂家提供的例程可能基于某个特定版本,最稳妥的做法是先装与例程配套的版本,不要去追最新版。追新版本容易遇到IP版本更新、约束文件格式变化这些额外麻烦。安装时记住一个原则:安装路径不要包含中文、不要包含空格,比如直接装到D:\Xilinx这种路径,否则后续综合、仿真都可能出现莫名其妙的问题。另外,Vivado正常运行要求电脑有足够内存和磁盘空间,8GB内存是最低要求,16GB以上体验才好,综合大工程时16GB内存也经常吃紧。

Windows系统下还有一个常见坑:WinPcap安装失败。这个问题多出现在Vivado安装程序准备以太网调试组件时,多数情况下可以跳过,不影响本地JTAG调试和固化流程,不用被它吓到。

2.2 硬件连接与JTAG链路确认,烧录前必做的三步检查

开始烧录之前,硬件连接一定要确认到位,否则浪费大量时间在找设备上。第一步,用JTAG调试器连接开发板的JTAG接口和电脑USB口。Xilinx USB Cable和Digilent JTAG-HS3/HSP都是常见选择。USB线尽量短,劣质线材在高速通信时会出现间歇性断连,这是很多“DLL被取消”报错的元凶。

第二步,打开电脑的设备管理器,在“通用串行总线设备”分类下能看到识别出来的调试器设备。不同厂商芯片显示的名字不一样,Digilent线通常显示为“Digilent USB Device”,Xilinx线显示为“Xilinx USB Cable”或“Xilinx Platform Cable USB”。如果这里看不到设备,优先重装驱动或更换USB口,不要急着打开Vivado。

第三步,打开Vivado的Hardware Manager,点击Open Target,正常情况下会列出JTAG链上的设备列表。Zynq系列芯片在JTAG链上会显示两个设备,一个是DAP,一个是ARM,分别对应调试访问接口和ARM处理器。能看到这两个设备才算链路正常,看不到就比对着第二步往下排查。硬件管理器里还可以设置JTAG频率,烧录和调试时保持在15MHz以下比较稳定,遇到线材一般或链路较长时降到3MHz能解决不少玄学问题。

2.3 确定板子上到底用的哪颗Flash,别想当然

Flash型号在烧录配置里必须选对,这是程序固化里最容易被忽略的环节。开发板不同,Flash芯片就不同。有的板子用Micron的N25Q128,有的用Winbond的W25Q256,还有用Spansion、ISSI的芯片。它们的基本命令协议大体兼容,但ID、密度、扇区大小各有差异,工具识别错误会导致擦除和编程地址错乱,表现就是烧录报“failed to communicate with the flash chip”。

从哪里查型号?第一去处是开发板原理图,搜索“Flash”“QSPI”“SPI”关键字,能看到具体的厂商和型号,比如“MT25QU256ABA1EW7”就是一颗Micron 256Mb的QSPI Flash。第二去处是板卡用户手册,通常会说明板载Flash容量和兼容型号。第三去处是直接读芯片丝印,芯片表面印有型号信息,找个放大镜看就能对上。

拿到型号后还要确认两个参数:供电电压和最大频率。同系列QSPI Flash有1.8V和3.3V两种版本,比如Micron的MT25Q系列带“E”后缀通常是1.8V,带“W”后缀是3.3V。烧录时SDK的Flash Device列表里会区分电压版本,选错电压类型同样会导致通信失败。

Flash厂商常见型号容量电压SDK中常显示的名称
MicronN25Q128A13E128Mb1.8Vn25q128-1.8v-spi-x1-x2-x4
MicronMT25QU256ABA256Mb1.8Vmt25qu256-1.8v-spi-x1-x2-x4
WinbondW25Q256JV256Mb3.3Vw25q256-3.3v-spi-x1-x2-x4
WinbondW25Q128JV128Mb3.3Vw25q128-3.3v-spi-x1-x2-x4
ISSIIS25LP128128Mb3.3Vis25lp128-3.3v-spi-x1-x2-x4

注意上表仅供参考,最终以板卡原理图和芯片数据手册为准。数据手册里还有每个命令的时序和地址范围,排查问题时用得上,建议下载一份放到手边。

3. 制作用于固化的产物:BIT与FSBL,一个都不能少

3.1 从Vivado导出硬件,为什么bitstream必须先生成

固化需要三类原料:PL侧的位流文件(bitstream)、FSBL的可执行文件、用户应用程序的可执行文件。这三个文件准备好了,才能合成最终的BOOT.bin镜像。

先说bitstream。在Vivado里完成综合、实现、生成bitstream三个步骤后,会得到一个.bit文件,默认路径在工程目录的工程名.runs/impl_1目录下,文件名类似design_1_wrapper.bit。很多新手卡在这一步,因为工程在Implementation阶段直接报错变红,根本到不了Generate Bitstream。遇到“implement design变红”别慌,点开Implementation的日志和Timing Summary,看看是时序违例、约束没写完整,还是DCP文件缺失。大部分实现失败都能在综合日志里找到根因,修掉再跑就是。

bitstream生成之后,下一步是导出硬件。在Vivado菜单栏选择File -> Export Hardware,弹出对话框后务必勾选“Include bitstream”选项。如果不勾选,导出的硬件描述文件里不包含PL侧配置,后面SDK生成BOOT.bin时没有bit可用。导出的文件后缀有两种:老版本是.hdf,新版本是.xsa,内容逻辑相同,都是描述当前硬件平台的文件。

导出完成后,打开Vivado SDK(或Vitis),工作空间选择你指定的目录,然后File -> New -> Hardware Platform,选中刚才导出的硬件文件。这一步很重要,SDK的所有工程都要挂在这个硬件平台上,否则后续找不到FSBL模板和bit文件。

3.2 SDK里创建FSBL工程,模板选择是唯一的关键

FSBL不需要自己从头写,Xilinx官方提供现成模板,你要做的事就是创建工程、编译、拿.elf文件。打开SDK后,在菜单栏选择File -> New -> Application Project,工程名可以叫fsbl,Processor选择当前Zynq芯片对应的ARM核,Next进入模板选择页面,在列表里找到“Zynq FSBL”模板,选中并Finish。

等待工程编译完成后,工程目录下会生成fsbl.elf文件,默认路径在fsbl/Debug/目录下。这个elf就是启动链里的引导加载程序。正常情况下不需要修改FSBL源码。只有当你有特殊需求,比如自定义DDR初始化时序、调整启动等待时间时,才需要修改FSBL源码里的相应函数,修改后重新编译即可。

编译FSBL时要注意一个坑:如果你的硬件工程里用了PS端的MIO引脚或者DDR配置,FSBL启动时会根据硬件描述文件里的配置去初始化DDR和MIO。所以硬件平台文件必须是最终版的、与你当前板卡匹配的,不能拿一个改过引脚约束的旧版本去凑合。否则虽然烧录成功,启动时DDR都可能初始化失败,程序一片空白。

用户应用程序的创建类似,File -> New -> Application Project,模板选“Hello World”或者“Empty Application”,写出你的裸机程序或者直接用于固化测试,编译后生成app.elf。如果你想用Linux系统固化,则这一步变成编译U-Boot得到u-boot.elf,原理相同,位置不同。

3.3 生成BOOT.bin:Create Boot Image的操作细节与bif结构

三个elf/bit准备好之后,就该打包了。SDK菜单栏选择Xilinx -> Create Boot Image,打开创建启动镜像对话框。这是固化流程里最关键的一步,分区顺序错了,哪怕烧录成功也启动不了。

操作流程如下。第一,在Boot Image Partitions区域,先添加FSBL文件,点击Add,选择fsbl.elf,Partition type选择“bootloader”。这一项必须标记为bootloader,Bootgen工具才能正确生成启动头。第二,再次点击Add,选择bit文件,Partition type保持默认的“datafile”。第三,第三次点击Add,选择用户应用程序的elf文件,比如app.elf,Partition type保持datafile。如果后续要启动Linux,这个位置放u-boot.elf。

Output格式默认是BIN,也可选MCS,这里用BIN即可。指定输出路径,建议输出到工程根目录下,然后点击Create Image。几秒后会在指定目录生成BOOT.bin文件。

你可以查看同一目录下自动生成的.bif文本文件,内容大致如下:

the_ROM_image: { [bootloader] fsbl.elf design_1_wrapper.bit app.elf }

这个bif是Bootgen工具的输入描述文件,用文本编辑器可以直接编辑。熟练掌握bif语法之后,可以在命令行用“bootgen -image xxx.bif -o BOOT.bin”的格式批量生成镜像,这在脚本化构建固件时非常有用。不过刚上手还是建议在SDK图形界面操作,直观、不易出错。

分区顺序是BOOT.bin生成中唯一需要用力记住的规则:FSBL必须在第一个分区,bitstream其次,应用elf最后。如果把bitstream放在第一位,BootROM会尝试把它当成FSBL加载,然后直接跑飞,串口上一行打印都没有。

4. Flash烧录实操:从擦除到校验的完整步骤

4.1 Program Flash Memory工具的每个选项到底在干什么

BOOT.bin拿到手,接下来就是烧录环节。在SDK里选择Xilinx -> Program Flash Memory,打开烧录工具。这个界面上有几个选项,每个都有意义,不能随便填。

Image File:选择要烧录的镜像,也就是前面生成的BOOT.bin。Offset:镜像烧写到Flash的起始地址,绝大多数情况下填0x0。BootROM上电后就是从这个地址读取启动头,填错地址则启动失败。Flash Type:Flash类型,常见选项是qspi-x4-single,意思是四线QSPI单die配置。还有qspi-x8、qspi-x1等选项,要根据板卡硬件连接方式选择。大部分开发板Flash的DQ0-DQ3四根线都连到了Zynq的QSPI控制器上,用x4模式即可。Flash Device:选择具体的Flash芯片型号,上一步查好的型号在这里用上。FSBL File:这里还要再选一次fsbl.elf,不过不是用来打包的,而是用来执行的。烧录程序本身需要跑在CPU上,XSCT工具会把fsbl.elf加载到OCM运行,FSBL再初始化QSPI控制器并执行Flash擦写操作。

很多新手不理解为什么烧录Flash还要FSBL文件。简单说,QSPI控制器位于PS侧的I/O外设区域,操作QSPI Flash前需要完成MIO引脚复用配置和时钟初始化,这些工作正是FSBL干的事。没有这个文件,工具连Flash芯片都访问不了。

4.2 烧录全流程实测:擦除、写入、校验一气呵成

确认硬件连接正常、镜像文件齐全、Flash型号无误后,就可以执行烧录了。整个流程我按顺序给你过一遍。

第一步,先确认当前JTAG链路中没有其他进程占用。Vivado Hardware Manager如果已经连着target,再在SDK里启动Program Flash可能会冲突。最稳妥的顺序是:先关闭Hardware Manager的session,再在SDK里执行烧录。

第二步,打开Program Flash Memory,按照上节所述的配置填好各个选项,点击Program按钮。这时脚本会自动执行:连接ARM核、下载FSBL到OCM、运行FSBL初始化、向Flash发送擦除命令、逐页写入BOOT.bin、回读校验。Console窗口会实时打印执行日志,整个过程根据镜像大小不同,几十秒到几分钟不等。

第三步,观察日志输出。出现“Flash Operation Successful”或者类似的成功提示才算真正完成。如果中途弹出“error: flash download failed - target dll has been cancelled”之类的内容,那就是第5章的排查内容了,先继续往下看正常流程。

这里补充一个自己总结的小技巧:正式烧录之前,先把目标Flash区域擦除一遍。SDK的Program Flash流程里自带擦除动作,但偶尔会因为Flash状态未准备好而跳过擦除,直接向非空区域编程,导致启动异常。稳妥做法是先通过工具或脚本对整片Flash执行擦除,确认“Erase Completed”后再执行完整烧录。强制擦除的代价只是多花十几秒,但能规避大量莫名启动失败问题。

4.3 固化完成后的启动验证:跳线、上电、看串口

烧录窗口显示成功并不等于万事大吉,最关键的验证动作是断电重启。首先,把开发板上的启动模式跳线或拨码开关切到QSPI启动模式。不同开发板的设置方式不同,有的在板子背面丝印了“QSPI/SD/JTAG”的说明,有的需要看原理图确认MIO[5:0]引脚对应的电平组合。以常见Zynq-7000为例,QSPI启动模式的MIO[5:0]电平通常为010010(具体值请查看你的板卡手册,不要盲抄网上数据)。

切换完成后,连接好串口线,打开串口终端工具,波特率设置为板卡示例工程规定的值(大部分是115200),然后给板卡重新上电。观察串口打印。如果一切正常,能看到FSBL的启动信息,接着是应用程序的打印输出。如果用的是纯PL逻辑工程而没有PS应用,可以通过观察板卡LED或加个逻辑分析仪来判断PL侧是否被正确配置。

如果重新上电后串口无任何输出,不要急着怀疑Flash没烧进去,先回头检查四点:启动模式拨对了没有;BOOT.bin是不是确实包含FSBL且FSBL排在第一个分区;Flash供电和WP引脚是否有正确的上下拉;QSPI Flash型号是否选择正确。这四个问题按优先级排查,大概率能定位。

5. 常见报错与排查技巧实录

5.1 “flash download failed - target dll has been cancelled”深度排查

这个报错是Xilinx论坛上被问得最多的问题之一,也是我最开始踩过的坑。报错信息本身并不说明具体原因,只表示下载过程中,target DLL(即与硬件通信的动态链接库)操作被外部取消或中断。从原理上讲,出现这个错误只有两大类的可能:一类是通信链路物理层不稳定,另一类是软件层面有多个进程抢占了调试器。

物理层排查顺序:先换一根高质量的USB线,长度不要超过1米,避开USB Hub直连主机;然后换电脑原生USB口,优先用蓝色USB3.0口,有时候主板前置面板的USB口供电不足会引发此问题;检查开发板是否独立供电且电源指示灯正常,调试器虽然能给JTAG链路供电,但不足以支撑整个板卡工作。一个很多工程师忽略的点是JTAG链路上的设备太多且IDCODE异常,建议断开JTAG链上其他不相关的设备,只留下目标Zynq芯片。

软件层面排查顺序:关闭所有可能占用调试器的窗口,包括Hardware Manager、多个SDK实例、Vivado Tcl Console;如果开着老版本SDK的调试会话,先全部停掉再重试;重新插拔USB线让Windows重新枚举设备,必要时重启一次电脑。我自己解决这个报错的最快路径是:拔掉USB线、关闭Vivado和SDK、重新插线、重启Hardware Manager、确认能看到设备后再去SDK烧录。这一套流程能解决七八成“DLL被取消”的玄学问题。

5.2 “failed to communicate with the flash chip”的三大真实原因

另一个高频报错就是“warning: failed to communicate with the flash chip, read/write operations wi...”。这个问题通常不是通信链路的问题,而是Flash本身没有被正确访问。

第一个原因是Flash型号选错。SDK的Flash Device列表按厂商、型号、电压分类,不同型号的读ID命令、状态寄存器地址可能有差异。工具先向Flash发送读ID命令,如果返回的ID与所选型号不匹配,就会报无法通信。解决办法是仔细核对芯片丝印和原理图,选择精确的型号,不要选“Generic SPI Flash”之类的模糊选项。

第二个原因是Flash供电电压配置错误。1.8V的Flash选了3.3V,或者反过来,芯片VCC引脚电平与Zynq QSPI控制器I/O bank电平不匹配,都会导致通信彻底失败。Zynq的QSPI控制器所在的MIO bank由VCCMIO引脚供电,必须保证Flash和VCCMIO电平一致。检查开发板原理图,确认VCCMIO的电平等级,再在SDK里选择对应电压版本的Flash型号。

第三个原因是FSBL没有成功初始化QSPI控制器。如果烧录时选择的FSBL文件与当前硬件工程的MIO配置不一致,尤其是MIO引脚复用表里没有把QSPI功能分配到正确的引脚组,那么FSBL运行时QSPI控制器引脚就是悬空的,自然无法访问Flash。这时要回硬件工程确认PS引脚配置里QSPI的MIO连接是否正确,重新导出硬件并编译FSBL后再试。

5.3 “cannot load flash device description”怎么破

还有一类报错会明确告知“cannot load flash device description”,意思是SDK/Vitis内置的Flash描述库中没有找到匹配的芯片描述文件。这个问题主要出现在Vivado版本较旧、Flash芯片较新,或者芯片型号冷门的情况下。

解决办法有三条路。一是升级Vivado/SDK版本,新版本工具的Flash描述库更加完整,很多新发布的Flash型号都能识别。二是绕过SDK的Flash Device下拉列表,直接使用Hardware Manager Programming Flash模块。在Vivado Hardware Manager中,右击设备选择“Add Configuration Memory Device”,工具会尝试自动探测Flash ID,并根据ID匹配已知部件型号,成功匹配后即可直接烧写,不需要在SDK里选择型号。三是自己手动创建MCS镜像并配置,用Program Flash中的Generic选项手动输入Flash命令参数,这个方法适合熟悉Flash底层时序的工程师,新手优先尝试前两种。

需要提醒的是,如果选择升级Vivado版本,要注意工程和IP核的版本兼容问题。老版本的IP在新版本Vivado中可能被标记为未升级,需要先跑一次IP Catalog里查看哪些IP需要升级,再继续后续流程。

5.4 一张表整理高频固化故障,按优先级排查

故障现象首要原因次要原因推荐排查动作
烧录报target dll cancelled调试器通信受干扰软件抢占调试器、驱动异常换USB口/线,重启Vivado与SDK,关闭多余调试会话
无法与Flash芯片通信Flash型号或电压选错QSPI控制器初始化失败核对芯片丝印,确认VCCMIO电平和Flash供电电压,更换精确型号
cannot load flash device descriptionSDK Flash库无此型号工具版本过旧升级工具版本或用Hardware Manager自动探测Flash ID
烧录成功但断电后不启动启动模式未切换到QSPIBOOT.bin分区顺序错误检查MIO[5:0]跳线,重新生成BOOT.bin并确认FSBL在首位
串口启动打印到一半卡死Flash地址与分区不符DDR初始化失败核对Offset是否为0x0,检查FSBL是否匹配当前DDR配置
JTAG链找不到设备驱动未装或线缆问题JTAG频率过高检查设备管理器,更换线缆,降低JTAG频率到3MHz
Flash写入后回读数据不符Flash坏块或工作电压不稳烧录频率过高降低烧写时钟频率,先整片擦除再重新写入

排查的基本原则是先从最基础的物理层查起,再一步步往上走。不要一上来就怀疑工具bug或者芯片坏掉,大多数问题都出在连接、配置、电源这三类常见原因上。

6. 一些只有踩过坑才知道的细节

这里分享几个实际操作中得来的心得,常规教程里不会写这么细,但每一条都能帮你省下半天时间。

第一,JTAG频率能调低就调低。我和同事在实际调试中发现,很多“下载失败”“DLL cancelled”问题,把JTAG频率从30MHz降到3MHz就自动消失了。在调试阶段,CPU运行频率和JTAG频率都无所谓,稳定压倒一切,烧录速度慢一点儿换来的是成功率大幅提升。

第二,养成保存bif文件的习惯。每次在SDK图形界面生成BOOT.bin时,工具都会生成对应的.bif文件。把这个文件保存好,以后改工程后可以直接命令行生成,避免了反复打开图形界面点选文件的重复劳动。命令行格式就是“bootgen -image xxx.bif -o BOOT.bin”,在Vivado的Tcl Console里就能执行。

第三,断电重启才是唯一标准。烧录成功后不要急着庆祝,也不要只看烧录工具提示成功就认为固件正确。把启动模式切到QSPI,断电,重新上电,观察应用是否正常运行。有些情况下烧录虽然成功,但BOOT.bin内部文件有问题,只有真正的断电启动才能暴露出来。

最后再说一个让我印象极深的案例。有次追查一个固化后启动随机失败的bug,挠头查了三个小时,换了各种Flash型号和烧录频率都没解决,最后发现是Flash芯片的WP(写保护)引脚被悬空了,导致电路噪声耦合使Flash进入写保护状态,部分扇区怎么擦都擦不掉。所以拿到一块新板子,先确认Flash的控制引脚(WP、HOLD)有正确的上下拉电阻,这类细节往往藏在原理图最不起眼的角落,却能把整个固化流程搅得天翻地覆。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询