ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32F769 TouchGFX工程下载失败全排查:从连接、烧写到运行

STM32F769 TouchGFX工程下载失败全排查:从连接、烧写到运行 前阵子调试一块基于 STM32F769 的 800x480 屏幕面板UI 用 TouchGFX 搭工程在 STM32CubeIDE 里编译得很顺利结果一进下载环节就现原形进度条出来不到一秒就弹错有时说找不到内核有时说 Flash 校验失败更玄的是重拔一次 USB 线可能又好了再来一次又坏。整个过程持续了大半天最后把所有可能的原因拆成连接层、烧写层、运行层三个层面才彻底解决。这篇应用笔记就是那段排错过程的完整记录项目编号 LAT1384。如果你遇到的情况也和“TouchGFX 工程编译通过但下载失败”或者“下载成功但屏幕没反应”有关建议从连接、烧写算法、链接脚本、初始化顺序这四条线去查大多数坑都藏在这些地方。1. 先说结论这个报错到底卡在哪一环1.1 出错场景还原我的实际硬件环境是这样主控 STM32F769NIH6板载一颗 SPI NOR FlashRGB 接口屏幕通过 FPC 连接调试器先用板载 ST-LINK后来换过独立 ST-LINK V2 和 J-Link V9。软件方面STM32CubeMX 负责外设初始化TouchGFX Designer 生成界面层代码STM32CubeIDE 负责编译和下载。第一次报错信息是 ST-LINK 连接失败原文大概是“Error in initializing ST-LINK device. Reason: No device found on target.”紧接着下载终止。我当时第一反应是接线问题检查一遍 SWD 四根线、供电、复位脚结果都没问题。多试几次偶尔能连上但下载到 90% 附近出现“Verification failed”的校验错误。这两种错误交替出现基本可以排除单纯接触不良应该往更深的配置问题去想。1.2 为什么 GUI 工程比普通工程更容易栽在这里普通 LED 点灯工程下载失败多半是接线或调试器驱动。但 GUI 工程把问题放大了第一TouchGFX 的资源文件动辄上 MB编译产物非常大对 Flash 烧写算法和地址布局很敏感第二GUI 通常需要外部 SDRAM 做帧缓冲链接脚本里多了一个内存区域稍有不对就会出现运行问题第三工程里由 CubeMX 和 TouchGFX Designer 分别生成代码两部分同步不好可能在初始化顺序上埋雷。所以排查时不能只看下载器要把工程配置、链接脚本、初始化代码全部考虑进去。1.3 三条排查主线我把整个问题归纳成三条主线连接层调试器到 MCU 的物理链路、驱动、供电、复位、RDP 读保护。烧写层CubeIDE 里的 Flash Download 算法、链接脚本、Flash 容量。运行层代码下载进去之后能否正常启动SDRAM 是否初始化、LTDC 时钟是否正确、TouchGFX 的帧缓冲是否有效。下文就按这三条线展开每一条都有我当时踩过的具体案例。2. 连接层ST-LINK 连不上先别急着怀疑线2.1 识别错误文本STM32CubeIDE 的下载错误大体分两类一类来自 ST-LINK 固件另一类来自 GDB 会话。常见文本整理成下面这张表错误提示常见原因优先排查方向No device found on targetSWD 接线、供电、内核未运行测量 VCC 和复位检查 SWDIO/SWCLKTarget connection lost下载过程中复位或掉电外部供电降低 SWD 频率Cannot access targetRDP 读保护或内核休眠使用 Connect under reset解除 RDPFlash Download failed烧写算法、地址不对检查 Debug Configuration 中的 AlgorithmVerification failedFlash 校验不一致或下载算法边界不正确核对芯片型号和算法列表2.2 硬件排查清单第一步永远是物理层。拿万用表量一下目标板的 3.3V 是否稳定尤其带屏幕的板子屏幕背光启动瞬间电流很大如果只靠 ST-LINK 的 3.3V 输出供电很可能会在枚举阶段把电压拉低导致连接不稳定。我当时把这个作为第一嫌疑后来确认不是但这条经验值得分享ST-LINK V2 的 3.3V 输出电流一般在 300mA 以内带屏跑 GUI 至少要外部供电。第二步看 SWD 引脚。PA13/SWDIO、PA14/SWCLK 这两根线容易被忽略的是上拉和串联电阻。大多数调试器板上已经有上拉但目标板如果还做了别的事可能影响时序。另一个容易踩坑的是引脚被复用TouchGFX 工程里引脚多如果 CubeMX 不小心把 PA13/PA14 配置成其他功能下载直接失败。这个问题的典型表现是“同一块板子用别的工程能下载换成 GUI 工程就失败”因为你的 .ioc 里动了 SWD 脚。第三步是驱动层面。如果板子是二手开发板或之前插过其他调试工具建议用 STM32CubeProgrammer 里的固件升级工具把 ST-LINK 固件刷到最新版。我遇到过旧版固件在 STM32F7 高主频目标上超时的情况刷完固件后再也没出现。2.3 用 STM32CubeProgrammer 做底层验证判断“是调试器问题还是工程问题”最好的办法是绕开 CubeIDE 直接连接。STM32CubeProgrammer 在连接模式里选择 ST-LINK点 Connect如果能读到寄存器、能看到 Flash 内容说明底层链路没问题问题大概率在 CubeIDE 的工程配置里。这里面有个细节需要注意STM32CubeProgrammer 的连接模式下拉框里默认是 Normal如果第一种连不上选择 Under reset 重新连接。对于调试过、擦除过的 MCU或者打开了 RDP 的 MCUUnder reset 模式是救命的。我在排查时就是先用 Under reset 模式连上了目标板排除了硬件链路故障后面才专心查工程配置。2.4 读保护与连接模式读保护RDP是很多人忽略的点。如果这块板子之前被烧录过量产固件或者被人设过读保护ST-LINK 在默认 Normal 模式下可能直接拒绝连接或者连接后无法下载。处理方法很简单STM32CubeProgrammer 里点开 Option Bytes把 RDP 级别设置为 Level 0确认后会触发全片擦除然后恢复出厂加密状态。注意这一步会清空 Flash一旦做了原来单片机的程序就没了。如果你手头只有一块板子且里面有重要固件操作前建议用 STM32CubeProgrammer 把 Flash 整个读出来备份。我排查的这块板子虽然没有开 RDP但在给客户做支持时遇到过不少次尤其是那种从产线流出来的“二手”开发板里面十有八九带着读保护不排查这一步很容易卡在连接阶段半天下不去。2.5 J-Link 下载时的额外注意点如果你不用 ST-LINK 而是用 J-Link需要到 Debug Configuration 里把调试探针改成 J-Link并且安装对应的 SEGGER 软件包。J-Link 的好处是可以拖一个 .JLinkScript 文件做初始化但坏处是如果芯片之前被 ST-LINK 设了 SWD 协议的特殊模式J-Link 可能连不上。我遇到过一个很实际的问题用 J-Link 连接时SWD 速率默认是 4MHz但线材比较长目标板供电又不太稳导致连接时好时坏。把速率降到 1MHz 就稳定了。J-Link 不用一味追求高速嵌入式 GUI 调试并不需要多高的下载速度稳定优先。3. 烧写层算法和链接脚本才是大头3.1 为什么 TouchGFX 工程特别容易爆 Flash我的这个工程编译产物大概 780KB主控 Flash 是 2MB看起来还有余量但 GUI 工程有几个隐蔽的扩容点图片资源TouchGFX 默认会将 PNG 文件转成 RGB565 或者 ARGB8888 的源文件一块 800x480 的全屏背景 RGB565 就是 768KBARGB8888 直接翻倍。字体资源每个字号的字体文件都是独立的中文字体比英文字体大得多。文本字典多语言资源累加。如果工程里图片多链接阶段就会在 .map 文件里看到 “region FLASH overflowed” 的提示。有时候编译刚过但 Flash 容量压线下载到后面还会出现校验失败。这时候要回头检查资源策略优先把图片转成 L8 或 RGB565 格式、压缩图片、把不用的动态字体关掉、把字体子集限制到实际用到的字符。不要一上来就考虑换芯片先看资源优化能挤出多少空间。3.2 Debug Configuration 里的下载算法如果编译没超容量但下载到一半失败很可能是 Debug Configuration 里的 Flash Download 设置不对。在 STM32CubeIDE 里点击 Run Debug Configurations选中当前调试配置切到 Debugger 标签页下的 Flash Download 区域。这里会列出当前使用的烧写算法和起始地址。工程创建正常时CubeIDE 会根据设备型号自动填好 STM32F7xx Flash 算法但如果从旧工程复制过配置或者手动改过算法可能对不上。我当时折腾了半个小时就是在这里算法列表里同时存在 STM32F7 和 STM32F4 两个算法CubeIDE 依次尝试第一次失败后直接终止。删掉不匹配的算法只留下对应芯片的算法问题消失。另外如果开发板外接 QSPI Flash且代码放了一部分资源在外面还需要额外添加对应的外部 Flash 算法并且起始地址要设置成外部 Flash 的映射地址。3.3 链接脚本里堆和栈的坑TouchGFX 的代码生成过程会重写链接脚本。CubeIDE 工程里链接脚本通常是 STM32F769NIHX_FLASH.ld 这样的文件TouchGFX Generator 会在合适的位置加入外部 RAM 段如果你自己在 CubeIDE 里手动改过这个文件下次代码生成时会被覆盖你的改动就没了。这里面最容易出错的是堆Heap大小。TouchGFX 基于 MVP 架构界面切换时会动态创建和销毁 Presenter、View 对象还有部分渲染资源也是在运行时申请。如果堆太小界面可能初始化时就跑飞或者 HardFault。我的经验是把 Heap Size 从默认的 0x200 调到至少 0x1000Stack 保持 0x400 以上。下面是链接脚本里常见的一段_estack ORIGIN(RAM) LENGTH(RAM); /* 堆大小TouchGFX 工程的常见设置 */ _heap_size 0x1000;链接脚本里还有一个点外部 SDRAM 的区域定义。TouchGFX 生成的链接脚本中通常会预留一段外部 RAM如果定义的起始地址和 FMC 初始化时的地址不一致运行时会访问到错误的内存区域表现就是花屏或者 HardFault。3.4 校验失败与 Verify 选项的关系Flash 校验失败不一定是 Flash 坏了更常见的是下载算法把数据写到错误地址或者下载的固件内容和目标 Flash 内容不一致。比如算法列表里同时有多颗芯片的算法时下载器可能把数据写到第一个算法的地址范围但实际芯片型号和算法不匹配校验自然过不去。在调试阶段可以把 Flash Download 面板里的 Verify 选项暂时取消掉这样能跳过校验快速确认程序是否能运行。但注意这只是临时手段最终要解决根因。我后来定位到校验错误是算法列表不干净删掉多余算法后勾选 Verify 也一直正常。4. 运行层下载成功只是开始4.1 帧缓冲没有着落SDRAM 初始化顺序我最初以为下载成功就万事大吉结果屏幕全黑用调试器看代码程序停在 HardFault_Handler。检查后发现问题出在 SDRAMTouchGFX 的帧缓冲默认放在外部 SDRAM代码里在 main() 中要先执行 MX_FMC_Init() 和 MX_SDRAM_Init()然后 TouchGFX 初始化代码才能把帧缓冲写到 SDRAM。这里有个参数要会算800x480 的 RGB565 屏幕单帧缓冲是 800x480x2 768KBTouchGFX 通常用双缓冲就是 1.5MB。STM32F769 内部 RAM 只有 512KB肯定放不下所以帧缓冲必须放到外部 SDRAM。判断帧缓冲有没有正常初始化我习惯这样做在 SDRAM 初始化函数返回后加断点然后随便往帧缓冲地址写一个 0xA5A5A5A5再用内存窗口回读如果值一致说明 SDRAM 数据链路正常。如果初始化顺序反了或者你为了调试把 SDRAM 相关代码注释掉TouchGFX 操作帧缓冲时就会触发总线错误表现就是 HardFault 或者下载后立刻跑飞。这里要特别提醒不要在确认 SDRAM 链路之前就怀疑屏幕和排线。屏幕问题的典型表现是背光亮但无内容SDRAM 问题的典型表现是 HardFault 或花屏两者要分开判断。4.2 LTDC 与时钟配置TouchGFX 的显示通路是 MCU 内部的 LTDC 控制器直接驱动 RGB 屏幕。LTDC 需要独立的像素时钟由 PLLSAI 提供。如果 CubeMX 里调整系统时钟后导致 PLLSAI 输出变化屏幕可能不亮或者画面撕裂。我的经验是先在 CubeMX 的 Clock Configuration 页面确认 LTDC 时钟频率和屏幕规格匹配比如 800x480 屏幕常见像素时钟范围在 25MHz 到 33MHz过高的设置会让屏幕直接不工作。有一个容易忽略的点LTDC 初始化函数里会读取层配置TouchGFX 生成的代码里会设置若干图层参数。如果 CubeMX 里图层数只配置了一层但 TouchGFX Designer 里用了两层下载后会出现一层画面不更新这不是下载阶段的错误但会让人误以为是固件有问题。检查方式是看 TouchGFX Designer 的 Display 配置里层设置和 CubeMX 的 LTDC Layer 配置是否一致。我还踩过一个坑屏幕的背光引脚如果由某个 GPIO 控制而这个 GPIO 在 TouchGFX 生成代码之前没有被初始化那么程序跑起来后屏幕背光不亮看起来像“黑屏”。实际上 MCU 已经在正常刷帧了只是背光没打开。排查时先用万用表量一下背光供电再看 GPIO 输出电平别上来就重刷固件。4.3 TouchGFX Designer 与 CubeMX 的同步TouchGFX 的开发流程通常是TouchGFX Designer 编辑 UI生成代码后由 CubeMX 里的 TouchGFX Generator 把生成结果合并进工程。这两个工具通过 .ioc 文件关联。如果你改了 TouchGFX Designer 里的 UI但没有在 CubeMX 里重新生成代码下载进去的固件还是旧的 UI如果两边版本不一致可能出现生成失败或编译错误。我通常的做法先在 TouchGFX Designer 里完成界面修改并保存然后打开 CubeMX确认左侧菜单里 TouchGFX 的配置项是启用状态点击右上角的生成代码按钮让 CubeMX 自动合并 TouchGFX 生成的代码最后回到 CubeIDE 编译。合并完成之后再去查看链接脚本和 debug 配置千万不要手动修改生成目录里的文件因为下次生成会被清掉。版本兼容性也值得一提。TouchGFX Designer 和 CubeMX 的版本之间有一定的配套关系比如新版 TouchGFX Designer 生成的工程结构老版 CubeMX 可能不认识导致 TouchGFX Generator 无法生成代码。装环境的时候最好统一到比较新的稳定版本不要混用差太多的大版本。5. 常见问题速查表与实战排查顺序5.1 速查表把这些经验整理成一张速查表遇到问题可以直接对照现象大概率原因解决动作连接阶段报 No deviceSWD 接触、供电、引脚复用外部供电量电压恢复 PA13/PA14Under reset 连不上RDP 读保护STM32CubeProgrammer 切 Level 0下载到一半校验失败Flash 容量压线、算法不对查资源大小核对 Flash Algorithm编译报 Flash overflow图片、字体资源过大压缩图片、用 L8、裁字体子集下载成功但 HardFaultSDRAM 未初始化或顺序不对查 FMC/SDRAM 初始化断点验证黑屏但有背光LTDC 时钟或图层配置不对核对像素时钟、图层数下载成功但界面还旧没有重新生成代码CubeMX 重新生成再编译下载每次连接都要重拔线接触不良或 SWD 速率过高换线、降低 SWD 频率到 1.8MHz5.2 整理一套排查顺序第一步用 STM32CubeProgrammer 连接目标板。能连上说明物理层和调试器没问题直接去检查 CubeIDE 的工程配置。不能连上先试 Under reset 模式还不行就要检查接线、供电以及是否开了 RDP。第二步在 CubeIDE 里打开 Debug Configuration核对调试探针类型、SWD 速率、Flash Download 算法列表去掉多余算法勾选 Reset and Run。第三步编译时留意 Console 窗口或 .map 文件里的 Flash 用量确认固件大小和占用比例如果接近满容量先做资源优化再下载免得在下载阶段卡校验。第四步下载成功后不要急着看屏幕先用调试器确认代码执行路径停住 main 函数单步走看 SDRAM 初始化是否正常、LTDC 层的寄存器值是否符合预期、Frame Buffer 地址是否落在 SDRAM 范围内且读写一致。第五步如果以上都正常才去怀疑屏幕排线、背光驱动、面板时序这些硬件层面的问题。这个顺序是我前前后后踩了很多次坑才固定下来的能省掉超过一半的无效排查时间。最后补一个实用习惯每次更换 TouchGFX Designer 版本或者 CubeMX 重新生成代码之后我都会把链接脚本、Debug Configuration、.ioc 文件一起提交到版本管理里出问题能快速 diff 出变化。另外调试阶段建议把 SWD 频率主动降到 1.8MHz 甚至更低速度慢一点换来的是连接稳定性等确认没问题再改回高速。按照这个思路处理你大概率能在一个小时内把问题定位到具体环节而不是像我第一次那样被各种错误信息带着走了大半天。
返回列表