实验一 嵌入式系统无系统模式编程实验

一、实验目的

  1. 理解 ZYNQ 系统中 PS 和 PL 的基本概念及工作原理。
  2. 掌握在 Vivado 环境中创建硬件工程和在 SDK 中编写嵌入式应用程序的流程。
  3. 学会编写并运行简单的嵌入式裸机程序。

二、实验原理

1. 概述

ZYNQ 系列 FPGA 的独特之处在于其集成了双核 Cortex-A9(PS)和 FPGA(PL)。实验将搭建一个最小 SOC 系统,并使用 HelloWorld 工程及自编写的 C 程序测试基本外设,通过详细的工程搭建和 ZYNQ IP 参数配置说明,学生将学会在 Vivado 和 SDK 中创建并运行一个最小的 SOC 系统。

2. 最小系统分析

最小系统由 ARM Cortex-A9、DDR3 内存和一个 UART 串口组成。程序加载到 DDR 内存中,由 CPU 执行,串口输出执行结果。

3. 硬件电路分析

使用 1GB 的 PS 端 DDR 内存。

使用 PS 端一个 UART 串口。

使用 JTAG 接口烧录程序。

硬件连接包括电脑和开发板之间的串口线及 USB 转 mini USB 线。

4. GPIO 简介

Zynq7000 系列芯片提供 54 个 MIO,这些 MIO 分配在 GPIO 的 Bank0 和 Bank1,直接隶属于 PS 部分,操作时不需要添加引脚约束。

三、实验步骤

  1. 创建 Vivado 工程。
  2. 新建 SDK 工程。
  3. 运行 Hello World 实验,通过串口打印 “hello world”。
  4. 进行 PS-MIO 点亮 LED 实验。

四、实验结果

img

五、实验中遇到的问题及解决办法

Vivado工程创建过程中卡顿或崩溃,关闭其他占用内存和 CPU 的程序,确保有足够的内存和 CPU 资源可用;SDK 无法识别开发板,确认开发板电源是否开启。

六、思考题

  1. 实验中 DDR 的作用是什么? UART 的作用是什么?

    DDR 用于存储程序代码和数据,CPU 从 DDR 中读取指令并执行。UART 用于串口通信,通过串口打印输出调试信息,如 “hello world”。

  2. PS 端的 MIO、 UART 等外设接口需要添加引脚约束吗?为什么?

不需要,因为 MIO 直接隶属于 PS 部分,与 PL 部分无关,不需要通过引脚约束定义。

  1. 什么是 EMIO? EMIO 和 MIO 的区别是什么?

EMIO(Extended MIO):用于将 PS 部分的信号扩展到 PL 部分,实现 PS 和 PL 之间的信号交互。

MIO(Multiuse I/O):PS 部分的多用途 I/O,直接用于 PS 部分的外设接口,不需要引脚约束

  1. 在 helloworld 实验中,示例 c 程序中哪个函数实现了串口打印?

print() 函数。

  1. 在 MIO 亮灯实验中, XGpioPs 结构体有哪些成员?它们的含义分别是什么?

BaseAddr:基地址,用于访问 GPIO 寄存器。

IsReady:指示设备是否已初始化并准备就绪。

Pin:GPIO 引脚编号。

Direction:引脚方向(输入或输出)。

OutputEnable:输出使能,控制引脚是否可作为输出。

七、实验收获、实验感想或对实验的建议(选做)

从基础的 Hello World 到 GPIO 控制,通过动手实践,理论知识得到了很好的应用和巩固。

实验二 基于ZYNQ SoC移植Ubuntu系统

一、实验目的

  1. 掌握Vivado和SDK中各类工程文件的功能。
  2. 了解Linux根文件系统、内核、设备树及uboot的作用。
  3. 学会制作系统启动文件BOOT.bin的流程。
  4. 学习制作在ZYNQ上运行并支持HDMI输出的Ubuntu系统。

二、实验原理

ZYNQ开发中涉及多个关键文件,包括bit文件、elf文件和hdf文件。bit文件是由Vivado生成的,在FPGA端(PL)运行的程序;elf文件是由SDK生成的,在ARM处理器端(PS)运行的程序;hdf文件是由Vivado生成的硬件描述文件,包含PS端外设内存映射和IP核配置等信息。

为了将Vivado和SDK生成的程序固化到如TF卡的非易失性存储器中,需要制作BOOT.bin文件。BOOT.bin包含FSBL.elf、工程.bit和工程.elf三个部分。FSBL(First Stage Boot Loader)是由SDK生成的工程,编译后以elf文件的形式存在,其作用是在ZYNQ启动的第一步,将bit和elf文件妥善安置。

ZYNQ的启动过程分为三个阶段:阶段0是传统的BootROM过程,ZYNQ芯片ROM内固化了一段不可修改的程序,上电后执行,初始化基本外设控制器并将程序拷贝到ZYNQ的片上内存OCM,这个被拷贝的程序就是BOOT.bin。阶段1由加载到OCM的BOOT.bin开始执行,配置PS部分,随后配置PL部分,并加载阶段2代码。阶段2主要完成Linux系统启动,本次实验暂不涉及。

