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.

Static memory allocation in Code Composer Studio 4.x

Other Parts Discussed in Thread: MSP430F2274

I'm writing a program in C, and I'm using a subroutine written in assembler that utilises a certaing ammount of memory (128 bytes starting from #0520h)

Instead of dynamically allocating it with malloc() I'd just like to tell the C/C++ linker/compiler not to use that part of a memory map to prevent overwriting working data between my asm and c routines. Any idea how to do this?

 I tried to use dynamic allocation but it would requite too many changes to my assembler routine so I would like to try static allocation 

  • Hi Istvan,

    below is an example I've made for storing ADC values transfered by DTC to RAM. I wanted to have them seperate from my other memory, so I decided
    to have a custom memory segment (at the beginning of RAM) for storing them.

    C code (refer to MSP430 assembler users guide for details):


    /*-----------------------------------------------------------------------------
    //   global variables stored in a seperate segment in RAM (ADCSAMPLE)
    //   contains the results of the ADC conversion  (ADRESULTS) and some special
    //   data (SPECIALS --> spare)
    //---------------------------------------------------------------------------*/
    #pragma DATA_SECTION (ADRESULTS, ".adcsample");
    #pragma DATA_ALIGN (ADRESULTS, 2);
    unsigned int ADRESULTS[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    #pragma DATA_SECTION (SPECIAL, ".adcsample");
    #pragma DATA_ALIGN (SPECIAL, 2);
    unsigned int SPECIAL[2] = {0, 0};

    Now, you need to make some changes to your linker command file too. I.e. for the code posted above:

    MEMORY
    {
        ...
        ADCSAMPLE    : origin = 0x0200, length = 0x0014 // added line; reduce RAM accordingly
        RAM                     : origin = 0x0214, length = 0x03E8
        ...


    SECTIONS
    {
        ...
        .adcsample : {} > ADCSAMPLE    /* RESERVED FOR SPECIAL VARIABLES    */

    Rgds
    aBUGSworstnightmare

  • Hello aBUGSworstnightmare.

    Thanks for the quick answer. 

     

    Says "badly formed pragma" for this one. Even tried to paste Your code into the source, same thing happens

     

    Regards,
    Istvan 

     

  • In fact.

    I don't think I need the C part of the code at all - I never address that part of the memory from C. Only the ASM routine uses it (with absolute addressing) and returns a result.

    So I'd say I'll go with the linker cmd changes (the part about the memory map that is) - that should make the linker exclude the address space that I'm using in assember...right?

  • Hi Istvan,

    yes, the memory segment will then be excluded by the linker.

    Rgds
    aBUGSworstnightmare

  • BTW,

    since we're already on this subject,
    any idea why the #pragma codes don't work?

    I pasted the whole code into my program and and it reports the error mentioned above 

  • Hi Istvan,

    I have no idea at the moment why it gives you an error on the #pragma's!

    I've just build the project were I took the code snipped from without problems (I'm using the latest CCS 4.2.0.10018).

    My setup is:

    I have a header file (i.e. globals.h) with:

    extern unsigned int ADRESULTS[8];
    extern unsigned int SPECIAL[2];

    and a source file (i.e. globals.c) with:

    /*-----------------------------------------------------------------------------
    //   global variables stored in a seperate segment in RAM (ADCSAMPLE)
    //   contains the results of the ADC conversion  (ADRESULTS) and some special
    //   data (SPECIALS --> spare)
    //---------------------------------------------------------------------------*/
    #pragma DATA_SECTION (ADRESULTS, ".adcsample");
    #pragma DATA_ALIGN (ADRESULTS, 2);
    unsigned int ADRESULTS[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    #pragma DATA_SECTION (SPECIAL, ".adcsample");
    #pragma DATA_ALIGN (SPECIAL, 2);
    unsigned int SPECIAL[2] = {0, 0};

     

    ADRESULTS and SPECIAL were global variables and could be accessed without problems!

    So, were did you copy&paste the code to? Try to add two files (one .c and one.h) as mentioned above and try to build the project.

    You may also want to have a look at 'my files' (http://e2e.ti.com/members/1371069/files/default.aspx); I have some demo code there which makes use of such kind of pragmas too. If you want to test if it comples on your machine open a new project (for MSP430F2274), add all files (.c, .h and .cmd) to it and build it.

    Rgds
    aBUGSworstnightmare

  • Istvan Prosinger said:
    I'm using a subroutine written in assembler that utilises a certaing ammount of memory (128 bytes starting from #0520h)

    Why do you need to have the memory located there?
    If you use the assembly function as a subroutine for your C project, you have already a C/ASM interchange. Why not creating a static array of the required size and use its reference inside the assembly part, letting the linker inserting the final fixed addresses?

    For the assembly code it is unimportant whether its data space is located at 0520h or 0500h or whereever, as long as it is a fixed address (so no indirect addressing is dropping the speed).

  • Hello Jens-Michael

    This is the 1st thing I tried, before I decided to search for a solution that doesn't include modifications on the assembly level.

    As I've explained above, I dont want to make radical changes to my ASM routine. It's an adaptive controller macro/subroutine I wrote several years ago, how it turns out rather complicated to change, and I'd like it as is if it's solveable with address space exclusion.

    Thanks for the sugestion though,

    Istvan

  • Istvan Prosinger said:
    This is the 1st thing I tried, before I decided to search for a solution that doesn't include modifications on the assembly level.

    It's not much of a change (unless the routine does something very 'smart', read:: uncommon)

    Just replace the static 0x520 address value by the symbol name of the array. That's it.  0x521 (if ever directly written in teh assembly source) becomes 'symbol +0x01' etc. It's good programming habit anyway, to use base address and offset (the linker will do the math at link time) instead of explicitely writing the resulting absolute values into the code.

    You can even define the array/workign area inside assembly language(wich is also way better than just occupying an arbitrary area in teh addressing range) and the linker will take care of the absolute placement later.

    Even if you insist in exactly  this location, simply defining an array at this location in the assembly file will tell the linker that this area is used, and no C variables or stack will be placed there.

**Attention** This is a public forum