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.

[参考译文] TMS320F28069:修改 cmd 文件的问题

Guru**** 2558250 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/989605/tms320f28069-problems-of-modifying-cmd-file

器件型号:TMS320F28069

大家好、我目前正在使用28069的 DSP 进行一个项目。 随着项目的增长、代码量变得越来越大。 最近、编译器告诉我这一点

"../28069_RAM_lnk.cmd", line 121: error #10099-D: program will not fit into
   available memory.  placement with alignment/blocking fails for section
   ".text" size 0x34e5 page 0.  Available memory ranges:
   RAML0_L3     size: 0x2000       unused: 0x2000       max hole: 0x2000    
   .text            : > RAML0_L3,   PAGE = 0

我想我可以自行放大.text。 然后、我尝试通过将 RAML0_L3的大小从0x002000增加到0x004000来放大.text 字段。 这个扩大的区域与 RAML4重叠、RAML4被 .ebss 占用、依此类推、我将其位置更改为 RAML5。 由于 RAML5被 "DMARAML5"占用、我还将 DMARAML5的位置更改为 RAML6。 下面是我的整个 cmd 文件

/*
// TI File $Revision: /main/3 $
// Checkin $Date: March 3, 2011   13:45:43 $
//###########################################################################
//
// FILE:    28069_RAM_lnk.cmd
//
// TITLE:   Linker Command File For F28069 examples that run out of RAM
//
//          This ONLY includes all SARAM blocks on the F28069 device.
//          This does not include flash or OTP.
//
//          Keep in mind that L0,L1,L2,L3 and L4 are protected by the code
//          security module.
//
//          What this means is in most cases you will want to move to
//          another memory map file which has more memory defined.
//
//###########################################################################
// $TI Release: $ 
// $Release Date: $ 
//###########################################################################
*/

/* ======================================================
// For Code Composer Studio V2.2 and later
// ---------------------------------------
// In addition to this memory linker command file,
// add the header linker command file directly to the project.
// The header linker command file is required to link the
// peripheral structures to the proper locations within
// the memory map.
//
// The header linker files are found in <base>\F2806x_headers\cmd
//
// For BIOS applications add:      F2806x_Headers_BIOS.cmd
// For nonBIOS applications add:   F2806x_Headers_nonBIOS.cmd
========================================================= */

/* ======================================================
// For Code Composer Studio prior to V2.2
// --------------------------------------
// 1) Use one of the following -l statements to include the
// header linker command file in the project. The header linker
// file is required to link the peripheral structures to the proper
// locations within the memory map                                    */

/* Uncomment this line to include file only for non-BIOS applications */
/* -l F2806x_Headers_nonBIOS.cmd */

/* Uncomment this line to include file only for BIOS applications */
/* -l F2806x_Headers_BIOS.cmd */

/* 2) In your project add the path to <base>\F2806x_headers\cmd to the
   library search path under project->build options, linker tab,
   library search path (-i).
/*========================================================= */

/* Define the memory block start/length for the F2806x
   PAGE 0 will be used to organize program sections
   PAGE 1 will be used to organize data sections

   Notes:
         Memory blocks on F28069 are uniform (ie same
         physical memory) in both PAGE 0 and PAGE 1.
         That is the same memory region should not be
         defined for both PAGE 0 and PAGE 1.
         Doing so will result in corruption of program
         and/or data.

         Contiguous SARAM memory blocks can be combined
         if required to create a larger memory block.
*/

