STM32H7外置QSPI Flash应用实战:分散加载与下载算法全解析

news2026/3/14 23:54:14
1. 为什么你的STM32H7项目必须搞定外置QSPI Flash如果你正在用STM32H750或者H743这类高性能的MCU大概率会遇到和我一样的问题芯片内置的Flash不够用了。尤其是H750官方手册上那128KB的Flash听起来就像是个“启动区”稍微复杂点的应用加上个IAP在应用编程升级功能这点空间瞬间就捉襟见肘。这时候外挂一颗QSPI接口的Flash芯片就成了最自然的选择——容量大、成本低、接线也相对简单。但问题也随之而来。你以为把代码放到外置Flash里就像给电脑加了个硬盘那么简单吗完全不是。这相当于你把操作系统和所有软件都装在了移动硬盘上电脑主板上的那个小存储内置Flash只够放个引导程序。怎么让电脑CPU从移动硬盘QSPI Flash里顺畅地启动和运行程序这就是我们要解决的核心难题。我刚开始做这个方案的时候也踩了不少坑。最直接的感觉就是MDKKeil或者IAR这些我们熟悉的开发环境默认都是为芯片内置存储器服务的。当你告诉它“嘿我的代码有一部分要放在外面那个芯片里”它是一脸懵的。这会导致两个最棘手的问题链接器不知道把代码、数据放哪儿编译好的程序代码段.text、只读数据.rodata、初始化数据.data等等应该被放到哪个具体的内存地址链接器需要一份精确的“地图”这就是分散加载文件Scatter File。默认的地图只标注了内置Flash这片“大陆”我们需要手动把外置Flash这片“新大陆”加进去。调试器不知道怎么把程序烧录进去你点下“Download”按钮调试器J-Link, ST-Link怎么知道如何操作你外挂的那颗具体型号的Flash芯片呢是发什么命令擦除、编程、校验的时序是怎样的这就需要我们提供一个下载算法Flash Download Algorithm本质上是一段能在芯片RAM里运行的小程序专门负责和调试器配合对外置Flash进行读写操作。搞不定这两个你的项目就卡住了。所以这篇文章我就结合自己的实战经验把从“地图绘制”分散加载到“专用烧录工具制作”下载算法的完整流程掰开揉碎了讲给你听。目标就一个让你能顺利地把代码跑在外置QSPI Flash上并且能像内置Flash一样方便地下载和调试。2. 绘制代码的“内存地图”深度解析分散加载文件2.1 分散加载文件到底是什么一个生动的比喻你可以把整个单片机系统的内存空间想象成一个巨大的、空荡荡的仓库。这个仓库有不同的区域有的区域是冷冻库Flash非易失断电数据还在有的是临时周转区RAM易失断电数据丢失。编译器的工作是把你的C代码“生产”成机器指令和数据就是那些.o, .axf文件。链接器Linker的职责就是扮演一个“仓库管理员”它需要根据一份“货物摆放清单”把这些指令和数据搬运到仓库的指定位置。这份清单就是分散加载文件。平时我们用芯片内置FlashKeil已经为我们提供了一份默认的、针对该芯片型号的清单所以我们无需关心。但现在我们新增了一个“外置冷冻库”QSPI Flash默认清单里没有它的位置信息。如果我们不更新清单链接器就会把本该放外置库的货物错误地塞进内置库导致内置库爆满或者根本找不到地址而链接失败。2.2 手动编写你的第一份分散加载文件以MDKKeil为例我们通常创建一个后缀为.sct的文件。别被它的内容吓到我们一步步拆解。一个典型的需要支持外置Flash的分散加载文件结构如下LR_IROM1 0x08000000 0x20000 { ; 加载区域1起始地址0x08000000内置Flash大小128KB ER_IROM1 0x08000000 0x20000 { ; 执行区域1代码和只读数据放在这里启动代码、核心中断向量表等 *.o (RESET, First) ; 首先放置中断向量表 *(InRoot$$Sections) ; 库函数需要的特殊段 .ANY (RO) ; 其他所有只读内容代码、常量默认放这里 } RW_IRAM1 0x24000000 0x80000 { ; 执行区域2RAM区域放全局变量、堆栈等 .ANY (RW ZI) } } LR_IROM2 0x90000000 0x800000 { ; 加载区域2起始地址0x90000000QSPI Flash映射地址大小8MB ER_IROM2 0x90000000 0x800000 { ; 执行区域2外置Flash执行区域 *.o (SectionForQSPI) ; 你可以把特定文件如图形库、字库强制放到这里 .ANY (RO -CodeInRAM) ; 将所有其他只读内容除了标记为RAM运行的代码放到外置Flash } }关键点解读加载域LR_ vs 执行域ER_加载域定义了一个连续的存储区域用于存放“原始数据”执行域则定义了程序实际运行时代码和数据所在的地址。对于Flash加载地址和执行地址通常是相同的XIP就地执行。对于我们外置的QSPI Flash通过芯片的存储器映射功能Memory Mapped Mode它被映射到了0x90000000这个地址CPU可以像访问内存一样直接读取其中的指令。地址分配0x08000000是STM32H7内置Flash的起始地址。0x90000000是QSPI Flash在内存映射模式下的典型起始地址具体请参考芯片参考手册和你的硬件连接。0x24000000是DTCM RAM的地址速度极快适合放关键数据。选择符解释RO包含代码Code和只读数据Read-Only data。RW已初始化的可读写数据。ZI未初始化的可读写数据零初始化。.ANY匹配所有未被前面规则分配的目标文件。*(InRoot$$Sections)这是ARM编译器需要的特殊段必须放在根区通常是内置Flash。如何指定特定函数/变量到外置Flash除了在分散加载文件中用.o文件名指定更常用的方法是在代码中使用__attribute__指定段。例如你把一个庞大的字库数组放到外置Flash// 在C文件中 const uint8_t hugeFontTable[] __attribute__((section(.ExtFlashSection))) { ... };然后在分散加载文件中确保.ExtFlashSection段被分配到了ER_IROM2区域ER_IROM2 0x90000000 0x800000 { *(.ExtFlashSection) ; 收集所有标记为该段的内容 .ANY (RO) }在Keil工程中应用编写好.sct文件后在Options for Target - Linker选项卡中取消勾选Use Memory Layout from Target Dialog然后在Scatter File框中选择你创建的sct文件。2.3 一个必须注意的坑中断向量表的放置这是新手最容易出错的地方。STM32芯片上电后会从0x00000000或0x08000000由BOOT引脚决定取址执行第一条指令。这里必须存放初始堆栈指针和复位向量即中断向量表的前两个内容。因此中断向量表必须放在CPU能直接访问的、非映射的存储区也就是内置Flash里。在你的分散加载文件中必须确保包含*(RESET, First)的这一行是在ER_IROM1内置Flash区域内并且有First属性保证它放在最前面。绝对不能把它放到外置Flash的区域。系统启动后通过内置Flash中的启动代码再配置好QSPI外设进入内存映射模式然后才能跳转到外置Flash中的主程序执行。3. 破解速度焦虑QSPI Flash真的慢吗缓存机制揭秘把代码放到外置Flash大家最担心的就是性能损失。毕竟H7内核跑在400MHz、500MHz甚至更高而常见的QSPI Flash芯片时钟频率通常在133MHz左右这看起来像是个瓶颈。我最初也这么想直到我做了对比测试。我用一个核心的数学算法比如FFT分别在代码位于内置Flash和外置QSPI Flash的情况下运行并测量时间。结果让我惊讶两者的执行时间差距远没有想象的那么大在很多情况下只有几个百分点的差异。这是为什么秘密就在于STM32H7强大的缓存系统。指令缓存I-CacheSTM32H7的Cortex-M7内核拥有一个独立的指令缓存。当CPU首次从外置Flash的某个地址取指令时速度确实受限于QSPI接口的时钟和读指令的延迟。但是一旦这条指令被取回它就会被保存在I-Cache中。当CPU再次需要执行同一段循环内的代码时它可以直接从高速的Cache中读取完全绕过QSPI总线。只要你的代码局部性好循环、频繁调用的函数Cache的命中率就会非常高有效平均速度就上来了。ART加速器仅限内置FlashSTM32H7内置Flash有一个叫做ART自适应实时存储器加速器的模块它相当于内置Flash的预取和缓存机制能让内置Flash实现零等待周期。这是内置Flash速度快的根本原因。但对于外置Flash我们依赖的是CPU的Cache。QSPI的内存映射模式当你正确配置QSPI外设为“内存映射模式”后CPU看待0x90000000开始的这片区域就像看待普通的内存一样。所有的取指、读数据操作都由内核的总线系统自动发起通过QSPI外设转换成Flash读命令。Cache机制对这片映射区域是完全透明的、自动工作的。所以给你的定心丸是对于大多数应用尤其是含有循环、函数调用的控制逻辑、UI处理等由于Cache的存在将代码放在外置QSPI Flash中运行性能衰减是完全可以接受的。当然如果你有一段极其时间敏感、要求单指令执行延迟最低的代码比如某个极端优化的中断服务例程你可以考虑用__attribute__((section(.CodeInRAM)))将其复制到RAM中执行并在分散加载文件中做好相应区域的分配。4. 打造专属烧录工具手把手编写下载算法分散加载文件解决了“代码在哪运行”的问题下载算法则要解决“代码怎么烧进去”的问题。没有正确的下载算法你的调试器根本无法把编译好的程序写入外置Flash。4.1 下载算法的本质一段“搬运工”程序理解这一点至关重要。下载算法文件.FLM不是一个静态的配置文件而是一个完整的、可执行的ARM程序。它的工作流程是这样的当你点击IDE的下载按钮时调试器如J-Link首先会把这个.FLM文件加载到目标芯片的RAM中地址在算法文件内部定义。然后调试器通过调试接口SWD/JTAG与这段RAM中的程序建立通信。调试器说“我要从地址0x90000000开始写入以下数据...”。RAM中的下载算法程序收到命令它调用你编写好的底层驱动操作STM32的QSPI外设向实际的外置Flash芯片发送“写使能”、“页编程”等命令将数据写入物理Flash。写入完成后算法程序可能还会执行“读取校验”操作并将结果返回给调试器。所以编写下载算法就是编写一个功能特定的STM32固件它包含初始化、擦除、编程、校验、复位等函数接口。4.2 基于Keil模板工程的实战开发Keil提供了一个官方模板位于你的安装目录ARM\Flash\_Template下。这是我们的起点。第一步复制并理解模板工程结构将整个_Template文件夹复制一份重命名为有意义的名字例如MyH750_QSPI_Flash。打开工程你会看到几个核心文件FlashPrg.c这是核心文件包含了Init,UnInit,EraseSector,ProgramPage等必须实现的函数。我们需要在这里填充针对我们硬件具体QSPI Flash型号的操作逻辑。FlashDev.c这是设备描述文件定义了Flash的大小、扇区大小、页大小、编程宽度等属性。Keil的下载配置界面会根据这个文件的信息来显示。Target.lin链接脚本定义了算法程序自身在RAM中的加载地址和大小。非常重要必须确保这个地址范围与你的应用程序使用的RAM区域没有冲突。通常使用默认的0x20000000AXI SRAM或0x24000000DTCM RAM开始的一段空间。第二步移植你的QSPI底层驱动模板工程是空的你需要把项目中已经调试成功的QSPI Flash驱动代码通常是qspi.c和qspi.h添加到这个算法工程中。确保驱动包含了QSPI外设的初始化进入内存映射模式可能不是必须的但引脚、时钟、DMA等要配好。芯片识别函数读取JEDEC ID。擦除函数支持扇区擦除、块擦除、整片擦除。页编程函数。读状态寄存器、等待忙状态函数。第三步实现FlashPrg.c中的关键函数模板已经给出了函数框架你只需要在// Add your Code注释处调用你的驱动。int Init (unsigned long adr, unsigned long clk, unsigned long fnc)初始化硬件。这里需要调用你的QSPI初始化函数并可以做一些检查比如读取Flash ID确认通信正常。int UnInit (unsigned long fnc)卸载初始化。通常可以什么都不做或关闭QSPI外设时钟。int EraseSector (unsigned long adr)擦除一个扇区。参数adr是目标地址在0x90000000映射空间内。你需要将这个地址转换为Flash的物理扇区地址然后调用你的扇区擦除驱动函数。int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf)编程一页。这是最重要的函数。adr是目标地址sz是数据大小buf是源数据指针。你需要循环调用页编程命令将buf中的数据写入Flash。注意处理页边界Flash编程通常不能跨页。unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf)验证数据。读取刚写入的数据并与buf中的原数据对比。可以不实现返回0但实现后能提高烧录可靠性。第四步配置FlashDev.c打开这个文件修改FlashDevice结构体变量。这是一个示例struct FlashDevice const FlashDevice { FLASH_DRV_VERS, // 驱动版本不用改 My H750 QSPI Flash, // 算法名称会在Keil下拉菜单中显示 EXTSPI, // 设备类型外置SPI Flash 0x90000000, // Flash映射的起始地址 0x00800000, // Flash总大小8MB (0x800000) 4096, // 编程页大小Page Size根据你的Flash型号定常见256/512/4096 0, // 保留必须为0 0xFF, // 擦除后的内存值通常是0xFF 100, // 页编程超时ms 3000, // 扇区擦除超时ms { // 扇区定义这是最灵活的部分 {0x00001000, 0x00000000}, // 每个扇区大小4KB起始偏移0。这里定义了一个4KB的扇区。 // 如果你的Flash是均匀扇区可以只写这一行。 // 如果是不均匀的如前面4KB后面64KB则需要按顺序列出所有扇区。 // 例如{0x00001000, 0x00000000}, {0x00010000, 0x00001000}, ... // 总大小加起来要等于上面的总大小。 } };扇区定义是关键。它告诉Keil如何擦除。如果你的Flash是统一4KB扇区就像上面那样写一个即可。Keil会自动计算需要擦除的扇区数量。如果你的Flash前面是4KB扇区后面是64KB大扇区很多大容量Flash如此就必须在这里详细列出每一个扇区的大小和起始偏移。第五步编译、部署与使用在Keil中编译这个算法工程确保零错误零警告。编译成功后在工程目录下的Objects文件夹里会生成一个.FLM文件。将这个.FLM文件复制到Keil的安装目录下的ARM\Flash文件夹中例如C:\Keil_v5\ARM\Flash。重启Keil MDK如果已打开。打开你的主应用程序工程进入Options for Target - Debug - Settings - Flash Download。点击Add按钮你应该能在列表中看到你刚刚命名的算法如My H750 QSPI Flash。选中它并确保它的起始地址0x90000000和大小被正确添加到了下载算法列表中。通常你还需要保留一个用于内置Flash的算法如STM32H7xx 128KB Flash用于烧录启动代码和中断向量表。现在你就可以像烧录内置Flash一样一键下载程序到外置QSPI Flash了。调试器会自动调用你的算法完成内外Flash的协同烧写。5. 实战中的避坑指南与高级技巧走到这一步基本功能已经通了。但实际项目总会遇到一些“妖孽”问题这里分享几个我踩过的坑和对应的解决方案。坑1下载算法调试困难下载算法本身也是程序它如果跑飞了整个下载过程就卡住。但它又运行在RAM里没法像普通程序一样在线调试。我的调试方法是使用串口打印在算法程序的Init、EraseSector、ProgramPage等函数的关键节点通过串口输出调试信息例如“Erase Sector at 0x%08X”。虽然麻烦但非常有效。记得算法工程和主工程要使用不同的串口引脚或复用配置避免冲突。点灯大法在算法关键步骤操作GPIO引脚点亮不同的LED用逻辑分析仪或示波器观察时序判断卡在哪一步。坑2程序在QSPI Flash中运行不稳定偶尔死机这可能和Cache一致性有关。当你使用DMA从外设如SD卡、以太网接收数据并直接写入到QSPI内存映射区域作为缓冲区时CPU的Cache里可能还保留着该地址的旧数据。后续CPU从该地址读取时可能读到Cache里的脏数据而非DMA刚写入的实际数据。解决方案在DMA写入完成后对写入的内存区域执行Cache清理Clean或无效化Invalidate操作。使用CMSIS提供的函数#include core_cm7.h // DMA写入完成后 SCB_CleanInvalidateDCache_by_Addr((uint32_t*)buffer_address, buffer_size);坑3从QSPI Flash跳转到RAM执行函数时崩溃如果你将某个函数用__attribute__放到.CodeInRAM段并在分散加载文件中将其分配到了RAM区域。主程序在QSPI Flash中运行时调用这个函数需要先将其代码从Flash复制到RAM。链接器会生成加载代码Load$$region_name$$Base等符号帮你完成复制但必须在main函数早期调用__main由启动文件调用或手动执行SCB_InvalidateICache()来清理指令缓存否则CPU可能执行到旧的、缓存中的指令。高级技巧混合存储优化对于性能要求极高的系统可以采用更精细的分散加载策略关键中断服务程序ISR放在ITCM RAMSTM32H7的ITCM RAM是零等待周期的将最苛刻的ISR放在这里能保证绝对的中断响应时间。高频调用的核心算法放在DTCM RAMDTCM RAM同样高速适合作为关键数据缓冲区或实时算法运算区。大容量只读数据字库、图片、音频资源放在QSPI Flash通过内存映射直接访问利用Cache加速。不常执行的配置代码、日志处理代码放在QSPI Flash。这需要你在分散加载文件中定义更多的执行域并在代码中灵活使用section属性进行分配。虽然增加了复杂度但对提升系统整体性能至关重要。最后别忘了在项目初期就规划好内存布局并留出足够的余量。分散加载文件和下载算法是嵌入式开发中比较底层的技能一旦掌握你就能真正驾驭像STM32H7这类高性能MCU的完整内存空间为复杂应用打下坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2412773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…