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.

[参考译文] SDK-AM243X:通过自己的实现覆盖 MCU-PLUS-SDK 功能不能正常工作

Guru**** 2399305 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1499529/mcu-plus-sdk-am243x-overwriting-sdk-functions-with-own-implementation-not-working-correctly

器件型号:AM243X - MCU-PLUS-SDK

工具/软件:

您好:

我们使用的是 MCU PLUS SDK 09.02、因为工业通信 SDK 也使用这个 SDK。 我们当前使用的工业通信 SDK 版本是09.02.00.15。

在 George 的帮助下,我发现了如何用我们自己的实现"覆盖"SDK.functions : https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1383392/mcu-plus-sdk-am243x-not-stripping-symbol-x-because-it-is-named-in-a-relocation/5313715?tisearch=e2e-sitesearch&keymatch=%2525252525252520user%252525252525253A453845#5313715

这一直都很好。 因此、一般来说、我们使用自己的实现覆盖了中止处理程序。 具体的工作方式是在我们的应用程序构建中另外提供实现和 SDK 文件(复制的)。 在链接 SDK 时(在本例中为 SDK 的 FreeRTOS 库)、使用了我们的中止处理程序。 我们的实现将调用 c++-code、因此会放在.cpp-file 内(用 extern "C"包围)。

在 SDK 中如下图所示:


如下所示:

其中"TIABORTImplTIFREERTOS.cpp"包含 Hwip_armv7r_handers_freertos.c-file 的复制代码 (extern "C"周围、并调用 C++代码)。

将.text.hwi 段放置在 TCMA 中、如下所示:

    GROUP
    {
        .text.hwi: palign(8)
    } > MCU1_0_TCMA

如前所述、这种方法效果非常好。 但我们注意到、一旦我们直接链接链接链接器脚本中的 FreeRTOS 库、如下所示:

     GROUP 
    {
        .code:
        {
            -l "freertos.am243x.r5f.ti-arm-clang.debug.lib"(.text),
        }
    } > MCU1_0_SRAM_DATA 

整个.text 段也将移动到这里、并且不会放在 TCMA 中、并且我们完整的中止处理程序实现方案也不存在。 它使用 FreeRTOS 库中的一个。 这在映射文件中也很常见。

我们像这样进行了尝试:

    GROUP
    {
        .text.hwi:
        {
            *(.text.hwi),
        } palign(8)
    } > MCU1_0_TCMA

但这也不起作用。

只有当我们明确地将其放置如下时、它才会起作用:

    GROUP
    {
        .text.hwi:
        {
            -l "libti-implementation-mcu1_0.a"(.text.hwi),
        } palign(8)
    } > MCU1_0_TCMA

我们确保最后按照链接顺序链接 freertos.am243x.r5f.ti-arm-clang.debug.lib。

此行为的解释是什么、是否有方法可以防止在链接器脚本中再次显式链接库? 重点是、包括 SDK 和我们的实现的整个软件包会被多个工程使用、如果 freeRTOS 库明确放置在某个位置、我们不希望修改每个工程中的每个链接器脚本。 我们还尝试尽量减少对 SDK 文件的修改、而是在软件包中提供自己的实现。

此致

