本文转载自:<span id="profileBt"><a href="https://mp.weixin.qq.com/s/U41537KQUl0dRrBX1mS_rg">OpenFPGA微信公众号</a></s…;
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
该项目演示如何在 Zynq SoC 上开始使用 FreeRTOS。
<strong>介绍</strong>
AMD Zynq SoC 器件将典型 FPGA 的可编程逻辑结构和 ARM 处理器内核提供的处理能力组合到单个芯片中,可用作构建各种嵌入式系统应用的平台。可以在 PL 中设计专用逻辑结构来处理计算密集型任务,而 PS 可以控制 PL 并提供用户应用程序。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
内窥镜就是可以利用这种功能的产品的一个例子。视频链在 PL 中实现,处理来自摄像头的图像信号,并提供视频保存、分辨率更改、色彩校正等额外功能。然后可以将处理后的视频发送到显示接收器。
在本教程中,将展示如何在 Zynq PS 中在 FreeRTOS 内核上运行应用程序。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
三种方法的区别在于软件部分的开发方式。软件可以分为用户空间(应用程序所在的位置)和内核空间(驱动程序和库所在的位置)。软件的大小从裸机到嵌入式操作系统递增。
FreeRTOS 是一款专用于实时应用程序的开源操作系统。它们提供了可以构建应用程序的内核空间。开发人员能够定制 FreeRTOS 内核,允许构建具有实时约束的应用程序。不适合 RTOS 的应用程序的一个示例是运行成熟的 GUI。
接下来让我们深入了解如何在 Zynq PS 上设置 FreeRTOS。
<strong>Vivado 中的硬件设计</strong>
打开Vivado并在新创建的block design中添加Zynq PS。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
在PS中自定义外设,我们这里主要注意添加 UART 外设。其他诸如GPIO、SD0、USB0 等按照自己的硬件启用。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
保存并验证设计。然后创建 HDL wrapper、生成输出产品并生成比特流。将硬件平台信息导出为 XSA。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
<strong>Vitis 软件开发</strong>
启动 Vitis IDE,并使用 XSA 创建一个新的平台项目。选择 freeRTOS 内核作为操作系统。
创建平台项目后,修改其BSP禁用xiltimer软件库。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
然后搭建平台。现在使用 freeRTOS Hello World 模板创建一个新的应用程序项目。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
在解释主要应用程序代码之前,我想提一下 freeRTOS 内核内的调度程序需要将计时器配置为默认频率 100Hz 才能运行。这可以是软件或硬件定时器。这就是为什么我选择在 BSP 中禁用软件定时器及其库。否则,应用程序运行时会与硬件定时器发生冲突。
主应用程序使用 xTaskCreate() 函数定义两个 FreeRTOS 任务:
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
然后,它将硬件定时器配置为 10 秒,之后就会过期。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
现在重要的是要弄清楚该设计使用的是哪个硬件定时器?请记住,在 Vivado 中自定义 Zynq PS 时,我们没有启用任何此类定时器 (TTC/SWDT)。我们可以查看平台项目中存在的移植代码。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
portZynq7000.c 文件包含有关如何移植 freeRTOS 内核以适应基于 Zynq 7000 SoC 的设备的信息。打开后我们可以看到如下的条件定义:
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
因此,在禁用 xiltimer 后,设计依赖于使用 scutimer 生成定时器中断。此 scutimer 是指每个 ARM-A9 内核内存在的 CPU 专用定时器。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
如果详细阅读 portZynq7000.c,就可以看到如何使用 scutimer 和 scugic 来设置定时器中断。
定时器启动后,使用 vTaskStartScheduler() 调用启动 freeRTOS 内核的调度程序。调度程序将启动上面定义的两个任务,并且程序将执行这两个任务中定义的任何代码。
<strong>最终结果</strong>
成功构建软件后,在板上运行应用程序。就会看到以下文本打印在 UART 控制台中:
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>
<strong>结论</strong>
就是这样!您已准备好开始在 Zynq SoC 上运行的 freeRTOS 内核上开发更复杂的程序。
<center><img src="https://cdn.eetrend.com/files/2023-10/%E5%8D%9A%E5%AE%A2/100575143-3211…; alt=""></center>