软件版本: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数据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(wfram1_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, val);
 - 
 -     val = 0x00;
 -     user_write(ADDR_PC2PL_INTC,  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);
 - }
 
  复制代码
  
上位机的接收函数如下: 
- 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实验结果 
 
  
 
 
 
 
 
 
 
 |