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.

MSP432P401M: stored variables in msp432 flash memory

Part Number: MSP432P401M

Hello everyone,

I have a MSP432P401M controller.

My programing have a variable, I want to store it into flash memory.

I want my variable don't lost after reset or haven't power.

Send mi example code related msp432 controller.

How to change in linker file settings??

Thanks

  • Can you please look at this forum thread and then tell me what further questions you have after doing so?  Thanks.

  • Hi john,

    I checked forum regarding variable stored in flash memory. I am doing changes in my command file also. I want to set variables like baud rate ,angle and offset in flash memory. can you write code for me?? or send mi any sample code where variables are set in flash.

    Thanks
  • I cannot write code for you, but I put a link in my last reply that does exactly this, storing variables into flash.  Please reference that link and then let me know if you have anymore specific problems after that.  Thank you.

  • Hi john,

     I have taken example code "flash program memory" from MSP432 simplelink and used only its erase flash part in my code which stores 5 default values starting from location 0x1F000(my data section in linker command file). But, the erase function isn't working.since it is expected to erase my default stored values as shown in memory browser.

    I am attaching main.c file:-

    7750.main.c
    //*****************************************************************************
    //
    // MSP432 main.c template - Empty main
    //
    //****************************************************************************
    
    #include "MSP432P401M.h"
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    #define CALIBRATION_START 0x0001F000
    #pragma SET_DATA_SECTION(".mydata")
    const unsigned int mydata[]={0x00000001,0x00000002,0x00000003,0x00000004,0x00000005};
    
    
    void main(void)
    {
    	
        WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer
        unsigned int arr[0x20];
        unsigned long data[5];
        unsigned long data1[4096];
            int i;
            for(i=0;i<0x20;i++)
                arr[i]=mydata[i];
        P9->DIR |= BIT7;
    
    //    dev_init();
    
        /* Unprotecting Info Bank 0, Sector 0  */
            MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will automatically try to erase the maximum number of tries. If it fails,
           trap in an infinite loop */
            MAP_FlashCtl_eraseSector(CALIBRATION_START);
    
       /* Setting the sector back to protected  */
            MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
            __no_operation();
    
      /*  data[0]= ReadFlash(0x00019800);
        data[1]= ReadFlash(0x00019804);
        data[2]= ReadFlash(0x00019808);
        data[3]= ReadFlash(0x0001980C);
        data[4]= ReadFlash(0x00019810);*/
    
       while(1);
     /*   {
    
            __delay_cycles(12000);  // for generating a square wave at 2Khz when 48MHz crystal is enabled
            P9->OUT |= BIT7;
            __delay_cycles(12000);
            P9->OUT &= ~BIT7;
    
        }*/
    }
    

  • Sayali,

    Thank you for giving me a little more context to work with.  I will take a look at this main.c today and get back to you by end of day. 

    Can you also send me your .cmd file so I can verify it as well?

  • Sayali,

    I read through your main.c and I will say I think you are very close to getting this completely correct.

    I would like to ask your feedback about the link I originally provided.  Was it just difficult to find the code or was the code difficult to interpret?

    I will say that reading through the thread and the code was fairly difficult because it was not formatted very nicely. 

    For that reason, I have attached below the main.c and msp430p401r.cmd files directly.  Please let me know if this does not make things more clear, but at least now you should be able to copy and paste the code and just make very modest adjustments to them to achieve your goal.  (The file msp430p401r.cmd is a ".c" file below for safety purposes.  Please just copy-paste that code into your project's existing msp430p401r.cmd file.)

    **Note Your start location is set as 0x0001_F000 but you are still using bank1, sector 31 which starts at 0x0003_F000.**

    8204.main.c
    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_50_00_02
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 Flash Controller - Programming Calibration Data
     *
     * Description: This example shows the use of the the Flash Controller APIs
     * to erase and program simulated calibration data to a specific area in memory.
     * Data in this example is programmed to user area of memory. The "fake"
     * calibration data is stored in a RAM array and set using the memset function,
     * however in a real application this buffer would be filled out using a serial
     * interface such as I2C.
     *
     *                MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST               |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     * Author: Timothy Logan (Modified by John Morrison for E2E post)
     *
     *
     * Description of Modification: The modification assigns a DATA_SECTION in
     * memory called ".mydata" (please reference msp432p401r.cmd which has also been
     * modified for this purpose).  The pragma DATA_SECTION is used to declare that
     * var1 is a variable stored in the memory section, ".mydata".  Then DATA_ALIGN
     * is used to align 2 bytes of memory to that variable since it will be a
     * uint16_t.  The main code will store the value in flash where var1 is stored
     * into the local variable (not stored in flash) var1LOCAL.  var1LOCAL has 1
     * added to it on every power on of the device and then is stored in the first
     * index of the array simulatedCalibrationData[] which is then stored into flash.
     * This updates the var1 in flash.
     ******************************************************************************/
    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    
    #define CALIBRATION_START 0x0003F000
    
    /* Statics */
    uint16_t simulatedCalibrationData[2048];
    
    /* pragmas to define the variables in flash */
    #pragma DATA_SECTION(var1, ".mydata");
    #pragma DATA_ALIGN(var1, 2);
    uint16_t var1, var1LOCAL = 0;
    
    int main(void)
    {
        var1LOCAL = var1;
        var1LOCAL++;
        /* Since this program has a huge buffer that simulates the calibration data,
         * halting the watch dog is done in the reset ISR to avoid a watchdog
         * timeout during the zero
         */
    
        /* Setting our MCLK to 48MHz for faster programming */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        FlashCtl_setWaitState(FLASH_BANK0, 2);
        FlashCtl_setWaitState(FLASH_BANK1, 2);
        MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    
        /* Initializing our buffer to a pattern of 0xA5 */
        memset(simulatedCalibrationData, 0xA5, 4096);
        simulatedCalibrationData[0] = var1LOCAL;
    
        /* Unprotecting Info Bank 0, Sector 0  */
        MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will
            automatically try to erase the maximum number of tries. If it fails,
             trap in an infinite loop */
        if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
            while(1);
    
        /* Trying to program the memory. Within this function, the API will
            automatically try to program the maximum number of tries. If it fails,
            trap inside an infinite loop */
        if(!MAP_FlashCtl_programMemory(simulatedCalibrationData,
                (void*) CALIBRATION_START, 4096))
                    while(1);
    
        /* Setting the sector back to protected  */
        MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
        /* Going to LPM3 when not in use */
        while (1)
        {
            MAP_PCM_gotoLPM3();
        }
    }
    

    msp432p401r.c
    /******************************************************************************
    *
    * Copyright (C) 2012 - 2016 Texas Instruments Incorporated - http://www.ti.com/
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the
    * distribution.
    *
    * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    * Default linker command file for Texas Instruments MSP432P401R
    *
    * File creation date: 2016-06-29
    *
    *****************************************************************************/
    --retain=flashMailbox
    MEMORY
    {
        MAIN (RX) : origin = 0x00000000, length = 0x0003F000
        MYDATA (RX) : origin = 0x0003F000, length = 0x00001000
        INFO (RX) : origin = 0x00200000, length = 0x00004000
    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
        ALIAS
        {
        SRAM_CODE (RWX): origin = 0x01000000
        SRAM_DATA (RW) : origin = 0x20000000
        } length = 0x00010000
    #else
        /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */
        /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */
        /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/
        SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000
        SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000
    #endif
    #endif
    }
    /* The following command line options are set as part of the CCS project. */
    /* If you are building using the command line, or for some reason want to */
    /* define them here, you can uncomment and modify these lines as needed. */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone. */
    /* */
    /* A heap size of 1024 bytes is recommended when you plan to use printf() */
    /* for debug output to the console window. */
    /* */
    /* --heap_size=1024 */
    /* --stack_size=512 */
    /* --library=rtsv7M4_T_le_eabi.lib */
    
    /* Section allocation in memory */
    
    
    SECTIONS
    {
        .intvecs: > 0x00000000
        .text : > MAIN
        .const : > MAIN
        .cinit : > MAIN
        .pinit : > MAIN
        .init_array : > MAIN
        .mydata : {} > MYDATA
        .binit : {} > MAIN
        /* The following sections show the usage of the INFO flash memory */
        /* INFO flash memory is intended to be used for the following */
        /* device specific purposes: */
        /* Flash mailbox for device security operations */
        .flashMailbox : > 0x00200000
        /* TLV table for device identification and characterization */
        .tlvTable : > 0x00201000
        /* BSL area for device bootstrap loader */
        .bslArea : > 0x00202000
    
        .vtable : > 0x20000000
        .data : > SRAM_DATA
        .bss : > SRAM_DATA
        .sysmem : > SRAM_DATA
        .stack : > SRAM_DATA (HIGH)
    
    #ifdef __TI_COMPILER_VERSION__
    #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT)
    #endif
    #endif
    }
    /* Symbolic definition of the WDTCTL register for RTS */
    WDTCTL_SYM = 0x4000480C;
    
    

  • Hi John,

      I am using MSP432P401M processor which has 128kB of flash memory.So,start location is set as 0x0001_F000 in main memory. As per your information I am using bank0, sector 31. Sitill,the value in memory browser  is not erased.

    I am attaching main.c 

    1055.main.c
    //*****************************************************************************
    //
    // MSP432 main.c template - Empty main
    //
    //****************************************************************************
    
    #include "MSP432P401M.h"
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    #define CALIBRATION_START 0x0001F000
    #pragma SET_DATA_SECTION(".mydata")
    const unsigned int mydata[]={0x00000001,0x00000002,0x00000003,0x00000004,0x00000005};
    
    
    void main(void)
    {
    	
        WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer
        unsigned int arr[0x20];
        unsigned long data[5];
        unsigned long data1[4096];
            int i;
            for(i=0;i<0x20;i++)
                arr[i]=mydata[i];
        P9->DIR |= BIT7;
    
    //    dev_init();
    
        /* Unprotecting Info Bank 0, Sector 0  */
            MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will automatically try to erase the maximum number of tries. If it fails,
           trap in an infinite loop */
            MAP_FlashCtl_eraseSector(CALIBRATION_START);
    
       /* Setting the sector back to protected  */
            MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);
    
            __no_operation();
    
      /*data[0]= ReadFlash(0x00019800);
        data[1]= ReadFlash(0x00019804);
        data[2]= ReadFlash(0x00019808);
        data[3]= ReadFlash(0x0001980C);
        data[4]= ReadFlash(0x00019810);*/
    
       while(1);
     /*   {
    
            __delay_cycles(12000);  // for generating a square wave at 2Khz when 48MHz crystal is enabled
            P9->OUT |= BIT7;
            __delay_cycles(12000);
            P9->OUT &= ~BIT7;
    
        }*/
    }
    

  • Hi John,
    I run that code file also which you given to me and I make some changes in code as follows:-
    1) Calibration start from 1F000 H because I am using MSP432P401M processor which has 128kB of memory.
    2) As well as I am changing memory address (main memory and mydata) in.cmd file.

    MAIN(RX) : origin = 0x00000000, length = 0x0001F000
    MYDATA(RX): origin= 0x0001F000, length = 0x00001000

    According to code 0xA5 should be stored in 1F000H location but, when I debug the code A5 value not able to stored in that memory location..why??
  • Sayali,

    I attached a file called msp432p401r.c in previous attachment.  Since you did not attach your .cmd file, I cannot verify it for you.  If all you changed were the 2 lines as you reference above, that will not be enough.

    You will need to navigate to the SECTIONS part of the .cmd file and add the .mydata line of code as below (I usually place it between those two sections, but I do not know what difference placing it elsewhere would or would not have.):

    .init_array : > MAIN
    .mydata : {} > MYDATA
    .binit : {} > MAIN

    Have you done this also?


    Additionally, your main.c only erases the sector and never makes a call to program it again such as: MAP_FlashCtl_programMemory seen below...

        /* Unprotecting Info Bank 0, Sector 0  */
        MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will
            automatically try to erase the maximum number of tries. If it fails,
             trap in an infinite loop */
        if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
            while(1);
    
        /* Trying to program the memory. Within this function, the API will
            automatically try to program the maximum number of tries. If it fails,
            trap inside an infinite loop */
        if(!MAP_FlashCtl_programMemory(simulatedCalibrationData,
                (void*) CALIBRATION_START, 4096))
                    while(1);
    
        /* Setting the sector back to protected  */
        MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    

  • Hello,

        I have stored some default values in flash starting from 1F000H. I want to firstly make sure that this default values can be erased in run time?? For that I only use the 3 functions in code as per follows:-

    /* Unprotecting Info Bank 0, Sector 0 */
    MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);

    /* Trying to erase the sector. Within this function, the API will
    automatically try to erase the maximum number of tries. If it fails,
    trap in an infinite loop */
    if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
    while(1);


    /* Setting the sector back to protected */
    MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);

    While debugging the code, It has to  been noticed that the programme is not erasing the flash. instead it fails and loops continuously run under the while(1) statement which is mentioned above.I have used the following default values:-


    #pragma SET_DATA_SECTION(".mydata")
    const unsigned int mydata[]={0x0001,0x0002,0x0003,0x0004,0x0005};

    I have confirmed this values are getting stored in flash by seeing them in memory browser at location start from 1F000H. I am attaching .cmd file for your reference

    flash.docx

  • Sayali,

    This all looks right to me.  The only thing I can think of is if you had a wrong CALIBRATION_START defined. 

    I took your main.c and your .cmd file and put them into a project on CCS (removed the MSP432P401M.h file since I am using LP with MSP432P401R silicon), and ran the code.  I verified that the data is being erased with memory browser(with the code below and breakpoints at the flash erase and program functions), so I am not sure what you are doing differently?

    If you just copy past the main.c and the flash.docx ( I will link these two below for ease of use) into a new project, I don't think you will need any modification to verify for yourself that those two are working; but let me know if this is not the case.

        /* Trying to erase the sector. Within this function, the API will automatically try to erase the maximum number of tries. If it fails,
           trap in an infinite loop */
            if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
                {
                while(1)
                    {
                        ;
                    }
                }
        /* Trying to program the memory. Within this function, the API will
            automatically try to program the maximum number of tries. If it fails,
            trap inside an infinite loop */
        if(!MAP_FlashCtl_programMemory(arr,
                (void*) CALIBRATION_START, NumBytes))
                    while(1);
        /* Trying to erase the sector. Within this function, the API will automatically try to erase the maximum number of tries. If it fails,
           trap in an infinite loop */
            if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
                {
                while(1)
                    {
                        ;
                    }
                }

    0486.flash.docx 

    2553.1055.main.c
    //*****************************************************************************
    //
    // MSP432 main.c template - Empty main
    //
    //****************************************************************************
    
    #include "MSP432P401M.h"
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    #define CALIBRATION_START 0x0001F000
    #pragma SET_DATA_SECTION(".mydata")
    const unsigned int mydata[]={0x00000001,0x00000002,0x00000003,0x00000004,0x00000005};
    
    
    void main(void)
    {
    	
        WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer
        unsigned int arr[0x20];
        unsigned long data[5];
        unsigned long data1[4096];
            int i;
            for(i=0;i<0x20;i++)
                arr[i]=mydata[i];
        P9->DIR |= BIT7;
    
    //    dev_init();
    
        /* Unprotecting Info Bank 0, Sector 0  */
            MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will automatically try to erase the maximum number of tries. If it fails,
           trap in an infinite loop */
            MAP_FlashCtl_eraseSector(CALIBRATION_START);
    
       /* Setting the sector back to protected  */
            MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK0,FLASH_SECTOR31);
    
            __no_operation();
    
      /*data[0]= ReadFlash(0x00019800);
        data[1]= ReadFlash(0x00019804);
        data[2]= ReadFlash(0x00019808);
        data[3]= ReadFlash(0x0001980C);
        data[4]= ReadFlash(0x00019810);*/
    
       while(1);
     /*   {
    
            __delay_cycles(12000);  // for generating a square wave at 2Khz when 48MHz crystal is enabled
            P9->OUT |= BIT7;
            __delay_cycles(12000);
            P9->OUT &= ~BIT7;
    
        }*/
    }
    

**Attention** This is a public forum