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.

which Optimization level should I use?

1. In my cmd file:

    RAML0 : origin = 0x008000, length = 0x000800 /* on-chip RAM block L0 */
    RAML00 : origin = 0x3F8000, length = 0x000800

    .ebss               : >> RAML0 | RAML00     PAGE = 1

2. In my .map

     00008011  _uiCanOnCon 

     003f800e  _SetF  

     uiCanOnCon is defined unsigned int,    SetF is struct ,  SetF.fCmd is a float and it's address is at 003f8011

3. When I used Optimization level off, and run this code  SetF.fCmd = 111.0,

     uiCanOnCon will be changed to 0x42DE. why the value of uiCanOnCon would be changed?

     But when I used Optimization level -O0 or higher, these is no problem.

     I am using CCS Version: 6.2.0.00050.   Compiler TI v15.12.3.LTS

4. I usually use  Optimization level off  to build my project.

    If I must use Optimization , how should the Optimization level?

  • It is likely you are experiencing a compiler problem that shows itself only when building with no optimization.

    I'm pretty sure the the data page (DP) register somehow has the wrong value.  Global variables are accessed with a two step process.  The upper bits of the address are loaded in the DP.  The lower bits of the address are encoded in the instruction.  Those bits are concatenated together to form the full address.  The compiler works hard to insure the DP register is loaded no more than necessary.  It seems likely that something causes the DP to be wrong, and this problem is exposed only when building with no optimization.

    Please submit a test case which allows us to reproduce the problem behavior.  Preprocess the file which contains the assignment to SetF.fCmd.  Attach it to your next post.  Also show all the build options exactly as the compiler sees them.

    Thanks and regards,

    -George

  • I am sorry I can not upload the file due to the file is encoded.
    I made a test liked this:
    void main(void)
    {
    InitPeripherals(); //config the peripherals
    SetF.fCmd = 111; //assign the value of SetF.fCmd which is at 0x003f8011
    DELAY_US(100000); //
    for(;;) //
    {
    }
    }
    The problem showed up again.

    So, I think the problem happen when meets these condition.
    1. The lower bits of the address of two variables are the same. Such like A is at 0x00008011, B is at 0x003F8011
    2. Assign the value to B
    3. Compiler with no optimization
  • I cannot build that source code.  Among other things, I do not have the definition of the structure for SetF.  Please preprocess the source file for this test case and attach that to your next post.  Also show all the build options exactly as the compiler sees them.

    Thanks and regards,

    -George

  • I am using F28035.

    my main()  :  

    //--------------------------------------------------------------------------------

    // Include files

    //--------------------------------------------------------------------------------

    #include "DSP28x_Project.h"

    #include "GlobalVariables.h"

    //--------------------------------------------------------------------------------

    // Global variables used in this example:

    //--------------------------------------------------------------------------------

    // Start of program

    //--------------------------------------------------------------------------------

    void main(void)

    {

    InitPeripherals();

       SetF.fCmd = 111.0;

    DELAY_US(100000);                               //等待100ms

    uiCanOnCon = 222;

    for(;;) // 主循环

    {

       ;

    }

    }

    When I assign the SetF.fCmd,the uiCanOnCon changed. And when I assign the uiCanOnCon, the SetF.fCmd changed too.

    I have attached the main.pp file.   Thanks

    Main.rar

  • Unfortunately, I am unable to reproduce the problem.  But I had to guess at the build options..  Please show the build options used, exactly as the compiler sees them.

    Thanks and regards,

    -George

  • Most of my build options are default. I only change the include path and the Optimization level.
    Here is my compiler flags:
    -v28 -ml -mt --cla_support=cla0 -Ooff --opt_for_speed=2 --include_path="${CG_TOOL_ROOT}/include" --include_path="${PROJECT_LOC}/../Common_Header" --include_path="${PROJECT_ROOT}/../Common_Include" --advice:performance=all -g --display_error_number --diag_warning=225

    linker flags:
    -m"${ProjName}.map" --stack_size=0x380 --warn_sections -i"${PROJECT_ROOT}/../Common_LIB" -i"${C2000_CG_ROOT}/lib" --reread_libs --define=CLA_SCRATCHPAD_SIZE=0x100 --diag_wrap=off --display_error_number --xml_link_info="${ProjName}_linkInfo.xml" --rom_model
  • I have no experience with the F28035. A quick look at the datasheet would suggest that "L0 SARAM (2K x 16) (0-Wait, Secure Zone + ECSL, Dual-Mapped)" is mapped to two base addresses of 0x00008000 and 0x003F8000, ie. there is only one chunk of memory accessed by two base addresses. Your linker command
    .ebss : >> RAML0 | RAML00 PAGE = 1
    should be either
    .ebss : >> RAML0 PAGE = 1
    or
    .ebss : >> RAML00 PAGE = 1
    I suspect optimization moved the allocation around so that uiCanOnCon did not overlap SetF. However you would probably get other overlaps in other variables. Unless you carefully use overlays, your code should not work. Check you map file foe the 0x00008000 range and 0x003F8000 range to see what overlaps with what.
  • This line from the linker command file ...

    Norman Wong said:
    .ebss : >> RAML0 | RAML00 PAGE = 1

    ... does not mean anything is overlaid.  It means the .ebss output section may be (and, in this case, actually is) split across those two memory ranges.  Please read more about section splitting here.

    Thanks and regards,

    -George

  • Edwin.Liu said:
    Here is my compiler flags:

    Thanks for sending those in.  I still cannot reproduce the problem.  I'll elaborate some more.

    I built the main.pp file you attached earlier with those options.  When I look at the resulting assembly language I see the following ...

            MOVW      DP,#_SetF+2           ; [CPU_U] 
            MOVL      @_SetF+2,ACC          ; [CPU_] |6550|
    
    ; many lines later 
    
            MOVW      DP,#_uiCanOnCon       ; [CPU_U] 
            MOVB      @_uiCanOnCon,#222,UNC ; [CPU_] |6552|

    So the DP is initialized with the correct value immediately before the write to those global variables.  This proves I am wrong to suspect an error in the compiler.

    Maybe the assembler or linker made an error when encoding those MOVW instructions.  While not impossible, this is very unlikely.  Those tools have handled this detail exactly the same way for many years.  

    One other possibility occurs to me ... Are either of these variables defined (not declared) in a .cla file?  Data pages are handled differently on the CLA.  If you need to share data between CLA and the C2000 CPU, then that data must be defined in a C file, and not a .cla file.

    Thanks and regards,

    -George

  • I agree "RAML0|RAML00" does not mean overlay but I suspect RAML0 and RAML00 are the exact same chunk of memory mapped to two different address ranges, one in the low 64K and the other in the high 64K. There is just one 2Kx16 RAM not two.
  • Thanks for your reply.
    These variables are not used in the .cla file.
  • Thank you for your reply.
    My variables are more than 2K . If there is only one, the .ess is not enough.
    And when I use Optimization level -O3, everything works fine. The variables in RAML0 or RAML00 are correct.
  • Unfortunately, I'm out of ideas on this one.  The only way I see forward is for you to submit the full CCS project, which will allow me to build and run the code, and reproduce the problem in full.  Please see this post for details on how to submit a CCS project.

    Thanks and regards,

    -George

  • TI documentation calls the L0 memory ranges are dual mapped or mirrored. Some simple code to check for that sort of thing:

    // Linker settings
    // RAML0 : origin = 0x008000, length = 0x000800 /* on-chip RAM block L0 */
    // RAML00 : origin = 0x3F8000, length = 0x000800
    // .ebss : >> RAML0 | RAML00     PAGE = 1
    #define MAXBUF 0x700 // As close to 0x800 as possible
    unsigned int buflo[MAXBUF]; // Allocated in 0x008000-0x008800
    unsigned int bufhi[MAXBUF]; // Allocated in 0x3F8000-0x3F8800
    
    void main()
    {
      int i;
      for{i=0; i<MAXBUF; i++) // Set high buf to zero
        bufhi[i] = 0x0000;
      for{i=0; i<MAXBUF; i++) // Set low buf to non zero
        buflo[i] = 0xFFFF;
      for{i=0; i<MAXBUF; i++) // Check that high buf is still zero.
        if(bufhi[i])
          break; // Found non-zero
    }
    

  • Pedantically, your test code is required to make buflo and bufhi volatile. Practically it probably won't matter.
  • You are right. Forgot the volatile. Yes, it probably won't matter but here's the changed code anyway:

    // Linker settings
    // RAML0 : origin = 0x008000, length = 0x000800 /* on-chip RAM block L0 */
    // RAML00 : origin = 0x3F8000, length = 0x000800
    // .ebss : >> RAML0 | RAML00     PAGE = 1
    #define MAXBUF 0x700 // As close to 0x800 as possible
    volatile unsigned int buflo[MAXBUF]; // Allocated in 0x008000-0x008800
    volatile unsigned int bufhi[MAXBUF]; // Allocated in 0x3F8000-0x3F8800
    
    void main()
    {
      int i;
      for{i=0; i<MAXBUF; i++) // Set high buf to zero
        bufhi[i] = 0x0000;
      for{i=0; i<MAXBUF; i++) // Set low buf to non zero
        buflo[i] = 0xFFFF;
      for{i=0; i<MAXBUF; i++) // Check that high buf is still zero.
        if(bufhi[i])
          break; // Found non-zero, put breakpoint here.
    }
    

  • There might be some confusion regarding the "dual mapped" memory on this device.   These blocks of memory that are marked as "dual mapped" in the data manual are physically one block of memory.  They appear in the memory map in two locations.  For example in the case of L0 on the F2803x:

    origin = 0x008000, length = 0x000800

    is the same physical memory as:

    origin = 0x3F8000, length = 0x000800

    If the tools are told they can allocate to either location, then variables and/or code will clobber each other.

    Pick only one mapping of the block and stick to it.  Likely the lower memory addresses starting at 0x8000 since there is more contiguous memory there.  The higher mapping is for some legacy porting that these devices allowed for (from the F240x MCUs).


    Regards

    Lori

  • Thanks for the confirmation. The point of the code was to demonstrate the "clobber" effect.