ZYNQ + VDMA + RGB TFT 显示实验复盘:黑屏、99% 卡死、platform 混乱的最终解决方案
摘要:本文记录了ZYNQ裸机开发中RGB TFT显示实验的完整排错过程。作者先后遇到Debug卡99%、System Debugger异常、屏幕黑屏等问题,排查发现核心原因是Vivado导出的platform与SDK中的BSP和Application工程未保持对应关系。通过重新梳理硬件设计、建立干净的工作空间,并确保platform-BSP-Application三者严格对应,最终解决了问题。文章
文章目录
概要
在做小梅哥 ZYNQ 裸机课程中的 RGB TFT 图像显示实验时,我先后遇到了 Debug 卡 99%、System Debugger 异常、DDR 参数修改后 platform 混乱、BSP 绑定错误以及屏幕黑屏等一系列问题。 一开始一直以为是代码、SDK、排线或者开发板硬件有问题,最后才发现,真正的核心原因是 Vivado 导出的 platform、SDK 中的 BSP 和 Application 工程没有保持一一对应,再叠加老版本 SDK 调试链路不稳定,导致问题越来越复杂。 本文记录了整个排查过程、踩坑原因以及最终成功点亮 RGB TFT 屏幕的正确流程,希望能帮到遇到类似问题的同学。
前言
最近在做 ZYNQ 裸机开发中的 VDMA + RGB TFT 图像显示实验 时,连续踩了几个很典型但又很折磨人的坑:
- Debug 一直卡在 99%
- System Debugger 经常异常
- TFT 屏幕一直黑屏,没有任何显示
- 改了 DDR 配置后,SDK 里出现多个 platform
- BSP、Application、hardware platform 三者关系越来越混乱
一开始我几乎把所有可能性都怀疑了一遍:
- 代码写错了
- RGB565 转换有问题
- DDR 配置不对
- LCD 排线插反了
- 背光没开
- SDK 坏了
- 板子坏了
但最后发现,这些都不是单一主因。真正的问题,是整个 Vivado → SDK 的工程关系被我越改越乱,最终导致 platform、BSP、Application 没有保持一致。
这篇文章就把我这次从黑屏、99% 卡死,到最后成功出图的整个过程完整复盘一下,希望能帮到做同类实验的同学。
1. 实验背景
我做的是小梅哥 ZYNQ 裸机课程中的 基于 VDMA 的 RGB TFT 显示实验。
整个显示链路大致是:
- PS 端 DDR 中存放图像数据
- VDMA 从 DDR 读取图像
- AXI4-Stream to Video Out 输出视频流
- VTC 提供时序
- RGB888 转 RGB565
- 最终驱动 RGB TFT 屏显示图像

从原理上看,这个实验逻辑并不算特别复杂,但一旦 Vivado 硬件配置、SDK 软件工程、DDR 参数、platform/BSP/Application 之间没有理顺,排查起来会非常痛苦。
2. 最开始出现的问题
2.1 Debug 一直卡在 99%
最开始最让我崩溃的现象就是:
点击 SDK 里的 Debug 之后,经常卡在:
Launching GDB Debug... (99%)
有时还伴随一些典型报错,比如:
AP transaction error, DAP status f0000021
或者:
Memory read error at 0xF8007080
以及:
Memory write error at 0x100000
这些报错会让人误以为:
- 是代码问题
- 是 DDR 坏了
- 是 JTAG 驱动坏了
- 是 SDK 坏了
但实际情况比这复杂得多。
2.2 屏幕一直黑屏
另一个更直接的问题是:
屏幕完全没显示
不是花屏,也不是错位,而是:
- 没图像
- 没明显背光变化
- 看起来像根本没驱动起来

这个时候最自然的怀疑方向就是:
- LCD 排线插错
- 屏坏了
- 背光没开
- RGB 数据没出来
但后面排查发现,真正的问题并不只是屏本身。
3. 一开始走过的弯路
3.1 怀疑 RGB888 转 RGB565 模块有问题
一开始我注意到了 rgb888to565 模块,担心是不是这里的位宽转换有问题。
后来证明,这不是导致黑屏和 99% 卡死的主因。
3.2 怀疑 LCD 排线问题
我反复检查了:
- 排线方向
- 插接位置
- 屏幕接口

