Zynq Vitis烧写QSPI Flash(W25Q256FV)完整指南与报错排查

软件测试面试题汇总 软件测试面试题汇总 测试技术面试题 ........................................................................................................................................................................ 5 1、什么是兼容 阅读详情

拿到一块Zynq板卡,大多数人第一件事是点灯、跑个Hello World,但真正让板子脱离JTAG和电脑独立工作,必须把启动镜像“固化”到板载Flash里。我最近用Vitis给Zynq-7020配合的W25Q256FV做烧写,先后碰到过芯片不识别、Flash下载时报“Target DLL has been cancelled”、烧写过程中提示无法与Flash芯片通信等一系列问题。这篇文章就是以W25Q256FV为对象,把Zynq通过Vitis烧写QSPI Flash的完整流程、每个环节的原理、以及这些报错的真实排查链路讲清楚。适合正在做Zynq-7000系列产品,或者刚接触Vitis烧写、卡在报错里出不来的同学参考。

1. 为什么板卡上选W25Q256FV:这颗Flash和Zynq的搭配逻辑

先别急着打开Vitis,得先搞清楚W25Q256FV到底是什么、在板子上承担什么职责。W25Q256FV是Winbond(华邦)的256Mbit SPI NOR Flash,换算过来是32MB存储空间,供电3.3V,支持标准SPI、Dual SPI、Quad SPI以及QPI模式。它和后面经常见到的W25Q256JV、W25Q128JV是同一个家族,指令集基本兼容,只是工艺、频率和ID有些差异,JEDEC ID通常是0xEF 0x40 0x19,这也是区分Flash型号时最直接的依据。

Zynq-7000系列的PS端自带一个QSPI控制器,通过固定的MIO引脚外接SPI NOR Flash。也就是说,只要在Vivado里把PS端QSPI外设打开,硬件连好线,软件侧就能通过FSBL、U-Boot或者裸机驱动访问这颗Flash。Zynq的上电启动流程是:BootROM先读取QSPI里的启动头,把FSBL加载到OCM(片上内存)运行,FSBL再初始化DDR、配置PL端bitstream、把应用程序加载到DDR里执行。所以这块Flash实际上承担的是“启动介质”的角色,一切脱离JTAG跑的裸机程序、Linux内核和根文件系统,最终都要落到它上面。

那么为什么很多Zynq开发板宁可选W25Q256FV,也不用SD卡或eMMC?我个人的理解是,QSPI NOR在几个维度上比较适合Zynq这种场景:

  • 引脚占用少,6根信号线就够,PCB布线压力小。
  • 启动时序简单,Zynq BootROM原生支持QSPI启动,不需要额外驱动。
  • 可靠性高,NOR Flash的随机读取性能远好于NAND,读写寿命一般标称10万次擦写,做启动介质很稳妥。
  • 比SD卡稳,不会出现接触不良、文件系统异常导致启动失败的问题。
  • 32MB容量足够放FSBL、bitstream和体积不大的应用程序,一些Linux系统如果裁剪得当也能塞进去。

要注意的是,W25Q256FV不是按照字节随机写入的,写入前必须先擦除,擦除最小单位是4KB扇区,读取则是按页(256字节)或连续读取。只要理解了“先擦后写、擦除粒度大、写地址要落到扇区内”这几个特性,后面看烧写日志就不会一头雾水。

还有一个很多人忽略的点:这颗Flash的地址宽度是24位/32位可切换。256Mbit总容量是32MB,而24位地址最多只能寻址16MB。上电默认是3字节地址模式,要访问高16MB空间,必须切换到4字节地址模式。这个特性直接关系到大镜像烧写和高地址分区,后面细说。

2. 烧写前的硬件核对清单与镜像类型选择

很多人烧写失败不是软件操作问题,而是硬件状态没对上。Vitis烧写Flash和普通JTAG调试有一个显著区别:Program Flash流程会把FSBL下载到Zynq内部运行,由FSBL来初始化QSPI控制器,然后通过JTAG间接完成Flash的擦除、写入和校验。换句话说,FSBL相当于一个“代理”,所以硬件上必须保证PS能正常工作,JTAG链路要通畅,而且QSPI引脚的电平、片选、时钟都要正确。

2.1 连线与电平:先查原理图再动手

Zynq-7000的QSPI控制器信号一般分配在MIO[6:0]这一组里,包括SCLK、DI/DO(IO0/IO1)、IO2、IO3、以及片选,具体哪一个MIO对应哪一个信号,不同板卡可能略有差异,强烈建议打开自己板卡原理图确认,不要照抄网上的引脚编号。确认点主要有三个:

  1. QSPI Flash的VCC是否和PS端的MIO bank共电源域,一般都要3.3V,如果Flash供电是1.8V而MIO bank是3.3V,通信会不稳定,甚至直接烧坏器件。
  2. 片选上拉、HOLD引脚和WP引脚的接法是否合理,HOLD和WP如果悬空,会导致进入写保护或者暂停状态,烧写时表现就是Flash ID能读、擦除却没反应。
  3. 板上是否使用了电平转换或总线开关,有些板子同时让QSPI和别的外设共享MIO,需要通过跳线切换,没有切过去的话信号被别的器件占用,必然通信失败。

