3、Vitis软件开发流程:创建Vitis平台工程、创建应用工程、编写Hello World程序、编译与下载调试
好,咱们进入正题。这一章讲的是Vitis的软件开发流程。说白了,就是教你怎么让Zynq的ARM核跑起来,跑一个最简单的Hello World。
我刚开始接触Vitis时,说实话有点懵。以前用SDK习惯了,突然换到Vitis,界面变了,概念也多了。但用顺手之后,你会发现Vitis其实更强大。嗯,咱们一步步来。
3.1 整体流程概览
先看一张图,把整个流程串起来。这样你心里有个谱,后面操作时不会迷路。
3.2 创建Vitis平台工程
平台工程是什么?你可以把它理解成一个「容器」。它包含了硬件描述(XSA文件)、软件驱动、启动代码等。应用工程跑在这个容器之上。
操作步骤:
- 启动Vitis:打开Vitis IDE,选择工作空间目录。我个人习惯把每个项目单独建一个workspace,方便管理。
- 创建平台工程:点击
File → New → Platform Project。 - 填写信息:给平台起个名字,比如
zynq_platform。 - 导入XSA文件:在
Hardware Specification处,选择Vivado导出的XSA文件。这个文件描述了硬件配置,比如DDR大小、外设接口等。 - 选择操作系统:一般选
standalone(裸机)或freertos。咱们入门先用standalone。 - 点击Finish:Vitis会自动生成平台工程,包含BSP(板级支持包)和驱动库。
小技巧:创建平台工程时,勾选 Generate boot components 选项。这样会自动生成FSBL(First Stage Boot Loader)代码,省去你手动配置的麻烦。
3.3 创建应用工程
平台工程建好了,接下来创建应用工程。应用工程就是你的业务代码所在的地方。
操作步骤:
- 创建应用工程:点击
File → New → Application Project。 - 选择平台:在
Platform处,选择刚才创建的zynq_platform。 - 填写应用名称:比如
hello_world_app。 - 选择模板:Vitis提供了很多模板。咱们选
Hello World模板,省得自己从头写。 - 点击Finish:Vitis会自动生成工程结构和代码。
注意:应用工程和平台工程是分离的。这意味着你可以把同一个平台工程分享给多个应用工程使用。我在项目中就经常这样干——一个硬件平台,跑多个测试程序,非常方便。
3.4 编写Hello World程序
Vitis生成的Hello World模板已经包含了基本代码。咱们来看看核心部分:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
int main()
{
init_platform(); // 初始化平台,包括串口、缓存等
print("Hello World!\n\r");
xil_printf("Hello from Zynq!\n\r");
cleanup_platform(); // 清理平台资源
return 0;
}
代码很简单,但有几点我想强调一下:
init_platform()和cleanup_platform()是平台初始化和清理函数。别小看它们,少了它们程序可能跑不起来。print()和xil_printf()都是打印函数。区别在于xil_printf()更轻量,适合嵌入式环境。我一般用xil_printf(),因为它不依赖完整的stdio库,节省内存。- 注意换行符用的是
\n\r,不是单纯的\n。这是因为串口终端需要回车换行两个字符。我曾经在这里吃过亏,打印出来的内容总是乱糟糟的,后来才发现是换行符的问题。
3.5 编译与下载调试
代码写好了,接下来编译和下载。这一步很关键,也是新手容易卡住的地方。
3.5.1 编译
右键点击应用工程,选择 Build Project。Vitis会自动编译整个工程,生成ELF文件。
编译过程中,控制台会输出编译信息。如果出现错误,双击错误信息可以跳转到对应代码行。这个功能很实用,我经常用它快速定位问题。
常见编译错误:
- 找不到头文件:检查BSP是否生成成功。如果BSP有问题,右键平台工程 →
Regenerate BSP Sources。 - 链接错误:检查是否引用了未定义的函数。比如你调用了某个驱动函数,但对应的库没有链接进来。
- 内存溢出:Zynq的OCM(片上内存)只有256KB。如果代码或数据太大,会链接失败。这时需要把代码放到DDR中运行。
3.5.2 下载与调试
编译成功后,就可以下载到板子上运行了。
操作步骤:
- 连接开发板:用JTAG线连接电脑和开发板。上电后,Vitis应该能自动识别到设备。
- 创建调试配置:右键应用工程 →
Debug As → Debug Configurations。 - 选择目标:在
Target处,选择你的开发板。如果没显示,点击Refresh按钮。 - 点击Debug:Vitis会下载程序到板子,并进入调试模式。
- 运行程序:点击
Resume(F8)让程序全速运行。在串口终端上应该能看到 "Hello World!" 输出。
调试小技巧:
- 设置断点:双击代码行号左侧,出现蓝色圆点表示断点设置成功。
- 查看变量:在调试模式下,鼠标悬停在变量上可以查看当前值。
- 单步执行:F5进入函数内部,F6单步执行,F7跳出函数。
- 我习惯在关键代码处设置断点,然后单步执行,观察变量变化。这样能快速定位逻辑错误。
3.6 避坑指南
最后,分享几个我踩过的坑,希望能帮你少走弯路。
我曾经...
- 忘记初始化平台:有一次我直接写
print("Hello"),没调用init_platform(),结果串口死活没输出。折腾了半天才发现是平台没初始化。 - XSA文件版本不匹配:Vivado导出的XSA文件版本和Vitis版本不一致,导致平台工程生成失败。后来我养成了习惯,每次升级工具链都重新导出XSA。
- 串口波特率设置错误:程序跑起来了,但串口终端显示乱码。检查发现是波特率设置不对。Zynq默认串口波特率是115200,记得在终端软件里也设置成这个值。
- 调试时程序卡在某个地方:后来发现是断点设置太多,影响了程序执行。调试时尽量少设断点,或者用条件断点。
好了,这一章的内容就到这里。你跟着操作一遍,应该就能让Zynq跑起Hello World了。记住,嵌入式开发就是不断试错的过程。遇到问题别慌,先检查硬件连接,再看软件配置,最后查代码逻辑。慢慢来,总会解决的。
可可精品资料库