This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于C6678与PC(X86)之间的PCIe Link通信,采用EDMA方式的问题。。。急,谢谢!



目前可以实现PC与DSP(C6678)之间的数据通信,但是通信的速率达不到项目的要求,因此考虑采用DMA方式进行数据传输,在实现过程中出现了一些问题,希望得到各位大牛的指导。

1,PC作为RC端,DSP作为EP端,此时如何去调用C6678内部的EDMA模块去完成数据搬移呢?如何将PC的地址设置为EDMA能够识别的地址?

      使用BAR1映射到EDMA config memory,使用PC配置好EDMA相关寄存器,可以完成一次EDMA操作,假设需要将PC上的数据搬移到DSP外挂的DDR3上,参考mcsdk下linux pciedemo.c文件的配置:

   /* Calculate the DSP PCI address for the PC address */   

 tmp = PCIE_DATA + (srcAddr & ~PCIE_1MB_BITMASK);

发现此时搬移的数据只是tmp地址本身存在的杂乱数据到DDR3:0x8000 0000,而PC上的数据并没有传输到C6678的tmp地址上。

想了解一下这个tmp地址的计算中srcAddr地址是指PC端开辟的虚拟地址所指向的物理地址吗?

 

2,如果只是想实现PC对DSP写数据,以及PC从DSP读数据,那么应该并不需要涉及到outbound address translation吧?PC为RC模式。因为已经调试好的对单个地址的读写都是使用inbound address translation完成的。

  • 1 做好PCIE outbound地址映射后,只需要将EDMA的destination 地址配置成PCIE data space的地址,在6678上就是0x60000000开头的地址

    2 PCIE没有虚拟地址和物理地址的概念,在PCIE典型传输中有4个地址,以DSP作为RC传输数据到EP(DSP)为例,RC DSP数据源地址---> DSP PCIE_Data空间地址(A)--->PCIE 总线地址 (B)--> EP 内部地址,其中在A 过程中,需要做outbound地址转换,而在B过程中需要做inbound地址转换。

    3  PC 写/读数据到DSP,这个地址转换是PC端完成的,DSP只需要做inbound address转换就可以了

  • Thomas Yang1 :

       您好,如果我想使用DMA方式在PC与DSP之间进行数据传输的话DSP只需完成inbound address translation的话,比如PC发送数据到DSP的话,配置EDMA的dstaddr为DDR3,那么srcaddr应该如何设置呢?

    就目前的调试结果,在PC上位机程序中造一些数据,使用该段数据临时占用的物理地址phyaddr,采用outbound设置将其映射到0x60000000区间,但是发现EDMA执行后只是搬移PCIE DATA区域内本身存在的数据(0x60000000)到DDR3,并没有看到PC端的数据。我想问我这么操作有问题吗?

    还是说PC作为RC是没法使用DSP(EP)内部的EDMA实现数据搬移的?

     

    谢谢!

  • 我觉得你把问题搞混淆了,EDMA是DSP内部的数据搬移引擎。PC(上位机)要采用的方式将数据放到PCIE总线上去是由PC侧决定,和DSP侧(接受)没有关系。DSP侧只是负责将PCIE总线上的数据经过inbound address translation 然后通过PCIE自带的DMA(不是EDMA)搬移到DSP的目标地址中去。

  • 之前提到的EDMA,是因为举的例子中RC是DSP,所以用EDMA方式将数据放到PCIE data space上去的。

  • Thomas Yang1:
     您好,感谢您的指导。还有两个小疑问想请教一下:
    1、在PCIe手册(sprugs6a)中有这么一句话:“The PCIESS does not have DMA capabilities built into it. ”那是不是说明C6678的PCIESS总线上并没有DMA功能呢?此时PCIE应该如何实现用自带的DMA搬移数据到DSP目标地址?或者说手册中提及的PCIE DMA传输是不是只能在DSP作为RC端的时候使用EDMA才可以实现?

    2、在mcsdk目录C:\ti\mcsdk_2_00_09_21\tools\boot_loader\examples\pcie\linux_host_loader下有一个pciedemo.c的例子,里面有这么一个函数
    void HAL_readDMA(uint32_t srcAddr, uint32_t dstAddr, uint32_t size, uint32_t flag),调用时设置的参数为
    HAL_readDMA(DDR_START, rData, DMA_TRANSFER_SIZE, 1);     /* Move from DSP to GPP */,其中源地址DDR_START=0x80000000,目的地址rData根据文件中的注释为dma_addr_t wData, rData;  /* Physical PCIE bus address */

    我想知道这个文件中应该是主机(Linux)作为RC,DSP作为EP端吧?因为DSP的EDMA中的OPT、SRC、DST等参数都是主机写入的。EP端应该是无法对RC主动发起写数据操作的?这个例子应该是DSP端的EDMA将数据从DDR搬移到了PCIE总线地址上,仅仅这个过程是DMA实现的,PC端从PCIE总线获取这些数据采用何种方式需要PC端的配置选择来实现。我这样理解对吗?
    如果参考这个例子,使用的时候rData这个PCIE的总线地址作为目标地址时,配置成哪些值才能被主机端所识别呢?


    期待您的解答,谢谢!

  • 是不是可以通过DSP向PC读数据,这样就可以用到EDMA来实现?看到mcsdk下那个linux下实现的例程,感觉XP下应该也是可以实现的。

  • 基本上你开发的过程没有问题,我刚开始也是用Windriver方式实现对DSP寄存器方式的读写操作,速度较慢!该方式主要通过配DSP inbound相关寄存器实现。

    现在我采用的DriverStudio方式开发进行开发,依然采用Inbound方式对DSP寄存器进行配置,但大规模数据传输上采用Outbound方式进行传输,Outbound方式主要通过配置OB_SIZE、OB_OFFSET_INDEX、OB_OFFSET_HI寄存器,其中OB_OFFSET_INDEX为你内核申请DMA缓冲区的物理地址,即以下代码:

    pageBase = srcAddr & PCIE_1MB_BITMASK;

    m_MemoryRange0.outd(OB_OFFSET_INDEX(0),pageBase|0x1);

    上述过程我也是参考pciedemo.c开发的,我理解的outbound的EDMA传输实现了DDR到PCIe data space空间传输,PCIe data space数据通过Outbound地址转换发送到PCIe链路地址,对于主机而言即主机内核缓冲区地址!

    有问题可以继续讨论,祝你开发顺利!

  • 您好:

    感谢您的回复!

    现在的情况是这样:DSP内部的EDMA能够搬移数据从DDR到PCIE DATA,但是主机端好像没有收到任何数据,一直是全0。比如说我在PC侧定义的一个数据buffer指针地址为0x008fd000,此时对应的page中的physicaladdr显示为0x0000 0000 0007 7000,其low-32bit为0x0007 7000 。然后我把PCIE DATA地址outbound为这个物理地址。但是无法收到数据。请教一下我这种配置是对的吗?

    期待您的回复~谢谢!

  • 基本流程应该是对的。我内核驱动缓冲区 是用DriverStudio自带的KCommonDmaBuffer申请的,不知道你的buffer如何申请的?是否确保物理地址连续?

    还有你的这个物理地址 跟我当时打印出来的好像不太一样,举个例子 我的virtualaddress 是88A33000,LogicalAddress(就是OutBound转换的地址)是8A33000!

    对应代码

    m_PAddr=m_Buffer.LogicalAddress().LowPart;
    m_LAddr=m_Buffer.VirtualAddress();

    你看看能否对你有所启发?

  • 我现在正在开发PCIE的驱动,也是使用DriverStudio,有些地方不太明白,能否将你写得的驱动共享一下,cetc41@126.com

  • 您好:

        我目前正在做C6678 EVM与PC(Win7 64)的PCIE接口,想实现DSP直接读写PC内存。

        我用WinDDK开发的驱动程序,通过IoMapTransfer函数得到了用户缓冲区映射后的逻辑地址(例如: 0x0FEB1000);

        请问这个逻辑地址可以直接用在DSP中设置Outbound吗?现在的情况是,用这个地址设置Outbound后,DSP向0x60000000区域写数时电脑会蓝屏。

        另,请问PC中得到的映射后的逻辑地址,怎样和PCI总线地址对应起来?DSP向0x60000000区域写数时应该是写在PCI总线地址上,该怎样到达PC内存?

        这部分内容实在是有点搞不清楚,求指点!或者帮忙推荐一下有关PCI DMA方面的资料,谢谢!

  • 请问您当时用windriver写的驱动速度大概有多少呢?我测得写速度由17MB,写速度只有2MB,请问这个正常吗?是不是速度高的话必须使用driverstdio了?

  • 你好,麻烦你看到后回复下,只需回答我一个问题,即:DSP端程序我是应该运行自带端pcie程序吗,并设置为EP模式?谢谢,麻烦你看到回复下

  • 大神想咨询一下,怎么实现dsp与linux系统下主机的pcie通信,怎么操作啊,有个dsp端的例程为ep端,主机端也需要写个app还是怎么做可以link up