如果你用的是杜邦线外接Flash模块来做实验,我劝你趁早放弃。QSPI在几十MHz下对信号完整性还是有要求的,杜邦线接触电阻大、寄生电感高,在2MHz下也许能跑,一旦提高QSPI时钟就会随机报错。板载贴片Flash是首选。

2.2 启动模式拨码:JTAG模式还是QSPI模式

Zynq的启动模式由MIO上的启动模式引脚决定,Vitis烧写时必须把板卡设置为JTAG启动模式。这样做的好处是,BootROM不会尝试从QSPI或SD卡执行代码,JTAG控制器能直接控制PS,FSBL能干净地从OCM启动。有些板卡在QSPI启动模式下也能烧写,但偶尔会发生启动代码和调试器抢总线的情况,排查起来很绕,所以不要给自己添乱。

烧写完成后,再把拨码切回QSPI启动,复位板卡。如果这个顺序搞反,经常出现“烧写显示成功,但一上电根本没反应”的现象。

2.3 镜像类型:BOOT.BIN、BIN还是ELF

Vitis的Program Flash界面能接受多种文件,但要注意它们的作用完全不同:

  • BOOT.BIN是最终用于启动的镜像,包含启动头、FSBL、bitstream和应用程序,通常烧写到Flash起始地址0x0。
  • FSBL.elf是第一阶段启动加载器,它既可以是BOOT.BIN的一部分,也可以在烧写时作为“过渡代理”,先被JTAG加载到OCM运行,再操作Flash。
  • .bit文件是PL配置数据,可以单独烧写,但单独烧写它不代表板子能启动,因为还需要FSBL来引导。

我见过不少初学者直接拿一个hello_world.elf去Program Flash,然后抱怨启动不了。单个elf本身不是启动镜像,必须通过Bootgen或者Vitis的Create Boot Image功能打包成BIN格式才行。所以烧写前脑袋里要有一张图: 烧BOOT.BIN是最终目标,FSBL是烧写过程用的代理,bitstream和应用程序只是BOOT.BIN的组成部分 。

3. Vitis中的实际烧写操作:GUI和命令行两种走法

这一章是操作主线。我以Vitis 2020.1及以上版本为例,因为从2019.2开始Xilinx SDK逐渐被Vitis取代,菜单名和界面有一些变化,但这个流程在Vitis 2020~2023版本里基本通用。

3.1 第一步:在Vivado里导出包含QSPI配置的XSA

烧写的前提是硬件工程要正确。打开Vivado的Block Design,在Zynq PS配置界面里,把QSPI外设打开,选择Single QSPI或Dual QSPI,并确认MIO分配和你板卡实际一致。QSPI的工作频率建议先按默认值,等烧写稳定后再考虑提高速度。然后generate bitstream,完成综合实现。

生成完bitstream后,菜单File -> Export Hardware,勾选Include bitstream,导出XSA文件。这个XSA会带着QSPI外设配置和bitstream信息,是后面Vitis工程的“硬件底座”。如果XSA里忘了包含bitstream,有些烧写环节也能跑,但Program Flash在需要配置PL时会找不到数据。

提示:Vivado和Vitis版本最好匹配,比如Vivado/Vitis 2021.1配2021.1。跨大版本使用XSA经常出现兼容性问题,最常见的现象就是Vitis里建平台时报错,或者打开硬件工程后外设列表为空。

3.2 第二步:在Vitis里创建平台工程并生成FSBL

打开Vitis,设置好Workspace后,用XSA创建Platform Project。平台工程里会自动包含FSBL相关的源文件和BSP。接着创建一个Application Project,模板选择“Empty Application(C)”即可,因为我们只想要一个能编过的裸机hello_world,或者干脆就用平台工程生成的FSBL作为烧写代理。

你可能会问:为什么明明只是烧写Flash,还要创建一个应用工程?原因在于Program Flash需要用到FSBL.elf,而FSBL一般随着平台工程生成。在Vitis里构建平台工程,构建选项里选择Release还是Debug都行,重点是最后能在工程目录下找到 fsbl.elf 。如果你后续要生成BOOT.BIN,还需要有一个应用elf,所以顺手建一个hello_world应用用来验证链路,也是常见做法。

3.3 第三步:确认JTAG连接和芯片识别

