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.

TM4C129ENCPDT: Programming variable to flash location only at load

Part Number: TM4C129ENCPDT

TI-RTOS 2.16.01.14

TivaWare C 2.2.0.295

CCS 10.2.0

I would like to be able to store some configuration information like a default IP address, firmware version, and some constants into empty (very separated from my program memory) locations in flash - looking around 0xf0000 for reference. Is there a way to manually or by script load these values? I can't seem to directly edit it in the Memory Browser. It needs to be somewhere that only runs at initial program load. Any suggestions? 

  • Hi Peter,

      Please refer to the ARM compiler user's guide on section 5.11.8 about using DATA_SECTION Pragma. The below post will be quite helpful too. 

    https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/897732/compiler-msp432e401y-pragma-data_section-requiring-my-variable-be-declared-as-constant

    I can't seem to directly edit it in the Memory Browser.

    The flash memory is non-volatile. You cannot write to flash in debugger like SRAM. if you want to write data to the flash during runtime you can use FlashProgram() and FlashErase() APIs. See below and also refer to the Tivaware Peripheral Driver user's guide for details. 

  • Thank you, that link is very helpful. I will look into the persistent pragma. 

    I am intrigued by the answer in that thread that suggests using EEPROM as that is what i originally started with. I switched to Flash in hopes that i could clumsily exploit the fact that you have to intentionally erase it before programming again. My plan was to program once in my application's initialization using just the Program API function. Then any time it needs to be changed, i would erase the block and program anew. In this manner, a reset would not overwrite newly programmed values but a program load would return it to default. 

    The issue here is that i have to either read, save, and compare anything that is unchanged within a block before erase or space every piece of data onto separate flash blocks. 

    By using EEPROM, not only do i avoid the erase but i also can overwrite specific locations and use memory much more densely. 

    The question, then, is would the persistent pragma also apply to locations in EEPROM?

    #define IP_ADDR_LOC 0x400AF420

    #pragma PERSISTENT

    #pragma location = IP_ADDR_LOC

    uint32_t IPAddr = 0xAC100A01;

    So that stuff could be in the header of main to set up a default - does that actually program that value into that location in EEPROM or do i need to use the API function? If the API, where should that be placed?

  • By using EEPROM, not only do i avoid the erase but i also can overwrite specific locations and use memory much more densely. 

    The question, then, is would the persistent pragma also apply to locations in EEPROM?

    Hi Peter,

      No, you cannot use the pragma on EEprom. EEprom memory is not memory mapped to CPU's address space. EEprom program and erase also need to go through API. Programming EEprom is different from programming the main flash. You need to treat them as two different non-volatile memories from programmer's model perspective.  I believe you have looked at EEprom API. Below is an example of how to use them. You said you were using EEprom in the beginning. What problems did you have?

     

    uint32_t ui32EEPROMInit;
    uint32_t pui32Data[2];
    uint32_t pui32Read[2];
    //
    // Enable the EEPROM module.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);
    //
    // Wait for the EEPROM module to be ready.
    //
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EEPROM0))
    {
    }
    //
    // Wait for the EEPROM Initialization to complete
    //
    ui32EEPROMInit = EEPROMInit();
    //
    // Check if the EEPROM Initialization returned an error
    // and inform the application
    //
    if(ui32EEPROMInit != EEPROM_INIT_OK)
    {
    while(1)
    {
    }
    }
    //
    // Program some data into the EEPROM at address 0x400.
    //
    pui32Data[0] = 0x12345678;
    pui32Data[1] = 0x56789abc;
    EEPROMProgram(pui32Data, 0x400, sizeof(pui32Data));
    //
    // Read it back.
    //
    EEPROMRead(pui32Read, 0x400, sizeof(pui32Read));

    So that stuff could be in the header of main to set up a default - does that actually program that value into that location in EEPROM or do i need to use the API function? If the API, where should that be placed?

    As I explained above, you must use the EEprom APIs to program data into EEprom. I also think EEprom is the right choice for your application if you need to update the data during runtime that will not be affected by reset or power cycle. 

  • My issue is initializing it only once at program load. That is very easily accomplished with the persistent pragma in flash but then flash has the drawback of overwriting an entire block and having to essentially save it, edit it, and reprogram it. I would much prefer to use EEPROM as you suggest and as i thought but i can't figure out how to initialize a location in it only once at program load. Here's a use case:

    1. I have a default IP address that i will program into each micro at program load. 

    2. User can change the address, upon reset the stack inits with the new IP (i have this part figured out)

    3. That IP should now be in EEPROM and used from now on after subsequent resets and power cycles <- this is what im missing because my initialization done for step 1 will overwrite with the default

  • Hi Peter,

      Can you not also store a flag on EEprom as a condition for you to initialize the default IP or skip in step 1. For example, if the flag value is equal to 0xA5A5, then don't run the initialization step. The flag will be default to 0xFFFFFFFF on EEprom as that will be the value on a virgin silicon. In your step 3, after a new IP is programmed then you will also program the flag to 0xA5A5 or whatever value you want.  In the next power cycle, the flag remains as 0xA5A5 and you will skip step 1. 

  • My issue is initializing it only once at program load.

    EEPROM write via CCS is an example CCS GEL file to program the EEPROM on a TM4C123 device. This could be used as the basis for a custom GEL script which is used when CCS downloads the program to also write to the EEPROM.

    I haven't attempted to test this myself.