Zynq UltraScale+ MPSoC IPI 通信

目录

前言

一、原理

二、c(app) 工程创建


前言

MPsoc 最大的特点是集成了4个A53和2个R5,只有异构通信才能发挥他的最大威力。

本文参照其他文档,实现了裸跑的A53和R5 IPI通信。


提示:以下是本篇文章正文内容,下面案例可供参考

一、原理

Zynq UltraScale+ MPSoC IPI 通信_第1张图片

 

Zynq UltraScale+ MPSoC IPI 通信_第2张图片

1.UltraScale+ MPSoC 的ipi通道一共有11条,其中PMU_0~PMU3这4条固定分配给PMU,其余7条可以任意配置给APR(四个A53共用一个通道),RPU,PL,默认配置见上图。

2.IPI通信其实是通道和通道间的通信,每个通道都有自己的GIC号码,某个通道可以和其他通道通信也可以和自己通信。

3.processor通过绑定通道(如默认的APU绑定chl0,RPU0绑定chl1),利用通道间的通信实现processor间通信。

        3.1 **注意不仅仅是同一个GIC间的通信**,在PL-390和GIC-400间也可以通信,这对于SGI是无法实现的。

        3.2 首先在vivado中配置processor与通道的绑定关系

Zynq UltraScale+ MPSoC IPI 通信_第3张图片

        3.3 vitis导入硬件后会自动生成库文件,其中“xipipsu_g.c”中描述了该整个硬件系统一共启用了多少通道,以及该processor一共绑定了多少通道。

Zynq UltraScale+ MPSoC IPI 通信_第4张图片

         3.4 这里有必要说明下一“XIpiPsu_Config”结构体。

Zynq UltraScale+ MPSoC IPI 通信_第5张图片

                DeviceID:每个processor绑定的每个通道都有一个ID,代码中可根据这个ID查找该通道的所以信息,ID与硬件无关仅仅是一个标识。

                BaseAddress:每个通道对应6个Interrupt Register,该值为这组寄存器的首地址。

                BitMask:个人感觉每个通道对应一个Mask号码,表明该processor占用(绑定了)该通道。

                BufferIndex:每个通道在XPPU中都对应一组IPI Message Buffers,代码可以根据源和目标通道的该序号找到对应buffer首地址,然后根据源消息类型对应到具体的32Byte。详情见“static u32* XIpiPsu_GetBufferAddress()”

                 IntId:该通道对应的GIC ID号。

                TargetCount:该系统中可通信的通道总数。

                TargetList:XIpiPsu_Target

                                Mask:目标通高的Mask码

                                 BufferIndex:目标通高的IPI Message Buffers序号

3.5 函数“XIpiPsu_LookupConfig(DeviceID)”

        轮循XIpiPsu_ConfigTable,根据DeviceID找到该通道对应的XIpiPsu_Config结构体,返回结构体指针。

3.6 函数“XScuGic_Connect()”

        绑定GIC中断相应函数        

3.7 函数“XScuGic_Enable()”

        在GIC_400文档中详细说明

3.8 函数“XIpiPsu_WriteMessage()” 

        这里重点说一下XPPU中 IPI Message Buffers 是如何分布的

Zynq UltraScale+ MPSoC IPI 通信_第6张图片

Zynq UltraScale+ MPSoC IPI 通信_第7张图片

Zynq UltraScale+ MPSoC IPI 通信_第8张图片         从上图可以看出Buffer是双工的,左侧的512Byte是通道0与其他通道通信的buf分布,这个buf为每个通道分配了request和response buf各32Byte,例如向通道1发请求信息是将msg存放在0xff99_0040,应答通道1则将回复信息填入0xff99_0060;同理右侧的512Byte是通道1与其他通道通信的buf分布,例如向通道0发请求信息是将msg存放在0xff99_0200,应答通道0则将回复信息填入0xff99_0220;

3.9 函数“XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask)”

        这里重点说一下 Interrupt Register(UG1085中说的太不明确了,看了源码才搞明白是怎么回事)

Zynq UltraScale+ MPSoC IPI 通信_第9张图片

Zynq UltraScale+ MPSoC IPI 通信_第10张图片         bit0 -> channel 0 mask bit
        bit8 -> channle 1 mask bit
        bit9 -> channle 2 mask bit
        bit16-> channle 3 mask bit
        bit17-> channle 4 mask bit
        bit18-> channle 5 mask bit
        bit19-> channle 6 mask bit
        bit24-> channle 7 mask bit
        bit25-> channle 8 mask bit
        bit26-> channle 9 mask bit
        bit27-> channle 10 mask bit
这6个寄存器分为两组send和receive

* send - TRIG,只支持写操作,向该寄存器写入相应通道的mask位可以触发IPI的IRQ(IRQ routed to RPU and APU GICs),从而中断相应的处理器。

* send - OBS,只支持读操作,用于观测接收方的中断状态

* receive - ISR,读取发送方mask bit 确认是哪个通道发来的数据,写入相应的mask bit清除中断

* receive - IMR,IRQ not generated if status bit is asserted.

* receive - IER,Set IMR = 1

* receive - IDR,Set IMR = 0

二、c(app) 工程创建

* On a terminal window,

change directory to

        * /src/tcl

* At the command prompt enter:

        * xsct create_vitis.tcl

你可能感兴趣的:(fpga开发,驱动开发)