烧写前一定先在Vivado Hardware Manager或Vitis的“Xilinx -> Hardware Manager”里确认目标芯片已经被识别。打开Hardware Manager,如果能看到xc7z020或者xc7z010,说明JTAG链路是通的。如果这里都识别不到,后面Program Flash大概率会报“Target DLL has been cancelled”或者“Cannot detect target”。

这一步顺便可以读一眼Flash的ID。有些版本的硬件管理器能直接看到连接的SPI Flash型号,如果显示0xEF4019,说明W25Q256FV在链路上应答正常。注意: 硬件管理器看到的是JTAG链上的器件,不一定代表QSPI通信正常 ,但它至少能证明PS没有死锁、电源没问题。

3.4 第四步:执行Program Flash

在Vitis菜单栏选择Xilinx -> Program Flash,或者直接点击工具栏里的“Program Flash”按钮,弹出对话框后填写:

  • Image File:选择BOOT.BIN,或者你想烧写的.bin文件。
  • FSBL File:选择前面构建出的fsbl.elf。
  • Flash Type:选择qspi-x4-single,这是最常用的Zynq QSPI四线模式。
  • Offset:通常填0x0。
  • Cable / Target:选择当前连接的JTAG目标。

点Program后,Vitis会先通过JTAG把FSBL加载到OCM,然后由FSBL初始化QSPI,执行擦除、写入、校验的流程。日志窗口会出现类似 Erase Operation. Please wait... 、 Program Operation... 、 Verify Operation... 的提示。整个烧写W25Q256FV的速度取决于镜像大小和QSPI时钟,一般BOOT.BIN在几MB以内,一两分钟内完成都算正常。

除了GUI,命令行方式适合批处理和脚本集成。在Vitis的Xilinx Shell(或Vivado的xsct环境)里可以调用program_flash工具:

program_flash -f BOOT.BIN -offset 0x0 -flash_type qspi-x4-single -fsbl fsbl.elf -cable type xilinx_tcf url TCP:127.0.0.1:3121

如果你想在烧写后额外做校验,可以加上 -verify 参数。命令行和GUI底层调用的其实是同一套东西,GUI适合单板调试,命令行适合量产或自动化流程。

烧写完成后,先不要急着断电。把启动模式拨码切换到QSPI启动,按一下板卡复位键,观察串口输出是否出现FSBL的启动日志或hello_world打印。如果这一步通过,说明整个固化流程闭环了。

4. 排查现场:目标取消、Flash通信失败、芯片识别不到

标题里的“常见问题解决”是重点,我按实际排障频率从高到低讲。每次排障我都会坚持一个习惯:先看完整日志,再猜原因,不要一上来就怀疑硬件。

4.1 Error: Flash download failed - Target DLL has been cancelled

这个报错很经典,基本每个用Vitis/SDK烧写过的人都会遇到一次。它的英文原文是 Flash download failed - Target DLL has been cancelled ,中文大概意思就是“Flash下载失败,目标DLL被取消”。很多人看到DLL这个词就以为是Windows动态库损坏,其实不是。

实际排查中,我发现这个报错绝大多数来自JTAG目标连接被中断,而不是Flash本身的问题。日志里如果已经出现“Connecting to target”然后立刻跳到“Target DLL has been cancelled”,优先检查下面几项:

  1. JTAG连接线是否松动,尤其是那种多根杜邦线拼出来的下载线,接触不良是最常见原因。
  2. Vitis是否和Vivado Hardware Manager同时打开了同一个目标,两个软件抢占JTAG资源,导致连接被取消。关掉其中一个再试。
  3. hw_server进程是否异常。Vitis连接目标时依赖后台的hw_server,这个进程如果崩溃或端口被占用,就会中断连接。可以用任务管理器关掉所有hw_server进程,重新打开Vitis再试。
  4. 板卡电源是否稳定。有些板子JTAG和PS供电是分开的,如果PS没上电,JTAG虽然能看到芯片,但一旦尝试加载FSBL到OCM,就会因为CPU没运行而中止。
  5. 目标连接地址设置问题。Vitis默认通过本地TCF端口连接,如果之前手动设置过远端地址,端口对不上同样会取消。

还有一个容易忽略的点:如果板卡处于QSPI启动模式,而QSPI里恰好有一个异常镜像,BootROM启动失败导致PS进入异常状态,也可能让JTAG无法建立控制。这时候先把启动模式切成JTAG,再重新连接。

4.2 Warning: failed to communicate with the flash chip

这个日志经常出现在Program Flash的早期阶段,完整信息类似 Warning: failed to communicate with the flash chip, read/write operations will fail 。它的直接含义是:FSBL的QSPI驱动已经尝试和Flash交互,但Flash没有给出正确的响应,或者响应超时。

