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.

[参考译文] TMS320F28386S:闪存内核加载于闪存中、从 RAM 运行。

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1197424/tms320f28386s-flash-kernel-loaded-in-flash-running-from-ram

器件型号:TMS320F28386S

我们需要通过串行闪存编程器开发固件更新的修改版本、因为我们的 TX/Rx 引脚对不在 SCIA 引导的接受列表中。 传输速度也很慢,因为基于 VS C++的串行闪存编程器中的 ReadFile()需要15ms 才能返回每个字节,即使波特率为115200也是如此。

解决方案的一部分是将3个闪存内核(3个而不是4个、因为我们不使用 CPU2)放置在 F28386的闪存中、然后复制到 RAM 并从 RAM 执行。 我不理解运行时设置等的复杂性、因此我必须提出一些愚蠢的问题。

每个内核项目都会生成一个.out 文件和多个目标文件。

Q1:是否可以将.out 文件从闪存复制到 RAM、然后运行?

我认为可能有效的另一种选择是使用来自每个内核项目的目标文件。 例如、flash_kernel_C28x_dual_ex1_c28x1工程会生成7个唯一对象。

问题2:能否在段中像这样指定目标文件? 当然、需要一个复制例程。

部分

(笑声)

flashKernelCPU1:>> FLASH5 | Flash6、运行>> RAMM1

FLASH_kernel_C28x_dual_ex1_sci_flash_kernel_cpu1.obj

FLASH_kernel_C28x_dual_ex1_sci_get_function_cpu1.obj

(笑声)

Q3:如何确定加载、运行和起始地址(函数 main()被剥离)?

我在 TI 文档中看到的另一种链接方法是使用输入段“.TI.ramfunc”来连接需要不同加载和运行地址的代码。

问题4:要使用此概念、是否需要在这些项目中使用以下类似的功能来预处理数十个功能:

#pragma CODE_SECTION (ldfuLoad、".TI.ramfunc")?

 

我们非常感谢您提供的任何帮助或建议、因为我非常期待提供此解决方案。

谢谢、

John

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

    John、

    我相信您不能将.out 文件从闪存"复制"到 RAM、因为.out 文件将由代码、数据等组成 您可以指定要从 RAM 运行的单个函数、正如您在.TI.ramfunc 中所做的那样、然后在初始化代码中使用相应的 memcpy()。

    例如、您可以将一组函数放置在一个名为 isrcodefuncs 的段中、并在链接器命令文件中包含以下内容、然后针对要放置在该段中的每个函数使用相应的 CODE_SECTION pragma。

    在这种情况下、链接器定义了所有符号、如 isrcodefuncsLoadStart、isrcodefuncsLoadSize 等。您可以使用 extern 关键字在代码中使用这些符号。

    链接器命令文件:

    isrcodefuncs:     load = flash_BANK0_SEC8_9_10,

                                           运行= RAMLS5LS6、

                                           load_start (isrcodefuncsLoadStart)、

                                           load_size (isrcodestfuncsLoadSize)、

                                           load_end (isrcodefuncsLoadEnd)、

                                           run_start (isrcodefuncsRunStart)、

                                           run_size (isrcodefuncsRunSize)、

                                           run_end (isrcodefuncsRunEnd)、

                                           对齐(8)

    链接器符号的 extern 声明(例如 device.h):

    extern uint16_t isrcodefuncsLoadStart;
    extern uint16_t isrcodefuncsLoadEnd;
    extern uint16_t isrcodefuncsLoadSize;
    extern uint16_t isrcodefuncsRunStart;
    extern uint16_t isrcodefuncsRunEnd;
    extern uint16_t isrcodefuncsRunSize;

    存储器副本(例如 device.c)

    memcpy (&isrcodefuncsRunStart、&isrcodefuncsLoadStart、(size_t)&isrcodefuncsLoadSize);  

    代码:

    #pragma CODE_SECTION (ISR1、"isrcodefuncs");

    void function_name (…。)

     

    为了进一步优化这种方法、还可以使用编译器提供的-ramfunc 选项来指定所有函数都需要从 RAM 运行。 此选项也可限制为特定源文件。 您将右键单击特定源文件并选择此选项、而不是为项目选择此选项。 我相信这等效于您在 Q2中指出的.obj 选项。 我不知道这种情况的语法。 同样、如果您的可执行文件中有一个要从 RAM 运行的特定库、您也可以执行该操作、同样、我不知道语法-我正在尝试对其进行深入分析。

    有关详细信息、请参阅此处: https://software-dl.ti.com/C2000/docs/optimization_guide/phase3/memory.html#executing-from-ram

    谢谢、

    Sira

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

    哇,Sira! 感谢您提供及时且非常详细的答案。

    您告诉我我我听了什么、将"#pragma CODE_SECTION "添加到所有函数中。 但你也给了我很多好的信息。 我期待着这方面的进展。

    ramfunc 控制将非常有用。 它允许从闪存运行常规应用程序代码、但在更新闪存时、内核可以从 RAM 运行。

    我认为我不需要 isrcodefuncsLoadEnd、isrcodefuncsRunStart 和 isrcodefuncsRunEnd。 您是否被链接器使用? 在映射文件中可能很有趣或有用?

    再次感谢大家。

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

    我注意到许多使用此结构的文件、其中第一个参数是下一个函数的名称。

    #ifdef __TI_COMPILER_VERSION__
        #if __TI_COMPILER_VERSION__ >= 15009000
            #pragma CODE_SECTION(exampleError,".TI.ramfunc");
        #else
            #pragma CODE_SECTION(exampleError,"ramfuncs");
        #endif
    #endif

    您在上面的示例如下所示:

    #pragma CODE_SECTION(ISR1,"isrcodefuncs");
    
    Void function_name(….)
    
    {
    
    }

    ISR1指的是什么?

    谢谢。

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

    John、

    您确实需要我指出的 memcpy()中使用的链接器变量。 是的、您可能不需要代码中的其他代码。

    谢谢、

    Sira

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

    是的、当我从代码复制和粘贴时、这是一个拼写错误。 我尝试将其变为通用、并将 ISR1更改为 FUNC功能性 名称。

    它应该是:

    #pragma CODE_SECTION(function_name,"isrcodefuncs");
    
    Void function_name(….)
    
    {
    
    }

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

    再次感谢。 您能否告诉我为什么将".TI.ramfunc"版本用于较高的编译器版本?

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

    John、

    如果您在项目中使用--ramfunc 选项(或用于特定源文件),链接器在较新的编译器版本(在 v15.9之后)中将这些内容放置在名为.TI.ramfunc 的段中,而不是 ramfuncs。 因此、它希望链接器命令文件定义一个名为.TI.ramfunc 的段。

    如果您将特定函数放在 RAM 中自己的用户定义段中、则此选项不会显示在图片中。

    谢谢、

    Sira

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

    已删除。