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.

CCS/LAUNCHXL-F28027F: Sine wave generation Build error due to exceeding memory limits

Part Number: LAUNCHXL-F28027F
Other Parts Discussed in Thread: CONTROLSUITE

Tool/software: Code Composer Studio

Hi Friends, 

I'm working on Sine wave generation coding utilizing ePWM and the controller I'm using is F28027F. 

I'm following a code from this thread

https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/553678/2025201

and altered the code in accordance with the Controller I'm using. 

ISSUE:

When I try to build and debug, it fails and this error report generates

"C:/ti/controlSUITE/device_support/f2802x/v230/f2802x_common/cmd/F2802x_generic_ram.cmd", line 121: error:
program will not fit into available memory. placement with
alignment/blocking fails for section ".econst" size 0x100 page 1. Available
memory ranges:
RAMM1 size: 0x400 unused: 0xd6 max hole: 0xd6
.econst : > RAMM1, PAGE = 1
error: errors encountered during linking; "Example_2802xEPwmUpDownAQ.out" not
built

>> Compilation failure
gmake: *** [Example_2802xEPwmUpDownAQ.out] Error 1
gmake: Target `all' not remade because of errors.

My thoughts:

There's a float array named b[101] (plz observe it in the given code). From the error report I think  build failed due to exceeding memory limits of the controller. Also I tried to reduced the number of Array to just 5 or replace float to Integers, then I can easily build the code, But by doing it is totally useless to me, can't achieve my target of sine wave generation.  Kindly help me out of this. Isn't it possible to use F28027f  for sine wave generation?  If it is then kindly let me know the way.

Thanks in advance.

 

 

#include "DSP28x_Project.h"    

#include "math.h"

#include "float.h"             // Not sure whether it is needed or not

 

typedef struct

{

   volatile struct EPWM_REGS *EPwmRegHandle;

 

}

EPWM_INFO;

 

 

 

 

#define EPWM2_TIMER_TBPRD 5000 // 5kHz PWM Period register

#define PI 3.14159265358979323846

 

void InitEPwm2Example(void);

__interrupt void epwm2_isr(void);

 

 

unsigned int i=0,m=0,k=0;

float a=0;

float b[101]={0};     //Here’s the b float array I’m talking about

 

 

void main(void)

{

   #ifdef _FLASH

       memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

   #endif

 

   InitSysCtrl();

 

   for(m=0;m<100;m++)

   {

     a=sin(PI*0.02*m);

     if(a<=0)

     {

       a=-a;

     }

     b[m]=5000*a;

   }

     b[100]=0;

 

 

 

   InitEPwm2Gpio();

   DINT;

 

   InitPieCtrl();

 

 

   IER = 0x0000;

   IFR = 0x0000;

 

   InitPieVectTable();

 

   EALLOW;

PieVectTable.EPWM2_INT = &epwm2_isr;

   EDIS

 

 

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;

   EDIS;

 

   InitEPwm2Example();

 

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;

   EDIS;

 

   IER |= M_INT3;

 

   PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

 

   EALLOW;

   SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK=1;

//Originally in the thread, this line was CpuSysRegs.PCLKCR2.bit.EPWM2=1; for F28377s

 

   EDIS;

 

   EINT;  

   ERTM;  

 

   for(;;)

   {

       __asm("         NOP");

   }

}

 

 

 

__interrupt void epwm2_isr(void)

{

       /*Here my code assign a new sin value into compare reg. For negative side of sin wave, pwm logic is inverted.*/

       a=sin(PI*0.02*i);

       if (a>=0){

       EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM2A on event A, up

       EPwm2Regs.AQCTLA.bit.CAD =AQ_SET; // Set PWM2A on event B, down

       EPwm2Regs.CMPA.half.CMPA =b[i];

       }

       else {

       EPwm2Regs.AQCTLA.bit.CAU =AQ_SET; // Set PWM2A on event A, up

       EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // Clear PWM2A on event B, down

 

       EPwm2Regs.CMPA.half.CMPA =b[i]; //For F28027F bit is replaced with half

       }

       i++;

       if (i==101){

       i=0;

       }

       EPwm2Regs.ETCLR.bit.INT = 1;

       PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

 

}

 

 

void InitEPwm2Example()

{

       EPwm2Regs.ETSEL.bit.INTSEL = 0;//ET_CTR_ZERO; // hem zero hemde TBPRD zamaninda intrrupt aliyo.

       EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT

       EPwm2Regs.ETPS.bit.INTPRD = 1;//ET_1ST; // Generate INT on 1st event

       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down

       EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading

       EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT

       EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2;

       EPwm2Regs.CMPCTL.bit.SHDWAMODE = 1; //CC_IMMEDIATE;

 

       //********* bit is replaced by half*********

       EPwm2Regs.CMPA.half.CMPA =0;

 

       EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer period 801 TBCLKs

 

       //********* bit is replaced by half*********

       EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0

 

       EPwm2Regs.TBCTR = 0x0000; // Clear counter

 

}

 

 

 

 

  • The key to the immediate problem lies in the linker command file. Clearly your program is exceeding the amount of memory available allocated for it. If you have not already done so, you may be able to load program or initialized data sections into flash to free more RAM. You seem to be loading the array into M0 memory. M1 is typically used for the stack - is that true here? What is in L0 memory?

    If you can paste the .cmd file I will try to advise.

    Please be aware also that you are using a fixed point processor with floating point data types. I assume you already know the implications of that, but you might want to consider either moving to a floating point device, or using IQmath to handle the data more efficiently.

    Regards,

    Richard
  • Many thanks for your quick response.

    Actually I'm relatively new in TI microcontrollers. Yes, you guessed right, Im just using RAM for the debug purpose. Indeed, I was  thinking about moving the floating data array into flash memory but I'm not sure how to do this.   Kindly guide me in this regard and IQmath too if possible.  I'm attaching CMD file here as per u suggest.

    Thanks a lot again Mr. Richard.

    /*
    //###########################################################################
    //
    // FILE:    F2802x_generic_ram.cmd
    //
    // TITLE:   Linker Command File For 2802x examples that run out of RAM
    //
    //          This ONLY includes all SARAM blocks on the 2802x device.
    //          This does not include flash or OTP.
    //
    //          Keep in mind that L0 is 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: F2802x Support Library v230 $
    // $Release Date: Fri May  8 07:43:05 CDT 2015 $
    // $Copyright: Copyright (C) 2008-2015 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    */
    
    /* ======================================================
    // 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>\F2802x_headers\cmd
    //
    // For BIOS applications add:      F2802x_Headers_BIOS.cmd
    // For nonBIOS applications add:   F2802x_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 F2802x_Headers_nonBIOS.cmd */
    
    /* Uncomment this line to include file only for BIOS applications */
    /* -l F2802x_Headers_BIOS.cmd */
    
    /* 2) In your project add the path to <base>\F2802x_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 F2802x
       PAGE 0 will be used to organize program sections
       PAGE 1 will be used to organize data sections
    
       Notes:
             Memory blocks on F2802x 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.
    
             The L0 memory blocks is mirrored - that is
             it can be accessed in high memory or low memory.
             For simplicity only one instance is used in this
             linker file.
    
             Contiguous SARAM memory blocks can be combined
             if required to create a larger memory block.
    */
    
    MEMORY
    {
    PAGE 0 :
       /* For this example, L0 is split between PAGE 0 and PAGE 1 */
       /* BEGIN is used for the "boot to SARAM" bootloader mode   */
    
       BEGIN      : origin = 0x000000, length = 0x000002
       RAMM0      : origin = 0x000050, length = 0x0003B0
       RAML0     : origin = 0x008000, length = 0x000800
       RESET      : origin = 0x3FFFC0, length = 0x000002
    
       IQTABLES   : origin = 0x3FE000, length = 0x000B50     /* IQ Math Tables in Boot ROM */
       IQTABLES2  : origin = 0x3FEB50, length = 0x00008C     /* IQ Math Tables in Boot ROM */
       IQTABLES3  : origin = 0x3FEBDC, length = 0x0000AA     /* IQ Math Tables in Boot ROM */
    
       BOOTROM    : origin = 0x3FF27C, length = 0x000D44
    
    
    PAGE 1 :
    
       /* For this example, L0 is split between PAGE 0 and 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 */
    }
    
    
    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 | RAML0      PAGE = 0
       .text            : >> RAMM0 | RAML0,      PAGE = 0
       .cinit           : > RAMM0,     PAGE = 0
       .pinit           : >> RAMM0 | RAML0,     PAGE = 0
       .switch          : > RAMM0,     PAGE = 0
       .reset           : >  RESET,              PAGE = 0, TYPE = DSECT /* not used, */
    
       .stack           : > RAMM1,     PAGE = 1
       .ebss            : > RAMM1,     PAGE = 1
       .econst          : > RAMM1,     PAGE = 1                    //This line indicating an error in CCS
       .esysmem         : > RAMM1,     PAGE = 1
    
       IQmath           : > RAML0,     PAGE = 0
       IQmathTables     : > IQTABLES,  PAGE = 0, TYPE = NOLOAD
    
      /* 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.
    //===========================================================================
    */
    

  • //There's some mistakes in the previous code, this is the correct one

    /*

    //###########################################################################
    //
    // FILE: F2802x_generic_ram.cmd
    //
    // TITLE: Linker Command File For 2802x examples that run out of RAM
    //
    // This ONLY includes all SARAM blocks on the 2802x device.
    // This does not include flash or OTP.
    //
    // Keep in mind that L0 is 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: F2802x Support Library v230 $
    // $Release Date: Fri May 8 07:43:05 CDT 2015 $
    // $Copyright: Copyright (C) 2008-2015 Texas Instruments Incorporated -
    // http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    */

    /* ======================================================
    // 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>\F2802x_headers\cmd
    //
    // For BIOS applications add: F2802x_Headers_BIOS.cmd
    // For nonBIOS applications add: F2802x_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 F2802x_Headers_nonBIOS.cmd */

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

    /* 2) In your project add the path to <base>\F2802x_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 F2802x
    PAGE 0 will be used to organize program sections
    PAGE 1 will be used to organize data sections

    Notes:
    Memory blocks on F2802x 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.

    The L0 memory blocks is mirrored - that is
    it can be accessed in high memory or low memory.
    For simplicity only one instance is used in this
    linker file.

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

    MEMORY
    {
    PAGE 0 :
    /* For this example, L0 is split between PAGE 0 and PAGE 1 */
    /* BEGIN is used for the "boot to SARAM" bootloader mode */

    BEGIN : origin = 0x000000, length = 0x000002
    RAMM0 : origin = 0x000050, length = 0x0003B0
    RAML0 : origin = 0x008000, length = 0x000800
    RESET : origin = 0x3FFFC0, length = 0x000002

    IQTABLES : origin = 0x3FE000, length = 0x000B50 /* IQ Math Tables in Boot ROM */
    IQTABLES2 : origin = 0x3FEB50, length = 0x00008C /* IQ Math Tables in Boot ROM */
    IQTABLES3 : origin = 0x3FEBDC, length = 0x0000AA /* IQ Math Tables in Boot ROM */

    BOOTROM : origin = 0x3FF27C, length = 0x000D44


    PAGE 1 :

    /* For this example, L0 is split between PAGE 0 and 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 */
    }


    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 | RAML0 PAGE = 0
    .text : >> RAMM0 | RAML0, PAGE = 0
    .cinit : > RAMM0, PAGE = 0
    .pinit : >> RAMM0 | RAML0, PAGE = 0
    .switch : > RAMM0, PAGE = 0
    .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */

    .stack : > RAMM1, PAGE = 1
    .ebss : > RAMM1, PAGE = 1
    .econst : > RAMM1, PAGE = 1 //This line generate an error in CCS window
    .esysmem : > RAMM1, PAGE = 1

    IQmath : > RAML0, PAGE = 0
    IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD

    /* 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.
    //===========================================================================
    */

  • Hi

    float b[101]={0};

    Unless you have meaningful array initializer, you shouldn't specify initializer here. Above line means that you have 101*sizeof(float) memory for b[] in .ebss, and 101*sizeof(float) memory for all zeros initializer in .econst. Just remove initializer and it should solve your problem:

    float b[101];

    Edward

  • Hi,
    I tried it, but didn't work. Then I assigned b[] as unsigned Int and my problem solved with some additional tweaks. I certainly don't need the floating array bcz sin value (which lie from -1 to 1) have to multiply with TBPRD, which is 5000 in my case, after multiplication, digits after decimal point doesn't mean that much. For tackling with -VE values, i.e Theta > 180, I just make them +VE by applying condition
    if(a< 0)
    a = -a; //This will change -ve values to +ve

    By doing this I got rectified sin wave having -ve cycle, which is from 180-360 now have +ve values.

    Then in EPWM ISR , I've to put a condition that is

    if (i < = 50) //For 100 samples 50 represents 180
    {
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    EPwm2Regs.AQCTLA.bit.CAD =AQ_SET;
    }

    else
    {
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAD =AQ_CLEAR;

    }

    Again thanks for your guidance.