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.

Storing constant "variables" in rom

Expert 2260 points

Other Parts Discussed in Thread: MSP430G2553, TEST2

Hello,

I'm a bit confused as to what data types can be stored in rom. The compiler data user guide says that:

using the const keyword you can define large constant tables and allocate them into system ROM. For example to allocate a ROM table you could use the following defination:

const int digits[] = {0,1,2,3,4,5,6,7,8,9};

 

I have been experimenting a bit with this and am somewhat confused as to how this is implemented. I have done a small but of PIC programming before and microchip used a rom keyword which (for what i needed at the time, which was strings) made things fairly clear but I'm not really getting this.

 

From what I can gather by building code on CCS for a msp430g2553, the only data I can place in rom has to be in an array and must be declared before main, is this correct?

I started this initially with the idea of putting some structures into rom, and a const single structure appears to take up data space, but two+ in an array of structures  takes up no data space which I found a bit strange. I don't understand why this is limited to arrays.

 

Any pointers would be appreciated, thanks.

  • Hi,

    the compiler for MSP430 acts like a standard C compiler here... Its linker takes care that all constants will be placed in code memory (e.g. Flash) and by this these constants cannot be written. A constant is marked in the code by adding the "const" in front of the variable declaration. There is no limitation that all constants has to be arrays. In case the "const" is not used in variable declaration the variable is placed in RAM and because of this it can be read and written. Here are some possible declarations of constants:

    const  int   Test1 = 0x1234;

    const char Test2 = 0x12;

    const char Test3 = 'k';

    const char Test4[]="Test";

    Regards, V.

  • What Voyager34 said is absolutely correct.

    However, you could use: #define Test1 (0x1234) instead of const int Test1 = 0x1234; and saved 2-byts of ROM usage.

  • I know that it should not be limited to arrays but here is some code I have been playing about with:

    /*##############################################################*/

    #include "msp430g2553.h"

    typedef struct myStruct{   int i;
                                                 int j;
                                                 int k;
                                             }  tmyStruct;
                           
    const tmyStruct singleStruct = {1,2,3};            //increases data size by six bytes

    const tmyStruct arrayStruct[] = {    {1,2,3},       //does not increase data size
                                                                {4,5,6},
                                                                {7,8,9}
                                                           };

    const int i = 1;                                                     //increases data by 2 bytes
    const int digits[] = {0,1,2,3,4,5,6,7,8,9};         //does not increase data size

    void main(void)
    {
       
    }

    /*##############################################################*/

     

    I was getting the data size information from the program loaded code status information from a CCS debug session, and it seemed to clearly suggest that only const arrays are stored into rom.

    Could anyone else confirm this?

     

  • Alan B said:
    const tmyStruct singleStruct = {1,2,3};            //increases data size by six bytes

    The problem here is IMHO that the struct may be const, but the the members of the struct aren't.
    So the pointer to the struct data is const (and does not even create space in flash, as it is a symbol that can be discarded after linking), but the data isn't.

    I'm on shakey ground here, as I don't know the the C standard about this, and it is also uncertain whether the actually used compiler follows this standard (GCC explicitely states that this or that follows a specific standard, but does nto claim to completely implement this standard in every detail - and there are details where it definitely doesn't: e.g. it does not explicitely zero the uninitialized variables area, so variables not explicitely initialized with zero can have any value on startup. This is faster on startup, but surprising)

    Alan B said:
    const int i = 1;                                                     //increases data by 2 bytes

    That's strange indeed. I can imagine an algorithm that eliminates i totally, if it's address is never referenced, only its value - the linker then could change the assembly instructions to not do an indirect access to teh addressof I but to use its value as immediate value - this is possible due to the orthogonalstructure of the MSP instruction set.
    But I have no explanation why it is not put into text segment rather than data.

  • Hmm good to know I'm not being completely stupid. One other thing I noticed was when I define one of the const arrays data space doesn't increase,  but neither does the text space that is stated which concerned me some what. Is there a third segment which simply isn't stated at debug?

    As for the compiler I think I remember reading in "The C Programming Languauge" than putting const's in rom is moreso recommended than forced, but for the life of me I cannot find that statement in there again. I remember it wasn't in an obvious place.

    Jens-Michael Gross said:

    about this, and it is also uncertain whether the actually used compiler follows this standard (GCC explicitely states that this or that follows a specific standard, but does nto claim to completely implement this standard in every detail - and there are details where it definitely doesn't: e.g. it does not explicitely zero the uninitialized variables area, so variables not explicitely initialized with zero can have any value on startup. This is faster on startup, but surprising)

    I think that in general gcc will do what it thinks is best for compilation but it is possible with a flag to make it force the rules of one standard over another. To my knowledge c90 at least doesn't specifically say that declared variables other than globals should be automatically initialised to zero. But I understand what you mean, by default gcc does somewhat do what it thinks is best with c, and has some of its own quirks.

     

     

     

  • Alan B said:
    I remember it wasn't in an obvious place.

    Important things never are :) It's easy to find the lengthy legal stuff (copyright, disclaimer, license agreement) in every datasheet, but the important informations are hidden on non-obvious places. :(

    Alan B said:
    One other thing I noticed was when I define one of the const arrays data space doesn't increase,  but neither does the text space that is stated which concerned me some what. Is there a third segment which simply isn't stated at debug?

    The compiler can merge constants if they are identical. If you create three constants with tame content (or, if the compiler/linker is smart, with overlapping contents), the compiler can jsut create a combined element, or the linker can link them on the same space.

    Usually the linker isn't that smart (especially for overlapping non-identical constants) and the compiler can do so only if they are defined in teh sdame compilation unit (same C file or its includes)

    In your examples, the first array has the same content as the first element of the array of arrays, so they can reside on the same place.

    Alan B said:
    gcc will do

    My fault, it was a typo. I was talking about CCS, not GCC.
    You're right about GCC - it supports lots of standards and if you set the proper flags you'll get the desired behavior. Well, at least if there isn't a bug. :)

**Attention** This is a public forum