[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_PCIE通信(linux)连载-14PCIE 与 ZYNQ PS数据交互

文档创建者:FPGA课程
浏览次数:150
最后更新:2024-09-20
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 7-FPGA PCIE通信(Linux)
本帖最后由 FPGA课程 于 2024-9-20 13:04 编辑

​ 软件版本: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系统构架
7211275554fd4145acbd665e1b64f277.jpg
3FPGA代码
be95509d07094cbfa8ebdc9fde3d399d.jpg
4SDK代码
2105d14ca249458ab8482a8591370b24.jpg
主要看下主程序,主程序中分配的内存地址必须确保和PCIE程序中分配的内存地址保持一致,上位机把数据写到UIFDMA_DBUF[0]指向的PS DDR内存地址,PS 程序读出数据并且修改,保持到UIFDMA_DBUF[1]指向的内存地址空间。数据修改完成后,通过GPIO反转,产生一个XDMA中断,通知PCIE数据处理完成。
  1. int main()
  2. {
  3.         u32 x=0,y=0 ;

  4.         UIFDMA_DBUF[0] = (void*)BUF_PC2PS;
  5.         UIFDMA_DBUF[1] = (void*)BUF_PS2PC;

  6.         memset(UIFDMA_DBUF[0], 0x00, IMG_SIZE);
  7.         memset(UIFDMA_DBUF[1], 0x00, IMG_SIZE);

  8. //initial reset gpio
  9.         XGpio_Initialize(&ps2pl_gpio, XPAR_PS2PC_INTR_DEVICE_ID);
  10.         XGpio_SetDataDirection(&ps2pl_gpio, 1, 0x0);
  11.         XGpio_DiscreteWrite(&ps2pl_gpio, 1, 0x0);

  12. //set up intrrupt
  13.         init_intr_sys();

  14.     while(1){

  15.                     if(wfram1_cap_done == 1)//wait vmda s2mm write channel intrrupt
  16.                     {

  17.                             wfram1_cap_done =0;
  18.                             //frush cache data all into ddr
  19.                             Xil_DCacheInvalidateRange((INTPTR) UIFDMA_DBUF[0], IMG_SIZE) ;

  20.                             for(y=0; y < VIDEO_VSIZE ; y++)
  21.                             {
  22.                                     for(x=0; x < 1920 ; x++)
  23.                                     {
  24.                                             UIFDMA_DBUF[1][x+y*1920] = UIFDMA_DBUF[0][x+y*1920]&0x000000ff;
  25.                                     }
  26.                             }

  27.                             //frush cache data all into ddr
  28.                             Xil_DCacheFlushRange((INTPTR)UIFDMA_DBUF[1], IMG_SIZE);

  29.                             //notice pc
  30.                             XGpio_DiscreteWrite(&ps2pl_gpio, 1, 0x1);
  31.                             usleep(1000);
  32.                             XGpio_DiscreteClear(&ps2pl_gpio, 1, 0x0);

  33.                             printf("image change done!");
  34.                     }
  35.     }

  36.     return XST_SUCCESS;
  37. }
复制代码

5上位机程序设计
295bbc82cb954c479f6d2d02ed79d313.jpg
本demo演示中,选择一个彩色的BMP测试图片发送到开发板的PS DDR中,并且通过GPIO产生一个PL中断通知PS,数据已经写入到DDR.
PS取出数据,对图像数据做修改后,再次写回到DDR中,并且通过GPIO产生一个中断通知PCIE上位机。
上位机的发送函数如下:
  1. void MainWindow::on_pushButton_clicked()
  2. {
  3.     QString filename;
  4.     QPixmap m_Qpixmap;

  5.     unsigned char val;
  6.     char * name;
  7.     filename = QFileDialog::getOpenFileName(this,tr("Select Pic"),"",tr("Images (*.bmp)"));
  8.     if(filename.isEmpty())
  9.     {
  10.         return;
  11.     }
  12.     QByteArray ba = filename.toLatin1();
  13.     name=ba.data();
  14.     get_image_data(&image_h,&image_v,name);

  15.     val = 0x01;
  16.     user_write(ADDR_PC2PL_INTC, val);

  17.     val = 0x00;
  18.     user_write(ADDR_PC2PL_INTC,  val);

  19.     QImage image(filename);
  20.     m_Qpixmap=QPixmap::fromImage(image,Qt::AutoColor);
  21.     m_Qpixmap=m_Qpixmap.scaled(ui->label1->width()/8*8,ui->label1->height()/8*8,Qt::IgnoreAspectRatio,Qt::FastTransformation);
  22.     ui->label1->setPixmap(m_Qpixmap);
  23. }
复制代码

上位机的接收函数如下:
  1. void MainWindow::on_pushButton_2_clicked()
  2. {
  3.         QPixmap m_Qpixmap;
  4.         QImage *m_Qimage = new QImage(c2h_align_mem_tmp, image_h, image_v, QImage::Format_RGB32);
  5.         c2h_transfer(FPGA_DDR_START_ADDR2, image_h*image_v * 4, c2h_align_mem_tmp);
  6.         m_Qpixmap = QPixmap::fromImage(*m_Qimage, Qt::AutoColor);
  7.         m_Qpixmap = m_Qpixmap.scaled(ui->label2->width() / 8 * 8, ui->label2->height() / 8 * 8, Qt::IgnoreAspectRatio, Qt::FastTransformation);
  8.         ui->label2->setPixmap(m_Qpixmap);
  9. }
复制代码

以上函数中回继续调用pcie_fun.c中的DMA通道函数,以及user_write函数,具体的可以打开源码阅读。
6硬件安装
88390b25b3c7441398ed88bf900f2e9c.jpg
7实验结果
9d108a618d6a4467baad9079f33c5bf5.jpg







您需要登录后才可以回帖 登录 | 立即注册

本版积分规则