ucos iii在zynq上的移植

时间:2022-02-22 18:38:33

介绍

本教程介绍了如何使用μC/ OS BSP建立在ZYNQ基本应用程序®使用Vivado -7000  IDE和赛灵思® SDK。在本教程中,您将使用Vivado IP集成器配置ZYNQ处理器系统以及FPGA架构集成软外设。然后,您将使用μC/ OS BSP来生成使用一个基本的应用程序μC/ OS-III实时内核。

本教程的视频版本也可在Micrium的YouTube频道:

本教程将让您体验以下概念:

  • 一个μC/ OS-III的应用程序和BSP的生成
  • BSP和驱动程序配置
  • 选择和使用赛灵思独立驱动和Micrium的自定义驱动程序
  • 标准输出(文字痕迹)
  • 中断处理
图标

本教程是不是意味着作为Vivado设计流程的演示。读者建议先通过官方赛灵思教程和文档尝试本教程之前。

软件要求

  1. 合适的Vivado设计套件是本教程所需。是否支持您的主板WebPACK的版本都可以使用。
  2. μC/ OS BSP。BSP是随μC/ OS-III的评估目的的完整的源代码。请参阅安装说明进行安装。
图标

Vivado设计套件2014.3版本在本教程中使用。截图和设计步骤可能会有所不同在其他版本。

硬件要求

本教程的编写和赛灵思ZC702,安富利ZedBoard测试™和MicroZed 。然而,大多数如果不是全部基于ZYNQ开发平台应该是适合本教程。为了达到最佳效果董事会应该有一个可用的UART输出连接到PS UART。

确保你有适当的调试器或调试电缆连接,并且板载跳线进行相应配置。

硬件设计

在写任何赛灵思可编程器件的软件应用程序是创建硬件设计首先需要。本教程的目的是建立一个硬件设计具有下列组件。

  • 的Cortex-A9处理器,硬化
  • 经由处理器系统的UART标准输出
  • 基本FPGA设计
    • AXI互连连接到PS通用AXI4主端口
    • 两个软AXI定时器

    • 这两个定时器到PS的路由

步骤1.调用Vivado IDE和创建项目

1.打开Vivado IDE作为起始页。 图- Vivado起始页

 

ucos iii在zynq上的移植图 - Vivado起始页

 

2.从入门页面中点击“创建新项目”。这应该打开新项目向导。 图- Vivado新建项目向导点击下一步。

 

ucos iii在zynq上的移植图 - Vivado新建项目向导

 

3.输入项目名称和位置。确保“创建项目的子目录”被选中。点击下一步。

4.选择“RTL工程”作为项目类型,并检查“不要指定此时来源”复选框。点击下一步。

5.在默认部分对话框中选择你板或部分。点击下一步。

6.在项目摘要页面单击Finish。

这应该在一个空白的项目主要Vivado IDE项目视图为您带来。 图- Vivado项目视图

 

ucos iii在zynq上的移植图 - Vivado项目视图

步骤2.创建一个IP集成器设计

1.在流动导航器中选择“创建模块设计”项目 图-模块化设计流程的项目

 

ucos iii在zynq上的移植图 - 模块化设计流程的项目

 

2.指定块设计一个名称,然后单击确定。

第3步:添加和设置ZYNQ处理器系统的IP块

1.通过右键单击程序框图画布,选择“添加IP ......”添加IP对话框。 图-添加IP上下文菜单

 

ucos iii在zynq上的移植图 - 添加IP上下文菜单

 

2.在搜索字段中键入“ZYNQ”,然后选择ZYNQ7处理系统,最后按回车键的ZYNQ IP模块添加到设计 图-添加IP ZYNQ

 

ucos iii在zynq上的移植图 - 添加IP ZYNQ

 

您现在应该看到ZYNQ块单独的程序段设计原理图的中间。 图-座ZYNQ

 

ucos iii在zynq上的移植图 - 座ZYNQ

 

3.调用的ZYNQ块自动化对话框。这应该高亮显示为绿色的画布上,并可以通过点击“运行座自动化”启动。 图- ZYNQ座自动化援助

图标

座自动化为Zynq7处理系统将只可当Vivado知道你正在使用的电路板。

ucos iii在zynq上的移植图 - ZYNQ座自动化援助

 

