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.

Ram or Flash usage with MSP430?!

Genius 4170 points
Other Parts Discussed in Thread: MSP430F5437A

Hello,

 

i am using the msp430f5437a controller, now i am getting deeper into the programming and i am really wondering on how i can tell the code what to store in which data spaces.

 

I already figured out the linker *.cmd file and how the RAM and FLASH is initialized in there and i compared that with my corresponding Datasheet page 15 called Memory Organization.

 

Now several questions are on my mind:

  • for my application i will need at least 12 kB of free memory to store some values, can i store those also in the Flash or are variables which are produced in real time code while running only ( by default) stored in RAM.
  • there are some tiny Flash Blocks called Information Memory, InfoA etc. , i cannot proof by Code that those are really Flash memory blocks, please could some TI eployee proof where i can get that information from.

    .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS */
    .infoB     : {} > INFOB
    .infoC     : {} > INFOC
    .infoD     : {} > INFOD

Now corresponding memory:

    INFOA                   : origin = 0x1980, length = 0x0080
    INFOB                   : origin = 0x1900, length = 0x0080
    INFOC                   : origin = 0x1880, length = 0x0080
    INFOD                   : origin = 0x1800, length = 0x0080

it also says RAM starts at

RAM                     : origin = 0x1C00, length = 0x4000

FLASH should start at:

FLASH                   : origin = 0x5C00, length = 0xA380
FLASH2                 : origin = 0x10000,length = 0x35C00

 

So do i have to trust TI that the Info is put into the right space?

 

Thank You in advance for time and effort :)

 