根文件系统是存储设备上数据和元数据的组织机制。它包含系统引导和加载其他文件系统所需的文件,如Linux启动时的init目录及/etc/fstab文件等。根文件系统包括许多应用程序和启动所必须的文件。

Linux内核目录结构包括arch目录(存放与体系结构相关的核心代码)、COPYING目录(GPL版权声明)、CREDITS目录(贡献者信息)、documentation目录(文档说明)、drivers目录(设备驱动程序)、fs目录(文件系统代码)、include目录(头文件)、init目录(核心初始化代码)、ipc目录(进程间通信代码)、kernel目录(内核管理核心代码)、MAINTAINERS目录(维护人员列表)、Makefile目录(内核模块组织文件)、mm目录(内存管理代码)、net目录(网络代码)、ReadMe目录(核心及编译配置方法简介)和REPORTING-BUGS目录(报告Bug内容),以及scripts目录(配置核心的脚本文件)。

三、实验步骤

  1. 使用Vivado创建HDMI裸机输出工程,并导出bit文件和硬件描述hdf文件。
  2. 在SDK中创建fsbl软件工程,编译生成elf格式的可执行文件。在Linux环境下构建根文件系统,编译Linux内核、设备树和uboot。
  3. 使用相关文件制作ZYNQ平台下的Linux系统启动镜像文件BOOT.bin。
  4. 制作TF卡启动盘,运行Ubuntu系统,通过串口连接主机,并使用HDMI接口连接显示屏以显示命令行系统。

四、实验结果

img

五、实验中遇到的问题及解决办法

Vivado中bitstream文件生成失败,检查设计中是否有未连接的信号或者错误的约束文件。确保所有的IP核配置正确,重新生成bitstream文件;在SDK中生成FSBL工程时编译报错,确保在Vivado中导出的硬件描述文件(HDF或XSA)正确无误。在SDK中创建FSBL工程时,选择正确的硬件平台文件。如果仍有错误,查看编译日志,修复具体错误。

六、思考题

1. 在Vivado中export hardware操作会产生什么文件?它的作用是什么?

在Vivado中执行“export hardware”操作会生成一个硬件描述文件(HDF)或者在更新版本中生成XSA文件。这些文件包含了硬件设计的描述信息,包括PS端的外设内存映射和IP核配置等信息。这些文件用于在SDK中创建和配置软件工程,使软件能够正确地与硬件交互。

2. 在**settings64.sh**脚本中,大量使用了**export**命令,它的作用是什么**? settings64.sh**脚本的作用是什么**?如果打开一个新的命令行窗口,需要重新运行settings64.sh**脚本吗**?**

settings64.sh脚本中大量使用export命令是为了设置环境变量,这些变量指定了工具链和开发环境的路径。settings64.sh脚本的主要作用是配置开发环境,使得系统能够找到并使用Vivado和SDK等工具。如果打开一个新的命令行窗口,确实需要重新运行settings64.sh脚本,因为环境变量在新窗口中不会自动继承,需要手动配置。

3. Bootbin**的制作需要哪三个文件**?**它们是如何得到的**?

Boot.bin的制作需要三个文件:FSBL.elf、bitstream文件(.bit)和应用程序的elf文件。FSBL.elf是通过在SDK中创建FSBL工程并编译得到的;bitstream文件(.bit)是通过在Vivado中生成硬件工程并导出得到的;应用程序的elf文件是通过在SDK中编译应用程序工程得到的。

4.**基于**ZynqSoC**移植**Ubuntu**系统需要编译哪些组件**?**它们的作用是什么**?

U-Boot:引导加载程序,用于初始化硬件和加载Linux内核。

Linux内核:操作系统的核心,负责硬件管理、系统资源分配和基本操作。

设备树(Device Tree Blob, DTB):描述硬件架构的二进制文件,内核启动时使用。

根文件系统:包括系统引导、挂载其他文件系统和运行应用程序所需的基础文件。

5.**在分区并烧录好的**sd**卡中,**boot**分区内有哪些文件**?**它们分别对应基于**Zynq SoC**移植**Ubuntu**系统的哪些部分**?

在分区并烧录好的SD卡的boot分区内,通常包含以下文件:

BOOT.bin:包含FSBL、bitstream文件和U-Boot,是系统启动的第一步。

uImage或Image:Linux内核映像文件。

system.dtb:设备树文件,描述硬件架构。

uEnv.txt(可选):环境变量配置文件,用于引导加载程序。

这些文件分别对应Zynq SoC移植Ubuntu系统的各个部分,其中BOOT.bin负责系统的初始引导,uImage或Image是操作系统的核心,system.dtb描述硬件架构,uEnv.txt配置引导加载程序的环境。

七、实验收获、实验感想或对实验的建议(选做)