4.在“运行座自动化”对话框中选择“应用预设董事会”,并留下了交叉触发设置为禁用 ​​。点击OK。 图- ZYNQ座自动化对话

 

ucos iii在zynq上的移植图 - ZYNQ座自动化对话

 

如果一切顺利阻止自动化应该连接外部存储器和固定的I / O自动。 图- ZYNQ座自动化结果

 

ucos iii在zynq上的移植图 - ZYNQ座自动化结果

步骤4.自定义ZYNQ块我们的设计

在上一步骤的Zynq7 IP模块加入到设计中。在这个步骤中,您将定制ZYNQ块教程设计和连接将用于软件演示两个AXI定时器。

对于软件演示,需要许多组件。

UART - 输出字符串消息的UART必须连接到外部源。

参考时钟 - 该ZYNQ可以导出多达四个时钟信号FPGA架构。一个是需要时钟AXI定时器和互连。

通用主端口 - 要访问位于PS的AXI4主端口的FPGA一个软外设必须被激活。

中断 - 要路由的定时器到PS对PS-PL中断必须启用的背面的中断。

 

1.打开Zynq7通过右键单击自定义对话框中的块,然后选择“自定义模块”。 图- ZYNQ块上下文菜单

 

ucos iii在zynq上的移植图 - ZYNQ块上下文菜单

 

重新定义IP对话框的Zynq7现在应该打开。 图- ZYNQ块上下文菜单

 

ucos iii在zynq上的移植图 - ZYNQ块上下文菜单

 

2.确保AXI通用主端口0是启用的PS-PL配置部分。。调用ZYNQ块时,这通常是完成默认 ZYNQ PS-PL配置-图

 

ucos iii在zynq上的移植图 - ZYNQ PS-PL配置

 

3.安装一个UART输出。大多数板都会有这样的配置为默认的“外设I / O引脚”部分中。 图- ZYNQ外围IO配置

 

ucos iii在zynq上的移植图 - ZYNQ外围IO配置

 

4.Setup从PS到PL一个50MHz的时钟。这通常是“时钟配置”部分中的默认设置。 图- ZYNQ时钟配置

 

 ucos iii在zynq上的移植图 - ZYNQ时钟配置

 

5.Enable FPGA来PS中断线路的“中断”一节中。这将使路由多达16个独立的中断从FPGA到了Cortex-A9中断控制器。 图- ZYNQ中断配置

 

 ucos iii在zynq上的移植图 - ZYNQ中断配置

 

在“重新定制IP”对话框6.依次点击确定。

第5步:添加软外设

现在,ZYNQ块被正确配置它的时间来添加软定时器。这些定时器随后将通过AXI互连连接到ZYNQ主端口和映射到主要的ARM互连地址空间。

 

1.添加两个AXI定时器,以块设计。这可以以类似的方式为ZYNQ块通过右键单击在画布上完成,然后选择添加IP。从添加IP对话框搜索“AXI定时器”,并将其添加到设计中。重复一次,第二次计时。 图- ZYNQ和未连接定时器示意图

 

 ucos iii在zynq上的移植图 - ZYNQ和未连接定时器示意图

 

2.连接自动化,可从突出绿色条,可用于自动连接定时器。 图-定时器连接自动化

 

 ucos iii在zynq上的移植图 - 定时器连接自动化

 

定时器现在应该经由一个新的AXI互连由连接自动化设计协助自动添加连接到ZYNQ块。您可能会注意到一个复位处理系统也是设计的一部分了。 图-定时器连接完成

 

 ucos iii在zynq上的移植图 - 定时器连接完成

 

连接自动化还自动连接的外设分配地址范围。您可以咨询所产生的地址映射在框图编辑器的“地址编辑器”窗格中。 图-定时器地址配置

 

 ucos iii在zynq上的移植图 - 定时器地址配置

 

3.从“添加IP”对话框中添加一个“Concat的”块实例。该块可以被用于聚合路由给PS的中断信号。该块的输出应连接到IRQ_F2P [0:0] ZYNQ块的端口。然后axi_timer_0连接的中断行脚0 Concat的块。同样应该做axi_timer_1并连接到管脚1块的毗连的。最终的原理应该像 图-最终的硬件设计原理图

 

 ucos iii在zynq上的移植图 - 最终的硬件设计原理图

 

4.设计可以检查通过点击“验证设计”按钮的错误。

 

