作者: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.
如需转载,请注明出处