上一篇简单解释了Zynq配置的相关概念,本文将对Zynq-7000的软件开发进行简单介绍。如果设计者已经对ARM的开发方法很熟悉,上手Zynq的软件开发也会更快,相关概念理解起来也更快。
平台架构选择
Zynq-7000内部有双核ARM Cortex-A9处理器,设计者在开始嵌入式开发前,要先考虑使用非对称多处理(AMP)还是对称多处理(SMP)。还要考虑是否使用操作系统、或使用哪个操作系统。
1.多处理模式的选择
非对称多处理AMP模式下,多处理器系统中的每个处理器可以执行不同的操作系统镜像,但是共享相同的物理内存。采用不同的操作系统主要是为了优势互补,比如一个处理器想要使用网络服务而使用Linux,另一个处理器可以使用一个轻量级的小型操作系统如FreeROTS,提高效率和实时性。AMP模式有两个重要问题:
- 系统设备的划分,比如串口、定时器、以太网等。总的来说,大多数设备必须专用于它们指定的处理器。中断控制器的设计可以使其被多个处理器共享,但是需要指定一个处理器作为主机,来初始化中断控制器。
- 处理器间的通信,让不同操作系统更有效率地工作,可以用内部处理器中断、共享内存、消息传递等方法实现。
对称多处理SMP模式下,多处理器系统中的每个处理器共同执行一个单独的操作系统镜像,操作系统的调度程序负责调度每个处理器上的进程。如果一个操作系统即可满足系统需求,则采用SMP更有效率。操作系统可以自动地使用多个处理器的处理能力,设计者也可以编程实现:
- 设定一个特定的处理器来执行某个进程。
- 使用任何可用的处理器来处理中断。
- 指派一个处理器作为主机,完成系统初始化,启动其它处理器。
2.操作系统的选择
如果一个软件系统不需要依赖太多操作系统提供的特性(如网络),那么完全可以在没有操作系统的环境中工作,这就是裸机(Bare-metal)。操作系统会消耗少量处理器的吞吐量,比裸机也增加了更多的不确定性。当然随着嵌入式处理速度的不断提高,操作系统的开销已经微乎其微。
某些设计中可能还是无法容忍操作系统的不确定性,或者某些设计者由于系统复杂性不会使用操作系统。通常可选的操作系统有:
- Linux:嵌入式设计中最常用的一个开源操作系统,有许多发布版本。Linux虽然本身不是实时操作系统,但也具有了很多实时特性。Linux的优点是功能齐全,可以发挥处理器的内存管理单元MMU的优势。Linux对SMP模式也有很好地支持。
- 实时操作系统,RTOS可以为对时间敏感的应用或系统提供所需的确定性和可预测的响应。FreeRTOS就是一个常用的实时操作系统。
裸机设备驱动架构
裸机的设备驱动采用分层架构设计,提供了跨操作系统、跨工具集、跨处理器的可移植性,如下图所示:
Layer2是RTOS和设备驱动之间的适配器,将Layer1层的设备驱动转换为一个接口,与RTOS的驱动模型的需求匹配。
Layer1是一个抽象的设备驱动程序接口,保护设计者免受底层硬件的更改,通常由宏和函数实现,允许设计者使用设备的所有功能。设备驱动程序与操作系统和处理器保持独立,具有高度可移植性。
Direct Hardware Interface通常以宏和清单常量的形式实现,这样设计者可以创建小型应用程序或创建自定义的设备驱动程序。
裸机应用程序开发
嵌入式设计工具创建的硬件平台数据文件包括:
- 基于XML的硬件描述文件,描述了处理器、外设、内存映射等系统数据;
- bit流文件,包括PL部分的编程数据
- 块RAM内存映射(BMM)文件
- Zynq第一阶段引导装载(FSBL)所需的PS配置数据
构成应用程序最底层的库与驱动的集合,称为裸机的板级支持包BSP。裸机程序的应用环境是一个简单的、半托管的单线程环境,提供了一些基本特性,包括:启动代码、缓存函数、异常处理、基本的文件I/O、支持内存分配和其它调用的C语言库、处理器硬件访问宏、定时器函数,以及其它一些支持裸机应用所需的函数。
下面是使用SDK进行裸机应用开发的典型流程图:
1. 导入硬件平台信息
Xilinx硬件配置工具可以创建硬件平台数据,设计者需要将这些数据导出到SDK,创建一个硬件平台工程。
2. 创建裸机BSP
创建好硬件平台工程后,用SDC创建一个裸机BSP工程。驱动程序和库的源文件基于硬件平台(处理器、IP特性集、硬件配置设置)进行组织和参数配置,创建头文件进行参数定义,之后再编译。BSP反映了在PS中启用的IP,包括MIO配置和PL中的自定义逻辑。设计者可以修改和重新生成BSP设置。
3. 创建裸机应用
SDK提供了几个示例程序,从简单的“Hello World”到复杂的LWIP测试等。在应用程序向导中可以选择并生成这些应用程序。当然也可以创建空白程序,或者将现有的程序导入到裸机BSP中。每个应用程序都要有个相关联的BSP。代码开发工具基于Eclipse平台和CDT插件,支持编辑、搜索、重构等基本功能。
4. 构建应用工程
SDK应用工程可以选择用户管理或自动管理。用户管理需要自己创建makefiles并维护。自动管理SDK会创建makefiles,当添加或删除源文件时自动更新makefiles,源文件在保存改动时会自动编译,还会自动构建ELF文件。SDK可以根据硬件平台和使用的BSP,推测和设置默认的构建选项,包括编译器、链接器和库路经。
5. 器件编程与应用运行
构建完裸机应用后,用SDK配置PS、对PL编程、运行应用。SDK使用系统级配置寄存器SLCR配置PS,同时配置数据也会用于FSBL。Bit流和块内存映射数据也会下载到Zynq中,将自定义的设计逻辑加载到PL中,如果仅需要在PS中运行应用,这步便可省略。下载和运行应用程序的ELF文件时,SDK的Terminal窗口可以通过STDIN和STDOUT和应用程序进行交互。
6. 调试应用程序
调试应用程序与运行应用程序步骤基本相同,只不过后者创建的是“运行配置”,前者创建的是“调试配置”。一组窗口提供了完整的调试环境,包括调用堆栈状态、源文件查看、分解器、内存、寄存器、其它一些视图,还有控制台。设计者可以设置断点,控制程序执行。对于熟悉Eclipse和CDT插件的程序员来说,该步骤应该相当熟悉。
7. 添加支持自定义IP的驱动程序
Xilinx硬件配置工具创建的硬件平台数据会捕获PL部分使用的Xilinx IP模块,裸机的BSP也会自动包含支持这些模块的驱动程序。包含硬件描述元数据文件的自定义块也可以被捕获,作为硬件平台的一部分传递给SDK。
此外,可以通过指定包含自定义驱动程序和元数据的路径,让SDK将其包含在裸机BSP中。也可以创建库工程,管理和构建自定义驱动程序的源文件。当硬件平台发生改变时,设计者可以通过MDD文件和Tcl文件重新配置自定义IP驱动程序。MDD文件设定了设置的驱动程序参数;Tcl文件则记录了生成.h和.c文件的过程。
8. 部署应用程序
在SDK中开发和调试完裸机应用后,设计者可以为应用程序创建一个boot镜像,用于部署在开发板上。SDK包含一个FSBL的应用程序模板,可以通过修改该模板来创建和构建最终的FSBL。FSBL、裸机应用程序、PL编程的bit流组合在一起生成一个boot镜像,用SDK Flash Wrier对支持的器件进行编程。
Linux应用程序开发
Linux是一个开源的操作系统,Xilinx提供了PS外设的驱动程序。使用硬件平台数据和Linux内核(Kernel),设计者可以用SDK对Linux用户程序进行编程、调试和部署。但是SDK不支持对Linux内核的调试,Linux内核的配置和构建过程需要用其它软件完成,或者可以用现成的Linux内核。
下面着重介绍以下与裸机程序开发不同的步骤,
1. 启动Linux
启动Linux有多种方法:(1).将boot镜像下载到Flash中,开发板上电或复位;(2).依次下载和运行FSBL、U-Boot和Linux内核;(3).使用U-Boot加载和运行镜像。当在Zynq上运行Linux时,SDK会把PS平台当作一个远程的Linux主机,实现的功能取决于文件系统中包含的组件。
启动过程中,首先会运行FSBL来设置PS,然后运行U-Boot来加载Linux镜像和启动Linux。实际的启动顺序和Flash镜像创建取决于Flash的类型和其它需求。比如FSBL可以用来配置包含自定义逻辑的PL、U-Boot镜像也可以包含FSBL。
2. 创建应用工程
与裸机应用工程相同,也是在SDK中完成。此外,SDK还提供了一个Bootgen程序生成可引导的镜像(.bin或.mcs)。设计者向Bootgen提供所有镜像和加载地址,即可创建boot镜像。SDK还提供一个程序,可以将镜像传送到Flash器件中。
3. 构建与运行应用程序
构建过程与裸机完全相同。运行时先创建一个SDK运行配置,将编译好的应用程序复制到文件系统中。当Zynq中运行Linux时,如果Linux环境中包含SSH,运行配置会用sftp把可执行文件复制到文件系统中。
4. 调试应用程序
调试时,Linux中的gdbserver会运行应用程序,SDK调试器通过TCP和其通信。其它调试特性与裸机时相同。
5. 添加支持自定义IP的驱动程序
SDK支持为PS中的外设和PL中的自定义IP生成Linux BSP。生成Linux BSP时,SDK会生成一个设备树。设备树本质上就是一种数据结构,描述了硬件系统,在启动时会传递给内核。设备驱动程序作为内核的一部分,或作为单独的模块使用;设备树定义了一组可用的硬件功能和启用的特性。PL中的自定义IP是高度可配置的,设备树参数定义了系统中可用的IP集,以及每个IP中启用的硬件特性。
6. 分析应用程序
在构建应用程序时加上-pg选项,可以分析Linux用户程序,基于gprof单元和一个附带的查看器来显示调用图和其他数据。SDK包含一个OProfile插件,可以在分析用户应用程序、内核、中断处理程序和其他模块中所有正在运行的代码时,做到可视化。OProfile是一个Linux系统范围内的开源分析器,通过内核驱动程序和守护进程来收集示例数据。
7. 向Linux文件系统添加应用
编译后的用户应用程序和所需的共享库可以添加到Linux文件系统中,可以通过如下三种方法实现:
- 当Linux运行在Zynq-7000 AP SoC上时,如果Linux环境包含SSH,可以使用sftp复制文件。
- 在SDK中,远程系统资源管理器(RSE)插件允许使用拖放来复制文件。
- 在SDK外部的工作流中,在创建文件系统映像并将其编程到flash之前,将应用程序和库添加到文件系统文件夹。
本系列会先介绍裸机应用程序的开发,再介绍带操作系统的应用程序开发,届时再对操作系统的相关概念做详细介绍。