第6步:生成HDL设计文件

1.在源树中右击该块设计文件,然后选择“生成输出文件”。 图-生成输出文件背景

 

 ucos iii在zynq上的移植图 - 生成输出文件背景

 

2.右键单击再次选择“创建HDL封装”这个时候。当系统提示选择“让Vivado管理创建包装器”。

 

第7步合成,实施和生成流

1.要进行综合,实现和位流生成一次全部单击“生成流”中的“程序和调试”的流程导航部分。当提示运行前一代点击合成和实施步骤是肯定的。 图-生成流

 

 ucos iii在zynq上的移植图 - 生成流

 

之后,它的完成你呈现一个对话框,您可以选择打开实现的设计。从那里,你就可以查看资源的使用情况,定时信息和最终实施的布局规划。该设计现在是准备出口到Xilinx SDK。

2.要导出的设计选择文件菜单中的“导出硬件”选项。请确保选择“包含比特流”。 图-导出硬件对话

 

ucos iii在zynq上的移植 图 - 导出硬件对话

 

3.在文件菜单中选择了“劳克SDK”选项,再次启动SDK。

这结束了本教程的硬件设计部分。

软件设计

本教程的软件部分的目标是创建一个基本的μC/ OS-III项目。然后证明同时使用Micrium公司定制的驱动程序和Xilinx独立的驱动程序与AXI定时器接口。

步骤1.安装了μC/ OS系统信息库

完整的安装说明在现有的用户手册

1.要安装存储库将其添加到从Xilinx工具-当前的工作空间>系统信息库菜单。 图-赛灵思SDK库首选项

 

ucos iii在zynq上的移植图 - 赛灵思SDK库首选项

第2步:生成μC/ OS BSP

第一步骤是生成的C / OS的BSP的硬件平台和一个简单的C / OS的“Hello World”类型的项目。

 

1.打开赛灵思SDK。这应该已经完成的硬件设计节的最后一步。 图-赛灵思SDK主屏幕

 

ucos iii在zynq上的移植图 - 赛灵思SDK主屏幕

 

2.打开“新的应用项目对话框”。它可以从文件 - >新建 - >应用程序项目菜单进行访问。

在此对话框中,输入项目名称,然后选择“UCOS”作为操作系统平台。点击下一步。 图-新的应用项目对话框

 

 ucos iii在zynq上的移植图 - 新的应用项目对话框

 

3.新项目模板对话框应该会出现下一个。选择的uC / OS-III的Hello World然后单击Finish。 图-新建项目对话框的模板

 

 ucos iii在zynq上的移植图 - 新建项目对话框的模板

 

您现在应该看到在IDE中板级支持包的摘要。

 

4.打开板支持包设置通过单击对话框中的“修改这个BSP的设置”。

5.选择必要的库ucos_common,ucos_osiii和ucos_standalone。 图- BSP设置概述

该ucos_common库始终需要由BSP以及内核之一或者ucos_osii或ucos_osiii但不能同时使用。该ucos_standalone包是一个兼容性组件能够使用赛灵思独立的驱动程序。在库组件的详细信息可以在中找到支持Micrium公司产品的链接到该文档中,用户手册部分。

 

 ucos iii在zynq上的移植图 - BSP设置概述

 

6.在“UCOS”配置section.For的ZC702和ZedBoard这应该是ps7_uart_1选择STDOUT提供商。 图- BSP标准输出设置

 

ucos iii在zynq上的移植 图 - BSP标准输出设置

 

7.配置的驱动程序AXI定时器。在本教程中axi_timer_0将与μC/ OS定制驱动程序进行编程,而axi_timer_1将使用Xilinx独立的驱动器。 图- BSP驱动程序配置

 

ucos iii在zynq上的移植图 - BSP驱动程序配置

 

8.单击确定。

第3步:构建和调试的示范项目

默认生成的项目是一个简单的Hello World消息的主要任务打印。

1.生成项目。这是自动赛灵思SDK修改BSP配置后,通常会完成。

2.选择项目(不是BSP)在工作区中,并从运行 - >调试配置...菜单打开调试配置对话框。

3.创建双击“赛灵思公司的C / C ++应用程序(系统调试)”一个新的调试配置。

4.检查“复位整个系统”和“计划FPGA”在新创建的调试配置。这将启动调试会话时自动编程的FPGA。 图-调试配置

 

