缓存在图像处理中非常重要,FPGA可以用来调整时序,CPU运算时用于存放数据。在Zynq UltraScale+ MPSoC一般存在三种方式实现缓存,连接到PS的DDR、连接到PL的DDR和PL上的片上BRAM。如果不涉及到处理器处理数据,数据只在FPGA中流转,那么PL的DDR或者BRAM的方式是最合适的,既可以降低延迟,又能减少编程的复杂度。如果要进行算法处理,需要ARM处理器的参与,就必须用到挂载在PS的DDR。
大量数据的搬移如果让CPU来完成,性价比会非常的低,不仅占用CPU大量的运行时间,效率也不高。所以DMA技术应用而生,可以在CPU不参与的情况下,自主搬移和传输数据,CPU做的工作也只是将DMA配置好。PS中数据的搬移可以使用PS的DMA,PL的数据要向搬移到PS的DDR,就要用到AXI DMA,AXI VDMA是AXI DMA的扩展IP,专门针对图像设计,在满足数据流的传输机制后,增加了usr信号,用于表示图像起始。同时,设置了多帧缓存,将读写数据分开,避免了读写冲突,用户也可以访问当前读写的帧缓存号,加入算法操作。
Camera Link接收IP接收的图像数据需要经VDMA送入PS的DDR,VDMA的输入使用的是Xilinx标准的Axi Stream接口,而Camera Link输出的信号是行场有效信号,中间需要加入一个转接模块,这个就是Video In To Axi Stream,Xilinx的图像处理IP核,可以将行场信号转换为Stream信号。所以,完整的采集摄像头数据逻辑为Camera Link In+Video In To Axi Stream+VDMA+PS DDR。在Vivado中的Block Design如下图所示,红色连接线为PS产生的100MHz时钟,绿色连接线为相机产生的65MHz时钟,也是采集数据时钟。Camera Link还需要一个300MHz的参考时钟,由PS产生的100MHz时钟倍频得到。

编译生成bit后,导出到Vitis软件中,新建板级支持包Platform以及新的Application Project,PS的工做只为初始化VDMA,设置VDMA的寄存器,数据存放地址、图像宽度和高度,并开启VDMA。代码如下所示,程序运行后图像数据以相机实际帧率的速率向0x10000000~0x30000000的3个循环缓存中写入图像数据。
#include "xil_io.h"
#include "xparameters.h"
int main()
{
//S2MM
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x108B); // enable run, circular_park
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x10000000); // Start address of the 1st frame
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB0, 0x20000000); // Start address of the 2nd frame
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB4, 0x30000000); // Start address of the 3rd frame
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 1620 * 3); // Stride number
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 1620 * 3); // number of bytes per line
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 1236); // number of lines per frame
while(1);
return 0;
}
图像数据可以通过仿真器从芯片中导出到PC,方便分析数据,图像是否全部缓存到DDR、中间是否有数据缺失以及查看图像质量等都可以使用这种简便的方式初步查看。导出方法如下,数据格式为raw原始数据格式,导出的数据使用ImageJ照片查看器打开。

为什么图像这么黑还这么绿?可以使用文本查看器UE打开image.raw原始数据,发现大部分数据位是0。用到的Camera Link相机是CB-200MCL-EB,通过阅读相机手册发现,Camera Link接收的24bit的数据不完全是有效数据,相机数据只占用了其中的10bit,并且是bayer模式,需要用bayertorgb模块将其转换到RGB颜色空间,才能得到真实的图像。虽然没有一次就成功,但这就是从内存导出数据查看的意义,发现问题,再调试,反而令我们欣慰的是,内存中起码有数据。
还有个问题,Video In To Axi Stream是个非常常用的IP,功能足够但是不够简洁,在上图的Block Design中需要配合Vector Logi和Constant一起使用,增加了画布的面积,而且非常容易连接错误。颜值即正义,如果它长得丑,或者用的不舒服,那么就有改进的空间,下一节讲如何使用手写一个Video In To Axi Stream的IP核。
746

被折叠的 条评论
为什么被折叠?