MEMORY
{
PAGE 0 :
   /* BEGIN is used for the "boot to SARAM" bootloader mode   */

   BEGIN       : origin = 0x000000, length = 0x000002
   RAMM0       : origin = 0x000050, length = 0x0003B0
   RAML0_L3    : origin = 0x008000, length = 0x004000	 /* RAML0-3 combined for size of .text */
   														 /* in Example_F2806xSWPrioritezedInterrupts */
   RESET       : origin = 0x3FFFC0, length = 0x000002
   FPUTABLES   : origin = 0x3FD860, length = 0x0006A0	 /* FPU Tables in Boot ROM */
   IQTABLES    : origin = 0x3FDF00, length = 0x000B50    /* IQ Math Tables in Boot ROM */
   IQTABLES2   : origin = 0x3FEA50, length = 0x00008C    /* IQ Math Tables in Boot ROM */
   IQTABLES3   : origin = 0x3FEADC, length = 0x0000AA	 /* IQ Math Tables in Boot ROM */

   BOOTROM    : origin = 0x3FF3B0, length = 0x000C10


PAGE 1 :

   BOOT_RSVD   : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */
   RAMM1       : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
   RAML4       : origin = 0x00A000, length = 0x002000     /* on-chip RAM block L4 */
   RAML5       : origin = 0x00C000, length = 0x002000     /* on-chip RAM block L5 */
   RAML6       : origin = 0x00E000, length = 0x002000     /* on-chip RAM block L6 */
   RAML7       : origin = 0x010000, length = 0x002000     /* on-chip RAM block L7 */
   RAML8       : origin = 0x012000, length = 0x002000     /* on-chip RAM block L8 */
   USB_RAM     : origin = 0x040000, length = 0x000800     /* USB RAM		  */
}


SECTIONS
{
   /* Setup for "boot to SARAM" mode:
      The codestart section (found in DSP28_CodeStartBranch.asm)
      re-directs execution to the start of user code.  */
   codestart        : > BEGIN,      PAGE = 0

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} > RAMM0,      PAGE = 0
   #else
   ramfuncs         : > RAMM0,      PAGE = 0   
   #endif
#endif
   
   .text            : > RAML0_L3,   PAGE = 0
   .cinit           : > RAMM0,      PAGE = 0
   .pinit           : > RAMM0,      PAGE = 0
   .switch          : > RAMM0,      PAGE = 0
   .reset           : > RESET,      PAGE = 0, TYPE = DSECT /* not used, */

   .stack           : > RAMM1,      PAGE = 1
   .ebss            : > RAML5,      PAGE = 1
   .econst          : > RAML5,      PAGE = 1
   .esysmem         : > RAML5,      PAGE = 1

   IQmath           : > RAML0_L3,   PAGE = 0
   IQmathTables     : > IQTABLES,   PAGE = 0, TYPE = NOLOAD
   
   /* Allocate FPU math areas: */
   FPUmathTables    : > FPUTABLES,  PAGE = 0, TYPE = NOLOAD

   DMARAML5	        : > RAML6,      PAGE = 1
   DMARAML6	        : > RAML6,      PAGE = 1
   DMARAML7	        : > RAML7,      PAGE = 1
   DMARAML8	        : > RAML8,      PAGE = 1

  /* Uncomment the section below if calling the IQNexp() or IQexp()
      functions from the IQMath.lib library in order to utilize the
      relevant IQ Math table in Boot ROM (This saves space and Boot ROM
      is 1 wait-state). If this section is not uncommented, IQmathTables2
      will be loaded into other memory (SARAM, Flash, etc.) and will take
      up space, but 0 wait-state is possible.
   */
   /*
   IQmathTables2    : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
   {

              IQmath.lib<IQNexpTable.obj> (IQmathTablesRam)

   }
   */
   /* Uncomment the section below if calling the IQNasin() or IQasin()
      functions from the IQMath.lib library in order to utilize the
      relevant IQ Math table in Boot ROM (This saves space and Boot ROM
      is 1 wait-state). If this section is not uncommented, IQmathTables2
      will be loaded into other memory (SARAM, Flash, etc.) and will take
      up space, but 0 wait-state is possible.
   */
   /*
   IQmathTables3    : > IQTABLES3, PAGE = 0, TYPE = NOLOAD
   {

              IQmath.lib<IQNasinTable.obj> (IQmathTablesRam)

   }
   */

}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

