ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

STM32N657双八线NOR Flash配置实战:从CubeMX到XIP运行全解析

STM32N657双八线NOR Flash配置实战:从CubeMX到XIP运行全解析 前两天在社区里看到有人问 STM32N657X0H3Q 怎么用 STM32CubeMX 配双八线Dual Octal存储器问得挺急的。这题我正好折腾过一阵子N657 这颗料配双八线 NOR Flash从 CubeMX 生成代码到 XIP 跑起来中间有不少坑文档里写得又不细我花了不少时间才把整套配置理顺。这篇就把我的完整配置思路、参数计算方法和踩坑记录整理出来给正在做 N657 板卡验证、或者准备把大容量代码资源外置到双片八线 Flash 的朋友做个参考。先交代一下使用背景STM32N657X0H3Q 是 ST N 系列第一款面向边缘 AI 和图形显示的高性能 MCUCortex-M55 内核主频能到 800MHz内部带 2MB SRAM外设资源很丰富适合做带屏的智能设备、机器视觉、工业 HMI 这类应用。这类应用有个共同点代码和 GUI 资源都很大动不动几十 MB完全放内部 Flash 不现实外部挂一片串行 NOR 是常规操作。但问题在于单纯挂一片八线 NOR在 800MHz 的 M55 面前带宽还是不够宽于是就有了 Dual Octal Memory 这种方案——把两片八线 NOR Flash 并排接上数据吞吐直接翻倍。CubeMX 对 N657 的双 OCTOSPI 是有专门组合配置项的搞对了以后CPU 可以直接在外部 Flash 上 XIP 执行代码不需要搬代码到 RAM体验和访问内部 Flash 接近读带宽实测能到几百 MB 级别。1. 项目背景与方案思路拆解1.1 STM32N657X0H3Q 选型背景与存储瓶颈N657 这颗芯片定位很明确不是我瞎吹它内部集成了 2MB SRAM 和硬件图形加速器还带视频编解码器。ST 在这颗料上用了外部存储接口来做大容量扩展其中两个 OCTOSPI 控制器是重点。OCTOSPI 顾名思义就是八线 SPI支持 1/2/4/8 线模式支持 SDR 和 DDR 双沿采样也支持 DQS 读反馈。这玩意儿在 H7 系列上面就见过但在 N657 上做成了双实例并且有配套的 dual mode 联动逻辑可以当做一个 16 位宽的外部存储总线来用。那为什么要上双八线而不是上一颗大容量的八线 Flash这里有个很现实的带宽账。假设你用的是一颗支持 DDR 200MHz 的八线 NOR时钟 200MHz双沿采样等于 400MT/s8 根数据线理论峰值带宽是 400MB/s。听着好像不错但 M55 在 800MHz 主频下跑高密度代码再加上图像资源、字库、音频素材的搬运400MB/s 很快就见顶了。尤其是做 GUI 的时候从 Flash 里读一张 JPEG 或者 PNG 解码带宽吞吐不够掉帧肉眼可见。双八线的思路就是把两片八线 Flash 并联一套命令同时驱动两个 bank理论上限直接翻倍到了 800MB/s 级别配合 cache 命中率实际体验会有本质区别。1.2 双八线Dual Octal Memory的工作原理双八线的名字容易让人误解以为是把两片 Flash 当独立设备管理。实际上在 N657 上两个 OCTOSPI 控制器是有主从关系的OCTOSPI1 是主控制器承担命令生成OCTOSPI2 是从控制器在主控制器的同步信号驱动下对连接在自己总线上的第二片 Flash 执行同样的命令序列。也就是说一次地址访问会同时打到两片 Flash 上读数据的时候OCTOSPI1 收到第一片的数据OCTOSPI2 收到第二片的数据总线矩阵再把两个数据拼起来合成一个更宽的数据字返回给 CPU。这个拼接是在硬件层面完成的软件无感。这个设计和用普通 GPIO 软件控制两片 Flash 有本质区别。软件方案要分别给两片 Flash 发命令、分别读数据、再软件拼接光命令开销就吃掉一大半收益。硬件双八线方案只需要配置一次命令参数后续访问就是纯数据流效率高得多。同时这种双 bank 模式需要考虑映射地址两片 Flash 的存储空间在地址上是连续排列还是一高一低交错排列取决于 Flash 配置寄存器里的 interleave 设置这一点在配置阶段就要想清楚不然代码段和数据段的地址会对不上。1.3 CubeMX 在这一整套配置里的角色N657 的存储配置牵涉到时钟树、两个外设的时序参数、DMA 映射、中断优先级、底层缓存策略手写寄存器会非常痛苦。CubeMX 的价值在于它把这些配置用图形界面帮你约束住了时钟树里选好 Flash 工作频率参数面板里填好命令序列生成代码时会自动算出分频系数、采样延迟等底层参数并且会校验时钟是否会溢出。另外N657 在 CubeMX 里面还有专门针对 dual memory 的选项勾选后它会自动帮你把两个控制器绑定为主从模式省掉大量手动配置。不过话说回来CubeMX 不是万能的。生成代码只是起点后面 linker script 要改MPU 要配启动流程要调这些它不会全包办。我见过不少人 CubeMX 页面配置完就信心满满去编译下载结果板子一点反应都没有回头来找问题全是细节没处理。2. 从零搭建 CubeMX 工程引脚、时钟与基础参数2.1 建立 STM32N657X0H3Q 工程的版本问题先说一个很多人没注意的问题STM32CubeMX 版本和 N657 固件包STM32Cube FW_N6版本必须匹配。N657 是相对较新的料早期 CubeMX 版本对它的支持不完整甚至可能出现配置界面上找不到两个 OCTOSPI 外设的情况。我当时用的 CubeMX 是 6.12 左右固件包拉了当时最新的 FW_N6界面显示正常。建议你用之前先在 CubeMX 的 Help - Manage embedded software packages 里把 N6 系列包更新到当前最新不要用安装包自带的旧版。工程建立以后第一件事不是配外设而是去 System Core - RCC 里确认 HSE 时钟源。很多 N657 评估板板载了外部晶振如果你的板子是自己画的双八线存储电路建议确认晶振有没有焊、频率是多少。HSE 的配置会直接影响后续 PLL 计算如果 HSE 选错了频率后面 OCTOSPI 的时钟树算出来的实际值会和你预期的完全不同这种问题排查起来非常隐蔽。2.2 引脚分配两个 OCTOSPI 怎么接第二片 Flash在 CubeMX 的芯片视图里搜索 OCTOSPI你会发现 STM32N657X0H3Q 引出了两套完整引脚OCTOSPI1 和 OCTOSPI2。每套包括 CLK、CS、DQS、DQ0 到 DQ7。双八线连接的时候硬件上要把两片 Flash 的对应引脚分别接到这两套接口上。需要注意OCTOSPI1 和 OCTOSPI2 的时钟线在硬件表里允许设计成共享一根还是独立两根具体要看 ST 的参考设计。我按参考设计走的是两片 Flash 的 CLK 各自连到对应的 OCTOSPI 引脚这样可以为后续时序调节保留灵活性。CubeMX 里分配引脚时把 OCTOSPI1 和 OCTOSPI2 的模式都选上然后让 CubeMX 自动分配或者手动锁定。这里有个容易出问题的地方有些引脚和 SDMMC、FMC 复用如果同一块板子上你还挂了 SDRAM 或者 SD 卡可能撞引脚。所以硬件设计阶段最好就先跑一遍 CubeMX 引脚冲突检查把外设需要的引脚固定下来再让 PCB 去画线比画完板再来想办法 remap 靠谱得多。接线要点我顺手列一下方便后面硬调时对照两片 Flash 的 DQ0-DQ7 分别接 OCTOSPI1/2 对应数据线一一对应不能交叉CS 分别接各自的 NCS不能并联否则选片逻辑会错乱DQS 必须接。DDR 模式下 DQS 是采样基准不接或者虚接高速读必挂RESET 引脚最好接到 MCU 的 GPIO 或者 RC 复位电路Flash 上电后要确保它不在复位状态2.3 时钟树配置能不能跑满 Flash 的规格线N657 的时钟树比 H7 系列还要复杂PLL 数量多每个外设的 kernel clock 来源都要单独选。OCTOSPI 的 kernel clock 一般在 CubeMX 的 Clock Configuration 页面里能看到常接在 PLL2 或 PLL3 的某个输出上。配置的原则很简单让 OCTOSPI kernel clock 尽可能接近你所用 Flash 的最高工作频率但绝对不能超过。这个最高工作频率怎么确定去查你选的 NOR Flash 的 datasheet重点看 DDR 模式下的最高时钟频率。举个例子如果你选 Macronix MX25LM51245G规格上最高支持 DDR 200MHz数据速率 400MT/s如果选的是更常见的一些 Winbond 八线 Flash比如 W25Q256JW最高可能是 133MHz SDR / 66MHz DDR。确定最高频率后回到 CubeMX 时钟树把 OCTOSPI kernel clock 设置成不超过这个值的频率同时满足 PLL 的整数分频关系。我当时的配置给的是 100MHz DDR。为什么不跑满 200MHz因为 PCB 走线质量摆在那双八线并联后信号完整性比单颗要复杂DQS 反馈时序会受走线长度影响初步调试阶段留一半余量先把功能跑通再慢慢冲高频。实测最终稳定跑在 100MHz DDR 时双 bank 带宽大约 400MB/s对大多数 GUI 场景已经够用。这里要注意一个立方体级别的坑CubeMX 里改时钟树时如果哪个 PLL 的输出无法精确分频到你想要的频率它会自动往上或往下凑一个值。你必须回 OCTOSPI 参数面板再确认一下实际分频后的 kernel clock 到底是多少别只盯着配置页里的目标值。我遇到过 CubeMX 自动把 PLL 调到 101MHz 的情况当时没注意导致 Flash 偶发读错。3. 双八线存储器的核心配置细节与参数计算方法3.1 OCTOSPI 参数面板逐项对照在 CubeMX 里展开 OCTOSPI1 的 Configuration 面板你会看到几个区域General Parameters、Flash Parameters、Commands。先用 General 区域把两个控制器绑定起来。如果界面里能看到 Dual memory mode 或者类似的选项勾上并确认 Master 是 OCTOSPI1、Slave 是 OCTOSPI2。这是我建议你一开始就做的动作别自己手动去配两个外设虽然也能跑但主从同步逻辑很容易配错。Flash Parameters 区域一般都允许你自己维护一个 Flash 列表CubeMX 内置了一个 Flash 数据库里面有不少 ST 和 Macronix 的型号。如果你的 Flash 型号正好在列表里选上就行厂家预设的命令序列会帮你把 read 命令、dummy cycle、状态寄存器配置都填好。如果不在列表里就自己新建一条配置把下列关键项填对Memory typeNORData size8 位或 1 字节双八线下每片 Flash 按 8bit 访问Clock divider / prescaler根据 kernel clock 和所需工作频率换算Sample shift / delay用 DQS 模式时调整采样点的关键参数Dummy cycles不同命令对应的等待周期数Flash datasheet 里面有明确表格Commands 区域是重头戏。你需要为每一种操作定义命令码、地址宽度、数据宽度和 dummy 周期。从实用角度讲最关心的是 Read 命令。八线 NOR 的 Read 命令族有很多种SDR 模式下的 8D-8D-8D 命令、DDR 模式下的 8D-8D-8D 命令命令码因厂商而异。比如很多八线 NOR 在 DDR Octal 模式下用的读命令是 0xEE四字节地址而在 SDR Octal 模式下可能是 0xEE 或 0xEC。这些在 Flash 手册的 Command Table 里都有照着填就行。还有 Read ID 命令 0x9F、Write Enable 0x06、Write Status Register 0x01 这些基础命令以及 sector erase 0x21 这类的操作命令初始化阶段和烧录阶段都要用到能填的尽量填全。3.2 时序参数换算从 datasheet 到 CubeMX 的 cycle 值时序参数是最容易让人懵的部分因为 Flash datasheet 里给的是绝对时间纳秒而 CubeMX 要的是时钟周期cycle。换算公式很简单周期数 绝对时间 × 时钟频率。这里有一个具体场景方便你理解假如你的 OCTOSPI kernel clock 配置为 100MHz一个周期就是 10ns。Flash 手册要求芯片使能到第一个数据有效之间的 tCSSCS 片选建立时间最小是 4ns那换算下来你留一个 cycle 就绰绰有余。但 dummy cycle 不是这样算的。Dummy cycle 是 Flash 内部准备好数据之前的等待周期数它是整数个时钟周期的概念而且和命令字节数、地址字节数都有关。以 MX25LM51245G 的 DDR 8D-8D-8D 读命令为例手册里会给出命令阶段后 14 或 20 个 dummy cycles取决于运行频率。这里必须完全按手册填不能用时间换算。另外一个关键是 DQS 采样延迟。DDR 模式下数据是在时钟双沿采样的Flash 会通过 DQS 信号把读数据同步回来。CubeMX 里的 sample shift / DQS delay 参数控制的是接收端把采样点往后挪多少用来补偿 PAD 到 Flash 芯片之间的走线延迟。这个话题展开会很长简单说在低频100MHz下通常不需要额外延迟默认值即可冲高频后如果发现数据偶发错误优先加大或减小这个参数试。我把一副通用换算流程放这遇到具体芯片照着走从 Flash datasheet 的 AC Timing 表找到 tCSS、tCHRX、tDSU、tV 等参数把绝对时间除以一个时钟周期得到最小 cycle 数向上取整拿这个最小 cycle 数和 CubeMX 默认值对比实际调试时从默认值开始出现不稳定再逐步增减 dummy/delay每次改动后跑一遍全地址校验验证片上的 CRC 或者连续读写3.3 双 bank 模式与地址映射的坑两个 OCTOSPI 在双八线模式下地址映射不是两片 Flash 各占一段、你手动决定把哪片放前面而是由总线矩阵按位拼接数据位来自 OCTOSPI1 的 DQ0-DQ7 算低字节OCTOSPI2 的 DQ0-DQ7 算高字节。因此在逻辑上双八线存储像是一个统一的连续地址空间。由于 OctoSPI 通常映射到 0x70000000具体以参考手册和生成的 linker script 为准你打开 CubeMX 生成的 .ld 文件或者 .icf 文件会在 MEMORY 段看到 OCTOSPI1 和 OCTOSPI2 对应的起始地址和大小。双八线模式下经常只看到一段连续的区域这正说明两个 bank 已经被合并了。这里有个我在实际项目里踩过的坑双八线模式下两个 Flash 的容量、厂商、时序参数必须完全一致。如果一片是 64MB、一片是 128MB地址拼接后整个映射区域逻辑大小按较小的算另一片多出来的空间会变成黑洞访问就会出总线错误。还有两颗 Flash 的 SFDP 内容如果因为固件版本不同而有差异也可能导致初始化阶段只有一颗成功读 ID。所以选料的时候务必整盘同批次不要混批用。另外启动时 Flash 必须同时 ready。如果一颗 Flash 还在执行内部擦写另一颗已经 ready而你直接往双 bank 区域发读命令从设备可能会回错误数据或者忙信号。双八线模式下控制器并不会分别等待两边的 busy 位所以在应用层做大块擦写期间不允许读的互斥或者在擦写前停掉访问是比较稳妥的做法。4. 实操配置双八线 XIP 并让代码在里面跑起来4.1 完整配置步骤把我自己的实际操作顺序整理成流程方便照着做CubeMX 里新建工程选 STM32N657X0H3QRCC 配置 HSE左侧 Connectivity 里打开 OCTOSPI1 和 OCTOSPI2两者模式都选择 Memory Mapped并勾选 dual memory 相关选项到 GPIO 设置里确认所有 OCTOSPI 引脚模式为 Alternate Function速度等级选 Very High上下拉按硬件设计时钟树里配置 PLL2把 OCTOSPI kernel clock 调到选定的目标频率建议先 100MHz回到 OCTOSPI 配置页选 Flash 型号核对 read 命令、dummy cycles、prescaler 等参数在 Project Manager 里生成代码编译先别急着烧代码进 Flash用 STM32CubeProgrammer 连接读两个 OCTOSPI 映射地址的内容验证此刻 Flash 能正常响应这个流程里第 7 步是最关键的验证点。CubeMX 生成代码后初始化函数会在 main 里被调用但默认情况下代码本身还是在内部 Flash 执行。你只需要在调试器里把内存窗口打开输入 OCTOSPI 映射区域的起始地址读一下看能不能读回 Flash 的内容。如果读出来全是 0xFF说明配置有问题直接进入排查环节如果能读到正常内容说明基础读写链路已经通了。然后才是真正的 XIP 应用。在链接脚本里把只读段.rodata和代码段.text定位到外部 Flash 映射区域把可写数据段.data定位在内部 SRAM。写链接脚本时注意N657 的 2MB SRAM 不算小但如果你用了图形库堆要留大一点。我在一个 GUI 项目里把堆设成 512KB因为图形对象的生命周期比较短频繁分配释放堆不够会直接 HardFault。4.2 链接脚本、Cache 与 MPU 的配套设置链接脚本是 XIP 能跑起来的关键也是新手最容易卡住的地方。如果你使用 STM32CubeIDE默认生成的 .ld 文件会把所有段都放在内部 Flash。要改成外部 XIP你得在 MEMORY 段里加一个外部 Flash 区域起始地址和长度对应映射区域然后把 TEXT 和 RODATA 放进去。还要注意启动向量表和一些初始化阶段的代码最好还是放在内部 Flash 或 SRAM 里执行避免出现CPU 刚开始运行就要访问外部存储、但外部存储还没初始化的循环依赖。我一般把复位向量和 SystemInit 相关代码留在内部 Flash跑完外部存储初始化后再让 main 里的代码整体从外部 Flash 执行这样调试方便排查启动问题也容易定位。Cache 和 MPU 的配置比链接脚本更隐蔽。Cortex-M55 有 DCache 和 ICache默认外部存储区域可能是 cacheable 的也可能不是取决于默认内存映射属性。N657 的 OCTOSPI 映射区域属于 device 或 normal memory需要你用 MPU 显式声明。我的经验是把外部 Flash 区域配成 Normal, Write-Back, Read Allocate, No-Write Allocate关闭 Write Through。原因是 Flash 是只读介质write-back 策略对读性能有利而且没有写的 dirty 数据需要回写。内部 SRAM 区域配成 Write-Back Write Allocate 作为默认 RAM 缓存策略。如果不配 MPU有些版本的默认策略会对这块区域按 Strongly-Ordered 处理性能会掉得很难看实测性能差距能到 30% 以上。还有一点打开 ICache 和 DCache 之后Debug 查看内存时会看到滞后现象你改了 Flash 内容但 CPU 读到的还是旧的缓存数据。调试阶段建议把 cache 临时关掉或者用 Cache Clean 指令处理等验证通过再把 cache 打开。这不是 BUG是缓存一致性带来的正常表现不要在这个上面浪费时间。4.3 从外部 Flash 启动的配置方法如果产品最终希望上电后直接从外部双八线 Flash 启动不依赖内部 Flash 里的引导代码设置会多一些。STM32N657 的 BootROM 支持从外部 OCTOSPI 设备启动但前提是 option bytes 里的 BOOT_CFG 配置成对应模式并且外部 Flash 的第一个有效数据块是合法启动头。启动头的格式包括堆栈指针、复位向量、一些配置标志具体字段长度和校验算法在应用笔记里有定义不能乱写。用 STM32CubeProgrammer 烧录的时候它会提供Option Bytes配置页面里面有 BOOT 相关的下拉选项选择从 OCTOSPI 启动然后写入。第一次配置完之后再复位板子CPU 就应该直接从外部 Flash 取指了。这里有个非常大的坑当 Boot 模式切换后SWD 调试口可能被重新配置成其他功能导致你无法再连接调试器。遇到这种情况不要慌把 BOOT0 引脚拉高或者按住板上的 BOOT 按键重新上电让 CPU 进入系统 Bootloader再用 STM32CubeProgrammer 把 option bytes 改回来。这句话听起来简单我当时第一次操作时确实被锁住过所以建议你手头留一个能触发系统 Bootloader 的方式别把复位引脚也省了。5. 常见问题与排查技巧实录5.1 现象速查表问题现象可能原因处理办法双八线只读到一片映射区域前半段能读后半段全 0xFF从控制器没进双模式或第二片 CS 没拉低检查 dual memory 勾选项和 OCTOSPI2 引脚配置读全是 0xFFID 读出来都是 FF写不进去时钟没起、CS 未拉低、Flash 处于复位用示波器量 CLK 和 CS 波形查复位引脚偶发读错同一地址反复读结果不稳定DQS 采样点不对或走线过长信号质量差调整 sample shift/delay降低时钟频率验证XIP 跳转后 HardFault在外部 Flash 执行不到几条指令就进异常MPU 配置缺失或链接脚本地址写错检查链接脚本映射地址确认 MPU 开了 region下载后无法连接调试器SWD 识别不到芯片Boot 配置改成了外部启动且 SWD 被复用接 BOOT0 进系统 bootloader恢复 option bytes擦写和读互相干扰擦除大块时CPU 卡死双 bank 模式没有互斥等待擦写期间关闭 XIP 访问或改用间接模式这张表基本覆盖了我碰到过的问题。具体排查时有一个通用原则先把双八线拆成两个独立的单八线来验证。每个控制器单独去读 ID、擦写、读回确认两片 Flash 各自都健康然后再合并双模式。千万别一上来就调双八线时序你先得把基础链路搞通。5.2 双八线项目特有的几个坑双八线最隐蔽的坑我认为有两个。第一个是主从绑定时序同步问题。双模式下OCTOSPI1 是否真正把同步信号送给了 OCTOSPI2有些时候不是配置一个勾选框就万事大吉。我曾经遇到过这种情况CubeMX 配置页显示 dual mode 开启生成代码里也看到对应的寄存器被写了但实际跑的时候第二片完全无响应。后来查资料才发现某些固件库版本里如果 OCTOSPI1 和 OCTOSPI2 的时钟来源分别选到了不同 PLL 输出同步逻辑就会失效。必须让两个控制器的 kernel clock 来自完全相同的 PLL 和相同的分频路径。这个在 CubeMX 里要手动点开时钟树确认不能只信默认。第二个是复位节奏问题。双八线下两片 Flash 的复位最好由同一个信号控制保证上电同时脱离复位。如果两片 Flash 的复位时序有几十毫秒的差异初始化阶段读写 SFDP 时可能会碰上其中一片仍然 busy导致 SFDP 解析失败。更稳妥的做法是在主控代码里加一段毫秒级延时Flash 上电后等 VCC 稳定再执行初始化。这个延时加在 main 里不要加在初始化函数里面便于裁剪。还有一个硬件相关的心得双八线高速读时的 DQS 信号质量。只要 DQS 走线在 PCB 上没有做等长到全部 DQ 线的长度匹配读时序就会出现窗口偏移。软件上唯一能救的手段是加大 dummy cycle 或者调整采样延迟。但这不是治本方案如果 DQS 和 DQ 之间偏了接近 1/4 个时钟周期软件怎么调都白搭。所以做板子的时候DQS 到每一根 DQ 的等长约束一定要做双八线比单八线更容易出问题因为第二片 Flash 的信号走线更长更容易产生阻抗不连续。5.3 调试工具与验证建议我调试双八线存储时主力工具是逻辑分析仪和 STM32CubeProgrammer。逻辑分析仪主要抓两个东西通信开始时的命令序列和 DQS 波形。注意逻辑分析仪的采样率至少要是 OCTOSPI 时钟的 4 到 5 倍不然抓到的波形边缘毛刺太多看不出问题。你在读 Flash ID 的时候抓一发命令波形和 Flash 手册期望的命令序列逐字节比对很容易发现命令码填错或者地址字节顺序不对的问题。CubeProgrammer 里也可以直接访问 OCTOSPI 映射地址做读写验证不需要编译烧录整个测试工程。连接芯片后在 Memory 视图输入映射起始地址读回数据做人工比对。更专业的做法是写一个轮询脚本对映射区域做全 0x00 和全 0xFF 模式的 CRC 校验连续跑 10 遍看有没有翻转。这个校验我一般会在每次调整时序参数后跑一遍当作回归冒烟测试。最后一个实用建议在正式从外部 Flash XIP 跑之前先在内部 Flash 里放一个测试固件用间接模式分别对两片 Flash 做整片擦除、写入、读回校验确认存储颗粒本身没有坏块和明显弱位。双八线方案遇到偶尔读错这种玄学问题先排除 Flash 本身质量问题再去折腾协议时序能少走很多弯路。以我个人的使用习惯我都是先把两片 Flash 的单片配置调稳定再切双模式最后才改链接脚本上 XIP。这个顺序能帮你把芯片配置问题Flash 时序问题软件链接问题三层风险分开。如果你正卡在 CubeMX 配置阶段先按第 2 节和第 3 节的顺序把引脚、时钟、命令参数检查一遍尤其是时钟来源和 dual memory 勾选大概率能解决大部分问题。
返回列表