ucos iii在zynq上的移植图 - 调试配置

 

5.单击调试。

对FPGA进行编程的调试之后,现在应该停在main()函数。

6.终端连接到你的开发板的COM端口。嵌入式终端或任何其他的终端应用程序都可以使用。 图-终端配置

 

ucos iii在zynq上的移植图 - 终端配置

 

7.按运行- >恢复或F8运行演示。您应该看到在终端文本输出。 图-端子输出

 

 ucos iii在zynq上的移植图 - 终端输出

 

第4步程序的AXI定时器0的ucos_axitimer驱动程序

对于一些外围设备,Micrium公司经销的自定义驱动,通常被设计为线程安全的通过RTOS服务使用。例如,ucos_axitimer主要作用是充当MicroBlaze的系统的内核时基的驱动。这些驱动程序可供一般使用的便利性。

在这个步骤中,您将创建一个新的内核任务在等待一个信号量定期发布的中断服务程序。这ISR将通过AXI定时器0使用ucos_axitimer被触发。在步骤5中相同的操作将使用Xilinx独立驱动来完成。

图标

为清楚起见由各个内核函数返回的错误码在下列实施例,不检查。错误应该通常在最终应用进行验证。

 

1.创建一个新的任务和信号量。

第一步是声明的任务功能,它的TCB(任务控制块)和堆栈空间邻近app.c.的顶 与此同时,我们需要在这个例子中名为Timer0Semaphore一个信号。 上市-定时器0声明的任务

 

1234 无效    Timer0Task(无效 * p_arg);OS_TCB   Timer0TCB;CPU_STK Timer0TaskStk [512]; OS_SEM   Timer0Semaphore;
上市 - 定时器0声明的任务

 

在μC/ OS-III裸任务是一个简单的功能,Timer0Task在这个例子中。为了帮助演示,我们可以在新的任务开始加UCOS_Print(),以确保它已成功创建。请参阅 上市-定时器0任务骷髅因为我们不希望此任务返回时(1)在接近函数的末尾添加。

 

12346789 无效 Timer0Task(无效 * p_arg){    OS_ERR os_err;     UCOS_Print(“Timer0Task达到\ r \ N” );      (1) {    }}
上市 - 定时器0任务骷髅
图标

该UCOS_Print()的实现是重入(线程安全的),这意味着它可以从多个任务被称为无特殊同步。

 

信号量是用在本实施例中,等待来自计时器的信号。创建于μC/ OS-III信号量是一个简单的函数调用,如图 上市-定时器0信号灯创建

 

1 OSSemCreate(Timer0Semaphore, “ 定时器0信号灯” ,0,&os_err);
上市 - 定时器0信号灯创建

 

定时器0的任务可以挂起(等待)这个信号量一旦它与OSSemPend()创建和输出的东西在终端上时,它发出信号。最后的任务应与OSTaskCreate()函数调用创建 列表-定时器0任务显示的主要和Timer0任务的当前内容。

 

123467891011121314151617181920212223242526272829三十313233343536373839 无效  MainTask的(无效 * p_arg){    OS_ERR        os_err;         UCOS_Print( “ 你好从主要任务\ r \ñ世界” );     OSSemCreate(Timer0Semaphore, “ 定时器0信号灯” ,0,&os_err);     OSTaskCreate(Timer0TCB,                  “定时器0的任务”                   Timer0Task,                  DEF_NULL                   10,                  Timer0TaskStk,                  0,                  512,                  0,                  0,                  DEF_NULL                   0,                 &os_err);      DEF_TRUE ){        OSTimeDlyHMSM(0,0,10,0,OS_OPT_TIME_HMSM_STRICT,&os_err);        UCOS_Print( “ 定期输出的主要任务\ r \ñ每10秒” );    }} 无效 Timer0Task(无效 * p_arg){    OS_ERR os_err;     UCOS_Print(“Timer0Task达到\ r \ N” );      (1) {        OSSemPend(Timer0Semaphore,0,0,DEF_NULL ,&os_err);        UCOS_Print( “ 定时器0旗语信号\ r \ N” );    }}
上市 - 定时器0任务

 

运行该程序现在将显示定时器0元起拍,但对未决信号无限期由于定时器尚未配置。

2.配置AXI定时器0信号定时器0信号。