通过本次实验,我们深入了解了Vivado和SDK中各类工程文件的作用,掌握了制作系统启动文件BOOT.bin的流程,熟悉了Linux内核、设备树和根文件系统的构建过程。

实验四 基于QTE的嵌入式GUI设计

一、实验目的

  1. 学习如何使用Qt Creator IDE编写简单的图形界面程序
  2. 掌握QTE的安装和使用方法
  3. 学习基于QTE对Qt程序进行嵌入式移植的技术

二、实验原理

Qt是一个由奇趣科技于1991年开发的跨平台C++图形用户界面应用程序开发框架。它不仅用于开发图形用户界面程序,还可以开发非图形用户界面程序,如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器,moc)以及一些宏,易于扩展,允许组件编程。Qt在2008年被诺基亚公司收购,随后在2012年被Digia收购。2014年4月,Qt Creator 3.1.0正式发布,实现了对iOS的完全支持,并新增了WinRT、Beautifier等插件,废弃了无Python接口的GDB调试支持,集成了基于Clang的C/C++代码模块,并对Android支持做出了调整,至此实现了全面支持iOS、Android、WP等平台。

Qt框架提供了开发图形用户界面所需的所有功能,采用C++语言编程,功能强大,使用简单,是目前Linux图形化开发工具中的主流之一。Qt的一个重要特性是信号和槽机制,这在图形用户界面编程中尤为重要。信号和槽机制用于对象之间的通信,当一个对象的状态改变时,信号被发射,槽函数用于处理该信号。信号和槽机制类型安全,编译器可以检测类型不匹配,并且它们之间的连接是松散耦合的。信号和槽机制提供了强大的组件编程能力,使得程序的模块化设计变得更加容易。

信号和槽机制具体表现为:当一个特定事件发生时,一个信号被发射。Qt的窗口部件有很多预定义的信号,但用户可以通过继承加入自己的信号。槽函数是用于处理特定信号的函数,可以是预定义的也可以是用户定义的。信号和槽机制确保了如果将一个信号和一个槽连接起来,槽函数会在正确的时间被调用,并使用信号的参数。信号和槽机制提供了类型安全的通信方式,避免了传统回调方式的缺点。

三、实验步骤

  1. 在PC上安装Qt软件,确保开发环境的搭建。
  2. 使用Qt Creator编写一个简单的Qt程序,并在PC上进行测试运行,确保程序功能的正确性。
  3. 进行QTE的编译和移植,确保在嵌入式平台上的运行环境准备就绪。
  4. 将编写好的Qt程序进行编译和移植,并在ZYNQ嵌入式平台上运行,验证程序在嵌入式系统中的执行效果。

四、实验结果

imgimg

五、实验中遇到的问题及解决办法

在编译和移植QTE时,遇到编译错误或者库文件缺失的问题,导致无法顺利完成编译,仔细阅读编译日志,找出错误信息并进行针对性解决。

六、思考题

1.**分析实验中使用的**qt**程序的源代码,是如何实现按钮控制文本显示的**?**如果使用多个按钮分别控制,程序怎么写**?**如果要实现多于**2**个文本的轮流显示,程序怎么写**?

通过信号槽机制,连接按钮点击信号到显示文本的槽函数,多个按钮控制时,每个按钮连接不同槽函数,实现多文本轮流显示,可在槽函数中循环切换文本。

2.fetch_sources.sh 脚本的作用是什么**? packages**目录下两个开发包分别是什么,有什么作用**?**

获取源代码或依赖包,准备编译环境,packages目录两个开发包:一个是Qt库,另一个可能是嵌入式库,分别提供Qt支持和嵌入式功能。

3.**编译**qt**时,**make_gt5_lib.sh 对编译过程进行了配置,其中 skip**参数的作用是什么**?**为什么要使用该参数**?

跳过特定编译步骤,节省时间或避免重复编译。

4.**在**build_arm_app.sh**脚本中,**qmake && make**对工程进行了编译其中**make**是什么**?qmake**的作用是什么**?qmake**使用了**helloqt**工程中的哪个文件**?qmake**和**make**的区别是什么**?

qmake生成Makefile,make执行编译,qmake使用.pro文件生成Makefile,qmake生成Makefile,make根据Makefile编译。

5.build_arm_app.sh 脚本编译得到的可执行文件**helloqt**为什么不能直接运行**?结合run_arm_app.sh**中的环境变量设置解释该问题

需要设置环境变量,run_arm_app.sh设置库路径和环境变量,确保程序找到所需库。

6.(**可选扩展实验**)**设计一个美观的动态程序界面,如显示正弦波等**

设计正弦波动态显示界面,定时器周期更新图形,使用QPainter绘制正弦波,QTimer控制刷新,实现动态效果。

七、实验收获、实验感想或对实验的建议(选做)

通过本次实验,掌握了使用Qt Creator IDE进行图形界面开发的基本方法,了解了QTE的安装和使用过程,并学习了Qt程序的嵌入式移植技术。