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 PCIE速率太慢

各位TI大神,这里请教下!

       我的板卡使用C6678的PCIE做EP,计算机做RC。经过两层PCIE交换机通信。配置的速率为X2的2.5Gbps。现在我测试的同步EDMA速率为:

C6678的SL2上传到计算机大概155MB/s,计算机下传到C6678的SL2速率大概184MB/s。这速度完全体现不出PCIEX2的速率啊。请问下有测试过的正常速率是多少?这速率不正常,有些什么原因引起的啊?

     PCIE相关的寄存器我基本都看了,没有涉及到速率的!往各位高手不吝赐教!!!!!!

  • 没TI工程师和大神关注吗?都两天了,还没人回个啊!6678玩的人这么少!!!

  • 我们实测的PCIe DMA 到DDR3的速度能到500MB。

    单次1MB,总大小1GB

  • 因为经过2层PCIE交换,涉及影响因素比较多。

    我们实测过2个6678的PCIE通信,采用EDMA搬移情况下峰值带宽可以达到800多M.

  • 哦,有没有可能是PCIE相关寄存器中配置不对造成速率慢的啊!

  • xiaozhang zhang 说:

    我们实测的PCIe DMA 到DDR3的速度能到500MB。

    单次1MB,总大小1GB

    我也是单次1MB测试的,请问你是C6678于计算机之间的测试吗?有没有什么寄存器配置影响速率啊?

  • 和计算机的dma,寄存器应该没有影响的,看看dma的上位机程序里面是不是有什么延迟

  • 请教一下PC与DSP之间的PCIE DMA代码怎么编写?

    我现在是用WinDriver实现了单个字节或者block方式的传输。

    下一步想实现,PC将大数据块,通过DMA写到DSP内部。请问是在PC端用WinDriver写DMA代码?还是说DSP这边需要DMA支持?

    谢谢!

  • Feng Jin 说:

    请教一下PC与DSP之间的PCIE DMA代码怎么编写?

    我现在是用WinDriver实现了单个字节或者block方式的传输。

    下一步想实现,PC将大数据块,通过DMA写到DSP内部。请问是在PC端用WinDriver写DMA代码?还是说DSP这边需要DMA支持?

    谢谢!

    PCIE做了有一个多月了,我说一下我的理解,给刚开始做的人一点启发,不知道理解对不对,请大神指点一下错误。

    我刚开始做的时候也是使用Windriver的block方式进行数据读写,这种方式对新手来说很好理解,但是这种方式的速率是在太慢了。你使用的这种方法应该是将数据写入到BAR映射的地址中吧?我开始是这样的,这种方式不论读写只涉及了C6678的inbound。

    我现在使用c6678 outbound方式,outbound对应区域为C6678的PCIE data 也就是0x60000000-0x6FFFFFFF(256M),这块区域被分成32块,通过OB_SIZE寄存器来确定如何将这块区域分成32块;具体的看c6678的PCIE手册。配置过了OB_SIZE,还需要配置OB_INDEX寄存器。

    使用outbound需要理解一件事情,PC向DSP传输数据,DSP使用outbound时,从DSP端来看其实这是一个outbound读操作;DSP向PC则是outbound写操作。

    使用outbound的Pcie Link数据通路应该是这样的:

    PC data buffer->PCIE LINK->PCIE DATA SPACE->EDMA->DSP device Memery

    PC data buffer中的数据携带着它自己所在的PCIE地址经过PCIE Link 最终到达 DSP 。中间需要通过设置inbound让BAR(n)映射到C6678的0x02700000地址,该地址是C6678的EDMA TC寄存器所在,这样你就可以在PC端按照你在已经实现的传单字节数据的方式来配置C6678的EDMA寄存器。

    由于x86体系的PCIE是没有inbound和outbound的,所以并不涉及PCIE地址的转换,换句话说,PC data buffer 中的数据携带的地址就是数据自己的在PC端的物理地址。

    当使用EDMA,假设源地址设在0x6000_1234时,如果启动传输,那么OB_SIZE(假设为1M)和OB_INDEX(假设为0xB6B0_0000)会自己发挥作用,将0x6000_0000这个地址按照文档所说,转换为PCIE地址(最终为0xB6B0_1234),传输给PC,由于x86没有inbound,这个PCIE地址实质就是PC内存的物理地址;这样,EDMA就会将PC内存上其实地址为0xB6B0_1234的数据搬移到DSP的目的地址中,从而实现了大块数据由PC传入DSP。

    Windriver里有两个函数WDC_DMAContigBufLock和WDC_DMASGBufLock,看下Windriver的手册,这两个函数可以申请一段Buffer并获得它的物理地址。有了PC上的物理地址,就可以使用EDMA了

  • xiaozhang zhang 说:

    我们实测的PCIe DMA 到DDR3的速度能到500MB。

    单次1MB,总大小1GB

    我实测怎么才398MB,单次8MB,总大小128M

  • xiaozhang zhang 说:

    和计算机的dma,寄存器应该没有影响的,看看dma的上位机程序里面是不是有什么延迟

    上位机驱动和测试程序都是我写的,没有延迟。驱动里配置EDMA,然后启动上传或下传

  • 你好!

    感谢你的回复!!

    我现在只能理解inbound方式,就是PC端Windriver通过单字或者block的方式去读写DSP端内存的数据。

    就是感觉理解outbound的方式有点困难。

    你说了很多细节,我得慢慢消化。

    有个问题请教一下,能描述一下具体的代码流程吗?

    比如我理解outbound方式的话,PC往DSP写数据的流程是不是如下:

    PC端WDC_DMAContigBufLock申请一段物理内存,初始化内存里的数据,然后通知DSP启动EDMA,DSP用EDMA将PC端buffe如上的数据读取到DSP自己的内存上?

    如果是这样的话,有个问题。

    1. PC端Windriver如何通过代码通知DSP启动EDMA以及EDMA的目的地址(PC侧的buffer)?是需要PC端给DSP发送一个PCIE message中断?因为我现在只做了inbound的代码,Windriver端只有用单字或者block方式读写DSP的内存。

    好像你的红字部分已经说明了


    如果能共享一个代码的话,就更好了,哈哈哈~

  • Feng Jin 说:

    你好!

    感谢你的回复!!

    我现在只能理解inbound方式,就是PC端Windriver通过单字或者block的方式去读写DSP端内存的数据。

    就是感觉理解outbound的方式有点困难。

    你说了很多细节,我得慢慢消化。

    有个问题请教一下,能描述一下具体的代码流程吗?

    比如我理解outbound方式的话,PC往DSP写数据的流程是不是如下:

    PC端WDC_DMAContigBufLock申请一段物理内存,初始化内存里的数据,然后通知DSP启动EDMA,DSP用EDMA将PC端buffe如上的数据读取到DSP自己的内存上?

    如果是这样的话,有个问题。

    1. PC端Windriver如何通过代码通知DSP启动EDMA以及EDMA的目的地址(PC侧的buffer)?是需要PC端给DSP发送一个PCIE message中断?因为我现在只做了inbound的代码,Windriver端只有用单字或者block方式读写DSP的内存。

    好像你的红字部分已经说明了


    如果能共享一个代码的话,就更好了,哈哈哈~

    你说的流程是没错的。

    代码请参照

    D:\ti\mcsdk_2_01_02_06\tools\boot_loader\examples\pcie\linux_host_loader\pciedemo.c中HAL_WriteDMA函数,我也是根据这个来做的outbound传输。自己的代码因为封装层数太多没有参考价值。

    你现在做到了可以使用inbound,用Windriver读写DSP的内存,那么你应该知道读写的DSP中哪一块的内存,这一块内存也是你通过配置IB_START0_LO和IB_OFFSET寄存器来选择的。那么你只需要配置这两个寄存器,让你读写的DSP内存地址指向DSP的EDMA寄存器的位置就可以通过Windriver直接读写这些寄存器来控制EDMA的各种参数和行为。

  • ti\mcsdk_2_01_02_06\tools\boot_loader\examples\pcie\linux_host_loader\pciedemo.c

    看到这个代码了。非常感谢!!我先试试,有问题再请教你!

  • 你好!

    我现在已经测通了,感谢你的帮助!!

    但是现在测速有个问题。感觉测出来的速度超过了理论值。

    为了简单起见,我的测试步骤是:

    1. PC端申请1MB的buffer,然后把OB_SIZE、OB_OFFSET_INDEX、OB_OFFSET_HI这三个量写到DSP PCIE的指定寄存器处,然后PC上位机暂停在断点处

    2. DSP主动调用EDMA发送函数,将0x9000_0000这个地址处512KB的数据发送到0x6000_0000

    3. DSP EDMA执行结束之后,可以在PC端观察申请的那个1MB buffer空间,可以观察到确实接收到了来自DSP的512KB的数据

    关于测速,我是在DSP端统计的。也就是测DSP端EDMA,把512KB的数据从0x9000_0000搬移到0x6000_0000处花了多长时间。

    每次EDMA,trigger EDMA通道之前记录一下TSCL,poll完成中断标志位后,再记录一下TSCL,从而计算得到时间差,从而计算带宽。

    下面是两次的统计结果,

    DSP runs @ 983MHz
    EDMA transfer 524288 data from DSP DDR3 address 0x90000000 to PCIE address 0x60000000 test:
    using cycles = 763334
    using times = 776535 ns
    The transfer bandwidth from DDR3 to DDR3 = 675.00 MB/s
    
    DSP runs @ 983MHz
    EDMA transfer 32768 data from DSP DDR3 address 0x90000000 to PCIE address 0x60000000 test:
    using cycles = 48374
    using times = 49210 ns
    The transfer bandwidth from DDR3 to DDR3 = 665.00 MB/s
    

    这个值超过了5Gbps。

    而我的代码中,配置的是2.5Gbps X1

    /* Setting PL_GEN2 */
    memset (&setRegs, 0, sizeof(setRegs));
    gen2.numFts = 0xF;
    gen2.dirSpd = 0x0;
    gen2.lnEn   = 1;
    setRegs.gen2 = &gen2;

    所以这个带宽感觉不合理。

    不知道问题在哪?

    问一下,在DSP程序跑完后与电脑建立起PCIE链路后,DSP端怎么确定到底建立在几Gbps X几?

    谢谢!!

  • 请查看LINK_STAT_CTRL寄存器(0x21801080)的NEGOTIATED_LINK_WD位和LINK_SPEED位,NEGOTIATED_LINK_WD为2h则是X2,1h为X1,LINK_SPEED为2h为5G,1h为2.5G

  • 谢谢!

    从这个寄存器看,PCIE确实建立在5Gbps X2.

  • Feng Jin 说:

    谢谢!

    从这个寄存器看,PCIE确实建立在5Gbps X2.

    你在X2 5Gbps情况下实测的速率是多少?

  • 目前,我代码虽然是写建立2.5Gbps X1的,

    /* Setting PL_GEN2 */
    memset (&setRegs, 0, sizeof(setRegs));
    gen2.numFts = 0xF;
    gen2.dirSpd = 0x0;
    gen2.lnEn   = 1;
    setRegs.gen2 = &gen2;

    但是跟主板实际跑的时候,建立成5Gbps X2了,按照你你提到的寄存器看的结果。还有就是这个帖子http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/524390/1909075#1909075

    在5Gbpx X2的情况下,我在DSP端PCIE EDMA的速度,可以到675MB/s

    测试步骤是:

    1. DSP端EDMA搬移512KB数据,从0x9000_0000到0x6000_0000,只搬移一次。

    2. EDMA trigger之前记录TSCL

    3. EDMA poll interrupt status while循环之后,再记录TSCL

    4. 然后用时间差、512KB数据量算带宽。

    我想再建立成2.5Gbps X1,然后再用同样的方法再测下,以做对比。

    但是根据上面E2E的帖子的说法

    Feng,

    Please follow the code examples 5/6 in http://www.ti.com.cn/cn/lit/an/sprabk8/sprabk8.pdf to configure GEN1 x 1 lane. Please note C6670 PCIE has x2 lanes, this is not the typical PCIE cards (x1, x4, x8, x16). So some PC's motherboard doesn't work well with it: even you configure this as PCIE GEN1 x 1, you may not get what you want.

    Regards, Eric

    好像不是那么容易建立成2.5Gbps X1。。

  • 您好,我现在刚开始尝试调试PCIE与PC通信,有很多不懂地方,您能方便加个联系方式指点下吗?我的QQ是516122452.

    看到楼上推荐的例程是Linux系统下的,如果是基于Windows系统会有何不同吗?我现在刚学完了PCIE原理机制和PCIE驱动程序以及相关寄存器的学习,

    对具体如何实现还是一头雾水,有什么比较好的资料推荐吗?

    小白一只,望大家给予指点一二,感激不尽!

  • Feng Jin 说:

    目前,我代码虽然是写建立2.5Gbps X1的,

    /* Setting PL_GEN2 */
    memset (&setRegs, 0, sizeof(setRegs));
    gen2.numFts = 0xF;
    gen2.dirSpd = 0x0;
    gen2.lnEn   = 1;
    setRegs.gen2 = &gen2;

    但是跟主板实际跑的时候,建立成5Gbps X2了,按照你你提到的寄存器看的结果。还有就是这个帖子http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/524390/1909075#1909075

    在5Gbpx X2的情况下,我在DSP端PCIE EDMA的速度,可以到675MB/s

    测试步骤是:

    1. DSP端EDMA搬移512KB数据,从0x9000_0000到0x6000_0000,只搬移一次。

    2. EDMA trigger之前记录TSCL

    3. EDMA poll interrupt status while循环之后,再记录TSCL

    4. 然后用时间差、512KB数据量算带宽。

    我想再建立成2.5Gbps X1,然后再用同样的方法再测下,以做对比。

    但是根据上面E2E的帖子的说法

    Feng,

    Please follow the code examples 5/6 in http://www.ti.com.cn/cn/lit/an/sprabk8/sprabk8.pdf to configure GEN1 x 1 lane. Please note C6670 PCIE has x2 lanes, this is not the typical PCIE cards (x1, x4, x8, x16). So some PC's motherboard doesn't work well with it: even you configure this as PCIE GEN1 x 1, you may not get what you want.

    Regards, Eric

    好像不是那么容易建立成2.5Gbps X1。。

    测试方法和你一样,我的速度能到790MB/S

    我目前的问题也是这个,完全按照手册里说的,代码也和你一样,想要建立2.5G x1,但是PC总是会协商到5G x2 。

    你的E2E帖子里,他的意思是X2不是PCIE标准里的,X1是标准里的,但是6678的X1居然不能用,想不明白。之前逛了逛TI的英文论坛,好像协商到X1 2.5G的人用的代码是KeyStone的PCIE例子,不是pdk里的PCIE_example,你可以试试,不过KeyStone的程序不是很好移植

  • dong zhang5 说:

    您好,我现在刚开始尝试调试PCIE与PC通信,有很多不懂地方,您能方便加个联系方式指点下吗?我的QQ是516122452.

    看到楼上推荐的例程是Linux系统下的,如果是基于Windows系统会有何不同吗?我现在刚学完了PCIE原理机制和PCIE驱动程序以及相关寄存器的学习,

    对具体如何实现还是一头雾水,有什么比较好的资料推荐吗?

    小白一只,望大家给予指点一二,感激不尽!

    推荐你结合Linux的例程看看Windriver自带的例子。Linux下的驱动API都在PCIE.h里,Windows的话还是使用Windriver的API比较方便

  • 嗯,之前我是怀疑我的675MB/s速度不合理,所以想着测一下5Gbps X1的,比对一下。

    但是这么看来,675MB/s也是个合理的结果,甚至还有提升空间,我也就不管了。

    刚把PC与DSP之间的MSI中断调通,PCIE我这边应该就没有什么问题了。

    感谢你的帮助!否则我还卡在EDMA传数的阶段。

  • 你好Herry Leo ,


    又来请教你一个问题。

    PC端Windriver申请1MB空间,其中physical address总是不是按照1MB对齐的(按照4KB对齐的),比如申请出来的buffer地址为0xdb21_2000,这样导致没法映射到DSP的一个1MB的region内。DSP给PC发1MB数据,会因为地址不对,导致PC蓝屏。

    请问PC端windriver怎么设置,使得申请出来的physical address是按照1MB对齐的,比如申请出来的地址为0xdb20_0000,这样的话能完整的对应到DSP的0x6000_0000~0x600F_FFFF?


    谢谢!

  • Feng Jin 说:

    你好Herry Leo ,


    又来请教你一个问题。

    PC端Windriver申请1MB空间,其中physical address总是不是按照1MB对齐的(按照4KB对齐的),比如申请出来的buffer地址为0xdb21_2000,这样导致没法映射到DSP的一个1MB的region内。DSP给PC发1MB数据,会因为地址不对,导致PC蓝屏。

    请问PC端windriver怎么设置,使得申请出来的physical address是按照1MB对齐的,比如申请出来的地址为0xdb20_0000,这样的话能完整的对应到DSP的0x6000_0000~0x600F_FFFF?


    谢谢!

    抱歉现在才看见贴子,TI为什么不给我发邮件呢?

    这个问题涉及到了Windows内存管理的太多方面,我之前尝试解决但是没有找到办法。

    我现在用的时候不追求Windows内存的对齐,比如发送一个1MB的数据,对于申请到的0xdb21_2000,配置OB_OFFSET(0)时应该配置为0xdb20_0000,DSP从0x6000_0000的偏移地址0x1_2000开始发送数据,然后我又配置了OB_OFFSET(1)为0xdb30_0000,继续发送从0x6010_0000到0x6011_2000的数据来保持数据的完整性。