按我的经验,主要原因有这些:

  • Flash Type选错。Vitis里的Flash Type要选对,W25Q256FV一般用 qspi-x4-single ,但你板子如果接的是1-bit SPI模式,那就要改成 qspi-x1-single 。模式不匹配时,Flash ID可能都读不出来。
  • 片选信号没拉低。检查板卡QSPI片选有没有连接到Zynq的QSPI CS引脚,有些板子把CS做成了GPIO控制,需要软件手动拉低,而FSBL默认不操作这个GPIO。
  • HOLD引脚被拉低。W25Q256FV的HOLD引脚(通常是IO3)如果被拉低,Flash会暂停通信。检查原理图上HOLD有没有接上拉电阻。
  • 供电不稳或Flash没焊接好。不要忽略这个基础问题,我曾遇到一块板子过回流焊后Flash虚焊,导致能识别JTAG但始终无法和Flash通信。
  • FSBL里的QSPI配置参数和实际Flash不匹配,比如时钟分频、模式寄存器配置不对。遇到这种情况,可以试试降低QSPI时钟频率,在Vitis的BSP设置里把QSPI时钟调低,排除高速信号问题。

如果上述都排除了,还有一个办法:直接Program Flash界面里手动选择Flash型号。Vitis会弹出一个下拉列表,里面有很多Spansion/Cypress/Micron的QSPI型号,如果你的W25Q256FV没有在列表里,可以手动添加或选择同容量、同类型的兼容型号。选择时要注意地址模式,32MB容量的Flash需要支持4字节地址。

4.3 Vitis下载调试时“不识别芯片”怎么解决

这个热搜问题经常出现在刚装完Vitis的用户身上。现象是Hardware Manager里空白,或者连接时提示“No hardware target detected”。排查思路按下面顺序来:

  1. 检查驱动。Vitis连JTAG通常依赖FTDI驱动或Digilent驱动。在Windows的设备管理器里,如果看到箭头感叹号,先重装驱动。
  2. 检查线缆类型。Platform Cable USB II、Digilent JTAG-HS3这类线缆有不同的驱动要求,确认你用的线缆被当前Vitis版本支持。
  3. 检查板卡的JTAG供电。有的板卡JTAG口需要板子主电源供电,只插USB下载线是不够的。
  4. 检查多个JTAG器件的菊花链。如果板上有多个JTAG器件,Zynq需要正确配置链的位置,Vitis有时识别不到是因为链上某个器件占用了IDCODE。
  5. 试着重启硬件服务器。Vitis菜单里有时候有Restart Hardware Server,或者直接关掉所有Vivado/Vitis进程,重新打开。

还有一种情况: 在隔离转接板或仿真头上,JTAG信号的电平和Zynq不匹配 。Zynq的JTAG引脚属于MIO bank,通常电平是1.8V或3.3V,取决于板卡设计。如果下载线是3.3V标准,而Zynq所在bank是1.8V,必须用转换板。

4.4 烧写期间Flash扇区擦除失败

Program Flash是“擦除-写入-校验”三步,如果擦除阶段失败,日志往往会指向某个扇区地址无法擦除,比如出现 Erase timeout 或者反复重试。这里要注意:W25Q256FV的擦除命令分为4KB扇区擦除、32KB块擦除、64KB块擦除和整片擦除。Vitis工具会根据镜像大小和Flash布局自动选择擦除粒度,但个别情况下,工具对这款Flash的支持不够完善,会把擦除命令发错。

这种情况的应急方案有三个:

  • 改小镜像尺寸,避开跨块边界的地址,看是否固定在某一个地址失败。
  • 手动切到 qspi-x1-single ,用最基础的单线SPI模式重试,排除四线模式下IO2/IO3虚焊或配置问题。
  • 先用Vivado Hardware Manager里的Flash编程功能把整片擦除,再回到Vitis写。这种做法相当于绕过程序自动擦除。

还有一个点,W25Q256FV有块保护(Block Protection)机制,状态寄存器里的BP位如果被置位,扇区会变成只读。FSBL或历史程序有可能修改过状态寄存器。遇到擦除不了的时候,可以先用Flash编程指令把状态寄存器恢复成非保护状态。Vitis界面里有些版本提供“Erase Entire Device”选项,实际执行时通常也会顺带清保护位。

4.5 烧写成功但上电不启动,或启动一半卡住

这个现象比上面几种更隐蔽。烧写流程全程没报错,校验也通过,但把启动模式切到QSPI后,板卡没有任何反应,或者只打印几行FSBL日志就卡住。

先查启动模式拨码是否真的切到了QSPI,有的板卡拨码丝印和实际逻辑是反的,我之前就被坑过。再查BOOT.BIN的组成是否正确,最稳妥的做法是在Vivado/Vitis的Create Boot Image界面里重新生成一次,确保启动头、FSBL、bitstream、app.elf的顺序和地址偏移正确。

