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.

[参考译文] TMS320C6678:对外部存储器进行分区以存储程序代码

Guru**** 2589300 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/587483/tms320c6678-partition-external-memory-to-store-program-code

器件型号:TMS320C6678

大家好、

我尝试将一些函数移动到外部存储器、因为我的程序非常大、内部存储器现在还不够。 八个内核使用的程序可能不同、因此我需要外部存储器的八个分区、每个分区将用于每个内核。 我进行了搜索、有一个建议是使用预定义内核 ID 创建八个编译配置、然后使用用户连接器命令文件将每个内核的代码段放置到八个不同外部存储器段中的一个。 但是、这种方法不适合我、因为我的项目要求每个版本我只能有一个具有一个编译配置的项目来创建一个 bin 文件。

我是否可以通过任何方法将每个内核的代码放入只具有一个项目和一个构建配置的不同外部存储器段之一?

提前感谢、

Chanh  

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

    据我所知、仅使用一个构建、您必须在所有内核上使用单个映像(相同代码)、每个内核只执行部分代码。

    这意味着:
    不能为指定在不同内核上执行的两个不同例程指定相同的名称(您将获得多个定义的符号)、但您会自动重复使用通用代码
    2.代码使用的逻辑地址对于所有内核都是相同的,因此在 L2 SRAM 上分配的变量将自动为每个内核专用(如果将 L2用作 RAM),而在共享存储器上分配的任何变量(MCSM 或 DDR) 默认情况下为共享

    第一个约束可以通过仔细编写源代码来解决、而逻辑数据地址重叠问题取决于您计划如何组织数据、如果您希望将 L2用作存储器或高速缓存、并且可能会受到您使用的 RTOS (SYS/BIOS?)的限制

    在这种情况下、您对代码存储器分区不会太在意、但您必须专注于数据存储器分区和逻辑到物理地址转换、以允许每个内核使用相同的逻辑数据地址来访问不同的物理数据。

    如果使用 SYS/BIOS、请查看:
    processors.wiki.ti.com/.../BIOS_on_Multi-Core_singleimage application&tisearch=Search-ZH
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Alberto、

    感谢您的回复。 我觉得我没有清楚解释这情况。

    我的项目只能在8个内核上运行一个或多个 bin 文件。 假设:
    - Bin_file_1包含 Lib_A 和 Lib_B
    - Bin_file_2包含 Lib_A 和 Lib_C
    - Bin_file_3包含 Lib_A 和 Lib_D
    -等等...

    lib_a 对于所有 bin 文件都是通用的、根据具体情况、没有规则在哪个内核上运行哪个 bin 文件。 我只能维护1个项目来构建一个 bin 文件(例如、PROJECT_1用于构建 Bin_file_1、Project_2用于构建 Bin_file_2等)

    现在问题是我的程序非常大、L2存储器不够、并且要求不同的 bin 文件可以使用不同版本的 lib_a、因此我计划将 lib_a 的某些函数移动到外部存储器的分区、 每个内核的分区必须不同。

    因此、对于如何将每个内核的代码段放入只具有一个工程和一个编译配置的不同外部存储器段之一、您有什么建议吗?

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

    因此、您需要 N 个内部版本、其中 N 是不同 exe 的数量、与执行内核无关。

    您是否已经考虑过 TI MAD 实用程序(processors.wiki.ti.com/.../MAD_Utils_User_Guide)

    如果您从不在多个内核上同时执行相同的 exe、则可以定义 N 个分区(在链接器文件中)、每个 exe (而不是每个内核)对应一个分区、并且每个 exe 应该能够在您选择的内核上运行、 一般而言、无需为特定内核构建。

    您还可以对所有 exe 使用相同的存储器分区(为代码和共享存储器中映射的数据保留逻辑地址),但必须在加载内核之前将逻辑地址重新映射到 N 个物理分区, 因此、您的加载程序需要运行时支持。

    这样、您就可以在多个内核上运行相同的代码、但在内核之间传递逻辑地址的指针时必须注意

    例如,假设您在0x8000000000-0x80100000 (1M)定义逻辑分区,则 N 个物理分区:
    0x80000000+N*0x00100000
    逻辑地址处的所有 exe 链接。 在执行代码之前、您必须初始化 MPAX 条目(请参阅 CorePac 手册 SPRUGW0)、以便根据内核编号从逻辑重新映射到物理。 您的加载程序必须知道如何将逻辑程序部分移动到物理程序部分。

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

    是的、我有 N 个程序、其中不同的程序仅在 Lib_B、Lib_C 上(如上例所示)、每个程序将有几个版本。 根据应用程序的不同、在每个内核上运行的程序可能相同或不同。

    将逻辑地址映射到多个物理地址、其中一个内核将保留一个物理地址、这似乎是我的方向。 但是、由于我的程序数量不受限制、因此我参考为8个内核定义8个存储器分区。 如何在代码执行之前初始化 MPAX 条目? 您是说我可以使用 MAD 工具实现这一点吗? 我正在检查 MAD 工具、如果您有任何建议或示例、请与我分享。

    对于我的项目、bin 文件将使用 SRIO 下载到每个 DSP 内核(取决于应用、可以将 bin_1下载到所有内核;或将 bin_1下载到 core_0、将 bin_5下载到 core_3、等等)。 您是否通过"加载 exe"来询问?

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

    当我询问加载程序时、我的意思是如何复制每个内核存储器中的可执行文件。
    作为一般模式、对于每个内核、您必须:
    1.为内核 N 将 MPAX 设置为逻辑与物理之间的映射
    2.通过 SRIO 加载代码
    3.启动从站内核,作为第一个操作(在从站中),将内核 MPAX 寄存器设置到专用内核分区

    要为每个内核设置 MPAX、必须使用自定义例程覆盖默认入口点、以:
    a.更改 MPAX
    b.跳转到标准启动例程(c_int0)

    请注意、不能使用 directio 加载代码、因为 directio 始终使用物理地址并绕过 MPAX 映射。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Alberto、

    我现在正在查看我的程序启动顺序(因为它是由另一个人开发的)。 到目前为止、我可以看到程序是通过 SRIO 加载的。 但是,似乎 MPAX 是在代码加载后完成的(因为设置 MPAX 寄存器的函数在 main()函数内调用)。

    您能否提供更多有关如何使用自定义例程覆盖默认入口点以更改 MPAX 并跳转到标准启动例程(c_int0)的建议? 很抱歉、我对该 DSP 非常陌生。

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

    您好!

    要覆盖入口点、请首先添加链接器选项"-entry_point custom_boot"。 由于这将是第一个要执行的例程、因此您必须设置最小的 C 运行时支持、即栈。 查看 TI libc 源文件(包含在 CCS 中)中的 boot.c 文件:

    extern void _c_int00 (void);
    
    __asm ("\t.global __TI_stack_end");
    __asm ("\t.global __TI_static_BAS");
    
    void __interrupt custom_boot (void)
    {/t/Stack
    setup for EABI},来自 TI _c_int00
    ()源代码_ mvstack、t_stack
    t_t
    ~、t_stack 4、t_stack t_t、t_mvr t_stack t_t、t_stack t_t、t_stack
    __asm ("\t MVKL\t\t __TI_STATIC_BASE,DP");
    __asm ("\t MVKH\t\t __TI_STATIC_BASE,DP");
    
    //使用 DNUM 和链接器命令文件中定义的硬编码地址或地址重新映射逻辑到物理地址 
    … _c_int00 ();//标准 TI 入口点 }

    由于尚未调用 C 初始化例程、因此您只能使用栈、使用引导编译单元(函数调用)或数据段中存储的常量数据外部的其他代码是不安全的。 无论如何、可以编写一个 MPAX 初始化代码、该代码仅使用在文本段中编码的值(即硬编码的整数字面量)。

    为了理解和验证您的代码,我建议您为单核准备一个小原型以在 EVM 上进行测试,并在 custom_boot()中重新映射之前添加 memcpy (physicial、logical、size_partition)。 libc memcpy()使用起来不安全(取决于它的位置),因此应将复制代码直接内联到 custom_boot()中。

    请注意、在引导加载程序中、您也可以使用相同的技术: 在每次内核加载后、将逻辑复制到每个内核的物理上、而不是使用 MPAX。

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

    很抱歉耽误你的回答。 Alberto、感谢您提供有关此主题的意见。

    根据我从您的解释中了解到的内容、每个 exe (每个内核)有一个项目。 这使得操作比具有不同构建配置的单个工程更简单。 为了对存储器进行分区、您可以创建一个链接器命令文件、其中如果在8个内核之间进行分区、则整个存储器空间都不会使用与分配给不同内核的存储器重叠的存储器区域。 使用针对 DSP 内部存储器的全局寻址、这样您也可以将它们单独添加到存储器部分。
    这同样适用于 TI RTOS、您可以创建定制平台配置、其中 MSMC 和 DDR 空间针对所有内核进行了分配、每个内核仅使用分配给它的存储器部分。

    如果您希望在多个内核之间维持库的单个副本、但会给项目增加大量的复杂性、因为这些工具具有复杂的构建步骤、并且该工具使用解析器和链接器创建图像的方式并非直接的 更好的理解。 n`t 您不介意维护库的多个副本、我将避免使用此工具。

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

    非常感谢您的回复。

    我的项目只需要维护一个副本。 现在、我的解决方案是在程序的早期状态配置 MPAX 寄存器。

    MAD 工具功能强大、但复杂、我不熟悉。 我打算研究一下、看看将来是否可以将其用于我的项目、但我希望可能需要一些时间。

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

    非常感谢您的建议、

    我可以更改入口点、但此时配置 MPAX 寄存器并不容易、将来也不容易维护。 因此、我计划在 xdc.runtime.Startup 上配置 MPAX、以便我可以使用 CSL 库中定义的结构和宏。 这似乎对我很有效。

    此致。
    Chanh