ZYNQ AMP详解

4 篇文章 1 订阅
1 篇文章 0 订阅

本实验是双核AMP(Asymmetric Multiprocessing)实验。双核实验需要CPU0向CPU1发出软件中断从而唤醒CPU1。CPU1对CPU0中的数据进行操作。

CPU0和CPU1共享一段内存空间(可以把这段共享空间当作数据交换的部分)。

 

首先要建立一个Vivado工程。这里完成的思路是:CPU0接收串口发来的数据,发出软件中断,唤醒CPU1. CPU1通过AXI接口控制LED的闪烁频率。

 

硬件部分:需要设计一个参数可调的分频器(输出频率10Hz-0.2Hz之间)。另外,还需要设计一个LED灯闪烁的模块,每当一个上升沿来临时,输出状态的LED就反转一下。(包括生成AXI总线的IP核的步骤,这里就不详细介绍了)

 

首先我们要明白:如果我们想要启动CPU1,那么只能通过CPU0唤醒CPU1。AMP相对比其余两种(分别是SMP、BMP)最大的优点点就是两个内核Run不同或相同的裸机程序/OS。

       既然为双核,那么这两个核肯定有单独的运行内存。难道只有单独运行的内存吗?不是这样的,除了单独的运行内存,当然也存在共享内存。(笔者认为,在SDK中完全也可以不设置共享内存,让两个核各自做各自的工作,井水永远不犯河水)。

如果既能让CPU0和CPU1单独实现工作,又能让CPU0和CPU2完成通信岂不美哉?上边说过,CPU0和CPU1共享一段内存,所谓共享就是CPU0能读写这段内存那么CPU1照样也能读写这段内存(就像学生宿舍里边的空调一样,同学A能操作空调,同学B照样能操作空调。如果只有A同学能操作这个空调,那么这个空调恐怕不能叫做shared air conditioner而应该叫做privacy air conditioner)。当然,共享的事物总是有不足之处的,比如A同学正在拿着遥控器操作这个空调的同时,那么其他同学就不能对这个共享空调进行操作了。类比可知,这个所谓的共享内存,是在一定的条件下,CPU0/CPU1才能进行操作,如果同时操作CPU0和CPU1就冲突“打架“了。

为了保证这两个CPU不打架,还是拿这两个同学做类比:

A:我现在正在用这个遥控器,麻烦兄弟等一会再用。

B:好的,你先调合适的温度,一会儿风向由我决定。

A:我好了,该你使用遥控器了。

B:好的,我知道了。

CPU0:我现在正在操作共享内存,麻烦兄弟等会儿再操作。

CPU1:好的,那我等一会儿再操作。

CPU0:我好了,该你读写共享内存了。

CPU1:那我就开始读写这块内存了。

 

那么究竟是什么导致CPU0和CPU1如此协调呢?在参考了正点原子和ALINX两家的例程后,笔者发现大致是这么个运行机制:

CPU0开启接收中断号1的中断;     CPU1开启接收中断号2的中断;

CPU0向CPU1发送2号中断;          CPU1向CPU0发送1号中断;

我们让这两个CPU约定好,你那边接收的中断号就是我这边发送出去的中断号,你那边发送的中断号就是我这边接收的中断号。这样一来,就形成了两个CPU的相互配合。我们还可以列个表格,更加清晰的认识这种机制(先读左半边,后读右半边)。

CPU0:我现在正在操作共享内存,麻烦兄弟等会儿再操作。

CPU1:好的,那我等一会儿再操作。

CPU0:我好了,该你读写共享内存了。

CPU1:那我就开始读写这块内存了。

CPU0:好的,啥时候到我了,请叫我!

CPU1:我好了,该你了。

CPU0:我现在正在操作共享内存,麻烦兄弟等会儿再操作。

CPU0:在我没有发送2号中断前,你不要读写共享内存。

CPU1:我知道了,我接收到2号中断信号后再进行读写共享内存。

CPU0:我已经给你发送过2号中断了。

CPU1:换我了。我没有发送1号中断前,你不要读写共享内存。

CPU0:OK,我接收到1号中断信号后再进行读写共享内存。

CPU1:我发送过1号中断了,该你了。

CPU0:在我没有发送2号中断前,你不要读写共享内存。

需要注意的是:用软件中断,必须要保证中断号在0~15内(参见UG585)。

 

现在给出配置这种机制的全部过程:

  1. 在Vivado中,配置Processing System(只需要配置1次)
  2. 搭建您想实现的功能。(笔者是设计了一个能改变LED闪烁频率的AXI的自定义IP;让CPU0通过UART的中断接收数字。将这个数字送入CPU1中,CPU1根据这个数字设定PL端LED的闪烁频率)
  3. 启动SDK,创建两个工程,创建工程的步骤就不说了,网上一大堆。
  4. 设定两个核的运行内存和共享内存。(注意!这两个核的内存不能重复)
  5. 软件程序设计(这个步骤繁琐,后边详细介绍)。
  6. 下载配置。(网上也有,还可参考ALINX或正点原子的教程)
  7. 程序固化(可选)。

 

现在对软件程序设计部分的步骤进行详细的描述:

创建CPU0的APP并设置运行内存的大小:

 

经过计算得知:现在的CPU0的内存范围:0x0010000~0X0FFFFFFF

按照这个,那么CPU1的内存的基地址设置成0X10000000最符合常理。

创建CPU1的APP并设置内存的大小。

CPU1的内存基地址是0X10000000,大小同样也设置成0X0FF00000。

那么CPU1的内存范围:0X1000_0000~0X1FEF_FFFF。

自认而然我们把0X1FF0_0000作为共享内存的基地址(其实所谓的共享内存基地址只要不是在CPU0和CPU1内存的范围内均可。正点原子是把下边的ps7_ram_1设置成了共享内存;而ALINX是在DDR3的最后留出了256Byte的共享地址)

现在需要对CPU1的板级支持包做额外的配置,只有这样CPU1才能正常工作,选中cpu1对应的bsp文件夹,右键选择板级支持包设置,图中显示的地方补充输入:  -DUSE_AMP=1

 

  

 

对CPU0进行程序设计(有关这两个程序的设计实在有点乱,也有点长。需要可以留言留下邮箱,看到之后会发送到邮箱):

CPU0实现的功能有:串口接收中断,设置软件1号中断(SGI #1),设置共享内存的基地址,设置CPU0的内存基地址及其大小,能够向CPU1发送软件2号中断。

 

对CPU1进行程序设计:

CPU1实现的功能有:能接收CPU0发来的2号中断,设置共享内存的基地址,设置CPU1的内存地址及其大小,能够向CPU0发送1号中断。将CPU0传输到共享内存的数据,传输到AXI的slv_reg0上。这样就能控制LED闪烁的频率了。

 

实验效果:发送2就是对10Hz 进行2分频。发送0x0A就是对10Hz进行10分频(注意16进制发送,不发送新行)。LED也会从快速闪烁到慢速闪烁!

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值