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.

[参考译文] 编译器/TMS320F28069F:RPTB GPIO

Guru**** 2553260 points
Other Parts Discussed in Thread: TMS320F28379D

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/927016/compiler-tms320f28069f-rptb-gpio

器件型号:TMS320F28069F
主题中讨论的其他器件:TMS320F28379D

工具/软件:TI C/C++编译器

您好!

我们尝试通过读取表来将 GPIO 驱动为并行总线(尽可能快),代码很简单:

for (j=0;j<30;j++)

       GpioDataRegs.GPADD.All   = tab[j];

使用此代码、我们得到的最大值可能是由于环路开销。

通过手动展开循环、我们得到大约22MHz

此时、我们认为 RPTB 会有所帮助、因为周期数是一个常数(在本例中为30)

我们尝试了不同的优化级别、但不会显示宝贵的 RPTB 指令。

-您知道原因吗?

如何强制在 C 中使用此指令?

此致、

Marc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对于包含此循环  的源文件、请按照文章如何提交编译器测试用例中的说明进行操作。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该代码基于 TI GPIO 示例、进行了少量修改、通过浏览表来更新 GPIO 端口。

    编译器版本:v20.2.1.LTS

    优化:lvl3,速度与大小:5 (最大值)浮点:宽松

    但是、我尝试了许多不同的级别、结果相同。

    这是压缩的.pp 文件。

    e2e.ti.com/.../1411.Example_5F00_2806xGpioToggle.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您提交测试案例。   

    问题的一部分是循环控制变量 j...

    for (j=0;j<30;j++) 

    (笑声) 是全局变量。  在函数中,添加一个也称为 j...的局部变量

    int j; 

    如果使用 --opt_level=3 --opt_for_speed=5进行编译,则编译器会完全展开循环。  这可以解决您的问题。

    我也构建了-opt_level=3 。  在这种情况下、生成的代码是错误的。  我提交了 EXT_EP-9940条目 以进行调查。  欢迎您使用我签名中的以下链接进行操作。  有关详细信息、请参阅该条目。

    我没有找到让编译器为内部循环使用重复块指令 RPTB 的方法。  我怀疑这是因为循环中的分配是对易失性变量的。  易失性表达式、尤其是赋值、通常会阻止编译器优化。  即使如此,我在我提交的条目中添加了一条注释,以研究在这种情况下是否可以这样做。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 George、

    这确实会展开环路、但频率不稳定/偶数。

    我尝试了一个基本循环:

    int N=0;
    对于(N=0;N<25;N++)
    {
    B+=a*N;
    } 

    222. 对于(N=0;N<25;N++)
    008545:B50900A6 RPTB @、T Ü V AR6
    C$L1:
    008547:2DA9 MOV T、@AL
    008548:761F0284 MOVW DP、#0x284
    224 B+=a*N;
    00854a:123C MPY ACC、T、@0x3c
    00854b:723D 添加 @0x3D、AL
    00854c:92AC MOV AL、@T
    222 对于(N=0;N<25;N++)
    00854d:9C01 ADDK AL、#1
    00854e:7700 NOP
    00854f:7700 NOP 

    指令 RPTB 确实出现了、所以您必须对、易失性寄存器可能会阻止编译器进一步优化代码。

    我尝试使用常数指针来欺骗它

    uint32* const pGpio = 0x00006FC0; 
    对于(j=0;j<30;j++)
    {
    *(pGpio)= tab[j];
    } 

    但是这次、编译器不展开循环、RPTB 指令仍然没有、但是频率是稳定的3.5MHz。

    目标是达到10MHz 以驱动一个或两个并联 DAC。



    此致、
    Marc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在我之前的帖子中、我注意到我在编译器中发现了一个错误。  请仔细查看该条目。  现在、看看编译器为您的循环的最新变体生成的汇编代码。  这个错误、或者一个几乎类似的错误、是否会影响事情?   

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    即使在未使用 volatile 关键字的 opt_level=3时、我也看不到 RPTB 的使用情况。

    我将向我们的一位应用专家征求有关这方面最佳实践的意见。

    谢谢
    Greg

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢 Greg、

    我们期待您的回答。

    Marc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    我收到的反馈表明、可能使用以下方法:

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/572480?TMS320F28069-TMS320F28069

    Greg

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Greg、

    抱歉、我不确定该线程中有关 SPI 的内容、也不知道该线程的位置、也没有提到 RPTB 指令。

    您是否指出此帖子

    Marc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    近期、我已要求为您的特定用例提供更多应用支持。  

    要跟踪先前提交的 TT 以及未来可能的编译器性能改进、请参阅以下内容:

    谢谢
    Greg

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marc:  

    我找不到一个完全符合您情况的示例。  Greg 提到的帖子只是我发现的一个使用 IO 仿真外设的帖子。  我了解它与您的特定应用不同。   

    此致

    Lori

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Marc Fournier">我们尝试通过读取表来驱动 GPIO (尽可能快)、而不是尝试使用 CPU 来驱动、是否可以改用 DMA 控制器?

    我必须承认、我没有尝试编写任何代码来对 TMS320x2806x 中的 DMA 控制器进行编程、 但通过查看 TRM、可以看到源地址和目标地址具有独立的步长、这可能允许源地址通过表递增、而 GPIO 数据寄存器的目标地址保持固定。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Chester Gillon"] DMA 控制器是否可以代替 CPU 使用,而不是尝试使用 CPU 来执行此操作?

    这是一个有趣的主意!   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Chester 和 Lori、您好!

    DMA 将是完美的、但根据数据表、它没有 GPIO 访问权限(或者它是否访问?)

    Marc

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    您的观察结果正确。 DMA 不能访问 GPIO 寄存器。

    此致、

    Vivek Singh

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    除了应用程序专家提供的更多近期解决方案建议之外、您还可以通过以下方式跟踪优化改进的进度:

    https://sir.ext.ti.com/jira/browse/EXT_EP-9940

    此致、
    Greg

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们尝试了 TMS320F28379D、但没有成功(相同的代码、相同的结果)。

    这个有一个 uPP 外设、但被限制在8位。 DMA 不能访问 GPIO。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marc:

    我现在参加讨论的时间有点晚,如果这已经包括在内,我就表示歉意。   我在发送给 George 的代码中看到了这一点、如果一个接一个地访问 GPIO、您是否能够获得所需的结果?  即

    my_GPIOMsg ()
    {
    GpioDataRegs.GPADD.All = TAB[0];
    GpioDataRegs.GPADAT.all = Tab[1];
    GpioDataRegs.GPADAT.all = Tab[2];
    ....
    GpioDataRegs.GPADAT.all = Tab[29];
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user ="Marc Fournier"]我们尝试 TMS320F28379D 后没有成功(相同的代码、相同的结果)。

    尊敬的 Marc:

    我知道编译器当前未生成满足您需求的解决方案。  我想了解您是否有任何解决方案可满足您的性能需求?   在原始帖子中、您提到了手动展开循环。  这是否产生了满足要求的代码?  我想了解您是否有权变措施?

    -洛里

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Lori、

    我们的目标是以10MHz 的频率为12位 DAC 提供高达4096点的 RAM。 我认为这通常是通过 FPGA 完成的、但我们不使用 FPGA、我们几乎在每个项目中都使用28069。

    手动展开循环显示了 MCU 的实际功能:它可以在 GPIO 端口上达到22MHz 的吞吐量,但它可以满足我们的需求,但手动执行是不切实际的。

    展开自动产生不均匀的输出频率、 经过优化、每个 GPIODAT 更新之间没有那么多指令。

    我认为 RPTB 指令可以解决这个问题、并允许快速"位感叹"的可能性(这可能对其他人有用)。 这可能可以通过简单的 ASM 功能来完成,如下所示:

    RPTB #4096、标签

    MOV32 GPIODATA、TAB[I++]

    NOP (可选?)

    标签

    但我对 ASM 的效率不高(如您所见)。

    最好是编译器更新、因此我们可以留在 C 中

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    感谢您的详细信息和摘要。  我将更详细地介绍这一点。  我同意、最终目标是增强编译器处理此类情形的能力;在这种情况发生之前、可能必须进行汇编。  

    此致

    Lori

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    这个带有 pragma UNROLL (5)的 C 代码组成了一个 RPTB 块。  您是否仍然需要无限循环?

    void GPIO_example_a (void)

      int j = 0;
    #pragma UNROLL (5)
      对于(j = 0;j<30;j++)
       GpioDataRegs.GPADD.All = tab[j];

    _GPIO_example_a:

      MOVB XAR6、#5        ;[cpu_alu]
      MOVL XAR4、#_TAB      ;[CPU_ARAU]
      RPTB $C$L4、AR6       ;[CPU_ALU]|8687|
    $C$L3:
      MOVL XAR7、* XAR4++     ;[CPU_ALU]|8689|
      MOVW DP,#_GpioDataRegs  ;[CPU_ARAU]
      MOVL ACC,*XAR4++      ;[CPU_ALU]|8689|
      MOVL @ GpioDataRegs、XAR7;[CPU_ALU]|8689|
      MOVL P,*XAR4++       ;[CPU_ALU]|8689|
      MOVL XAR7、* XAR4++     ;[CPU_ALU]|8689|
      MOVL @ GpioDataRegs、ACC ;[CPU_ALU]|8689|
      MOVL @ GpioDataRegs,P  ;[CPU_ALU]|8689|
      MOVL ACC,*XAR4++      ;[CPU_ALU]|8689|
      MOVL @ GpioDataRegs、XAR7;[CPU_ALU]|8689|
      MOVL @ GpioDataRegs、ACC ;[CPU_ALU]|8689|
    $C$L4:
      LRETR           ;[cpu_alu]

    此致、

    Greg

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马克

    这是一个您可以尝试的手动编码汇编函数。  它假定 MyTable 中有30个条目、MyTable 是全局条目、数据寄存 器的地址是硬编码的(0x7F00)我对 F2837x 进行了快速检查、因为我没有 F2806x 与我一起使用;尚未对其进行完全测试。   

    void sendGPIO (void) 

    .if _TI_EABI _
    .asg sendGPIO、_sendGPIO
    .asg MyTable、_MyTable
    .asg my_GPIO_loop、_my_GPIO_loop
    .endif
    
    .ref _MyTable
    全局_sendGPIO
    GPIO_DATA_register .set 0x7F00
    
    .text
    _sendGPIO:
    MOVL XAR6、#MyTable
    MOVL XAR7、#GPIO_DATA_register
    
    ; RPTB 要求最小块大小为9个字
    ;每个 MOVL 都是一个16位操作码
    RPTB my_GPIO_LOOP、#(6-1);循环6次、总共= 30次写入
    MOVL ACC,*XAR6++
    MOVL *XAR7,ACC ;写入1
    MOVL ACC,*XAR6++
    MOVL *XAR7,ACC ;写入2
    MOVL ACC,*XAR6++
    MOVL *XAR7,ACC ;写入3
    MOVL ACC,*XAR6++
    MOVL *XAR7,ACC ;写入4
    MOVL ACC,*XAR6++
    MOVL *XAR7,ACC ;写入5、blocksize 10
    _my_GPIO_loop