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.

[参考译文] TMS320F280039C:memcpy 函数和#pragma CODE_SECTION (".TI.ramfunc")

Guru**** 2482105 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1452210/tms320f280039c-memcpy-function-and-pragma-code_section-ti-ramfunc

器件型号:TMS320F280039C

工具与软件:

尊敬的 Champ:

我要求为我的客户提供服务。

参考这篇文章、  

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1085141/tms320f280049-introduction-to-memcpy-function

由于链接器命令文件 已 创建了一个名为.TI.ramfuncs 的输出节、因此用户 必须 使用手动执行闪存到 RAM 的复制 memcpy  在应用程序中 、Ramfuncs 段中任何函数被调用前的代码。

但从我们的测试中、我们看到#pragma CODE_SECTION (".TI.ramfunc")也具有相同的作用、那就是为 加载到闪存并从 RAM 执行的符号分配空间。

通过尝试 注释掉 应用程序代码中的 memcpy、只需在 ADCC1_ISR 之前保留#pragma CODE_SECTION (ADCC1_ISR、".TI.ramfunc")行 、并在一个地址加载、然后从链接器命令文件中的不同地址运行、如下所示。 在编译的.map 文件中、ADCC1_isr.obj 生于 闪存的加载地址、但仍然映射到 RAM (不使用 memcpy 线)来执行闪存到 RAM 复制。

/* In a C file */

// memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);    // comment out the memcpy

#pragma CODE_SECTION(ADCC1_ISR, ".TI.ramfunc")
__interrupt void ADCC1_ISR( void )
{
    ...
}


/* In a linker command file */
   .TI.ramfunc      : LOAD = FLASH_BANK0_SEC1|FLASH_BANK0_SEC2 | FLASH_BANK0_SEC3 | FLASH_BANK0_SEC4,
                      RUN = RAMLS0_1_2_3,
                      LOAD_START(RamfuncsLoadStart),
                      LOAD_SIZE(RamfuncsLoadSize),
                      LOAD_END(RamfuncsLoadEnd),
                      RUN_START(RamfuncsRunStart),
                      RUN_SIZE(RamfuncsRunSize),
                      RUN_END(RamfuncsRunEnd),
                      ALIGN(4)

1.专家能否澄清#pragma CODE_SECTION (".TI.ramfunc")是否  执行与 memcpy 完全相同的操作来将符号加载到闪存中并从 RAM 执行? 因为看到该符号的.obj 也 映射到 RAM 并从 RAM 执行该符号。

2.如果没有,请解释两个区别是什么?

3.这两个必须绑定并一起使用,让符号从 outpst 节".TI.ramfunc"执行?

如果您能提供任何见解、我将不胜感激。

谢谢。此致、

Johnny

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

    您的理解部分正确。  编译器选项 -- ramfunc 使该文件中的所有函数都放置在名为的段中 .TI.ramfunc .  在编译时、就是这样。  对于一个函数、可以使用执行相同的操作 #pragma CODE_SECTION (".TI.ramfunc") .   

    若要了解链接器命令文件中的代码、请在 链接器命令文件入门  一文中搜索标题为"Load at one Address、Run from a different Address"的部分。  请注意从加载地址到运行地址的复制是不会自动发生的。  在您的情况下 memcpy 必须执行。  否则、是中函数的代码 .TI.ramfunc 不在运行地址、

    谢谢。此致、

    -George.

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

    您好、George:

    感谢您的答复。

    什么是缺省编译器选项--ramfunc 而没有任何选择、在那里留下空格?

    在您的案例中 memcpy 必须执行。  否则、是中函数的代码 .TI.ramfunc 在调用其中一个函数时不在运行地址。[/QUOT]

    如果这里是 w/o memcpy execution 和 w/o compiler option --ramfunc 的情况,这是否意味着虽然它仍然可以  从映射文件中看到在 RAM 中分配了#pragma CODE_SECTION 的空间的代码,在运行时,可能会出现程序计数器在执行函数的代码行时飞出的问题,因为它不在运行地址,对吗?  

    如果还有一个名为 XX 的段也在闪存中的某个位置加载并运行特定的 RAM、显示 GSRAM、那么我是否 需要如下所示的单独 memcpy 行?   

    /* In a cmd file */
    
    XX			: LOAD = FLASH_BANK0_SEC4,
                  RUN = RAMGS0_1,
                  LOAD_START(XXfuncsLoadStart),
                  RUN_START(XXfuncsRunStart),
                  LOAD_SIZE(XXfuncsLoadSize),
                  ALIGN(4)
                  
    /* In a C file */
    
    extern Uint16 XXfuncsRunStart, XXfuncsLoadStart, XXfuncsLoadSize; 
    
    memcpy((uint16_t *)&XXfuncsRunStart, (uint16_t *)&XXfuncsLoadStart, (uint16_t)&XXfuncsLoadSize);

    然后、是否需要在 函数前面为#pragma CODE_SECTION ("XX")添加一行、以便从 GSRAM 执行函数? 或者 、我能否跳过#pragma CODE_SECTION ("XX")行 、然后也实现了从 GSRAM 执行的相同目标。

    我仍然感到困惑、在这里哪个行(memcpy /#pragma)到底是从 RAM 执行的函数、 试图在这里明确说明这一点。

    感谢您的耐心。

    谢谢。此致、

    Johnny

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    默认编译器选项--ramfunc 没有任何选择、在其中留下空格是什么?

    -- ramfunc=on

    如果情况是 w/o memcpy execution and w/o compiler option --ramfunc here、这是否意味着它仍然可以  在 RAM 中看到分配了空间的代码、且映射文件中有#pragma CODE_SECTION、在运行时、它可能会遇到程序计数器在执行函数行代码时飞出的问题、因为它不是正确的地址?  [报价]

    如果有另一个名为 XX 的部分也在闪存上的某个位置加载并运行特定 RAM、则显示 GSRAM、我是否 需要如下所示的单独 memcpy 行?   [报价]

    然后、我是否需要在 函数前面添加#pragma CODE_SECTION ("XX")一行、以便从 GSRAM 执行函数?[/QUOT]

    或者 能否跳过#pragma CODE_SECTION ("XX")行 、然后实现从 GSRAM 执行的相同目标。[/QUOT]

    #pragma 使得编写链接器命令文件代码变得更加容易、这个代码创建包含这些函数的输出段、然后将那个输出段分配到不同的载入和运行地址。  在没有 pragma 和没有 pragma 的情况下、可以实现此操作 -- ramfunc=on .  但它们比较困难。  使用简单的方法即可。

    我仍然困惑哪个行(memcpy /#pragma)恰好从 RAM 执行函数
    [/quote]
    [/quote][/quote]
    [/quote][/quote][/quote]

    您需要两者兼而有之。  可能有几种不同的方法可以进行思考。  我在这里将其分解为3个步骤。

    1. 将所有函数放入同名的段中。  该驱动程序 -- ramfunc=on 、那么这个名字就是 .TI.ramfunc .  另一种选择是申请 #pragma CODE_SECTION 功能。
    2. 编写链接器命令文件代码、以使用该名称创建输出段。  由于所有函数都位于具有匹配名称的输入段中、因此将它们收集到此输出段中。  将该段分配到不同的加载地址和运行地址。
    3. 在  调用任何这些函数之前、请使用 memcpy 将函数的代码从加载地址复制到运行地址。

    谢谢。此致、

    -George.

    [/quote][/quote][/quote][/quote]