还有一个经常被忽略的点: 如果你的镜像超过16MB,而FSBL或者BootROM没有正确进入4字节地址模式,那高16MB的内容虽然被“写进去”了,但启动时根本读不到 。W25Q256FV上电默认3字节地址模式,Zynq的QSPI驱动虽然能配置4字节模式,但不是所有版本的FSBL都默认开启。遇到大镜像启动失败,先确认FSBL的QSPI驱动配置里地址宽度是否正确,或者干脆把镜像控制在16MB以内验证。

如果启动只卡在FSBL阶段,优先怀疑DDR初始化失败。Zynq的FSBL一大功能就是初始化DDR控制器,如果DDR颗粒型号、时序参数和实际硬件不匹配,FSBL会在DDR测试或者加载阶段卡死。这个和Flash本身没有关系,但很多人不知道,会误以为Flash没烧好。

5. 固化后的启动验证、DDR问题与批量生产建议

5.1 烧写完成后如何“证明”真的好了

很多工程师的习惯是烧完马上断电切拨码,其实更好的顺序是:烧写完成后,保持JTAG连接,先读回Flash内容做个校验,再切到QSPI启动模式。Vitis Program Flash默认带校验,但如果你用的是命令行且没加 -verify 参数,就要额外做一次读回验证。

读回验证有两个层面:

  • 在Vitis里重新执行Program Flash,但不勾选擦除,只做Verify,或者使用Hardware Manager的Readback功能,把Flash内容读成二进制文件,和原始BOOT.BIN做对比。
  • 在U-Boot或Linux环境下执行 sf probe && sf read ,把Flash某段内容读到DDR,再用md5sum和原文件比对。

我个人更推荐第二种,因为它在真实启动环境下验证了Flash可读性。如果U-Boot环境下能正常 sf probe 识别到W25Q256FV,基本说明Flash通信、地址模式、ID识别都正常。

5.2 Zynq-7020用JTAG固化Flash时,必须使用DDR吗

这问题被问得非常多。答案是不必须,但在标准Vitis流程里,DDR往往会被初始化一次,于是很多人产生了“固化Flash必须依赖DDR”的错觉。

Program Flash的机制是:先把FSBL加载到Zynq的OCM里运行,FSBL再去控制QSPI。FSBL是由Vivado硬件工程生成的,如果硬件工程里启用了DDR控制器,FSBL启动时就会初始化DDR。所以你会看到烧写过程中DDR其实已经被初始化了一遍,但这不是“烧写Flash”本身的要求,而是FSBL顺带做的动作。

如果你的板卡没有DDR、DDR焊接有问题、或者DDR颗粒型号和Vivado配置不一致,标准流程就会在FSBL阶段失败,表现为Target DLL被打断、或者FSBL日志卡在DDR初始化相关位置。解决办法不是“必须有DDR”,而是让FSBL跳过DDR初始化,或者使用一个只针对QSPI的FSBL版本。在Vitis的BSP里可以调整FSBL源码,把DDR初始化相关代码注释掉,重新编译FSBL,再用这个FSBL去Program Flash。这样即使板上没有DDR,也能完成QSPI烧写。

对于Zynq-7020这种片内只有256KB OCM的芯片,如果你想在完全没有DDR的情况下跑应用程序,程序必须链接在OCM里。固化这类小镜像时,只要FSBL不初始化DDR,QSPI烧写是可以顺利完成的。

5.3 镜像布局建议:不要一股脑塞在0地址

很多人的BOOT.BIN就是把FSBL、bitstream、app.elf依次排开,全部烧在Flash偏移0x0。这样不是不行,但会给后续升级带来麻烦。更常见的做法是在BIF文件里显式指定每个分区的偏移地址:

the_ROM_image:
{
    [bootloader] fsbl.elf
    [offset=0x100000] system.bit
    [offset=0x500000] app.elf
}

这样FSBL在0x0,bitstream在1MB处,应用程序在5MB处。后续如果只更新app,就不需要把整个Flash擦掉重写,可以按分区擦除和烧写,速度更快,风险也更小。

实际项目中,QSPI Flash不只有启动镜像,还可以划出几个区域用来存参数、日志、或者做OTA备份。W25Q256FV有32MB空间,合理规划分区能让开发和量产都轻松很多。我的建议是至少预留两个镜像槽位:一个当前运行镜像,一个备份镜像,升级时先写备份区,校验成功后再切换,避免升级中途断电导致板子变砖。

5.4 烧写速度优化和量产烧写

开发阶段烧写慢一点无所谓的,但到了量产阶段,几十块板子每块等两三分钟,生产效率就很受影响。烧写速度主要受QSPI时钟频率影响,Vitis默认的FSBL里QSPI时钟通常比较保守,可以适当提高。改FSBL的BSP设置,把QSPI时钟从几十MHz提高到100MHz以上,但前提是板子布线质量要过关,否则会擦写失败或校验不一致。