Felix

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

    您好 Felix:

    哪个库文件包含您的实现? 是 freertos.am243x.r5f.ti-arm-clang.debug.lib 还是 libti-implementation-mcu1_0.a?

    您的代码实现位于中  libti-implementation-mcu1_0.a  文件中、将完整的库放入 TCMA、就像对.text .hwi 所做的那样。

    此致、

    Tushar

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

    尊敬的 Tushar:

    是的、我们的实现就在内部 libti-implementation-mcu1_0.a 。 内部还有更多可能无法放置在 tcma 内的部分、这就是我们仅引用.text.hwi-section 的原因。

    但这对我们来说只是一种权变措施。 问题是、如果我们引用 freertos.am243x.r5f.ti-arm-clang.debug.lib 的.text 段、但不在链接器脚本中解释我们的库、则我们自己的实现方案将被丢弃。 它似乎也包含所有子段、例如 freertos.am243x.r5f.ti-arm-clang.debug.lib 的.text.hwi、因此是中止处理程序的实现。 如果我们没有显式链接 libti-implementation-mcu1_0.a 在链接器脚本中、链接器根本不会使用我们的实现。

    我的意思是、从技术上讲、我可能理解链接器在这里的作用、但我的问题是、我们是否能够以某种方式阻止额外显式链接 libti-implementation-mcu1_0.a 元素? 因为它已经与链接器命令链接、所以我们不会获得有关我们的实现被丢弃的任何信息。
    这种链接器行为真的很容易出错、因为如果我们覆盖了 SDK 的任何实现、这会静默丢弃我们的实现。 例如、如果我们要将 SDK 的驱动程序库放置在某个位置、但我们在 SDK 之外使用自己的实现对驱动程序进行了一些修改。 如果未在链接器脚本中再次显式引用这些警告或消息、也会丢弃这些警告或消息。 这可能会破坏我们的整个固件。

    再次要明确一点:如果我们不解释在链接器脚本中引用 freertos.am243x.r5f.ti-arm-clang.debug.lib、覆盖功能就可以正常工作。
    还让它更容易理解:我们的目标是为多个工程提供一个平台、因此用户只需使用一个完整的软件包、其中包含 SDK 以及我们的实现、它们可能会覆盖 SDK 的某些部分。 用户不知道也不应该知道是否覆盖 SDK 实现、因为他/她只是想使用软件包并依赖其功能。 将 SDK 库显式放置在存储器中的位置不应导致只丢弃覆盖实现的行为。 它应该只需将.text 段放置在用户定义.text 段的位置、无论库的.text 段是否放置在其他位置都是如此。 我的意思是、如果可以使用*(.text.hwi)解决方案、我们完全可以使用它、但它不能使用。 我们仍需要显式链接包含覆盖的库。

    是否有可能实现这一目标?

    我在以下在线文档中尝试了更深入地理解 TI 的 CLANG 链接器: https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/linker_description/05_linker_command_files/accessing-files-and-libraries-from-a-linker-command-file-spnu1185422.html

    此处的特殊子段处理(https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/intro_to_object_modules/how-the-assembler-handles-sections-stdz0693935-add.html#subsections)指出:
    "默认情况下、当链接器在链接器命令文件(如".text")中看到一条 SECTION 指令时、 它将.text 和.text 的所有子段收集到一个名为".text"的大型输出段中 。 您也可以使用 SECTION 指令分别控制子段。 有关示例、请参阅 SECTIONS 指令语法。"

    我明白这一点。 因此、链接器的作用在中是完全有意义的 默认情况 。 但第二句话是说、我可以完全使用此段指令来独立控制子段。

    如果我们看这里(https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/linker_description/05_linker_command_files/the-sections-directive-stdz0759595.html#specifying-input-sections):
    "规范*(.text)表示所有输入文件中未分配的.text 段。"

    我想这两个子段已从 freertos.am243x.r5f.ti-arm-clang.debug.lib?分配 (.text.hwi)不会考虑它们、对吧? 但为什么呢? 我猜、上述库对于链接器具有更高的"优先级"、子段将自动包含在其中。 只有在之后、库之外的所有其他.text.hwi-sections 才会链接到.text .hwi-input-section 的放置位置。

    还有其他章节用于包含库、但如果在提到的库之外存在对同一子段名的通配符引用、这些章节不会涵盖如何处理子段的情况。

    因此、如果在链接器脚本中的其他位置已经提到了库的同名子段、是否有可能以某种方式告诉链接器不要使用该子段? 或者是否有任何其他解决方案可以实现这一点而不会意外删除我们所有的覆盖实现?

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

    我已将此线程提请编译器专家注意以进行进一步分析。

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

    请注意、我无法测试我在此主题中提出的建议。   

    每当链接器在命令行或命令文件中看到指定的库时、它都会使用该库中的文件来解析对符号的引用、这些符号在链接中的那个时刻未解析。  因此、在链接器命令文件中命名库往往会令人困惑、应避免这样做。

    请参阅 在线文档的这一部分 以了解相关信息 --- reread_libraries --优先级 。  控制 多个库顺序的典型方法是使用 --优先级 、并按所需顺序在命令行中指定库。

    这种做法是否可行?

    谢谢。此致、

    -乔治

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

    嘿、George、

    感谢您的提示。 它澄清了一些情况,是的,我们确实使用--reread_libs-option。 为了正确起见:链接器使用命令行中的库。 如果引用了未定义的符号并且链接器在库中找到这些符号、它们将会被解析。 然后它将处理链接器命令文件(?)。 如果仍然有未解析的符号、它将使用--reread_libs-option 再次读取库。 我知道在命令文件中提及库会造成混淆、但有时需要将代码放置在更快的存储器器件中、尤其是在使用具有 TCM、内部 SRAM 以及外部 RAM 的 ARM 内核时。 我们可以减少但永远不能完全避免。

    链接器命令文件中是否还有处理顺序? 这里需要注意的是、矢量表中引用了中止处理程序和 irq-service-roadery、该矢量表仅放入链接器命令文件中的0x00000000-address。 矢量表也是我们库的一部分、链接顺序中首先提到该矢量表。 向量表被放置在 SDK 的复制文件中、如下所示(符号在右侧提到、"HwiP_DATA_ABORT_HANDLER "等等):

    我检查了链接命令、首先链接包含我们实现的库、因此也链接了引用我们的中止处理程序实现的矢量表。  带有矢量表和中止处理程序的 SDK 实现的 FreeRTOS 库最后链接。
    因此、我预计*(.text.hwi)会首先出现在链接器命令文件中、在提到的 freertos-library (也包含相同的符号)之前会引用它们并将它们放入 tcma 中。 但我需要明确提及我们的库。
    这是我不明白的一点。 因为符号和矢量表已经存在、并呈现给链接器、在 FreeRTOS 库之前。 从链接器命令文件中删除 FreeRTOS 库将再次使用我们的实现。

    因此、链接器命令文件中的库似乎具有更高的优先级。 或者我真的不知道在链接顺序中的哪个阶段使用命令文件。

    此致

    Felix

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

    您好:

    请注意,由于某些假期/假期,可能需要几天的时间才能得到答复。

    谢谢你

    Ki

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

    我认为大多数困惑来自试图同时解决这些不同的问题。

    1. 哪个库用于解析对函数的调用?
    2. 如何 将库中的函数分配到特殊存储器中?

    最好单独解决这些问题。   

    要求解#1...请停止使用 -- reread_libs 连接和使用 --优先级 相反。  然后按所需顺序在命令行中指定库。   

     我想,我是真的爱你。  TIAbortImplTIFREERTOS.cpp 是您实现的一个文件。  它最终成为自定义库中的目标文件。  它定义了一个名为的输入节 .text.hwi 。  将此输入段的名称更改为类似的内容 .text.custom_hwi 。  这样做的代码类似于...

    __attribute__((section (".text.custom_hwi"))

    这意味着您需要在链接器命令文件中分配代码 .text.custom_hwi 。  据我所知、您不想更改现有的链接器命令文件。  而不是,提供另一个链接器命令文件与类似的行...

    SECTIONS
    {
        .text.custom_hwi > MCU1_0_TCMA, palign(8)
    }

    该附加链接器命令文件假定一些其他链接器命令文件定义了名为 MCU1_0_TCMA 的存储器范围。   注意支持在不同文件中指定多个段指令。

    谢谢。此致、

    -乔治

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

    谢谢您的回答、George、

    我们将首先尝试第二个选项,并在长期做第一个选项,因为我们的项目增长真的很大,-- reread_libs 解决了我们面临的问题。 您知道短期解决方案在某些项目中持续的时间有多长...

    在尝试之前、有一个问题需要更好地理解:
    为什么*(.text.hwi)-input-section 不采用我们已链接库的.text.hwi、或者在遇到 freeRTOS 库时以某种方式丢弃它们、以及为什么显式链接我们的库 libti-implementation-mcu1_0.a 效果

    .text.hwi:
            {
                -l "libti-implementation-mcu1_0.a"(.text.hwi),
            } palign(8)

    再次工作? 我假设*正在捕获 libti-implementation-mcu1_0.a 因此在本例中的工作方式与*相同。 我想它与"-l"有什么关系?

    此致

    Felix

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    为什么*(.text.hwi)-input-section 不采用我们已链接库的.text .hwi、或者在遇到 freertos-library
    时以某种方式丢弃它们

    可以肯定的是、我需要查看有关该链接的更多详细信息。  但我有信心这...

    每当链接器在命令行或命令文件中看到指定的库时、它都会使用该库中的文件来解析对链接中该点未解析的符号的引用。

    ...解释。

    谢谢。此致、

    -乔治