在这之后、我进行了编译、一切看起来都很好、没有错误、没有警告。 但是、当我在电路板上运行此代码时、我可以从"Expressions"窗口中看到我的所有变量都是随机变化的。 代码似乎已失控。

我已经从数据表中读取了存储器映射、L0到 L3看起来与 L4不同、L0到 L3是 DPSARAM、而 L4是 SARAM。 这是因为这种差异,.text 永远不应该使用 L4吗?

有人能 向我解释一下吗? 衷心感谢您的帮助!

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

    感谢您访问 TI E2E 论坛。

    我在上面附加的.cmd 中发现了一个小错误、在第138/139行、您已将 DMARAML5和 DMARAML6分配给相同的物理内存空间。 由于 L5现在被分配给您的.ebss/.econst、我们肯定不希望 DMARAML5映射到那里、因此我只需删除那一行代码、如果您需要为 DMA 单独分配、您也可以将 RAML6拆分成更小的块。

       DMARAML5	        : > RAML6,      PAGE = 1
       DMARAML6	        : > RAML6,      PAGE = 1

    在代码或数据的功能方面、所有 LX RAM 的性能都是相同的。  DPSRAM 是双端口、因为它们在 CPU 和 CLA (L0-L3)或 DMA (L5-L8)之间共享。  如果您不使用任何一种、则 C28x 数据或程序不会降低性能。  CLA 有一个初始化过程、因此我不相信您意外激活了它。  如果您使用的是 DMA、我们可能需要进行检查

    最后、尽管我们已经为 DMA 分配了特定的 RAM、但 DMA 本身不会自动阻止它访问的任何地址。  因此、即使 L5未分配给链接器中的 DMA、但如果您已将其编程为写入 L5中的那些地址、则没有什么可以阻止它执行此操作。  ESP 如果您之前使用 L5作为 DMA、我应该查看 DMA 初始化代码、以确保它在活动或影子寄存器加载/重新加载中不会仍然指向 L5。

    请告诉我您发现了什么以及我是否能提供更多帮助。

    最棒的

    Matthew

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="8973" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/989605/tms320f28069-problems-of-modifying-cmd-file/3656375 #3656375"] esp[/quot]

    感谢您的及时回复。 我删除了你提到的 DMARAML5分配行。 但问题仍然 相同。 现在、我的 cmd 文件如下所示

    MEMORY
    {
    PAGE 0 :
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */
    
       BEGIN       : origin = 0x000000, length = 0x000002
       RAMM0       : origin = 0x000050, length = 0x0003B0
       RAML0_L3    : origin = 0x008000, length = 0x004000	 /* RAML0-3 combined for size of .text */
       														 /* in Example_F2806xSWPrioritezedInterrupts */
       RESET       : origin = 0x3FFFC0, length = 0x000002
       FPUTABLES   : origin = 0x3FD860, length = 0x0006A0	 /* FPU Tables in Boot ROM */
       IQTABLES    : origin = 0x3FDF00, length = 0x000B50    /* IQ Math Tables in Boot ROM */
       IQTABLES2   : origin = 0x3FEA50, length = 0x00008C    /* IQ Math Tables in Boot ROM */
       IQTABLES3   : origin = 0x3FEADC, length = 0x0000AA	 /* IQ Math Tables in Boot ROM */
    
       BOOTROM    : origin = 0x3FF3B0, length = 0x000C10
    
    
    PAGE 1 :
    
       BOOT_RSVD   : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */
       RAMM1       : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
       RAML5       : origin = 0x00C000, length = 0x002000     /* on-chip RAM block L5 */
       RAML6       : origin = 0x00E000, length = 0x002000     /* on-chip RAM block L6 */
       RAML7       : origin = 0x010000, length = 0x002000     /* on-chip RAM block L7 */
       RAML8       : origin = 0x012000, length = 0x002000     /* on-chip RAM block L8 */
       USB_RAM     : origin = 0x040000, length = 0x000800     /* USB RAM		  */
    }
    
    
    SECTIONS
    {
       /* Setup for "boot to SARAM" mode:
          The codestart section (found in DSP28_CodeStartBranch.asm)
          re-directs execution to the start of user code.  */
       codestart        : > BEGIN,      PAGE = 0
    
       ramfuncs         : > RAMM0,      PAGE = 0
       .text            : > RAML0_L3,   PAGE = 0
       .cinit           : > RAMM0,      PAGE = 0
       .pinit           : > RAMM0,      PAGE = 0
       .switch          : > RAMM0,      PAGE = 0
       .reset           : > RESET,      PAGE = 0, TYPE = DSECT /* not used, */
    
       .stack           : > RAMM1,      PAGE = 1
       .ebss            : > RAML5,      PAGE = 1
       .econst          : > RAML5,      PAGE = 1
       .esysmem         : > RAML5,      PAGE = 1
    
       IQmath           : > RAML0_L3,   PAGE = 0
       IQmathTables     : > IQTABLES,   PAGE = 0, TYPE = NOLOAD
    
       /* Allocate FPU math areas: */
       FPUmathTables    : > FPUTABLES,  PAGE = 0, TYPE = NOLOAD
    
       DMARAML6	        : > RAML6,      PAGE = 1
       DMARAML7	        : > RAML7,      PAGE = 1
       DMARAML8	        : > RAML8,      PAGE = 1
    
    }
    

    此外、我在项目中不使用 DMA。 也许我已经初始化了 DMA 的时钟、但绝对没有为 DMA 编写任何代码。

    已找到其他线索。 在我运行代码后、所有变量都随机变化、暂停时、它会显示"在地址"0x89"处中断、没有可用的调试信息、或在程序代码之外。" 如下所示。 我认为 代码已经失控了。

    当我切换到闪存模式的默认 cmd 时、代码工作正常、这证明我的代码没有错误。

    总之、RAM 的 cmd 仍然不起作用、您能给我附加帮助吗?

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

    我找到了新的线索。

    我尝试逐行运行代码、发现每当程序运行到此函数的第三行时、它都会崩溃。

    void send_data(char screen,const char control_id[2],float freq,char* format){
        char *result;
    
        result = malloc(40);
        sprintf(result,format,freq);
    
        scia_send_char(send_begin, 3);
        if(screen == 0){
            scia_send_char(screen_id0, 2);
        }else{
            scia_send_char(screen_id1, 2);
        }
        scia_send_char((char *)control_id, 2);
        scia_msg(result);
        scia_xmit('\0');
        scia_send_char(send_end, 4);
        free(result);
    }

    我想这可能是变量"结果"的问题。 我检查了它的地址、发现它位于映射到 M1 SARAM 的".stack"区域内。

       .stack           : > RAMM1,      PAGE = 1
     

    我尝试将.stack 重新映射到另一个位置、即 L6、然后它可以正常工作、代码工作正常。

    虽然我已经解决了这个问题、但我完全困惑、我仍然不知道原因。 期待您的重播!

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

    很高兴您能够继续调试/开发代码。  您是否正在将闪存中的任何段复制到 RAM 中以加快执行速度?  您会在代码中看到 memcpy()函数。  

    查看链接器、除了栈外、没有任何有意分配给 M1的内容。  我将添加 M0/M1是连续的、因此如果 M0大于我们认为它可以对 M1进行过写操作的大小。  如果 M0段超过您分配的值、链接器本应抛出错误、除非 Pinit 或 cinit 是动态的。

    如果您在调试目录中查看、应该会生成一个.map 文件、如果您可以使用旧链接器查看此文件、则会显示是否有某种 M1空间分配。  

    现在、我认为 memcpy 是最明显的原因。

    最棒的

    Matthew

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

    大家好、MathewRate、感谢您的回复。

    实际上、我没有使用 memcpy()将任何段从闪存复制到 RAM。 但是、在您的建议的启发下、我尝试查看结果的地址、该地址在下面的函数中动态分配。 采用旧链接器时、我发现 结果的地址分配到"0x00000408"、位于 M1段内。

    void send_data(char screen,const char control_id[2],float freq,char* format){
        char *result;
    
        result = malloc(40);
        sprintf(result,format,freq);
    
        scia_send_char(send_begin, 3);
        if(screen == 0){
            scia_send_char(screen_id0, 2);
        }else{
            scia_send_char(screen_id1, 2);
        }
        scia_send_char((char *)control_id, 2);
        scia_msg(result);
        scia_xmit('\0');
        scia_send_char(send_end, 4);
        free(result);
    }

    由于0x00000408位于".stack"中、我认为可能存在问题、因为据我所知、动态分配的内存应该 位于堆中。 那么、是因为这种情况导致代码崩溃了吗?

    根据编译器用户指南"SPRU514"中的信息、动态分配的存储器应 位于".sysmem "部分中。 但是、".sysmem"未在链接器中定义、因此、我是否应该尝试在特定位置定义".sysmem"以解决此问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="427056" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/989605/tms320f28069-problems-of-modifying-cmd-file/3657014 #3657014"]根据编译器用户指南"SPRU514"中的信息,动态分配的内存应 位于".sysmem "部分

    中用于 EABI 的".sysmim"段和用于 COFF 的".esysmim"段。

    在 CCS 工程属性中、"CCS General"-> Project is Output Format is set to "legacy COFF" or "eabi (ELF)"?

    一些 C2000示例链接器命令文件仅包含 COFF 的段、如果工程更改为 EABI、则需要将 EABI 段名称添加到链接器命令文件中。 例如、如果您收到以下警告:

    警告#10440-D:在没有 SECTIONS 规范的情况下创建输出段".sysmim"。 有关此部分的其他信息、请参阅 https://software-dl.ti.com/ccs/esd/documents/C2000_c28x_migration_from_coff_to_eabi.html 上的"C2000从 COFF 迁移到 EABI "指南

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

    您好、Gillon。 感谢您的回答。 目前、输出格式为传统 COFF。
    但关于我所面临的问题、您有什么想法吗?
    谢谢你

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="427056" URL"~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/989605/tms320f28069-problems-of-modifying-cmd-file/3657014 #3657014"]由于0x00000408位于".stack"中、我认为可能会有问题、因为据我所知、动态分配的内存应该 位于堆中。

    您是指结果变量的地址、还是指结果指向的地址?

    以下是使用 COFF 的示例:

    链接器映射包含:

    .stack     1    00000050    00000300     UNINITIALIZED
                      00000050    00000300     --HOLE--
    
    .esysmem   1    00008c00    00000400     UNINITIALIZED
                      00008c00    00000004     rts2800_fpu32.lib : memory.c.obj (.esysmem)
                      00008c04    000003fc     --HOLE--

    结果变量位于堆栈上的地址0x00000058。

    而结果指向已从堆分配的地址0x00008C02。

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

    大家好、Gillon。 感谢您的及时回复。 是的、你是对的、我以前犯了一个错误。 分配的地址实际上在堆中、指针在堆栈中、这符合我的实验结果。

    我认为我的目标是这个问题、这是由"sprintf"而不是动态内存分配引起的。 我在">e2e.ti.com/.../tms320f28069m-printf-issues-and-stack-overflow"中发现其他人也遇到了同样的问题。  

    他们建议增加堆栈的大小、因为 sprintf 可能需要大于0x400的堆栈存储器、而0x400是 默认链接器文件中.stack 的大小。 因此、我从编译器设置中更改了堆栈大小、并将其增加到0x800。 此外、由于.stack 默认映射到大小仅为0x400的 M1、因此我将.stack 重新映射到 RAML6。 然后、问题得到了解决。

    无论如何感谢您的帮助! 感谢大家。