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.

[参考译文] TM4C1294KCPDT:CCS 添加 ARM pragma 数据段会创建巨大的 bin 文件

Guru**** 2549170 points
Other Parts Discussed in Thread: TM4C1294KCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179026/tm4c1294kcpdt-ccs-adding-arm-pragma-data-sections-creates-huge-bin-file

器件型号:TM4C1294KCPDT

您好!

内存分配显示通过6个 pragma 语句将闪存函数的一部分移动到 RAM 后、编译的工程低于1兆字节。 但是、编译后的 bin 文件增加到了512MB、最初为106KB、而未通过#pragma 将函数从闪存移动到 RAM。 为什么*。out 文件大小934KB 相对较小、为什么内存 分配工具显示的 bin 文件大小要小得多?

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

    请参阅文章 二进制文件简介。  除其他外、它还说明了二进制文件如何变得非常大、以及如何避免该问题。

    谢谢、此致、

    乔治

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

    尊敬的乔治:

    为什么您没有回答这些问题或其中的任何部分?

    我不需要介绍二进制文件。 该项目是相同的、只有部分器件通过#pragma 从闪存移至 RAM。 CPU 和堆栈指针应处理入栈/出栈跳转和调用 far 的返回地址。 在我看来、IP 比调用更容易、只需移动到不同的存储器地址。  这是 CPU 的函数、用于通过调用栈和 IP 来了解程序的一部分在存储器中的位置。 C2000 CPU 上没有创建的所有 ARM trampoline 是什么?

    内存分配工具仅在 hex2bin.exe 运行后才不同意已编译的 bin 文件大小、该文件大小从106KB 增加到524MB。 其他情况出错了、没有警告这些段是 C2000编译器生成的无效 trampoline。 此外、添加了链接器命令--minimize_trampoline 无效、在以黑色文本添加的每个新段中都有50个或更多内容。 如映射文件中所示、一些空穴是可以接受的。

    然而、闪存和 RAM 中的应用程序的大小与输出 bin 文件的大小完全不同。 只有在编译完成且没有错误的情况下、并且为闪存加载创建了 hex2bin.exe 后、内存分配工具才会反映编译。

    请注意、甚至添加了一个 pragma (ISR 函数) bin 文件 、该文件的大小会增加到 524MB、其他段会返回到闪存。

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

    我曾多次看到类似你的问题。  请阅读文章。  它可以解决您的问题。

    谢谢、此致、

    乔治

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

    我阅读了这篇文章、但它并未解决添加308字节单个 pragma 后的500兆字节空洞问题。 编译器似乎为单次 Far 调用添加了数千个字节、对于308字节 pragma 的每个8字节 trampoline、似乎都是这样。

    您认为3个 trampoline (每个8字节)在二进制文件输出中可以等于500 MB 吗? 我们无法查看500MB 二进制文件、因为它会冻结十六进制查看工具。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="48581" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179026/tm4c1294kcpdt-ccs-adding-arm-pragma-data-sections-creates-huge-bin-file/4441116 #4441116"]我阅读了本文,它没有解决500兆字节的空穴问题

    是的。  该示例中有一个孔洞。  发生这种情况的原因是已初始化段之间的存储器中存在间隙。  您的空穴发生的原因相同。  这是二进制文件中可能出现空洞的唯一原因。  孔要大得多、因为已初始化段之间的存储器距离要大得多。   本文还讨论了如何避免此类漏洞。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="4373 " URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179026/tm4c1294kcpdt-ccs-adding-arm-pragma-data-sections-creates-huge-bin-file/4442822 #4442822"] 本文还讨论了如何避免此类漏洞。

    奇怪的是、当 CMD 文件末尾放置了其他 pragma 定义时、C2000没有此类问题。 移动 RAM 定义的其他部分上方的 ARM pragma 部分并不会阻止巨大的孔洞的形成。 另一个段定义与闪存相关。 为什么有人会考虑将 RAM pragma 移动到闪存写入固件的闪存部分上方?

    BTW:引用的(*。out)文章文件大小不是 MkHex4Bin.exe 文件大小。  奇怪的是、最小尺寸的 pragma 始终显示在最大到最小尺寸 RAM 模块的内存分配末尾。 .out 文件仍然相当小、930KB。 编译器和链接器不会解析 --gap-fill 指令。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="48581" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179026/tm4c1294kcpdt-ccs-adding-arm-pragma-data-sections-creates-huge-bin-file ]但是编译后的 bin 文件增加到512MB、最初为106KB、而不是通过#pragma 将函数从闪存移动到 RAM。 [/报价]

    在 TM4C1294KCPDT 上、闪存从地址0开始、RAM 从地址0x20000000 (512MB)开始。 使用#pragma 将函数的加载地址设置为 RAM 会导致二进制文件变为512MB、因为二进制文件格式在地址范围内不能有空洞。

    使用#pragma 将函数的加载地址设置为 RAM 的另一个问题是、在器件复位/下电上电时、没有机制将函数加载到 RAM 中。 因此、此类程序只能从 CCS 调试器运行。

    要将函数放置在 RAM 中、请使用 TI ARM 编译器、而是在 源代码中的函数上使用__attribute (((ramfunc))。 例如:

    __attribute ((ramfunc))
    void
    UARTIntHandler(void)

    在链接器命令文件中、声明 .binit 和 .TI.ramfunc 段。 例如:

    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > APP_BASE
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
        .binit > FLASH
    
        .vtable :   > RAM_BASE
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
    #endif
    #endif
    }
    

    这会导致运行时启动代码将函数从闪存中的加载地址复制到 SRAM 中的运行地址、而不会导致二进制文件变为512MB。

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

    切斯特、您好!

    我有多个 pragma 要加载到 RAM 地址中并将大量配置函数保留在闪存中。 ARM 编译器应该在 CMD 文件中处理适当的 pragma 段而不添加孔洞、因为没有包含此 conundrum 的文本。 C2000编译器可让我们了解 CMD 文件是否已使用 trampoline 创建段。

    默认的 TM4C1294项目 CMD 文件在范围内非常通用、引导加载程序应用程序加载到闪存中、从0x4000开始甚至更高。 添加.binit > FLASH 可能有助于从各种函数加载多个 pragma。 引导加载程序会复制到 RAM 中指向闪存矢量表或沿这些行的内容、即使它有自己的矢量表。 这可能是*。bin 文件变得如此大的原因。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="91588" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1179026/tm4c1294kcpdt-ccs-adding-arm-pragma-data-sections-creates-huge-bin-file/4447826 #4447826"]因此,此类程序只能从 CCS 调试器运行。

    应用程序(main.c)应添加 mcopy()作为将.TI.ramfunc code_section 从闪存复制到 RAM。 ARM 编译器似乎应该在复制#pragma 函数后添加 pragma 偏移地址。 忘记添加 mcopy()命令,可能会导致内存大漏洞。

    C2000 mcopy()、pragma 和 CMD 文件部分:

    #include

    device.h:

    extern uint16_t RamfuncsLoadStart;
    extern uint16_t RamfuncsLoadEnd;
    extern uint16_t RamfuncsLoadSize;
    extern uint16_t RamfuncsRunStart;
    extern uint16_t RamfuncsRunEnd;
    extern uint16_t RamfuncsRunSize;

    // RamfuncsLoadStart、RamfuncsLoadSize 和 RamfuncsRunStart 符号
    //由链接器创建。 请参阅 device.h CMD 文件。
    memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);

    存储器

      第0页:

      RAMLS0_1      :origin = 0x008000、length = 0x001000 //4096KB

      RAMLS2_3      :origin = 0x009100,length = 0x000F00 //4096KB -16个字,勘误建议读取内存组末尾会导致 CRC 错误。

    #pragma CODE_SECTION (myISR、".TI.ramfunc")

    部分{
       codestart:>开始,align (4)

    //仅需要第一个 pragma 的 RAM 地址位置、所有其他(DATA_SECTION) pragma 具有如下所示的简单段

       .TI.ramfunc:load = FLASHB0_SA,
                 运行= RAMLS2_3、// RAM 组
                 Load_start (RamfuncsLoadStart)、
                 load_size (RamfuncsLoadSize)、
                 Load_End (RamfuncsLoadEnd)、
                 RUN_START (RamfuncsRunStart)、
                 run_size (RamfuncsRunSize)、
                 RUN_END (RamfuncsRunEnd)、
                 对齐(4)

    置于函数上方:#pragma DATA_SECTION (MyParams、".params.ramdata");

    部分{

      params.ramdata:> RAMLS0_1 //将存储器定义为闪存页0或1

      myvars.ramdata :> RAMLS0_1

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

    我在第0页创建了更复杂的 tm4c1294 CMD 文件、其中包含4个 SRAM 65KB 段(262KB)。 与上述 C2000 CMD 文件语法类似、mcopy()放置位置为3、而 SRAM_0默认为:.bss、.stack、.vtable、.data 定义。 没有机会加载该文件、但在 main.c 断言 mcopy()命令后*。bin 文件大小为107KB。 请注意、闪存会在 mcopy()之后将3个 pragma 段保留到 C2000项目中也需要的 RAM 中。