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.

[参考译文] TMS320F28388D:如何将 C++虚拟方法表放置在 RAM 中而不是闪存中?

Guru**** 2540720 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1324755/tms320f28388d-how-to-place-c-virtual-method-table-into-ram-instead-of-flash

器件型号:TMS320F28388D

大家好!

我们针对 TMS28388D 上的 CM 内核使用 ARM C++编译器 TI Clang v3.2.0.LTS。

在执行闪存固件更新时、我遇到了问题、因为更新过程所需的一切都不能位于已擦除的闪存扇区中。 在大多数情况下、这很简单-只需将所有必需的函数定义为 ramfunction、即分配到段".TI.ramfunc"。

但现在我遇到了一个包含虚拟方法的类的问题。 方法实现可成功定义为 ramfunction、但事实证明虚拟方法表仍然位于闪存中、在闪存擦除后将0xFFFFFFFF 作为方法指针、并导致调用崩溃。

我尝试放入"__attribute___(section(...))" 进入类定义,希望它将适用于整个类,包括 VMT。 但这不起作用(编译器错误"仅适用于函数、全局变量、Objective-C 方法和 Objective-C 属性")。

我如何将 VMT 移动到 RAM 或将其分配到特定的 RAM 部分?   从映射文件来看、似乎表格位于.rodata 段中。 我不确定是否明智地将整个段移动到 RAM、因为显然它还包含其他常量(最好是(?) 应放置在靠近使用函数的位置-如果我没记错、可能会有一个4k 增量寻址限制)。

此致
克里斯

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

    这篇文章中的所有示例代码都包含在 部分 链接器命令文件的指令。

    如果将创建虚拟表的代码隔离到一个文件中是可行的,那么你可以写一些类似于...

        virtual_tables
        {
            file_name.o(.rodata)
        } > RAM    

    这会创建一个名为 虚拟表 。  该器件包含 .rodata 名为 MSP432的目标文件中的 文件名.o 。   

    如果这是不实际的,那么你可以写...

        virtual_tables
        {
           *(.rodata._ZTV*)
        } > RAM

    这会创建一个名为 虚拟表 。  该器件包含实现 .rodata 子段名称以输入段开头 ZTV 。  这是打破了规则。  所有虚拟表段名称都以 .rodata ._ZTV  是不被视为公共接口一部分的编译器实现的详细信息。  此类详细信息可随时更改、恕不另行通知。  说着,妈妈准备起床了。 ZTV 部分来自所有 Arm 编译器用于改编 C++函数名称、虚拟表等的算法。  很长一段时间以来,它一直是相同的。  我们有理由不希望它很快就会改变。

    谢谢。此致、

    -乔治

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

    感谢您的快速回复。

    同时、我尝试将所有.rodata 都放入 RAM。 这似乎可行、但代价是将宝贵的 RAM 占用不需要的东西、这些东西也可以保存在闪存中。
    您的建议看起来很有希望、因为它可能有助于限制给定.o 文件的 RAM 消耗。

    规格是累积的吗? 也就是说、对于 RAM、我可以首先说"file_name.o (.rodata)"、然后说"*(.rodata)"将所有其他内容都放入闪存?
    software-dl.ti.com/.../sdto_cgt_Linker-Command-File-Primer.html 上的 cmd 文件入门函数 在同一个部分内给出了一个示例(虽然这对我来说似乎是多余的-首先包含 s/BIOS th 特定的、然后是所有内容)。 这种表示法是否适用于各个部分?

    或者、最后一个规范优先(首先刷写所有内容、然后覆盖特定文件到 RAM)?

    此致
    克里斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我能否先说"file_name.o (.rodata)"(RAM)、然后说"*(.rodata)"将所有其他内容放入闪存?

    可以。  您正确地指出此细节。  输入规格 *(.rodata) "贪婪"。  当它被发现时,它发现所有的 .rodata 不属于任何其他输出段的输入段。  因此、该规格 file_name.o (.rodata)  必须首先出现。  无论这些输入规格是在同一个输出段还是不同的输出段中写入、情况都是如此。

    谢谢。此致、

    -乔治

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

    工作得像一种魅力。 感谢您提供快速且简洁的帮助。 非常感谢。

    此致
    克里斯