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.

TI-RTOS NVS driver example for CC13xx

Other Parts Discussed in Thread: CC1310, CC2650

Hi Team,

I am trying to find an example for driving the new NVS API in driverlib for the latest TI-RTOS release 2_20_00_06 for CC13xx/CC26xx. I can see the API in the drivers (C:\ti\tirtos_cc13xx_cc26xx_2_20_00_06\products\tidrivers_cc13xx_cc26xx_2_20_00_08\packages\ti\drivers\nvs\NVSCC26XX.c) but no worked examples of how to use this from an application. 

My requirement is to maintain a set of parametric and configuration data stored in Flash at a fixed address comprising up to 256 bytes, with the ability to update the data safely from application code on a CC1310. It seems that the NVS block granularity is governed by the smallest flash erase page size on the CC13xx/CC26xx which is 4K (4096) bytes which is a consideration for smaller capacity variants but workable I think.

Do we have any code examples or app notes for NVS API?

Regards,

Garry

  • Hi Garry,

    I'll send you the preliminary write-up for the NVS module.

    Todd

  • Thanks Todd.

    We will work through the prelim doc and let you know any feedback.

    Regards,

    Garry

  • Update:

    the following CCS 6.1.3.0033 examples use the NVS driver featured in tirtos_cc13xx_cc26xx_2_20_00_06 and specifically for the CC1310 within the cc13xxware_2_04_02_17240 codebase shared by Todd and to be included and fully documents in a future TI RTOS release.

    The examples use a RAM copyBlock and the FLASH page size is 4096 bytes and with minimum Supported flash erase cycles before failure of 100K cycles on the CC13xx and CC26xx (See CC1310 datasheet section  5.10.4 Flash Memory Characteristics). The RAM copyBlock is used when you specify NVS_WRITE_ERASE in the NVS_write. Since you might only be writing a part of the page size and you want that part erased first, we need to copy the other parts of the page into the copyBlock. Then the page is erased, the other parts are written back and then the new content is written. You can share a copyBlock (RAM or Flash) between different NVS instances.

    In summary the modifications are:

    #1: Add the CC1310_LAUNCHXL_NVSBufName buffer typedef definition to the platform CC1310_LAUNCHXL.h file

    /*!
     *  @def    CC1310_LAUNCHXL_NVSBufName
     *  @brief  Enum of NVSBufs
     */
    typedef enum CC1310_LAUNCHXL_NVSBufName {
        CC1310_LAUNCHXL_NVS1F000 = 0,
        CC1310_LAUNCHXL_NVSCOUNT
    } CC1310_LAUNCHXL_NVSBufName;
    

    #2:Add the NVS driver object definitions nvsCC26xxHWAttrs and NVS_config to the end of the CC1310_LAUNCHXL.c file which in this case is configured to be the last 4096 byes in flash which incorporates the CCFG block at the very end (note this is always flashed by the firmware examples)

    /*
     *  ========================== NVS begin =========================================
     */
    /* Place into subsections to allow the TI linker to remove items properly */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_SECTION(NVS_config, ".const:NVS_config")
    #pragma DATA_SECTION(nvsCC26xxHWAttrs, ".const:nvsCC26xxHWAttrs")
    #endif
    
    /* Include drivers */
    #include <ti/drivers/NVS.h>
    #include <ti/drivers/nvs/NVSCC26XX.h>
    
    
    /* NVS objects */
    NVSCC26XX_Object nvsCC26xxObjects[CC1310_LAUNCHXL_NVSCOUNT];
    /*
     * Block to be used if making a copy of the flash page is needed.
     * Could use another block of flash, but there is not alot of flash on
     * these devices...
     */
    char myCopyBlock[4096];
    const NVSCC26XX_HWAttrs nvsCC26xxHWAttrs[CC1310_LAUNCHXL_NVSCOUNT] = {
    {
            .block = (void *)(0x20000 - 4096), // Flash sector to use is top 4096 of flash on a 128K part
            .blockSize = 4096,
            .copyBlock = myCopyBlock,
            .isRam = true
        }
    };
    
    const NVS_Config NVS_config[] = {
        {
            .fxnTablePtr = &NVSCC26XX_fxnTable,
            .object      = &nvsCC26xxObjects[0],
            .hwAttrs     = &nvsCC26xxHWAttrs[0]
        },
        {NULL, NULL, NULL}
    };
    
    /*
     *  ========================== NVS end =========================================
     */
    

    #3: Add the NVS driver headers  #include <ti/drivers/NVS.h> and #include <driverlib/flash.h> to the application code, in this case empty.c. Add the NVS driver calls and associated variable declarations to the appropriate place in your application code as per example :- NVS_init(),NVS_open(),NVS_read(),NVS_write() etc…

    :
    : #include <ti/drivers/NVS.h> #include <driverlib/flash.h> /* Board Header files */ #include "Board.h"
    :
    :
    #define MYBUFFERSIZE 128 // Size of NV application data block /* * ======== main ======== */ int main(void) { NVS_Handle nvsHandle; char buffer[MYBUFFERSIZE]; int status; unsigned int strSize;
    :
    : /* Confirming the sector size on this device is 4096 */ if (FlashSectorSizeGet() != 4096) { System_abort("Oops! The sector size is not 4096"); } NVS_init(); nvsHandle = NVS_open(CC1310_LAUNCHXL_NVS1F000, NULL); /* + 1 to make sure to write the '\0' character */ strSize = strlen("bar1") + 1; /* make sure the buffer size is a multiple of 4 */ strSize = (strSize + 4) & 0xFFFFFFFFC; status = NVS_write(nvsHandle, 0, "bar1", strSize, NVS_WRITE_ERASE | NVS_WRITE_VALIDATE); if (status != NVS_SOK) { System_abort("NVS_write failed"); } status = NVS_read(nvsHandle, 0, buffer, MYBUFFERSIZE); if (status != NVS_SOK) { System_abort("NVS_read failed"); } status = strcmp("bar1", buffer); if (status != 0) { System_abort("comparison failed"); } :
    : return (0); }

    Example code projects for CC1310 Launchpad and CC1310DK (CC1310EM + SmartRF06):

    6175.nvs_CC1310_LAUNCHXL_TI_CC1310F128.zip

     0880.nvs_CC1310DK_7XD_TI_CC1310F128.zip

    Depending on application use case it is possible though not mandatory to reserve the NVSFLASH segment within the MEMORY map in the linker file to ensure that the segment is set aside.

    Regards,

    Garry

  • Dear Garry,

    same procedure i followed for CC26XX .Once i call NVS_init() in application it is not working. If you have any example for CC26XX or suggest a solution .
  • Hi Suresh,

    here is a version for the CC2650 Launchpad which works on my board Rev 1.1. Please make sure you have first installed the latest TI-RTOS SDK for the Simplelink devices eg: tirtos_cc13xx_cc26xx_2_20_00_06.

    5123.nvs_CC2650_LAUNCHXL_TI_CC2650F128.zip

    The process I followed was the same as above starting with importing a CCS empty project as a baseline using TI Resource Explorer then adding the code blocks as per above:

    Regards,

    Garry

  • Hi,

    Thank you for the example.

    I tested it and everything is working well.

    Now, I would like to use the NVS driver to replace a application stored in the flash memory.

    I have a bootloader program stored in the address 0x00 of the flash memory and a application program stored in the address 0x10000.

    // Application
    
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    #define FLASH_BASE              0x10000
    #define FLASH_SIZE              0x10000
    #define RAM_BASE                0x20000000
    #define RAM_SIZE                0x5000

    The bootloader must receive a new application through the UART and replace the original application stored in the address 0x10000.

    Based on your example, I created this:

    /* NVS objects */
    NVSCC26XX_Object nvsCC26xxObjects[CC1310_LAUNCHXL_NVSCOUNT];
    /*
     * Block to be used if making a copy of the flash page is needed.
     * Could use another block of flash, but there is not alot of flash on
     * these devices...
     */
    //char myCopyBlock[4096]; Don't use RAM
    const NVSCC26XX_HWAttrs nvsCC26xxHWAttrs[CC1310_LAUNCHXL_NVSCOUNT] = {
    {
            .block = (void *)0x10000, // Start in the application address
            .blockSize = 0x10000, // Maximum application size
            .copyBlock = NULL, // Don't use RAM
            .isRam = false
        }
    };
    
    const NVS_Config NVS_config[] = {
        {
            .fxnTablePtr = &NVSCC26XX_fxnTable,
            .object      = &nvsCC26xxObjects[0],
            .hwAttrs     = &nvsCC26xxHWAttrs[0]
        },
        {NULL, NULL, NULL}
    };

    Are my changes correct?

    Best regards,

  • Hi,
    We generally discourage posting a new question to an old closed thread because the person who answered before may no longer be available, and also it will allow whomever is currently assigned to monitor the forum to respond to you more quickly. For these reasons, I suggest you start a new thread with your question and reference this thread.

    Thank you
  • Kenia Guinto said:
    Hi,
    We generally discourage posting a new question to an old closed thread because the person who answered before may no longer be available, and also it will allow whomever is currently assigned to monitor the forum to respond to you more quickly. For these reasons, I suggest you start a new thread with your question and reference this thread.

    Thank you

    Ok.

    I created a new thread, but it appears that it was not approved yet.

    The page loaded in a wierd way when I clicked the POST button.

    Can you check if my the new thread is waiting for approval?

    Thank you.

  • The only other thread I see is this one: e2e.ti.com/.../574086. Can you try open another one for the NVS question?

    Todd
  • ToddMullanix said:
    The only other thread I see is this one: e2e.ti.com/.../574086. Can you try open another one for the NVS question?

    Todd

    Sure.