量产烧写还要考虑另一个问题:不要用JTAG一板一板慢慢烧。如果产品量级达到几百上千,建议优先考虑以下方案:

  1. 制作烧写底板,用Vivado Hardware Manager配合批量烧写脚本,通过多路JTAG转接板同时烧写多块板。
  2. 如果产品有网口或USB口,先把一个Bootloader烧进Flash,后续通过Bootloader配合串口或网口升级应用程序,这也是最常见的量产流程。
  3. 出厂前把W25Q256FV先通过编程器烧好镜像,再贴片到PCB上,适合镜像内容固定、不需要现场烧写的场景。

我个人在实际项目里的习惯是:开发阶段用Vitis GUI烧,方便观察日志;小批量试产用命令行脚本烧,稳定可追溯;真正量产让产线用专用烧录底板。三种方式并不冲突,重要的是把镜像内容、分区布局、烧写版本号都管理好,否则半年后连自己都分不清板上烧的是哪一版。

回到这篇文章的主题,Vitis给Zynq烧写W25Q256FV本身并不神秘,本质就是FSBL当代理、QSPI控制器操作NOR Flash。把硬件连接、启动模式、镜像格式、FSBL可用性这几个要素理清楚,绝大多数报错都能在十分钟内定位。如果以后你在烧写时再遇到“Target DLL has been cancelled”,先别急着重装Vitis,按第4章的链路排查一遍,大概率是连接问题或FSBL启动问题。烧写已经到了最后一步,多花几分钟做一次完整的启动验证,能省下后面一整天的调试时间。

制作3D地形图的方法-使用GlobalMapper和3ds Max软件 打开GlobalMapper软件,在菜单栏中选择“文件”>“打开数据文件”,然后选择相应的高程数据文件。在菜单栏中选择“渲染”>“渲染设置”,根据需要进行设置,如分辨率和输出格式。选择地形对象,点击菜单栏中的“渲染”>“材质编辑器”,然后根据需要调整材质属性,如颜色、纹理和光照等。在菜单栏中选择“工具”>“高程栅格和网格”>“创建地形网格”。在菜单栏中选择“文件”>“导出”>“导出栅格格式”。打开3ds Max软件,在菜单栏中选择“文件”>“导入”,然后选择之前导出的地形数据文件。步骤3:导出地形网格。 阅读详情

相关推荐

【AUCell打分】:评估一个基因集在单细胞转录组的每个细胞中特定的活性程度

AUCell使用曲线下面积来计算输入基因集的一个有意义的基因子集是否在每个细胞的表达基因中富集。AUC 分数在所有细胞中的分布允许探索特征的相对表达。由于评分方法是基于排名的,因此 AUCell 与基因表达单位和归一化程序无关。此外,由于细胞是单独评估的,因此可以很容易地应用于更大的数据集。

weixin_40695088的博客 1万+

Codeforces Round #422 (Div. 2)

A: 给你两个数 (最小的那个<=12) 问这两个数阶乘的GCD 我都吓傻了 直接fac(min(a,b)) 搞定 //By SiriusRen #include <bits/stdc++.h> using namespace std; int A,B; long long t=1; int main(){ scanf("%d%d",&amp...

weixin_33912445的博客 102

从零到一:Firefly-RK3399上的Ubuntu镜像构建与GPU加速实战

本文详细介绍了在Firefly-RK3399开发板上从零构建深度优化的Ubuntu系统镜像的全过程,包括交叉编译环境配置、内核定制、GPU加速环境部署(Mesa Panfrost驱动、OpenCL/Vulkan支持)以及深度学习推理优化(TFLite + LinuxNN)。通过实战案例展示了如何充分发挥Mali-T860 GPU的硬件潜力,提升边缘AI应用的性能和能效。

pz8901234的博客 989

Codeforces Round #422 (Div. 2) A B C D

A I’m bored with life time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Holidays have finished. Thanks to the help of the hacker Leha, Noor

lzs_lazy 834

cf----2019-11-01(Water The Garden,Water The Garden,Tea Queue)

世上只有一种英雄主义,就是在认清生活真相之后依然热爱生活。 It is winter now, and Max decided it's about time he watered the garden. The garden can be represented asnconsecutive garden beds, numbered from1ton.kbeds conta...

0k-ok 522

如何理解Apollo模型参考自适应控制MRAC

