作者:Adam Taylor
在上一篇博客中我们了解了Zynq SoC的OCM(片上存储器) ,利用它可以实现在AMP模式下内部处理器内核之间的通信。现在我们将写一些程序代码将这个设备(OCM)利用起来。
在这个演示示例中我们将使用UART接口实现CPU0 与上位机(笔记本)之间的通信连接,我们将从上位机发送8位ASCII码值到Zynq SoC的串口,一旦被接收,这个8位的ASCII码值将被传输到指定的OCM内存地址,并且这个内存地址是被两个处理器内核所共享的。每次CPU1的定时器时间到期后,CPU1将读取这个内存地址的值,并将相应的GPIO输出管脚的值设置为所读取到的数值。LED灯是设计在MicroZed I/O载板上的,载板通过Micro Header器件与Zynq SoC相连,通过相应的设置,LED灯就会根据读取到的ASCII码值进行亮灭显示。我们通过查看LED灯的状态就可以确认在两个CPU之间传递的值是否正确。
显然我们首先要做的事就是设置要使用的内存地址,我们将只传递8位无符号整数,所以我们只需要申请一个地址空间,这里我已经选择使用ZynqSoC的OCM的最高的64K字节的存储区完成这个工作,我禁止了这块存储空间的cache(缓存)功能,在应用程序中我们可以使用下面的函数命令来实现。
Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
我将利用0XFFFF0000这个内存地址作为介质实现在CPU0与CPU1之间传递一个字节的数据,当然有很多方式可以实现这个功能,下面我们将介绍两种最常用的方式:
第一种方法是利用通用的Xilinx I/O接口函数实现对制定地址的读取与写入,这些函数包含在Xil_IO.h头文件中,允许在CPU的地址空间内实现存储与访问8位、16位或者32位的字符型、短整型或整型的数值数据。使用这些函数你就可以读取指定地址的数据,或者像指定地址写入指定的数据。
Xil_Out8(0xFFFF0000,0x55);
read_char = Xil_In8(0xFFFF0000);
为了确保这些地址指向的是同一个OCM位置,尤其是当不同的人编写不同的应用程序,他们将会调用共同的头文件,头文件中包含的对这个地址的宏定义,这是一个非常好的工程实践的例子,例如下面所示:
#define LED_PAT 0xFFFF0000
第二种方法是在两个程序中使用指针指向通一个存储位置。我们可以定义一个指针指向一个常量地址,使用C语言我们会定义一个宏,如下所示
#define LED_OP (*(volatileunsignedint *)(0xFFFF0000))
这种方法不需要再调用Xilinx I/O接口的库函数,通过指针就可以实现访问功能。
上面这两种方法都可以成功实现我的笔记本通过UART与CPU0通信,然后数据传输给CPU1,最后控制在MicroZed I/O载板上的LED灯的亮灭状态,如下面的图片所示(我们用黑白相机拍照为了阻止眩光,最右侧是LED灯的最低位):
下面的信息是从ZynqSoC接收到的:
当然当我们通过OCM来实现ZynqSoC上的处理器之间的通信时,我们必须记住寄存器的值的更新速度比我们目前看到的要快,因为我们使用了CPU1的定时器来触发存储器的读操作,在下一篇博客中,我们将介绍ZynqSoC的处理器之间更加复杂的通信方法,我们将集中介绍软件中断的方式。
© Copyright 2014 Xilinx Inc.
如需转载,请注明出处
本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念
本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“
课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了
@2003-2020 中国电子顶级开发网