Micrium公司定制的驱动程序通常注册了一个默认的中断处理函数时初始化。中断源是从硬件设计中扣除。在ucos_axitimer驱动程序有可能注册一个回调的情况下,要调用的中断触发时。使用该功能显示在 列表-定时器0 ISR

 

1234 无效 Timer0ISR(AXITIMER_HANDLE手柄,CPU_INT32U tmr_nbr){    OS_ERR os_err;    OSSemPost(Timer0Semaphore,0,&os_err);}
上市 - 定时器0 ISR

 

该ISR只是张贴定时器0信号。

最后一步是配置AXI定时器。驾驶员的公共API可以通过包括访问ucos_axitimer.h头文件app.c. Micrium的司机都围绕这是由不同的初始化函数返回的句柄。 上市-定时器0手柄宣言表明的AXI定时器申报办理定时器0。

 

1 AXITIMER_HANDLE定时器0;
上市 - 定时器0声明手柄

 

要配置定时器必须首先进行初始化,然后配置为倒计时,自动重装定时器启用中断。在硬件设计的定时器由一个50MHz的时钟驱动,我们将使用100万美元的负载值给予2秒的延时中断之间 上市-定时器0设置

 

1234 定时器0
= AXITimer_Init 
(0);
AXITimer_OptSet(定时器0,0,AXITIMER_OPT_DOWN
| AXITIMER_OPT_AUTO_RELOAD | AXITIMER_OPT_INT);
AXITimer_LoadSet(定时器0,0,亿);AXITimer_CallbackSet(定时器0,0,Timer0ISR);
上市 - 定时器0设置

 

最后,计时器可以启动。 上市-定时器0开始

 

1 AXITimer_Start(定时器0,0);
上市 - 定时器0开始

 

3.运行应用程序。输出应该看起来像 图-定时器0端子输出

 

ucos iii在zynq上的移植图 - 定时器0端子输出

第5步程序的AXI定时器1与赛灵思tmrctr驱动程序

在步骤4中的Micrium定制驱动ucos_axitimer用于产生周期性中断唤醒的应用程序的任务。同样可以通过使用分布式的SDK赛灵思独立的驱动程序来实现。

当使用一个独立的驱动程序是很重要的有ucos_standalone列入项目库。此外,如果外设从多个线程所使用的必需的同步,必须由应用程序提供,或者通过使用内核信号量或互斥。

1.创建一个新的任务和信号灯类似于步骤4的1项。

2.编写一个自定义的中断服务程序定时器。 上市-定时器1 ISR

 

123467891011121314151617 无效 Timer1ISR(无效 * p_arg,CPU_INT32U CPU){    CPU_INT32U ControlStatusReg;    OS_ERR os_err;     ControlStatusReg = XTmrCtr_ReadReg(Timer1.BaseAddress,                                       0,                                       XTC_TCSR_OFFSET);     XTmrCtr_WriteReg(Timer1.BaseAddress,                     0,                     XTC_TCSR_OFFSET,                     ControlStatusReg |                     XTC_CSR_INT_OCCURED_MASK);     OSSemPost(Timer1Semaphore,0,&os_err);}
上市 - 定时器1 ISR

 

在μC/ OS下的原始中断程序都具有相同的签名,其中一部分只与在某些情况下。该p_arg参数是注册时中断给用户指定的参数。该CPU的说法是,所产生的中断,并且只针对相应和对的Cortex-A9产生软件中断的CPU核心ID。CPU的参数将是0在所有其他情况。

3.注册和启用自定义中断 上市-定时器1中断配置

 

123 UCOS_IntVectSet(62,0,DEF_BIT_00 ,Timer1ISR,和定时器1); UCOS_IntSrcEn (62);
上市 - 定时器1中断配置

 

4.建立和运行。输出应该类似于从第4步以前的输出最终app.c文件可以在这里下载- app.c

结论

在本教程中,您创建了一个基本的ZYNQ硬件设计和写利用μC/ OS BSP一个基本的应用程序。无论是Micrium公司自定义驱动程序和Xilinx独立驱动器的使用,提出与中断处理。读者新的生态系统Micrium公司建议阅读UC-OS-III文档深入了解有关使用Micrium的实时内核。在另一方面,长期以来Micrium公司强烈建议用户检查Vivado设计套件的各种教程和培训。