Zynq UltraScale+ MPSoC – IPI在异构多核中的应用

注意:本文所有内容皆来源于Xilinx工程师,如需转载,请写明出处作者及赛灵思论坛链接并发邮件至cncrc@xilinx.com,未经Xilinx及著作权人许可,禁止用作商业用途。

Zynq UltraScale+ MPSoC – IPI在异构多核中的应用

本篇将讨论MPSoC中IPI的应用。首先澄清这里的IPI不是小伙伴们熟知的Vivado IPI Design Flow的IPI(IP Integrator),而是Inter-Processor Interrupt,是MPSoC中用来在异构多核系统中以中断的形式实现小批量信息交互的结构单元。

IPI共提供11个channel,其中4个channel(3~6)固定分配给PMU,其他7个channel(0~2,7~10)可分配给APU/RPU/PL来控制。每个Channel中包含有6个可供用户访问的寄存器,分成Sender(TRIG/OBS)和Receiver(ISR/IMR/IER/IDR)两组。每个Channel的每个寄存器中,都有与其他channel的对应控制/状态位,如下图所示。

Figure 1

Figure 2

寄存器操作与中断响应过程可参考下图。比如由Channel 8向Channel 2发起中断请求:Channel 8的Master向其TRIG寄存器的BIT9(对应Channel 2)写入1,即向Channel 2的Master发起中断请求。Channel 2的Master收到中断后,可查询ISR的状态位以确定中断来源。

Figure 3

IPI系统中,除Channel 3~6外,每个Channel对应一组Message Buffer Agent,每组有8个Requester和8个Responder,每个Buffer为32Bytes。在中断过程中,可借助这些Buffer,实现两个Processor间的信息交互。

Figure 4

更多详细内容可参考UG1085->Chapter 13: Interrupts->IPI Interrupts and Message Buffers章节。

本篇实现IPI应用将完成下述功能:

APU控制IPI-Channel0,RPU0控制IPI-Channel1(默认设置)。
APU向其Requester/Message Buffer填充信息后,触发Channel1中断。
RPU收到中断后,读取Buffer内容,并填充Responder Buffer,触发Channel0中断。
APU收到中断后,读取Responder Buffer内容。

一共分为三个步骤:

新建Vivado工程,确定IPI channel的Master分配。
新建基于APU的XSDK Application工程。
新建基于RPU的XSDK Application工程。
(限于篇幅,这里只列出每个步骤中的关键部分。)

Step1. 新建Vivado工程,在Block Design中添加MPSoC,并确定MPSoC的配置中IPI的Master设置。如下图所示。

IPI的设置默认是不显示的,需要切换至Advanced Mode,在Advanced Configuration选项下,就可以找到Inter Processor Interrupt(IPI) Configuration。默认情况下,Channel 0/1/2分别分配给APU/RPU0/RPU1。这里我们就采用默认配置。小伙伴们也可以根据自己的需求来配置Master。

Figure 5

确认完成后,继续完成完整的MPSoC的Block Design设计。使用到PL的直到产生完BITSTREAM;未使用PL的,Generate Output Product即可,当然也要Create HDL Wrapper。

接下来,Export Hardware,然后Launch SDK。后续的Step2和Step3顺序无先后。

Step2. 新建基于APU的XSDK Application工程,并导入apu_ipi.c。

注意新建工程时指定Processor为psu_cortexa53_0;并确保BSP设置中stdin/stdout为psu_uart_0(与Step3中不一样就行)。(来完成这个实验的时候用的ZCU106板卡,提供了两个PS的UART可以用。小伙伴们自己的开发板如果没有2个UART,Step2/3其中一个可设置为psu_coresight_0,借助Coresight在Console中直接查看打印信息。)

Figure 6

一起来看一下APU的工作过程:

(1)初始化IPI设备,初始化中断系统,使能IPI相关中断。此处中断号为67,与GUI中配置的APU对应的Channel 0一致。中断号可参考Figure 1。

Figure 7

(2)等待接受键盘输入,以触发IPI工作。

Figure 8

(3)接受键盘输入后,调用DoIpiTest(),完成将Message写入Buffer,触发对RPU0的IPI中断。

Figure 9

(4)等待RPU返回中断,读取回复的Message。

Figure 10

(5)完成一次交互过程,进入下一次触发等待。

Step3. 新建基于RPU的XSDK Application工程,并导入rpu_ipi.c。

注意新建工程时指定Processor为psu_cortexr5_0。并确保BSP设置中stdin/stdout为psu_uart_1(与Step2中不一样就行)。

同样,一起看一下RPU主要工作过程:

(1)初始化IPI设备,初始化系统中断,使能IPI相关中断。此处中断号为65,与GUI中配置的RPU0对应的Channel 1一致。中断号可参考Figure 1。

Figure 11

(2)等待来自APU的中断请求。收到中断后读取Buffer内容,并调用DoIpiTest()执行数据返回处理。

Figure 12

(3)在DoIpiTest()中,将返回数据填充Buffer,并触发对APU的IPI中断。

Figure 13

(4)完成一次响应过程,进入下一次中断等待。

再然后,就是验证结果了。可以Create Boot Image从SD卡直接启动,也可以直接通过XSDK来Run/Debug,这里就不详细叙述过程了(相信来看这篇帖子的小伙伴肯定有足够的MPSoC开发经验),直接上运行结果,方便大家对照。

PS:整理过程过于仓促,如有疏漏或问题,欢迎到赛灵思中文论坛讨论学习!

原帖地址:https://forums.xilinx.com/t5/Xilinx-%E4%BA%A7%E5%93%81%E8%AE%BE%E8%AE%A1...

此文章含有具体demo,见附件

文章来源: 赛灵思中文社区论坛

推荐阅读