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 factory data when programing the mcu

Other Parts Discussed in Thread: TM4C123GH6PGE

Hi,

I am using the TM4C123GH6PGE micro controller, with css 5.4

I need to place some data (lets call it factory data) of some elements in my project. And the user will have an ability to change the factory settings which I want to store in a diffrent location on the flash.
the reason to do that is to be able if needed to restore the device to the initial configuration.

I manged to declare memory sections in the flash for that.

My question is if there is a way to store my data in the flash when I program the micro controller (jtag or dfu).

the memory sections:


MEMORY
{
    FLASH (RX) : origin = 0x00000000, length = 0x00036000
    FACTORY_DATA (RX) : origin = 0x00036000, length = 0x00002000
    USER_DATA (RX) : origin = 0x00038000, length = 0x00002000
    SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* Section allocation in memory */

SECTIONS
{
    .intvecs:   > 0x00000000
    .text   :   > FLASH
    .const  :   > FLASH
    .cinit  :   > FLASH
    .pinit  :   > FLASH
    .init_array : > FLASH
    .machineFactoryData  :   > FACTORY_DATA
    .machineUserData  :   > USER_DATA

    .vtable :   > 0x20000000
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM
}

I tried, just for the example to store array with the value of 5 in the flash with no success.

#pragma DATA_SECTION(_MachineFactoryData, ".machineUserData")
#pragma RETAIN (_MachineFactoryData)
#pragma DATA_SECTION(_MachineUserData, ".machineFactoryData")
#pragma RETAIN (_MachineUserData)

uint32_t _MachineFactoryData[2048] = {5} ;

uint32_t _MachineUserData[2048] ;

but all the values are 0xffffffff

what am I doing wrong?

thanks Asi.

  • A couple of observations

    Asi Lazar said:

    uint32_t _MachineFactoryData[2048] = {5} ;

    uint32_t _MachineUserData[2048] ;

    With those declarations the compiler will expect the memory to be stored in RAM and set up run time initializations for them rather than compile time. 

     

    You should probably have

    const uint32_t _MachineFactoryData[2048] = {5} ;
    
    const uint32_t _MachineUserData[2048] ;
    

    instead.  That should initialize MachineUserData to zeros and MachineFactoryData to zeros except for the first element.

    Second, if MachineFactoryData is the factory defaults and is not to be programmed over, there is probably no reason to explicitly place it.  It will save yourself future headaches if you can avoid explicit placements.

     

    Third, if you haven't yet done so.  Check the map produced by link to check that your variables did get located correctly.  I don't know the link & locate directives of your compiler althought they look reasonable.

     

    Robert

  • Thanks.

    It did the job of storing the _MachineFactoryData[2048] = {5} ; at the correct place and with the correct values (5 at the first element and the rest with zeros).

    For the second array, it kept it with 0xffffffff, and did not initiate the array to zeros, but that is only for the test of placing data in the flash memory and it is even better that way.

    I hope there will be no difference when I will change the array to a structure of the factory data.

    About not defining the location for the factory data, I understand that probably I will never erase it but I figured that I want to keep the 1KB alignment anyway.


    I have looked at the map produced by link the arrays are at the correct place in the memory and they have the correct size as well.

    Thanks again,

    Asi.

  • Hi Robert,

    I have another question that maybe you encouter and know how to deal with, The reason that I need the const array in the flash is to store the "factory" data. My intention was to create a struct that contain all the information (this sturct can contain other structs as well) and to program it to the flash memory. But when I try to do it I get this error message:


    #28 expression must have a constant value

    when I try to enter a struct to the factory data structure.

    And it doesn't matter what I try, I cant manage to set the data to the flash.

    Do you have any insights about it?

    Thanks again,

    Asi.


    Is there a way to store

  • Asi Lazar said:

    #28 expression must have a constant value

    when I try to enter a struct to the factory data structure.

    And it doesn't matter what I try, I cant manage to set the data to the flash.

    The error message is fairly self contained.  The expression must be a compile time constant, it cannot contain variables or function calls.  The compiler must be able to determine the value while compiling.

    If that still doesn't make sense, reduce the initialization to the smallest piece that shows the problem and let us take a look at it.

    Robert

  • Hi,

    Here is an example of my problem:

    where I define a basic structure and than when I try to enter it to another structure I get the error.

    // the basic structure

    typedef struct
    {
        int32_t A;
        int32_t B;
    }
    BasicStruct;

    // the structure with a structure in it:

    typedef struct
    {
    	BasicStruct s;
    }
    SturctOfStruct;
    const BasicStruct bs = { 5,10}; const SturctOfStruct st = { bs, };

    when I try to do it I get the " error #28: expression must have a constant value ".

    I actually found a way to overcome it if I will write it this way:

    const SturctOfStruct st =
    {
    		{ 5,10},
    };

    I found it only after adding the post here, and I still hope there is a more elegant way to do it.
    Thanks again,

    Asi.

  • Asi Lazar said:

    where I define a basic structure and than when I try to enter it to another structure I get the error.

    Asi Lazar said:
    const BasicStruct bs = { 5,10}; const SturctOfStruct st = { bs, };

    You get the error since bs is a variable not a constant.  A const variable is not a constant (at least in C).

    You could use a pointer to a structure rather than a structure but I think that will make things too complex in your case since updating now requires walking the structure tree.

     

    typedef struct
    {
    	BasicStruct *s;
    }
    SturctOfStruct;
    const BasicStruct bs = { 5,10};
    
    const SturctOfStruct st =
    {
    		&bs,
    };

    Robert

  • It will be too complex...

    I guess I will stick to the "ugly" way of just writing the values I want in the sturct...

    Thanks for all the help.

    Asi.

  • Glad I could help.  This is one of the areas of the language that is more usually noticed by embedded programmers.

    Another thing to consider is making an application specific code generator for the factory default structure init.  You can set up the data in a more friendly form (such as a csv file with labels) and generate the initialization data with that.  Languages like AWK and PERL (or even, uggh,  vbscript) allow you to put something together pretty quickly.

     

    Robert