第4章:Vitis基础操作——创建应用工程、编写Hello World、编译与下载调试

好,咱们进入实操环节。

前面几章我们把Zynq的架构、开发流程、工具链都捋了一遍。说实话,光看理论容易犯困。这一章咱们直接上手,用Vitis跑一个真正的Hello World程序。你想想看,当那个“Hello World”从串口打印出来的时候,整个开发板才算真正“活”了。

本章核心目标:掌握Vitis IDE的基本操作流程,从创建工程到下载调试,跑通第一个Zynq裸机应用。

4.1 准备工作:硬件与软件环境

在动手之前,先确认几件事。我个人习惯把环境检查放在第一步,省得后面出问题再回头找原因。

  • 硬件:Zynq开发板(我常用ZedBoard或PYNQ-Z2)、Micro USB线(用于JTAG调试和串口通信)、电源
  • 软件:Vitis 2020.2或更新版本(我建议用2021.1以上,稳定性好一些)、Vivado生成的硬件描述文件(.xsa)
  • 驱动:确保USB驱动安装正确,设备管理器里能看到“Digilent USB Device”或类似设备

注意:我曾经遇到过好几次,学生拿着新买的开发板,插上电脑没反应。结果发现是USB线的问题——有些线只能充电,不能传数据。一定要用带数据传输功能的线。

4.2 创建Vitis应用工程

打开Vitis,工作空间(Workspace)选一个干净的目录。我个人习惯把每个项目单独放一个文件夹,比如 D:/Zynq_Projects/Hello_World。

4.2.1 新建平台工程

Vitis里有个概念叫“平台”(Platform),它包含了硬件描述和驱动。说白了,平台就是Zynq的“底子”。

  1. 点击 File → New → Platform Project
  2. 输入工程名,比如 hello_world_platform
  3. 在 Hardware Specification 里选择之前Vivado导出的 .xsa 文件
  4. 勾选 Generate boot components(生成启动文件,后面调试要用)
  5. 点击 Finish

Vitis会自动解析 .xsa 文件,生成BSP(板级支持包)。这个过程大概需要几十秒,你可以去倒杯水。

4.2.2 新建应用工程

平台建好后,咱们在上面跑应用。

  1. 点击 File → New → Application Project
  2. 工程名填 hello_world_app
  3. 在 Platform 里选择刚才创建的 hello_world_platform
  4. Domain 选择 standalone(裸机运行,没有操作系统)
  5. CPU 选择 ps7_cortexa9_0(Zynq的双核A9,咱们先用核0)
  6. 点击 Next

到了模板选择界面,Vitis提供了很多现成的模板。咱们选 Hello World,然后点 Finish。

小技巧:Vitis的模板其实挺实用的。比如“Empty Application”适合从零开始写,“Dhrystone”可以用来跑分。但第一次上手,Hello World最直观。

4.3 编写Hello World代码

工程创建好后,Vitis会自动生成一个 helloworld.c 文件。双击打开,你会看到类似这样的代码:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

int main()
{
    init_platform();

    print("Hello World\n\r");

    cleanup_platform();
    return 0;
}

嗯,这里要注意几个细节:

  • init_platform() 和 cleanup_platform() 是Vitis自动生成的,负责初始化串口、中断等外设。说白了就是让板子“准备好说话”。
  • print() 函数输出到串口,默认用的是UART0。如果你板子的串口接在UART1上,需要改BSP设置。
  • \n\r 是换行加回车。只写 \n 的话,在有些串口终端上会显示不正常。

我个人习惯在打印信息前加个时间戳或者项目标识,比如:

print("===== Hello World from Zynq (v1.0) =====\n\r");

这样调试的时候一眼就能认出是哪个版本的程序。

4.4 编译工程

代码写好了,接下来编译。Vitis的编译操作很简单:

  1. 在 Project Explorer 里右键点击 hello_world_app
  2. 选择 Build Project
  3. 或者直接按快捷键 Ctrl+B

Vitis会调用ARM GCC编译器,把C代码编译成ARM指令。编译过程会在Console窗口打印信息。如果一切顺利,你会看到 Build Finished 的提示。

常见编译错误:

  • 找不到头文件:检查BSP是否生成成功。如果BSP没生成,应用工程会报一堆“undefined reference”错误。
  • 链接错误:检查LScript(链接脚本)是否正确。裸机程序默认用 lscript.ld,一般不用改。

我曾经遇到过一个坑:编译通过了,但下载后程序不跑。查了半天,发现是BSP里串口波特率设错了。Vitis默认是115200,但我的串口助手设成了9600。嗯,这种低级错误,犯过一次就记住了。

4.5 下载与调试

编译通过后,咱们把程序下载到板子上跑起来。

4.5.1 连接开发板

用Micro USB线连接开发板的JTAG/UART口(通常是标有“PROG”或“UART”的那个口)。上电后,打开设备管理器,确认能看到两个虚拟串口:一个用于JTAG调试,一个用于串口通信。

4.5.2 配置串口终端

打开串口助手(我用的是Putty或Tera Term),配置如下:

参数 值
波特率 115200
数据位 8
停止位 1
校验位 None
流控制 None

4.5.3 下载程序

在Vitis里,右键点击 hello_world_app,选择 Run As → Launch on Hardware (Single Application Debug)。Vitis会自动下载程序到板子的DDR里,然后复位CPU开始执行。

如果一切正常,串口终端上会打印出:

===== Hello World from Zynq (v1.0) =====

看到这行字,恭喜你,第一个Zynq裸机程序跑通了!

4.5.4 调试模式

如果程序有问题,可以用调试模式。右键选择 Debug As → Launch on Hardware (Single Application Debug)。Vitis会进入调试视图,你可以设置断点、单步执行、查看变量值。

我个人习惯在 print() 函数前后各设一个断点,确认程序执行到了哪里。如果连 init_platform() 都没跑过去,那八成是硬件初始化有问题。

注意:调试模式下,如果程序卡在某个地方不动,先检查JTAG连接是否稳定。我遇到过好几次,USB线接触不良导致调试器断连。换根线就好了。

4.6 本章小结

这一章我们走完了Vitis开发的完整流程:创建平台工程 → 创建应用工程 → 编写代码 → 编译 → 下载调试。说白了,就是让Zynq“开口说话”。

你想想看,从Vivado里画Block Design,到Vitis里写C代码,再到串口看到输出——整个Zynq软硬件协同设计的闭环,在这一刻真正打通了。

嗯,这里要提醒一句:Hello World虽然简单,但背后的流程是通用的。后面不管是写UART驱动、I2C驱动,还是跑FreeRTOS,操作步骤都差不多。把这一步练熟了,后面的路就好走了。

个人经验:我建议初学者至少重复做三遍这个流程。第一遍照着做,第二遍不看教程自己做,第三遍换一块板子或者换一个.xsa文件再做一遍。三遍下来,Vitis的基本操作就刻在肌肉记忆里了。

Vitis Hello World 开发流程 1. 创建平台工程 导入.xsa硬件描述 2. 创建应用工程 选择Hello World模板 3. 编写代码 修改helloworld.c 4. 编译 Ctrl+B 5. 下载调试 Run/Debug on Hardware 6. 查看串口输出 Hello World! 调试 → 修改代码 → 重新编译 虚线表示调试循环:发现问题 → 修改代码 → 重新编译下载

可可精品资料库