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.

Large data memory model for MSP430: Why does the compiler use a 16-bit pointer instead of a 20-bit one?

Other Parts Discussed in Thread: MSP430F5418

Hi,

below is a small sample program which I will use to ask a question. It is for MSP430F5418 with large data memory model enabled.
Because I don't know the real answer to this question (see http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/66903/242754.aspx#242754) and was only able to present a solution I'd like to have this question asked here.

#include "msp430f5418.h"

int test[7680] = { 1 };


#pragma DATA_SECTION(testByte, ".testObjSeg") ;
unsigned char testByte [50];
unsigned char *pointer;

void main( void )
{
  // disable watchdog timer
  //------------------------
  WDTCTL = WDTPW + WDTHOLD;               // Stop WDT
 
  pointer = &testByte[4];
  test[3] = *pointer;
  test[7678] = 0xaa;
  test[7679] = 0xa0;
  test[0] = test[7679] - test[7678];
}

with an user-defined-segment (TEST_OBJ_SEG) at the end of flash memory:

MEMORY
{
    ...
    FLASH                   : origin = 0x5C00, length = 0xA380
    FLASH2                  : origin = 0x10000,length = 0x0DC00 /* keep in mind to reduce the size of FLASH2 because of TEST_OBJ_SEG !*/
    TEST_OBJ_SEG    : origin = 0x1DC00,length = 0x08000   
    INT00                   : origin = 0xFF80, length = 0x0002
    ...


The code above is the solution for the problem with the code below.

void main( void )
// disable watchdog timer
//------------------------
WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
test[3] = testByte[4]; // problem with this line!
test[7678] = 0xaa;
test[7679] = 0xa0;
test[0] = test[7679] - test[7678];
}

The question is: Why does the compiler uses a 16-bit pointer for acessing testByte[4] (test[3] = testByte[4];) instead of using a 20-bit ones (as I already mentioned large data memory model is enabled)?

Thanks for your help, kind regards
aBUGSworstnightmare

 

  • aBUGSworstnightmare,

    Starting with the latest tools release (3.3 codegen tools), the compiler assumes by default that all non-constant global and static variables are located in the low 64k of memory.  This is done since no current devices have RAM above the 64k boundary and it allows the compiler to generate more efficient code.  In this specific case, it can generate:

    MOV.B   &testByte+4, r15   ; 4 byte instruction, only supports 16-bit address

    instead of:

    MOVX.B &testByte+4, r15   ; 6 byte instruction, supports 20-bit address

    This assumption can be disabled by using the --near_data=none option:

      --near_data=none,globals
                              Indicates whether certain types of data are
                               guaranteed to be in the near 64k of memory and
                               allows the compiler to optimize performance based on
                               this information.  Globals indicates that all global
                               and static variables will be located in near memory.
                                This option only applies to MSP430X devices.
                               (Default:globals)

    However, this can incur a decent code size hit.  Since testByte is located in flash and can't actually be written to it probably makes more sense to make it a constant:

    const unsigned char testByte[50];

    This will cause a 20-bit pointer to be used when accessing testByte, but the optimization will still be applied to variables located in RAM.

    Also, as an aside, the latest tools also introduced a restricted data-model (--data_model=restricted) that is usually preferable to the classic large-data model unless you use really large structures.  It still allows data to be located anywhere in memory.  I highly encourage people to try using it instead of --data_model=large/--large_memory_model.

    Thanks,

    Todd