Greetings. Seb

 

  • seb said:
    for my application i will need at least 12 kB of free memory to store some values, can i store those also in the Flash or are variables which are produced in real time code while running only ( by default) stored in RAM.

    All variabels that you declare as variables are default stored in RAM. If you apply any initial value to the variable definition, then these values are stored in a separate flash area (attached on the code) and copied form there to ram on every reset.

    You can put constants directly in flash, then the value is stored in flash and the reference to the value points to flash adn every access ot it goes there.

    However, writing something to flash is a more complex thing, as you cannot overwrite a value in flash: you can only change '1' bits to '0' but not back. To return a flash cell to '1', it mus tbe erased, and you can only erase a complete flash block togheter (which in case of code flash is 512 bytes which are all erased). This is why there are teh INFO flash blocks with a smaller block size.
    Erasing, however, takes a looooong time (several milliseconds).  Also, the writing process takes a long time during which the flash is unavailable (and cannot provide the code to the CPU). So if you want to store data on flash, it requires a dedicated 'write data to flash' function and cannot be done by just assigning a value to a variable that is located in flash.

    seb said:
    i cannot proof by Code that those are really Flash memory blocks, please could some TI eployee proof where i can get that information from.

    I recommend the device datasheet. Short-Form Description -> Memory Organization. It's all there.

    seb said:
    So do i have to trust TI that the Info is put into the right space?

    You can compare it with the datasheet. If you quesiton that and the linker scripts, well, the only way to be sure is to rent a raster-force microscope and analyze the die - or write test code that confirms it (but then, if it does not confirm the result - and even if it does - I'd also question the test code)

  • Hi Jens-Michael Gross

    "All variabels that you declare as variables are default stored in RAM. If you apply any initial value to the variable definition, then these values are stored in a separate flash area (attached on the code) and copied form there to ram on every reset."

    I have a follow-up question on this.

    Let's assume that in a given MSP430 application, there are certain parameters that can be changed via the MSP430's UART, with the use of PC software.

    These parameters are initialized to some default values set by the firmware designer ("factory defaults").

    After the user changes the parameters, he/she would like to save these parameters so that if power is removed from the device, when power is applied again, the firmware will load the customized parameters instead of the factory defaults. This of course requires writing to the flash when the user requests to do so via the software, and then reading from the flash upon subsequent power-ups.

    My question has to do with the variable types of these changeable parameters with respect to best C coding practices. Would it be best to allocate these parameters to specific RAM locations, as described here: http://processors.wiki.ti.com/index.php/Placing_Variables_in_Specific_Memory_Location_-_MSP430

    The reason I ask this is that it seems that would make the flash writing process cleaner. The read pointer would point to the RAM location where the first parameter starts. The write pointer would point to the flash location where the first parameter should be stored. Since we know the number of bytes that these parameters take up, we could simply write a routine that copies data from RAM to flash, increment both pointers, and stop after having done the specified number of bytes.

    However, I have a feeling that there may be other problems associated with this method. For example, the firmware designer would have to make sure that these RAM locations are never overwritten automatically by the program. I believe this could be done by adjusting the linker file.

    I also have a feeling that I may be complicating the programming approach here, which itself would introduce more errors, but I want to make sure I use the best approach.

    Thanks in advance,

    Mehdi
  • I know this situation. Let me tell you how I did solve this in my projects:
    I have a struct type defined which contains all configuration parameters. Of this struct, I have three instances: One is a const. It contains all the factory defaults. The second is a ram variable. Th ewhole program reads and writes any values from this. The third is a pointer that points to info memory.
    At program start, the program copies the config data from info memory to the ram struct and performs a CRC check. If the CRC check fails (because the info memory was never initilalized), the factrory defautls are copied from the const data to the ram data and then written to info memory.
    I actually have two info memory locations. So when I make changes to the config in ram and write it back, I write to the second location and then invalidate (erase) the first. When reading, I try to read both, where normally one would fail the CRC check and the second won't. This ensures that even if there is a system failure right when writing the config, the old one is still valid, as it is only erased after a successful write. (the config struct contains a field where the read funciton writes down from which location the data was read, so when writing, it knows to use the other one)
    This has proven to work reliable, and quite fail-safe.
    Lately, I have refined this method: at startup, I only check which one is the right one and set the pointer accordingly. The program therefore accesses the config directly from info memory. On config changes, I read the config to ram, make the change, and write it back (and update the pointer).
    This methodha sa little bit more overhead, since all program code that reads a config entry, now has to do it though a pointer indirectly, rather than accessing the ram version. However, it adds a bit more security, and the overhead isn't that large.
    Once you have implemented this the first time, you can re-use the read and write function for all projects, even if the config struct changes. Only the part where the defaults are copied needs to be changed, base on the struct members. (or you use memcpy, then it is transparent and 100% re-usable too).
  • >least 12 kB of free memory to store some values

    That is not some values, but a boat-load of values in the micro controller world.

    1: Find a mcu that have that much ram.

    2: Does the data really need to be all of it available at one time?
        can you generate 512bytes at a time to send to what ever external device?

    Are the values generated by the code once and then never changed (or at least not very often)?, use Flash.

    As you need so much, you align it to use whole flash blocks.
    But for less than a block you can write to reserved empty space that are 0xff and store a few bytes once.

  • Indeed, 12k are quite a lot.
    However, if these 12k are just lookup tables which are constant (or only seldom changed), then they can be stored in flash rather than in ram.

    Here's a trick to safely store large data in flash that can be safely rewritten (won't work for data that needs to get some initial value):

    1) declare a constant array of bytes that is 511 bytes larger than the size of the table. This will ensure that the reserved flash space has an area as large as your storage space aligned to 512bytes flash sectors. Initialize its first byte with 0xff
    2) declare a pointer to your data
    3) assign the pointer the address of the data table +0x100 & 0xFe00. So your pointer points to the beginning of the first full 512 byte flash segment inside the reserved space.
    4) check whether the table is empty. If so, manually initialize it.
    5) access your data table through the pointer.
    5) if you later need to fill the table with new data (e.g. from PC), just erase and refill it.

    It is a bit complex, but does not require tweaking of linker files and is portable across different compilers. And even allows changing the reserved space in source code (all values can be calculated at compile time)
    This complexity is needed to ensure that you don't have both, table data and code, mixed in one flash segment. Because you can only erase a full 512byte flash segment together, so even if backing the overlapping part up into ram, part of your code would be temporarily gone - perhaps just the copy code itself.

    Example:
    typedef struct mystruct {...}
    #define NUM_ELEMENTS 10
    const unsigned char reserved1[(NUM_ELEMENTS*sizeof(mystruct))+511] ) {};
    const mystruct * const mydata = (reserved1&0xFFE0)+0x100;

    Access it with x = mydata{y]->z;

    It works even if the struct or the number of structs in the data changes.
    Writing to the data requires a dedicated flash write function anyway.

**Attention** This is a public forum