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.

MSPM33-SDK: EEPROM management

Part Number: MSPM33-SDK
Other Parts Discussed in Thread: MSPM33C321A, SYSCONFIG, UNIFLASH

Hello,

I use the µc MSPM33C321A, and I would like to manage EEPROM.

I do not want to use example, which manage EEPROM in Type_A or Type_B, I want to manage myself the EEPROM.

So I need to know, the following points:

1 - Does it modify the makefile or other to declare the EEPROM memory ?

2 - How to intialize the EEPROM memory (if necessary), which function(s) used ?

3 - Which function used to read 8 bits in EEPROM memory ?

4 - Which function used to write 8 bits in EEPROM memory ?

5 - Which function used to erase a sector ?

6 - EEPROM memory is always 32Kb, means 32 sectors ?

Have a nice day

  • Hi 
    1. Does it modify the makefile or other to declare the eeprom memory?
    No, you do not need to modify the Makefile. Instead, you must configure your Linker Command File . You must ensure that the 32KB data flash region starting at its designated memory address is marked as reserved or designated as a specific section so that the compiler does not place executable application code or standard RAM variables there
    I will reply the other question later.
    I do not want to use example, which manage EEPROM in Type_A or Type_B
    May I know why you don't use EEPROM emulation?
    how many data you will save and how long you will update these data?
  • Hello,

    ok for Linker Command File modification, but could you tell me how to do, what write ?

    I do not want use the Type_A or B because I will have a EEPROM management, very specific, I means I have lot of structures to save, but independantly managed,, any will be redondant, other no. And the examples are not adapted.

  • 1. What to Write in your Linker Command File (.cmd)
    Open your project's .cmd file (typically found in the root directory of your Code Composer Studio project) and update both the MEMORY and SECTIONS blocks
    +++++++++++++++++++++++++++++++++++++++++++++++++++++
    MEMORY
    {
    /* Existing Main Flash and SRAM definitions (Keep these as they are) */
    FLASH (RX) : origin = 0x00000000, length = 0x00100000 /* Example 1MB Main Flash */
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000 /* Example 256KB SRAM */

    /* ADD THIS LINE: Define the physical MSPM33 Data Flash region */
    DATA_FLASH (RW) : origin = 0x80000000, length = 0x00008000 /* 32KB high-endurance region */
    }

    SECTIONS
    {
    /* Existing sections like .text, .cinit, .data, etc. go here */

    /* ADD THIS BLOCK: Map your custom EEPROM section to the new memory area */
    .eeprom_section : > DATA_FLASH, type = NOLOAD
    }
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++
    • origin = 0x80000000: This points directly to the starting boundary of the physical MSPM33 Data Flash.
    • length = 0x00008000: Allocates the full 32KB area for your EEPROM variables.
    • type = NOLOAD: Directs the debugger/programmer not to overwrite or erase this block when you flash new code, preserving your saved non-volatile data.
    2. What to Write in Your C Source Code
    To link a structure or array directly into this newly isolated memory space, use the section attribute in your variable declaration:
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #include <stdint.h>

    // Define a macro for easy section assignment
    #define EEPROM_STORAGE __attribute__((section(".eeprom_section")))

    // Example structure for your application settings
    typedef struct {
    uint32_t boot_count;
    uint8_t device_mode;
    char serial_number[16];
    } AppSettings;

    // Place the structure into the dedicated Data Flash area
    volatile const AppSettings my_eeprom_data EEPROM_STORAGE;
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Notes: 
    • Flash Sector Grids: The flash erase granularity for MSPM family devices is handled in 1KB sectors. Ensure your software driver erases the exact sector boundaries within the 0x80000000 block before modifying any bytes.
    • SysConfig Generation: If your project automatically generates code via Texas Instruments SysConfig, ensure that "Linker file generation" doesn't overwrite your manual changes. If it does, disable auto-generation for the .cmd file within the SysConfig interface. refer to MSPM0G3507: Linker Command File 

    Thanks!

  • Hello,

    first question about cmd file

    You requested me to add:

    DATA_FLASH (RW) : origin = 0x80000000, length = 0x00008000 /* 32KB high-endurance region */

    but I have:

    SRAM (RWX) : origin = 0x30000000, length = 0x0003FFFF
    DATA (R) : origin = 0x80000000, length = 0x00007FFF
    BCR_CONFIG (R) : origin = 0x80101800, length = 0x000003FF
    BSL_CONFIG (R) : origin = 0x80101C00, length = 0x000003FF

    That means it will be a conflict with DATA, BCR_CONFIG and BSL_CONFIG.

    How can do because DATA and DATA_FLASH are in same place ? 

    And what to do of DATA, BCR_CONFIG and BSL_CONFIG ?

    Thanks

  • Hi 

    I will check the detailed and feedback early of next week

    Thanks

  • Hello,

    do you have news ?

    Thanks

  • There is no conflict with bcr_config and bsl_config because they are located at a higher address space (0x8010xxxx) that does not overlap with the data flash region. The region named data (r) in your original file and the requested data_flash (rw) refer to the exact same physical 32KB high-endurance flash memory on MSPM33C321A.
    How to Modify Your Linker Command (.cmd) File
    You do not need to keep both data and data_flash. Simply replace or modify the existing data region definition. MSPM0G3507: Linker Command File 
    1. Modify the data region: Rename data (r) to data_flash (rw) and ensure the length is set to 0x00008000 (full 32KB).
    2. Leave configuration regions alone: Keep bcr_config and bsl_config exactly as they are. They reside in the separate NONMAIN flash area and are required for the device to boot safely
    Updated MEMORY Directive Example
    Update the MEMORY block in your .cmd file to look like this:
    MEMORY
    {
    sram (rwx) : origin = 0x30000000, length = 0x0003ffff
    data_flash (rw) : origin = 0x80000000, length = 0x00008000 /* 32kb high-endurance region */
    bcr_config (r) : origin = 0x80101800, length = 0x000003ff
    bsl_config (r) : origin = 0x80101c00, length = 0x000003ff
    /* Include your standard FLASH/MAIN program memory regions here as well */
    }
    What to Do Next in the SECTIONS Directive
    To map your EEPROM emulation variables to this newly defined space, add a section placement inside the SECTIONS block of your file https://software-dl.ti.com/ccs/esd/documents/sdto_cgt_Linker-Command-File-Primer.html
    SECTIONS
    {
    /* Maps your EEPROM data variables to the high-endurance flash */
    .TI.eeprom : {} > data_flash
    }
    In your C code, you can then place your EEPROM emulation array into this section using compiler attributes (such as #pragma DATA_SECTION or __attribute__((section(".TI.eeprom")))).
    Thanks
  • Hello,

    thanks a lot for all these information, but I have again some questions:

    ******************************************************************************************

    Question 1 : Do you confirm, the modification are correct ?

    In device_linker.cmd file :

    Before

    MEMORY
    {
    FLASH (RX) : origin = 0x10000000, length = 0x000FFFFF
    SRAM (RWX) : origin = 0x30000000, length = 0x0003FFFF
    DATA (R) : origin = 0x80000000, length = 0x00007FFF
    BCR_CONFIG (R) : origin = 0x80101800, length = 0x000003FF
    BSL_CONFIG (R) : origin = 0x80101C00, length = 0x000003FF
    }

    SECTIONS
    {
    .intvecs: palign(16) {} > 0x10000000
    .text : palign(16) {} > FLASH
    .const : palign(16) {} > FLASH
    .cinit : palign(16) {} > FLASH
    .pinit : palign(16) {} > FLASH
    .rodata : palign(16) {} > FLASH
    .ARM.exidx : palign(16) {} > FLASH
    .init_array : palign(16) {} > FLASH
    .binit : palign(16) {} > FLASH
    .TI.ramfunc : load = FLASH, palign(16), run=SRAM, table(BINIT)

    .vtable : > SRAM
    .args : > SRAM
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM (HIGH)

    .BCRConfig : {} > BCR_CONFIG
    .BSLConfig : {} > BSL_CONFIG

    .DataBank : palign(16) {} > DATA

    }

    Now

    MEMORY
    {
    FLASH (RX) : origin = 0x10000000, length = 0x000FFFFF
    SRAM (RWX) : origin = 0x30000000, length = 0x0003FFFF
    /* DATA (R) : origin = 0x80000000, length = 0x00007FFF*/
    DATA_FLASH (RW) : origin = 0x80000000, length = 0x00008000 /* 32KB high-endurance region */
    BCR_CONFIG (R) : origin = 0x80101800, length = 0x000003FF
    BSL_CONFIG (R) : origin = 0x80101C00, length = 0x000003FF
    }

    SECTIONS
    {
    .intvecs: palign(16) {} > 0x10000000
    .text : palign(16) {} > FLASH
    .const : palign(16) {} > FLASH
    .cinit : palign(16) {} > FLASH
    .pinit : palign(16) {} > FLASH
    .rodata : palign(16) {} > FLASH
    .ARM.exidx : palign(16) {} > FLASH
    .init_array : palign(16) {} > FLASH
    .binit : palign(16) {} > FLASH
    .TI.ramfunc : load = FLASH, palign(16), run=SRAM, table(BINIT)
    .eeprom_section : > DATA_FLASH, type = NOLOAD                                /* <-- Add here */

    .vtable : > SRAM
    .args : > SRAM
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM (HIGH)

    .BCRConfig : {} > BCR_CONFIG
    .BSLConfig : {} > BSL_CONFIG

    .DataBank : palign(16) {} > DATA

    }

    ******************************************************************************************

    Question 2 : About eeprom declaration in SECTION

    first answer, you tell to add :

    .eeprom_section : > DATA_FLASH, type = NOLOAD

    and in last:

    .TI.eeprom : {} > DATA_FLASH

    So which one is the good one, and for second, that means when I will reflash the SW, this section will be reflash to ? Due to no "NOLOAD"

    ******************************************************************************************

    Question 3 : EEPROM declartion

    you tell me to declare like this:

    #pragma DATA_SECTION

     or

     __attribute__((section(".TI.eeprom"))))

    Does it declare all EEPROM, means 32Kb ?

    Or Can I declare like this:

    __attribute__ ((section(".TI.eeprom"))) uint8_t EEPROM_Memory[32768];

    Thanks

  • Hello,

    other point, now, when I compile, I have this

    [13]warning #10247-D: creating output section ".text" without a SECTIONS specification
    [14]warning #10247-D: creating output section ".data" without a SECTIONS specification
    [15]warning #10247-D: creating output section ".bss" without a SECTIONS specification
    [16]warning #10247-D: creating output section ".cinit" without a SECTIONS specification
    [17]warning #10247-D: creating output section ".rodata" without a SECTIONS specification
    [18]warning #10247-D: creating output section ".intvecs" without a SECTIONS specification
    [19]warning #10247-D: creating output section ".stack" without a SECTIONS specification
    [20]warning #10210-D: creating ".stack" section with default size of 0x800; use the -stack option to change the default size

    Thanks

  • Hi Sebastien Le Diour

    I will check the detailed later. discuss and feedback in the early of next week

    Thanks

  • Hello,

    any news ?

    Thanks

  • Hi Sebastien Le Diour

    Question 1 : Do you confirm, the modification are correct ?

    No, the modifications are not completely correct and will cause a compilation error.
    While your changes to the MEMORY block are a good fix for the length typo (0x00008000 instead of 0x00007fff) and accurately update the permissions to read/write (rw), you forgot to update the section mapping at the bottom of the script.
    Because you commented out the data memory region identifier, the linker will throw a "memory range not found" error when it tries to place .databank into data.
    The Correction
    Update .databank at the end of your sections block to point to data_flash
    sections {
    /* ... (rest of your sections remain the same) ... */

    .eeprom_section : > data_flash, type = noload

    .vtable : > sram
    .args : > sram
    .data : > sram
    .bss : > sram
    .sysmem : > sram
    .stack : > sram (high)

    .bcrconfig : {} > bcr_config
    .bslconfig : {} > bsl_config

    /* FIX: Change 'data' to 'data_flash' */
    .databank : palign(16) {} > data_flash
    }
    Why your other changes are correct:
    • length = 0x00008000: This properly maps the full 32KB high-endurance DATA flash range.
    • (rw) permission: Necessary since your application code will need to perform erase and write operations on this sector.
    • type = noload: This is ideal for EEPROM emulation. It prevents your IDE/debugger from overwriting your saved data every time you flash a new firmware update.

    Question 2 :About eeprom declaration in SECTION

    The .eeprom_section : > data_flash, type = noload syntax is the correct and safest pattern to use.
    The name of the section (.eeprom_section vs. .TI.eeprom) is completely up to your preference, provided it matches the exact section name declared in your C variables. However, omitting the type = noload attribute introduces significant data risks.
    What happens when you reflash without type = noload?
    If you map a section using .TI.eeprom : {} > data_flash without the noload attribute, your saved EEPROM data will be wiped out every time you reflash or debug your software.
    Without this flag, the debugger/programmer encounters the following issues:
    • Automatic Sector Erases: Tools like Code Composer Studio (CCS) or UniFlash default to erasing all active flash sectors before writing new code. It will view your EEPROM partition as regular application memory and erase it.
    • Payload Overwrites: If you initialize any array or structure in your C code within that section, the compiler packages those defaults into the compiled binary file (.out / .bin). Flashing will force-overwrite your real, runtime-saved data with those compiler defaults.
    • Bloated Binaries: The flashing tool will attempt to actively track and program that section, wasting time during development cycles.
    Why type = noload protects your data
    The type = noload directive acts as an explicit instruction to the linker and the hardware debugger:
    • Memory Allocation: It tells the linker to reserve this exact block of memory so that standard application code (.text or .rodata) never accidentally spills into your EEPROM partition.
    • Flashing Exclusion: It orders the debugger to bypass this area completely during code uploads, preventing pre-flash erases and preserving your runtime data intact across separate software versions.
    Recommended Implementation
    Keep a single, clean declaration in your device_linker.cmd script:
    /* Safely allocate the sector for EEPROM, preventing debuggers from wiping it */
    .eeprom_section : > data_flash, type = noload
    Then, map your persistent structures or arrays in your C source file like this:
    __attribute__((section(".eeprom_section"))) uint8_t My_EEPROM_Buffer[256];
    Question 3 : EEPROM declartion
    The declaration __attribute__ ((section(".TI.eeprom"))) uint8_t EEPROM_Memory[32768]; is exactly how you allocate the entire 32KB block.
    Here is how the compiler and linker interpret your options:
    1. Does just naming the section allocate all 32KB?
    No. The #pragma DATA_SECTION or __attribute__((section("..."))) attributes only tell the compiler where to put a variable. They do not automatically define its size.
    • If you apply it to a 10-byte array, only 10 bytes will be reserved in that section.
    • The remaining space in the 32KB data_flash region would technically sit empty, but could be vulnerable to errors if you try to read/write past your 10-byte variable in C.
    2. Is your 32KB array declaration correct?
    Yes, it is the best practice. Declaring the full array size explicitly tells the compiler and linker to consume all 32,768 bytes of that region.
    This approach offers two critical protections:
    • Overrun Prevention: It prevents you from accidentally declaring other standard variables inside that specific memory section.
    • Compiler Awareness: Your C code becomes fully aware of the boundaries of your EEPROM simulation, allowing you to use sizeof(EEPROM_Memory) safely in your flash read/write functions.
    How to implement this in your C file
    Because you are using type = noload in your linker command file, you should never initialize this array with a value (like = {0}). It should be declared as uninitialized data.
    /* Allocate the entire 32KB block for EEPROM emulation */
    __attribute__ ((section(".eeprom_section"))) uint8_t EEPROM_Memory[32768];
    (Note: Ensure the section name ".eeprom_section" perfectly matches whatever name you settled on in your device_linker.cmd file).
  • Hello, 

    thanks a lot for all these explanation, unfortunatly the first part (regarding linker) does not work.

    I have now, this:

    -uinterruptVectors
    --stack_size=256

    MEMORY
    {
    FLASH (RX) : origin = 0x10000000, length = 0x000FFFFF
    SRAM (RWX) : origin = 0x30000000, length = 0x0003FFFF
    /* DATA (R) : origin = 0x80000000, length = 0x00007FFF*/
    DATA_FLASH (RW) : origin = 0x80000000, length = 0x00008000 /* 32KB high-endurance region */
    BCR_CONFIG (R) : origin = 0x80101800, length = 0x000003FF
    BSL_CONFIG (R) : origin = 0x80101C00, length = 0x000003FF
    }

    SECTIONS
    {
    .intvecs: palign(16) {} > 0x10000000
    .text : palign(16) {} > FLASH
    .const : palign(16) {} > FLASH
    .cinit : palign(16) {} > FLASH
    .pinit : palign(16) {} > FLASH
    .rodata : palign(16) {} > FLASH
    .ARM.exidx : palign(16) {} > FLASH
    .init_array : palign(16) {} > FLASH
    .binit : palign(16) {} > FLASH
    .TI.ramfunc : load = FLASH, palign(16), run=SRAM, table(BINIT)
    .eeprom_section : > DATA_FLASH, type = NOLOAD

    .vtable : > SRAM
    .args : > SRAM
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM (HIGH)

    .BCRConfig : {} > BCR_CONFIG
    .BSLConfig : {} > BSL_CONFIG

    /* .DataBank : palign(16) {} > DATA*/
    .DataBank : palign(16) {} > DATA_FLASH
    }

    And when I compile, I have this:

    [13]warning #10247-D: creating output section ".text" without a SECTIONS specification
    [14]warning #10247-D: creating output section ".data" without a SECTIONS specification
    [15]warning #10247-D: creating output section ".bss" without a SECTIONS specification
    [16]warning #10247-D: creating output section ".cinit" without a SECTIONS specification
    [17]warning #10247-D: creating output section ".rodata" without a SECTIONS specification
    [18]warning #10247-D: creating output section ".intvecs" without a SECTIONS specification
    [19]warning #10247-D: creating output section ".stack" without a SECTIONS specification
    [20]warning #10210-D: creating ".stack" section with default size of 0x800; use the -stack option to change the default size

    Could you tell me if you see something wrongly defined ?

    Have a nice day

  • Hi Sebastien Le Diour

    I will check and reply to you later.

  • Hello,

    any news ?

    Thanks

  • Hi Sebastien Le Diour

    The linker is generating these warnings because of a subtle syntax issue in your SECTIONS block: the empty curly braces {}.
    In the TI Linker command language, adding empty braces tells the linker: "Create this section, but place absolutely nothing inside it."
    Because of this, the actual code and data compiled from your files (like .text from main.c) cannot fit into your defined sections. The linker is forced to ignore your directives, create its own default sections from scratch, and throw the #10247-D warnings.
    How to Fix It
    1. Remove the empty curly braces {}
    For standard sections, you should either remove the braces completely or use the correct syntax to inherit input sections. Omitting the braces completely is the cleanest way.
    2. Fix the Stack option syntax
    The warning #10210-D indicates that --stack_size=256 wasn't recognized by your specific toolchain version. It expects -stack or --stack.
    Corrected Linker Script
    Here is the corrected version of your linker script. It removes the empty braces and fixes the alignment/stack configuration:
    -uinterruptVectors
    --stack=256 /* Fixed: Changed from --stack_size to --stack */

    MEMORY
    {
    FLASH (RX) : origin = 0x10000000, length = 0x000FFFFF
    SRAM (RWX) : origin = 0x30000000, length = 0x0003FFFF
    DATA_FLASH (RW) : origin = 0x80000000, length = 0x00008000 /* 32KB high-endurance region */
    BCR_CONFIG (R) : origin = 0x80101800, length = 0x000003FF
    BSL_CONFIG (R) : origin = 0x80101C00, length = 0x000003FF
    }

    SECTIONS
    {
    /* Removed {} from all standard allocations */
    .intvecs : palign(16) > 0x10000000
    .text : palign(16) > FLASH
    .const : palign(16) > FLASH
    .cinit : palign(16) > FLASH
    .pinit : palign(16) > FLASH
    .rodata : palign(16) > FLASH
    .ARM.exidx : palign(16) > FLASH
    .init_array : palign(16) > FLASH
    .binit : palign(16) > FLASH

    /* TI Ramfunc configuration */
    .TI.ramfunc : load = FLASH, palign(16), run = SRAM, table(BINIT)

    /* EEPROM Emulation Emptiness flag NOLOAD is correct without braces */
    .eeprom_section : > DATA_FLASH, type = NOLOAD

    .vtable : > SRAM
    .args : > SRAM
    .data : > SRAM
    .bss : > SRAM
    .sysmem : > SRAM
    .stack : > SRAM (HIGH)

    .BCRConfig : > BCR_CONFIG
    .BSLConfig : > BSL_CONFIG

    .DataBank : palign(16) > DATA_FLASH
    }
    Why this works:
    • .text : palign(16) > FLASH: This tells the linker to gather all .text input sections from your compiled object files, align them to a 16-byte boundary, and place them into FLASH.
    • --stack=256: Matches the exact option the linker was looking for, which will resolve the final warning and properly restrict your stack size to 256 bytes.
    Clean your project and try rebuilding it. Let me know if you encounter any new compilation errors or if your EEPROM variables aren't mapping to .eeprom_section properly!
    Thanks!

     

  • Hello Xiaodong,

    I integrated your remarks, and unfortunatly, same result

    [13]warning #10247-D: creating output section ".text" without a SECTIONS specification
    [14]warning #10247-D: creating output section ".data" without a SECTIONS specification
    [15]warning #10247-D: creating output section ".bss" without a SECTIONS specification
    [16]warning #10247-D: creating output section ".cinit" without a SECTIONS specification
    [17]warning #10247-D: creating output section ".rodata" without a SECTIONS specification
    [18]warning #10247-D: creating output section ".intvecs" without a SECTIONS specification
    [19]warning #10247-D: creating output section ".stack" without a SECTIONS specification
    [20]warning #10210-D: creating ".stack" section with default size of 0x800; use the -stack option to change the default size

    Thanks

  • Hi Sebastien Le Diouris 

    Please compare the header file and link configuration with EEPROM type A and type B of SDK in the latest version www.ti.com/.../MSPM33-SDK
    Version: 1.04.00.00 Release date: Jul 6, 2026

    I understand that you do not want to have our EEPROM solutions, compared to our standard solutions, perhaps you can find some detailed ways to solve your own solution.

    Thanks!

  • Hello Xiaodong,

    I donwloaded the EEPROM type B project, and the linker files are identical (without modification on my project), means there is nothing about EEPROM memory. configuration 

    So where the EEPROM memory declaration is done ?

    Thanks

  • Hi Sebastien Le Diouris 

    I am out of office. I have discuss with my colleague to look at this thread as well.

    I will reply to you later.

    Thanks

  • Hi Sebastien,

    There is no EEPROM on MSPM33, and example/library in SDK is to emulate EEPROM in FLASH(based on FLASHCTL API from driverlib).

    The example/library itself doesn't need to modify cmd file but just use the general FLASH range. You can find the address definition in header file.

    If you want to develop your own EEPROM emulation code, you can refer to FLASH example as a base.

  • Hello Yuhao,

    yes, that what I saw in example, Ok so prefect if there is no configuration to do.

    Thanks for your answer.

    I have some questions regarding, EEPROM management, can I continue on this topic, or should I create another one ?

    Thanks

  • Hi Sebastien

    >> can I continue on this topic, or should I create another one ?

    this thread is long and let's focus on one topic.

    Please create another one thread.

    Thanks