|  软件版本:VIVADO2021.1 操作系统:WIN10 64bit
 硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
 实验平台:米联客-MLK-H3-CZ08-7100开发板
 板卡获取平台:https://milianke.tmall.com/
 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
 
 
 
 1概述
         有一些网友跟我提出需要让PS做一些加密算法,PCIE把需要加密的数据发送给下位机,也就是PS的ARM ,ARM计算后,再把数据发送给PCIE。为了正确演示这个数据通路,我们以上位机发送图片数据到开发板的PS,然后PS的ARM对部分数据修改后发送给PCIE上位机。本方案演示PCIE数据和PS DDR数据的交互方案。2系统构架 
     3FPGA代码
 
     4SDK代码
 
     
         主要看下主程序,主程序中分配的内存地址必须确保和PCIE程序中分配的内存地址保持一致,上位机把数据写到UIFDMA_DBUF[0]指向的PS DDR内存地址,PS 程序读出数据并且修改,保持到UIFDMA_DBUF[1]指向的内存地址空间。数据修改完成后,通过GPIO反转,产生一个XDMA中断,通知PCIE数据处理完成。 复制代码int main()
{
u32 x=0,y=0 ;
UIFDMA_DBUF[0] = (void*)BUF_PC2PS;
UIFDMA_DBUF[1] = (void*)BUF_PS2PC;
memset(UIFDMA_DBUF[0], 0x00, IMG_SIZE);
memset(UIFDMA_DBUF[1], 0x00, IMG_SIZE);
//initial reset gpio
XGpio_Initialize(&ps2pl_gpio, XPAR_PS2PC_INTR_DEVICE_ID);
XGpio_SetDataDirection(&ps2pl_gpio, 1, 0x0); XGpio_DiscreteWrite(&ps2pl_gpio, 1, 0x0);
//set up intrrupt
init_intr_sys();
while(1){
if(wf ram1_cap_done == 1)//wait vmda s2mm write channel intrrupt {
wfram1_cap_done =0;
//frush cache data all into ddr
Xil_DCacheInvalidateRange((INTPTR) UIFDMA_DBUF[0], IMG_SIZE) ;
for(y=0; y < VIDEO_VSIZE ; y++)
{
for(x=0; x < 1920 ; x++)
{
UIFDMA_DBUF[1][x+y*1920] = UIFDMA_DBUF[0][x+y*1920]&0x000000ff;
}
}
//frush cache data all into ddr
Xil_DCacheFlushRange((INTPTR)UIFDMA_DBUF[1], IMG_SIZE);
//notice pc
XGpio_DiscreteWrite(&ps2pl_gpio, 1, 0x1);
usleep(1000);
XGpio_DiscreteClear(&ps2pl_gpio, 1, 0x0);
printf("image change done !");
}
}
return XST_SUCCESS;
}
 5上位机程序设计
 
     
         本demo演示中,选择一个彩色的BMP测试图片发送到开发板的PS DDR中,并且通过GPIO产生一个PL中断通知PS,数据已经写入到DDR.         PS取出数据,对图像数据做修改后,再次写回到DDR中,并且通过GPIO产生一个中断通知PCIE上位机。上位机的发送函数如下: 
 上位机的接收函数如下:复制代码void MainWindow::on_pushButton_clicked()
{
        QString filename;
        QPixmap m_Qpixmap;
        unsigned char val;
        char * name;
        filename = QFileDialog::getOpenFileName(this, tr("Select Pic"), "", tr("Images (*.bmp)"));
        if (filename.isEmpty())
        {
                return;
        }
        QByteArray ba = filename.toLatin1();
        name = ba.data();
        get_image_data(&image_h, &image_v, name);
        val = 0x01;
        user_write(ADDR_PC2PL_INTC, 4, &val);
        QImage image(filename);
        m_Qpixmap = QPixmap::fromImage(image, Qt::AutoColor);
        m_Qpixmap = m_Qpixmap.scaled(ui->label1->width() / 8 * 8, ui->label1->height() / 8 * 8, Qt::IgnoreAspectRatio, Qt::FastTransformation);
        ui->label1->setPixmap(m_Qpixmap);
        val = 0x00;
        user_write(ADDR_PC2PL_INTC, 4, &val);
}
 复制代码void MainWindow ::on_pushButton 2 clicked()
{
QPixmap m_Qpixmap ;
QImage *m_Qimage = new QImage(c2h_align_mem_tmp, image_h, image_v, QImage ::Format_RGB32) ;
c2h_transfer(FPGA_DDR_START_ADDR2, image_h*image_v * 4, c2h_align_mem_tmp) ;
m_Qpixmap = QPixmap ::fromImage(*m_Qimage, Qt::AutoColor) ;
m_Qpixmap = m_Qpixmap.scaled(ui->label2->width() / 8 * 8, ui->label2->height() / 8 * 8, Qt::IgnoreAspectRatio, Qt::FastTransformation) ;
ui->label2->setPixmap (m_Qpixmap) ;
}
 以上函数中回继续调用pcie_fun.c中的DMA通道函数,以及user_write函数,具体的可以打开源码阅读。
 6硬件安装
 
     7实验结果
 
     
 
 
 
 
 
 
 
 |