确认排线本身没有插反,也没有松脱。
3.3 怀疑 DDR 型号不正确
我的板子实际 DDR 型号是:

而工程最开始的 DDR 配置并不完全对应,后面确实做了修改。
这个点是问题的一部分,但并不是全部。
3.4 怀疑 SDK 软件坏了
因为 Debug 一直卡 99%,很容易让人以为是软件本身坏了。
但最后证明,SDK 本身不是“坏了”,而是:
工程关系乱了 + SDK 的调试链路本身也不稳定
4. 真正的核心问题是什么
最后把整个过程回头复盘后,我发现根因其实主要有三类。
4.1 修改 DDR 后,SDK 里生成了多个 platform
在 Vivado 里改过 DDR 参数后,我重新导出了硬件。
结果 SDK 里先后出现了:
system_wrapper_hw_platform_0
system_wrapper_hw_platform_1
system_wrapper_hw_platform_2

这本身并不是绝对错误,但如果继续在旧 workspace 里反复更新,就会非常容易混乱。
因为你很容易出现这种情况:
- 当前硬件平台是新的
- BSP 还是旧的
- Application 工程又是另一套
- Run/Debug 配置还可能指向更旧的一套 platform
于是最终结果就是:
- 工程能编译
- 但运行不正常
- BSP regenerate 报错
- Debug 卡 99%
- 屏幕黑屏

4.2 platform、BSP、Application 没有一一对应
这个是本次问题里最关键的点。
在 ZYNQ 的 Vivado + SDK 开发流程里,三者关系必须清楚:
platform
是 Vivado 导出的 硬件平台
BSP
是基于 platform 自动生成的 软件支持包
Application
是你自己的 应用程序
它们的关系应该始终是:
Vivado硬件设计
↓
platform
↓
BSP
↓
Application
也就是说:
一个 platform 对应一个 BSP,对应一个 Application
而我前面的问题,本质就是这三者关系被多次导入、更新之后弄乱了。
4.3 lcd_bl 背光信号处理有问题
在继续排查硬件设计时,我还发现了一个很关键的点:
lcd_bl 背光信号一开始没有被正确处理
如果背光控制信号不对,即使视频链路本身起来了,屏幕看起来仍然可能像“完全黑”。
这一点在后面的修正中也是影响最终能不能正常显示的重要因素。
5. 对 platform、BSP、Application 的重新理解
这次踩坑之后,我对这几个概念终于真正理解清楚了。
5.1 platform 是什么
platform 就是 硬件平台,来自 Vivado 导出的硬件设计信息,里面包括:
DDR 配置
PS 配置
bitstream
ps7_init
外设地址映射
你可以把它理解成:
当前这套硬件设计的“说明书 + 初始化信息”
5.2 BSP 是什么
BSP 是 Board Support Package,是基于当前 platform 自动生成的软件支持包,里面包括:
xparameters.h
各种驱动
standalone 库
设备地址宏定义
你代码里能直接使用的:
XPAR_VTC_0_DEVICE_ID
XPAR_PS7_DDR_0_S_AXI_BASEADDR
这些其实都来自 BSP。
5.3 Application 是什么
Application 就是你自己真正写的程序,比如:
helloworld.c
vdma_api.c
pic0.h
5.4 为什么这三者一定要对应
因为一旦你改了 Vivado 里的 DDR 或硬件结构,platform 就变了。
platform 一变,BSP 理论上也要重新生成,Application 也应该绑定新的 BSP 和 platform。
如果只是改了 platform,BSP 和 Application 还沿用旧的,那很容易出现:
编译没问题,运行异常,Debug 卡 99%,内存地址不对,程序下载失败。
6. 最终正确解决方案
真正让我最终跑通这套实验的办法,不是继续在旧工程上修修补补,而是:
开一个全新的 SDK workspace,重新搭一套干净工程
6.1 Vivado 侧:重新确认并导出正确硬件
在 Vivado 中,我重新确认了以下几点:
DDR 型号和板子实际一致
硬件设计连接正确
lcd_bl 背光信号处理正确
Validate Design
Generate Bitstream
Export Hardware,并勾选 Include bitstream
这一步的目标只有一个:
导出一份唯一正确的 hardware platform
6.2 SDK 侧:新建一个干净 workspace
这一点非常关键。
不要继续在旧 workspace 上修,因为旧 workspace 里很容易已经混进了:
多个 platform
多个 BSP
多个测试工程
多份 Run/Debug 配置
正确做法是:
在 SDK 里 Switch Workspace
选一个全新的空目录
从 Vivado 重新 Launch SDK

