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.

[参考译文] F29H85X-SDK-EVM SOM:F29-SDK:SysCtl_delay 直接及优化

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1659317/f29h85x-som-evm-f29-sdk-sysctl_delay-inccorect-with-optimization

器件型号: F29H85X-EVM-EVM SOM

您好:

我目前正在 F29H85x 平台上工作、在启用优化后、我观察到了与 device_delay_US () 宏相关的意外行为。

我从官方的例子: led_ex1_blinky 开始。 代码以较低的优化级别按预期运行、但启用-O1 -flto 时 、LED 闪烁行为变得不正确(时序不一致或完全错误)。

这一问题似乎是由于拖延的执行而产生的:

void SysCtl_delay(uint32_t count)
{
    __asm volatile("    MV A0, D0           \n" \
                   "    DECB A0, #1, 0x0    \n");
}

但是,如果我将 sysctl_delay () 移到一个单独的.c 文件中(而不是被内联),即使启用了 LTO 优化,该行为也会再次变得正确。

问题似乎与链接时优化 (LTO) 有关

在 SDK 文档中、“不支持的功能“一节对其进行了说明:
“适用于所有库和示例的链接时优化 (LTO) 编译器选项。“

这是否意味着在构建应用程序时应对所有 DriverLib 文件禁用 LTO?

我还想获得有关在 F29H85x 上使用链接时优化 (LTO) 的指导。

虽然 LTO 在提高性能方面似乎非常有效、但我担心它会在从 F28x 迁移到 F29x 时对旧代码的影响。

特别是、我观察到、即使是示例中广泛使用的简单延迟函数 (SysCtl_delay) 在启用 LTO 时也可能行为不正确。

从迁移的角度来看、这提出了一个重要问题:
在哪些情况下、建议避免使用 LTO、尤其是在处理旧版嵌入式代码时?

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

    您好、

    我们已确定您提到的问题、下面是修复:

    • sysctl_delay() 被移到一个单独的文件中
    • 定义 修改如下:
    void SysCtl_delay (uint32_t count)
    {
      //易失性、因为此块不“写入“任何内容、否则会“写入“
      //在优化过程中被编译器删除。
      __asm volatile
      (
          “ MV   A14、  %【计数】\n“
          “ SDECB  A14、  1\n“/*  如果使用特殊 SDECB、则无需标签*/
          :              /*未写入输出寄存器*/
          :【计数】“D“(计数)   /*生成 ASM 符号“COUNT“、与 C 符号绑定
                        'count'、并将其与 D 寄存器类*/绑定
          :“A14“           /* A14 被写入,又称为 clubced */
      );
    }
    我们计划在 8 月即将发布的 LTS 版本中为库和示例启用 LTO
    此致、
    Anand
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、此更改 解决了该问题。

    我仍然收到诊断消息 “unknown register name 'A14' C/C++(1118)“、但是工程编译成功、代码在启用 LTO 的情况下运行正常。

    当使用优化级别-O3 时、我在“spi.c“中还遇到另一个问题、这会导致以下错误:“error:耗尽寄存器“。

    本文提到、此问题将在编译器版本 3.0.0.0 LTS 中得到修复。 能否确认此版本何时可用? 是不是在八月份?

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

    您好、

    我没有观察到 “unknown register name 'A14' C/C++(1118)“、您的编译选项是什么?

     编译器中将修复“error:run out of registers“、此错误将作为 LTS 版本的一部分。

    此致、

    Anand

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

    你(们)好

    此警告似乎来自“ms-vscode.cpptools“扩展。

     如果我禁用此扩展、消息将消失。 我认为、此扩展不了解 TI 特定的寄存器名称(如“A14“)、因此会报告错误诊断。

     因此、这似乎是此扩展的 IntelliSense 引擎的限制、而不是编译器问题。

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

    您是否认为可以考虑对 SSU.h 上的 LTS 新版本进行另一项更改?  
    以下结构包含“disable“(禁用)
    结构
    {
    uint32_t lock:1;
    uint32_t rsvd1:11;
    uint32_t start:20;
    uint32_t commit:1;
    uint32_t rsvd2:11;
    uint32_t end:20;
    uint32_t 访问;
    uint16_t rsvd3;
    uint32_t LinkID:4;
    uint32_t rsvd4:2;
    uint32_t disabled:1;
    uint32_t xe:1;
    uint32_t APILINK:4;
    uint32_t rsvd5:2;
    uint32_t APILINKE:1;
    uint32_t rsvd6:1;
    }AP_REGS[96];// 0x000 - 0x5F8

    但是、DISABLE 是一个很常见的宏名称、通常已经在工程中定义过(例如,用于启用/禁用值)。 这可能会在集成库时导致编译问题、因为宏可能会与此结构字段相冲突。

    在参考手册中、此字段定义为“APD“。 是否可以 在将来的版本中将此字段重命名为“APD“以提高与已使用 disable 宏的现有项目的兼容性?

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

    您好、

    当然、我们会考虑该反馈

    此致、

    Anand

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

    您好、

    我请求了更改;它将作为下一个版本的一部分提供

    此致、

    Anand

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

    您好、

    编译器的较新版本 (2.2.1.LTS) 发布、附带针对您所面临的以下问题的修复:
     编译器中将修复“error:run out of registers“、此错误将作为 LTS 版本的一部分。

    PL 从 https://www.ti.com/tool/download/C29-CGT/2.2.1.LTS 安装 并验证

    此致、

    Anand

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

    尊敬的 Anand:

    我测试了新的 C29 编译器 v2.2.1.LTS、并可以确认 SPI.c 中先前的“run out of registers“错误 不再存在。 感谢您的修复。

    我还将运行时性能与 v2.0.0.STS 进行了比较、并在我们的一个函数中观察到了一个小的回归:

    • v2.0.0.STS:9.66µs
    • v2.2.1.LTS:9.85µs

    该差异相对较小 (~2%)、但仅供参考。 该测试对工程 O3 + RAM 函数+ flto + ffast-math + finline-functions 进行了相同的优化。

    此外、我注意到 v2.2.1.LTS 出现了一个新错误、但在 v2.0.0.STS 时未报告该错误。 将 uint32_t *指针(解析为 unsigned int*)传递给定义为 const DT_U32*(内部数据类型)的参数 (解析为 const unsigned long *)时、会发生这种情况:

    “不兼容的指针类型将“uint32_t *“(又名“unsigned int *“)传递到类型为“const DT_U32 *“的参数(也称为“const unsigned long *“)[-Wincompatible pointer-types]“

    在此平台上、两种类型都是 32 位的、此诊断不是使用编译器 v2.0.0.STS 生成的。

    此错误是由于 v2.2.1.LTS 中更严格的类型检查导致的、还是与之前的编译器版本相比、这可能是回归?

    此致、

    Nicolas