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.

[参考译文] 编译器/MSP432P401R:MSP432中的RAM函数(后续问题)

Guru**** 2529560 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/579376/compiler-msp432p401r-ram-function-in-msp432-followup-question

部件号:MSP432P401R

工具/软件:TI C/C++编译器

TI论坛社区您好,

 我收到编译器警告,表示库调用"sprintf"是POWER不可恢复的,我应该将函数移到RAM中。

 我在本论坛中找到的关于此主题的示例和链接指的是非图书馆,即"我自己的代码"。

 如何将以下内容添加到获取参数并返回值的库调用中?

__attribute___((ramfunc)
void f (void){...}

谢谢!  

Bob s

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

    以下两个链接均指MSP430的ULP Advisor,而不是MSP432。  但几乎所有信息都适用于这两种设备。

    谢谢,此致,

    -George

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

    我正在查看网页上的"ULP顾问规则5.3 :

    "将以下行添加到链接程序命令文件中,以将这些对象重定向到flash_execute//RAM_execute区域
    ...
    text:rts430-lib_printf:{ RTS*.lib<*printf.obj>(.text)} load = flash_execute,run = RAM_execute"

    “帮助”是2013年的,我使用的是CCS v 6.1 3 (2016?),似乎已过时。
    即,CCS由菜单驱动后,“链接器命令文件”在哪里?

    选择项目->属性会显示一个复杂的选项菜单,其中包括MSP链接程序,基本选项和高级选项。
    高级选项提供命令文件预处理功能,但仅提供定义预处理程序宏的功能。
    还有其他选项:运行时环境,链接时间优化和其他,但我不确定...

    是否有任何帮助?

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

    Robert Schaefer 说:
    将以下行添加到链接器命令文件

    链接程序命令文件是项目中的另一个源文件。  它的名称类似于 msp432p401r.cmd。  这是您应该修改的文件。

    有关链接程序命令文件的一般了解,请参阅Wiki文章 链接程序命令文件入门

    链接程序命令文件将包含类似于...的行。

    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>= 1500.9万
    .TI.ramfunc :{} load=main, run=sRAM_code, table(BINIT)
    #endif
    #endif 

    IF行检查编译器版本符号是否可用,编译器版本是否大于或等于15.9 .0.LTS。  第3行创建名为.ti.ramfunc的输出部分。  它由名为.ti.ramfunc的所有输入部分组成。  这是编译器用于标记有ramfunc属性的函数的部分的名称。  它在主存储器范围内分配了用于加载的空间,并在SRAM_CODE存储器范围内分配了用于运行的空间。  在BINIT表中输入一个条目。  BINIT表由系统启动代码处理。  此处理将此输出部分从主位置复制到SRAM_CODE位置。

    下一步是对该代码进行更改,以便出现类似这些行的内容...

    .text:rts430-lib_printf:{ rts*.lib<*printf.obj>(.text)} load = flash_execute,run = RAM_execute

    这第一个变化只是最终解决方案的中间步骤。  将.TI.ramfunc行更改为这些行...

    .ti.ramfunc:
    {
    *(.ti.ramfunc)
    } load=main,run=SRAM_CODE,table (BINIIT)
    

    这与以前完全相同。  行*(.TI.ramfunc)表示以.TI.ramfunc名收集所有输入部分。  此更改的目的是在语法中创建一个点,以便在其中添加库输入部分的条目。  看起来像这样...

    .ti.ramfunc:
    {
    --library=RTS*.lib<*printf*.obj>(.text)
    *(.ti.ramfunc)
    } load=main,run=SRAM_CODE,table (BINIIT)
    

    第3行是新增内容。  --library选项告诉链接程序输入文件不在当前目录中,而是在使用--include_path (或-i)选项列出的目录中。  语法RTS*.lib表示使用以RTS开头,以.lib结尾的任何输入文件。  查看链接程序映射文件以查看使用的RTS库。  您将看到类似 rtsv7R4_T_be_eabi.lib的内容。  语法<*printf*.obj>(.text)表示使用RTS库中具有名称printf的文件中名为.text的所有输入部分。  例如,sprintf.obj。  

    谢谢,此致,

    -George

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

    谢谢你。

    我终于找到了链接程序命令文件。 因为我用一个示例项目的副本开始我的项目,它的名称是原始项目的名称-这与我现在的工作无关,所以它总是存在,我只是忽略了它,因为我不知道该文件是什么。

    新问题,链接器在您给我的缺口上消失。

    但是,由于我使用CCS两次,在Mac上的桌面上编译,然后在Windows框上重新编译以到达目标,因为只有Windows框可以与XDS200 JTAG调试器配合使用,

    我有另一个.cmd文件可以查看。 在Windows框中,链接程序修改为:

    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>= 1500.9万
    别名

     SRAM_CODE (rwx):原始= 0x100万
     SRAM_DATA (RW):原点= 0x2000万
    }长度= 0x1万
    #否则
     /*提示:如果用户要使用ram功能,请注意SRAM_CODE */
     /*和SRAM_DATA存储器区域重叠。 您需要采取措施分离*/
     /* RAM中代码的数据。 这仅对早于15.09 .0.STS.*/的编译器版本有效
     SRAM_CODE (rwx):原始= 0x100万,长度= 0x1万
     SRAM_DATA (RW):原点= 0x2000万,长度= 0x1万
    #endif

    当我将以上行重新安装到Mac版本的CCS时,链接成功。 因此,下一步是添加:  

    .TI.ramfunc :{} load=main, run=SRAM_code, table(BINIT) 

    但是,我不知道在哪里添加该行。 我将其放在别名上方,链接步骤失败。 我将其放在“别名{"之后,链接步骤失败。 我将其放在端括号后},链接步骤失败。

    我会提供一条错误消息,但错误消息会根据我在何处发表声明而发生变化。 

    接下来应该尝试什么?


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

    我假定您的链接程序命令文件已经有一个类似于的行  

    .TI.ramfunc :{} load=main, run=SRAM_code, table(BINIT) 

    如果不是这样,那么使用我所描述的更改是没有意义的。

    我为什么会这样想呢?  当您在CCS中启动新项目时,您需要指明您使用的是哪种设备。 根据此选择,将自动设置许多详细信息。  其中包括链接程序命令文件。  对于诸如MSP432之类的ARM设备,所有链接器命令文件都来自类似的目录...

    C:\ti\ccsv7\css_base\arm\include 

    我检查了此目录,只找到了2个MSP432的链接器命令文件。  这两种方法都有相同的.TI.ramfunc线。  因此,我假定您的链接程序命令文件具有此行,并从该处开始工作。

    此时,我不确定您有什么链接程序命令文件,或者应该如何更改它。  请将原始链接器命令文件附加到下一篇文章中。  添加文件扩展名.txt,否则论坛将拒绝它。

    谢谢,此致,

    -George

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

    很抱歉回复太晚,由于某些原因,我在您回复后未收到电子邮件,上周被跟踪。

    e2e.ti.com/.../uart_5F00_loopback_5F00_24mhz_5F00_brclk_5F00_ccs.txt

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

    我建议的更改位于本文末尾附加的链接器命令文件中。  虽然我不能测试这些变化,但我非常有信心它能奏效。  主要错误是您在内存指令中有一个节规范。  

    一个更好的修复…… 您似乎从某些TI软件包中获得了此文件。  更新到该软件包的最新版本,并使用此处找到的链接程序命令文件。

    谢谢,此致,

    -George

    e2e.ti.com/.../update.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你。 您附加的文件提供了线索/解决方案。
    我要对内存部分进行更改,更改必须在分区部分进行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发言太快了。 只是因为它链接并不意味着它可以运行。
    使用XDS200调试器时,我看到代码在进入其第一个sprintf时立即消失。
    回顾项目构建,我在表(BINIT)中看到一条警告,
    "../linker _directions.cmd",第85行:警告#1.0068万-D:没有匹配的部分
    警告#1.0247万-D:创建不带书帖规范的输出书帖".binit "
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    binit输出部分包含一个复制表,处理该表的目的是将.ramfuncs输出部分从主存储器范围复制到SRAM_CODE存储器范围。  此诊断...

    Robert Schaefer 说:
    警告#1.0247万-D:创建不带节规范的输出节".binit "

    ...意味着.binit在系统内存中分配,无需您的任何指导。  因此,它可能被错误地分配。  

    当我查看MSP432设备的类似链接器命令文件时,我看到此行...

    二进制 :>主页 

    因此,请先尝试一下。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    一个错误已删除,一个新错误。
    下面是文件中的内容,希望我没有添加拼写错误:

    二进制 :>主页
    #ifdef __TI_Compiler_version__
    #if __TI_Compiler_version__>= 1500.9万
    .ti.ramfunc:

    --library=RTS*.lib<*printf*.obj>(.text)
    *(.ti.ramfunc)
    } load=main,run=SRAM_CODE,table (BINIIT)
    #endif
    #endif

    现在编译错误为:
    "../linker _directions.cmd",第86行:警告#1.0068万-D:没有匹配的部分

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

    请在看到“无匹配部分”警告后附加所获得的链接器映射文件。  与以前一样,添加文件扩展名.txt。

    谢谢,此致,

    -George

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

    附加了链接程序指令文件。

    e2e.ti.com/.../linker_5F00_directives.txt

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

    抱歉,您发送了错误的文件。  您发送了链接程序命令文件。  我需要链接器映射文件。  它是由链接程序自动生成的文本文件,文件扩展名为.map。

    谢谢,此致,

    -George

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

    第二个trye2e.ti.com/.../RapidEnergyUnit.txt

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

    映射文件中包含这些行...

    .ti.ramfunc
    * 000008 00008c5万 0000.117万 运行ADDR = 100万
    0.0008万c50 000000605万00060</s>0.006万 rtsv7M4_T_le_v4SPD16_eabi.lib:sprintf.obj (.text)
    0.0008万cb0 00001110000001110 :_printfi.obj (.text) 

    这说明.TI.ramfunc输出部分从加载地址0x0.0008万c50开始,运行地址为0x100万。  它只有两个输入部分,即rtsv7M4_T_le_v4SPD16_eabi.lib中printf相关函数的.text输入部分。

    您得到“没有匹配的部分”警告,因为链接程序命令文件中的此行...

    *(.ti.ramfunc)
    

    ...对应于无输入部分。  不能使用选项--ramfunc进行构建,也不能将ramfunc属性应用于任何函数。  ARM编译器手册中介绍了这两种功能。  搜索ramfunc以查找详细信息。  如果您不打算将函数置于RAM中,则可以忽略该警告。

    谢谢,此致,

    -George

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

    您好,George,

    现在我比开始时更困惑。

    让我从开始。

    当我编译时,我收到警告:“Detected sprintf() operation(s)。 建议在运行期间或不使用时将它们移至RAM,因为它们需要处理/耗电。"

    请假设我没有线索,即使 编译器手册中有一个解释,即我不理解如何将 手册说明映射到CCS按钮对按。

    但是如果我可以在CCS工具 抽象功能的“属性”迷宫中的某个位置找到--ramfunc开关,那么所有库函数是否都将被移动到RAM中,并且我不需要向 链接器命令文件添加其他语句?

    Bob s

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

    您的总体目标是什么?  这将帮助我了解需要关注的方面。

    ULP建议的总体目标是帮助您降低系统的功耗。  与闪存相比,它需要较少的电源来执行SRAM。  因此,将使用更多周期的函数放在SRAM中是有意义的。  如果您的系统调用sprintf,则可以合理地假定这需要大量的周期,因此将该例程置于SRAM中是有意义的。

    我们讨论的大部分内容都涉及如何在SRAM中获取sprintf (和相关函数)的详细信息。  我怀疑您可能不知道下一部分。  Sprintf例程实际上在闪存中启动。  在系统启动期间,.binit部分中的信息用于将闪存复制到SRAM。  对于系统执行的其余部分,sprintf出现在SRAM中,就像它一直存在一样。

    链接程序命令文件中排列此内容的行如下:

    .TI.ramfunc :
    {
    --library=RTS*.lib<*printf*.obj>(.text)
    *(.TI.ramfunc)
    } load=main,run=SRAM_CODE,table (BINIT)
    

    第1行将输出部分命名为.TI.ramfunc。  第3行说明将RTS库中文件的所有.text部分用作输入部分,文件名中包含printf。  更具体地说,这仅适用于代码实际调用的RTS库中的printf函数。  第4行表示包括任何名为.TI.ramfunc的输入部分。  稍后将介绍更多信息。  第5行说明要将此输出部分分配给主内存范围以进行加载,将此输出部分分配给SRAM_CODE内存范围以执行,并在BINIT复制表中放置一个条目。  BINIT复制表由启动代码自动处理,以将此输出部分从main复制到SRAM_CODE。  在这种特殊情况下,表条目具有.TI.ramfunc输出部分的加载地址,运行地址和长度。  BINIT表项的位置位于名为.binit的不同输出部分中。  虽然名称相似,相互关联,但请将其视为单独的内容。  BINIT是一个复制表,而.binit是包含它的输出部分。

    更多信息在第4行... 您可能会感到困惑的是,输出部分名为.ti.ramfunc,还有一些名为.ti.ramfunc的输入部分。  可以重复使用这样的节名称。  事实上,这是很常见的。  即使名称相同,也不要失去输入部分和包含它们的输出部分之间的区别。

    更多信息请在第4行...  你得到一个关于这条线的诊断"没有匹配的部分"。  您必须没有名为.TI.ramfunc的输入部分。  有两种方法可以获得名为.TI.ramfunc的输入部分。  如果使用选项--ramfunc进行构建,则每个函数都位于.ti.ramfunc输入部分中。  鉴于您的SRAM有限,这可能不是您想要的。  另一种方法是应用ramfunc函数属性。

    __attribute___((ramfunc)
    void function_name(void){/*
    
    此处为代码*/
    } 

    使用此方法,您可以选择哪些功能进入SRAM。  是否将您自己的任何功能实际置于SRAM中取决于您。  如果您决定否,则可以忽略"无匹配部分"警告。

    谢谢,此致,

    -George