这样做完后,左边的 Project Explorer 里只剩下:
system_wrapper_hw_platform_0

这就说明环境干净了。
6.3 新建 BSP
在 SDK 中执行:
File -> New -> Board Support Package

新建:
rgb_tft_bsp
并绑定当前唯一的:
system_wrapper_hw_platform_0
6.4 新建应用工程
继续执行:
File -> New -> Application Project
新建:
rgb_tft
并选择已有 BSP:
rgb_tft_bsp

6.5 只复制旧工程里的源码文件
这里有一个非常容易出错的点:
只复制源码文件,不复制旧 BSP 和旧链接脚本
我最后只从旧工程里复制了这几个文件到新的 rgb_tft/src:
helloworld.c
pic0.h
platform.c
platform.h
platform_config.h
vdma_api.c
我没有复制:
旧的 lscript.ld
旧的 BSP
旧的 launch 配置

因为这些都应该基于新的 platform 重新生成。
6.6 Build + Program FPGA + Run
在新工程里完成这些操作后,我执行了:
Build Project
Xilinx Tools -> Program FPGA
右键 rgb_tft -> Run As
这里有一个非常重要的经验:
先 Run,不要先 Debug
因为老版本 Xilinx SDK 的 System Debugger 在这个实验环境下非常容易卡 99%。
7. 最终结果
在重新理顺:
platform
BSP
Application
背光控制
这些关系之后,RGB TFT 屏幕终于成功显示了图片。

接下来Debug调试。

在这里就进入了单步调试。
最终结果:
这说明问题并不是:
板子坏了
屏幕坏了
代码完全错了
SDK 完全坏了
而是:
工程关系乱了,导致 platform / BSP / Application 没保持一致
8. 这次踩坑最大的经验总结
8.1 修改硬件后,不要让 SDK 里堆很多 platform
如果 DDR、PS、硬件设计改了,最稳的办法是:
开一个干净 workspace
重新导入唯一一套 platform
而不是一直叠加 _1、_2。
8.2 一个 platform 只对应一套 BSP 和一套 Application
这是本次最核心的经验。
8.3 旧代码可以复制,但旧 BSP 和旧 lscript.ld 不要直接搬
源码文件可以复用,但软件支持包和链接脚本必须跟着当前新的 platform 重新生成。
8.4 Debug 卡 99% 不一定是代码问题
很多时候是:
SDK 调试链路本身不稳定
platform 混乱
Run/Debug 配置混乱
所以不要一开始就被 99% 带跑。
8.5 对这种实验,先 Run,后 Debug
能先跑起来、能先看到屏幕变化,比单步调试更重要。
9. 给后来者的建议
如果你也在做 ZYNQ 的 RGB TFT 显示实验,并且遇到了:
Debug 卡 99%
BSP regenerate 报错
platform 越来越多
屏幕黑屏
下载内存地址异常
我的建议是:
不要在旧工程上死磕太久
最有效的方式通常是:
Vivado 导出正确 hardware
新建干净 SDK workspace
只保留一个 platform
新建 BSP
新建 Application
只复制自己的源码文件
先 Run
这样往往比在旧环境上继续修补更快。
10. 结语
这次问题折腾了很久,但也正因为踩了这些坑,我终于真正理解了:
Vivado 导出的 platform 是什么
BSP 的作用是什么
Application 应该如何依赖 BSP 和 platform
为什么修改 DDR 后,SDK 里的旧工程不能随便继续用
以前这些概念总觉得有点抽象,这次算是被迫踩坑踩明白了。
更多推荐



所有评论(0)