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.

[参考译文] MSP430FR6043:如何防止在 TI-CGT 编译器上进行 SFR 相关代码优化?

Guru**** 1628430 points
Other Parts Discussed in Thread: MSP430FR6043, TI-CGT
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1358633/msp430fr6043-how-to-prevent-sfr-related-code-optimisation-on-ti-cgt-compiler

器件型号:MSP430FR6043
主题中讨论的其他器件: TI-CGT

根据 MSP430优化 C/C++编译器 v21.6.0.LTS (slau132y)章节"5.7.4 volatile 关键字":"编译器不会优化对声明为 volatile 的变量的任何访问"。

但是、当优化级别为1或更多时、以下代码会受到影响:

    // Repeated block transfer, increase src address, increase dst address
    DMA2CTL = (uint16_t)DMADT_5 | (uint16_t)DMASRCINCR | (uint16_t)DMADSTINCR;

    // these are loaded when next DMA2CTL |= DMAEN is executed
    DMA2SA = (uint16_t)(uintptr_t)RAM_XE;          //    <-    THIS !!!!
    // DMA2SA=RAM_XE[0/1/2] -> DMA2DA=SAPH_APGC, SAPH_APGLPER, SAPH_APGHPER are setup for consumption here (3 words per block)
    DMA2DA = (uint16_t)(uintptr_t)&SAPHPGC;        //    <-    AND THIS !!!!
    
    // enable DMA2: this will load above DMA2SA and DMA2DA
    DMA2CTL |= (uint16_t)DMAEN;
    // these are loaded when prev. DMA2 transfer would end
    DMA2SA = (uint16_t)(uintptr_t)(RAM_XE + 3U);
    // pending next DMA2SA=RAM_XE[3/4/5] -> DMA2DA=SAPH_AXPGCTL, SAPH_AXPGLPER, SAPH_AXPGHPER are setup for consumption here (3 words per block)
    DMA2DA = (uint16_t)(uintptr_t)&SAPHXPGCTL;
    
 

我没有找到 SFR_8BIT / SFR_16BIT / SFR_20BIT 定义、但是我认为它们应该被视为 volatile。

是否有办法让 TI 编译器不优化 DMA 寄存器访问?

谢谢!

丹尼尔

 随附测试项目:

e2e.ti.com/.../test_5F00_1.zip

屏幕截图:

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

    消除这些写入并不符合我所知的 C 标准。 这将是编译器错误。

    我不知道您正在使用的编译器、但在 GCC 中、这些寄存器是使用 SFR_x 宏定义的。 从 msp430fr6043.h 开始:

    sfr_a(DMA2SA);                                /* DMA Channel 2 Source Address */
    
    sfr_a(DMA2DA);                                /* DMA Channel 2 Destination Address */
    
    

    等等

    如 iomacros.h 中所定义、

    #define sfr_a(x) extern volatile unsigned long int x
    

    快速检查显示 GCC 不会使用-O2优化这些写入。

    至少 TI-CGT 编译器可以更好地处理 DMASA 和 DMADA 寄存器。

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

    尊敬的 David:您好、我们使用的编译器是最新的 TI-CGT v 21.6.1 。 LTS:

    对于 TI-CGT、也使用 SFR 宏定义这些 DMA 寄存器:

    不确定上面是否是 SFR_20BIT 的定义 、但如果是、似乎错过了 易失性 关键字?

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

    似乎只有 DMAxSA 和 DMAxDA 受此 SFR_20BIT 定义的困扰:

     对我来说、一种权变措施是使用 L 寄存器(SFR_16BIT)、因为它们 看起来运行良好:

    在本例中、此变通方法是可以接受的、因为寻址地址全部位于低存储器中、只需要确保  h 寄存器保持为0、但当地址超过64K 时、这可能对其他寄存器不起作用...

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

    您当然可以将易失性添加到头文件中。

    DMA 地址寄存器是唯一的、因为要向它们写入20位地址、必须通过 movx.a (或等效的 MOVA)指令来完成。 对下半部分进行16位写入会自动清除 DMA 地址的上半部分。

    就像将16位值加载到 CPU 寄存器中一样。

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

    非常感谢你指出上半场清理,我错过了!  UM 为相同的"当使用 字词 指令、位19-16被清除"。

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

    Daniel、您好!

    在我看来、我不知道为什么不为 SFR_20BIT 使用 Volatile。

    我想 David 已经为您的问题做了一些澄清。 您可以尝试检查是否存在进一步的问题。

    B.R.

    萨尔