最近有了解到百度无人驾驶Apollo项目中的横向控制有用到MRAC(Model Reference Adaptive Control),于是便详细研究了一下这个控制方法,在此总结一下心得。 什么是MRAC MRAC控制系统的基本结构图如下所示: 它由两个环路组成,由控制器和受控对象组成内环,这一部分称之为可调系统,由参考模型和自适应机构组成外环。实际上,该系统是在常规的反馈控制回路上再附加一个参考模型和控制器参数的自动调节回路而形成。在该系统中,参考模型的输出或状态相当于给定一个动态性能指标,(通常,参考模

zmhzmhzm的博客 6456

codeforce 11 27 A C

A Polycarpus has been working in the analytic department of the "F.R.A.U.D." company for as much as n days. Right now his task is to make a series of reports about the company's performance for the l

yumao19921006的专栏 657

AHB不对称半桥反激电路设计(一)变换器拓扑工作原理详解

本文详细分析了AHB(不对称半桥)反激变换器拓扑的工作原理及关键优势。该拓扑通过谐振腔结构实现原边功率管的零电压开通(ZVS)和副边整流管的零电流关断(ZCS),显著提升效率至95%以上。文章阐述了6个工作阶段的时序特征,包括谐振电感电流和电容电压的数学模型推导。AHB拓扑具有漏感能量回收、宽电压输出(适配PD快充等场景)和协同储能等优势,相比传统方案可缩小变压器体积30%,成为100-300W隔离电源的理想选择。

【Simon】的博客 6803

Codeforces Round #422 (Div. 2) D. My pretty girl Noora

题目链接:Codeforces Round #422 (Div. 2) D. My pretty girl Noora 题意: 给你一个数n和t,l,r,让你求t0·f(l) + t1·f(l + 1) + ... + tr - l·f(r). 其中f(n)是n个人的最少比较次数。 比如n为4,可以先2 2分,然后胜出2个人,最后再比较一次,所以f(4)=3。 f(3)=3,因为3为...

weixin_30678349的博客 152

Codeforces Round #422 (Div. 2) C. Hacker, pack your bags!

题目链接:Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 题意: 有n条线段,现在让你找两条线段,使得这两条不重合并且两条线段的长度和为x。 然后使得这两条线段的价值最小。 题解: 先将所有线段按照左端点排序,然后将对应长度的线段扔进容器里。 然后枚举每个线段,在对应的x-len的容器中去找左端点大于这条右端点并且价值...

weixin_30836759的博客 154

【Flutter 面试题】 怎么减少Widget的重新构建?

关于 const 关键字的使用:在 Flutter 开发中,任何时候当你确定一个 Widget 在其整个生命周期内都不会发生变化时,使用 const 关键字声明这个 Widget。这样的声明告诉 Flutter 框架这个 Widget 可以在编译时生成,后续的构建周期中可以重用已经创建的 Widget,从而避免了重复的构建开销。这适用于静态文本、图标或整个不变的 Widget 树。

Code Metaverse 1554

Codeforces Round #422 (Div. 2) 题解

比赛链接:http://codeforces.com/contest/822A. I’m bored with life解法:水题,模拟一下。#include <bits/stdc++.h> using namespace std;int main() { int A,B; scanf("%d%d",&A,&B); int C=min(A,B),ans=1; for(

I good vegetable a! 481

【002】C++ 语言核心:关键字深度解析与分类指南

auto:自动类型推导bool:布尔类型break:跳出循环或switch语句case:switch语句分支char:字符类型class:定义类const:常量continue:结束当前循环,开始下一次循环default:switch语句默认分支delete:删除对象do:do-while循环double:双精度浮点数类型else:if语句的否定分支enum:枚举类型explicit:显式构造函数export:导出符号extern:声明外部变量或函数。

Lion_Long的博客 1217

Codeforces Round #422 (Div. 2) 解题报告

A. I’m bored with life//Author: Lixiang #include<stdio.h> struct A{ int A,B; void init(){ scanf("%d%d",&A,&B); } void work(){ if(A>B){ int t=A; A

理想之国 439

【Codeforces Round #422 (Div. 2) B】Crossword solving

【题目链接】:http://codeforces.com/contest/822/problem/B 【题意】 让你用s去匹配t,问你最少需要修改s中的多少个字符; 才能在t中匹配到s; 【题解】 O(n2)的暴力搞就好; 【Number Of WA】 1 【反思】 一开始判断的时候脑抽了; 写成只有s[1]==t[1]的...

AWCXV 132

【C2000系列DSP的Bootloader详解】实现过程、流程图与示例代码

C2000 Bootloader 的核心逻辑可概括为 “初始化→选模式→加载程序→校验→跳转” 五步。对于小白来说,无需纠结底层寄存器配置(驱动库已封装),重点理解 “启动流程” 和 “数据传输 + 校验” 的核心思想即可。 通过本文的流程图和示例代码,相信你已经掌握了 C2000 Bootloader 的核心原理。实际开发中,可基于 TI 提供的 Bootloader 示例(C2000Ware 中自带)进行修改,快速适配自己的硬件和应用场景。

昔时扬尘处 343

Codeforces Round #422(Div 2)

A =w= B QvQ C 题意: 有n条线段(n<=2e5) 每条线段有左端点li,右端点ri,价值cost(1<=li<=ri<=2e5,cost<=1e9) 对于一个给定的x(x<=2e5),寻找两个不相交的线段,使它们的长度和恰好为x,并且价值和最小 分析: 想法肯定是枚举一个线段,然后去check剩余长度的线段中cost最小的那个 ...

weixin_30668887的博客 67

LeRobot 入门教程(七)数据集

LeRobot Dataset v3.0 是机器人学习数据的标准化格式,支持多模态时间序列数据和视频的统一访问。该版本通过基于文件的存储(Parquet/MP4)、关联元数据和Hub原生流式处理等新特性,显著提升了性能并降低了存储开销。文档详细介绍了格式设计、安装使用、数据记录与加载方法,以及从v2.1迁移到v3.0的步骤,特别针对大型数据集(如DROID 1.0.1)的处理提供了SLURM集群移植方案。v3.0通过优化文件组织和元数据管理,实现了更快的加载速度、更高的内存效率和更好的可扩展性。

2506_90492529的博客 2009

Codeforces Round #422 (Div. 2) B. Crossword solving

题目大意给出较短串s和较长串t,s可以对应在任何位置,最少有多少位置不匹配。题解暴力。。。。 (注意把边界去掉) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read() { char ch=getchar();int f=0;

mengbi_er的博客 279

Codeforces Beta Round #46 (Div. 2) E. Common ancestor

题意     定义变换:ai->bici :表示把字符串中的ai 字符变成bici 字符。再定义两个字符串 s1 s2 的公共祖先 s3:s1 s2 能够由 s3 经过一些变换分别得到。现在给你两个长度不超过 50 的字符串,问你他们的公共祖先中长度最短的是多少,输出这个最短长度。 做法分析     动态规划,如果我们知道了每个字符串中从第 i 个位置到第 j 个位置能否变成某个特定

蛤蛤~ 1万+

EasyRecovery Professional 6.22.02 ldr汉化

EasyRecovery 是世界著名数据恢复公司 Ontrack 的技术杰作,它是一个威力非常强大的硬盘数据恢复工具。能够帮你恢复丢失的数据以及重建文件系统。EasyRecovery不会向你的原始驱动器写入任何东东,它主要是在内存中重建文件分区表使数据能够安全地传输到其他驱动器中。你可以从被病毒破坏或是已经格式化的硬盘中恢复数据。该软件可以恢复大于 8.4GB的硬盘。支持长文件名。被破坏的硬盘中像丢失的引导记录、BIOS参数数据块;分区表;FAT 表;引导区都可以由它来进行恢复。这个版本使用新的数据恢复引擎,并且能够对 ZIP 文件以及微软的 Office系列文档进行修复!Professioanl (专业) 版更是囊括了磁盘诊断、数据恢复、文件修复、E-mail 修复等全部 4 大类目 19 个项目的各种数据文件修复和磁盘诊断方案。

Codeforces Round #777 (Div. 2) 简训

Codeforces Round #777 (Div. 2) 简训 日常训练,D题的分类很繁琐

C_eeking的博客 2055

C#ASP.NET大型合同管理系统源码 项目合同源码数据库 SQL2008源码类型 WebForm

ASP.NET大型合同管理系统源码 项目合同源码源码功能包含:合同管理系统(客户,供应商,项目,合同,进度)资金(计划收款,实际收款,计划付款,实际付款,发票)统计图(合同统计图,资金统计图)其它(知识库,日程,消息,计算器,天气预报)系统(组织机构,用户,权限设置,字典设置,提醒设置,密码设置,广告图片)帮助等,系统全开源,支持二次开发

Codeforces Round #269 (Div. 2) A~D

这次的CF除了最后一个都比较简单, 第一次用JAVA写CF....... Codeforces Round #269 (Div. 2) A. MUH and Sticks time limit per test 1 second memory limit per test 256 megabytes input

码代码的猿猿 2232

Codeforces Round #771 (Div. 2)简训

Codeforces Round #771 (Div. 2) 很巧,很多很妙的思路

C_eeking的博客 2021

电力场景电柜箱门把手检测数据集VOC+YOLO格式1167张1类别.7z

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):1167标注数量(xml文件个数):1167标注数量(txt文件个数):1167标注类别数:1标注类别名称:["red"]每个类别标注的框数:red 框数 = 1164总框数:1164使用标注工具:labelImg标注规则:对类别进行画矩形框重要说明:图片都是对一个场景下门把手进行标注,可能场景比较单一,请认真看图片示例谨慎下载。特别声明:本数据集不对训练的模型或者权重文件精度作任何保证,数据集只提供准确且合理标注更多信息:https://blog.csdn.net/FL1623863129/article/details/140017250

上一篇: 看门狗协同PMOS缓启电路:外设断电重启与浪涌抑制设计
下一篇: ResNet50食物图像识别落地实践:Food-101数据清洗到OpenVINO CPU实时推理
weixin_34226182
博客等级 码龄11年 3054粉丝 937原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值