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.

CC1312R: Need help using NVS in OAD project

Part Number: CC1312R

Hello,

I am working on a project based off sensor_oad (SDK 4.10). Everything works well, including OAD with BIM and persistent app flashed onto the device.

Here is the NVS area I am using (0x30000 is just after the end of my app).

I use the following to initialise NVS:

    NVS_Params nvsParams;

    NVS_init();
    NVS_Params_init(&nvsParams);
    nvsHandle = NVS_open(CONFIG_NVS_DEVICE_STATE, &nvsParams);

and in flash_interface_int_rtos.c, I commented out initialisation of NVS:

void flash_init(void)
{
//    NVS_init();
//    NVS_Params_init(&nvsParams);
}

The app runs fine, OAD still works. But, if I write to flash thus:

NVS_write(nvsHandle, 0, (void *)internalState, sizeof(*internalState), NVS_WRITE_ERASE | NVS_WRITE_POST_VERIFY);

the app is still functional, but trying an OAD firmware update no longer works:

Info: Sending 0x0001 Target Reset Req
Info: Retrying 0x0001 Target Reset - Attempt 1
Info: Retrying 0x0001 Target Reset - Attempt 2
Info: Retrying 0x0001 Target Reset - Attempt 3
Info: OAD Failed

Any help appreciated.

 

  • Hi MH,

    Could you elaborate on what you are trying to do more exactly, are you trying to add an additional NVS region in parallel to the others or simply replace the one normally used in the "flash_interface" implementation?

  • Hi M-W,

    I am trying to add a third region in parallel for storage unrelated to OAD. Some of my app's own internal data needs to survive reboots.

  • Hi MH,

    In that case, why do you modify the flash interface files used by the stack? Even if you do the init at some other location, the NVS params in the flash interface file as this would still be needed internally.

    As it is not super clear what you are doing, it almost sounds like you are modifying the flash_interface_* files to do what you want, I would expect that you leave these alone and use the NVS driver for your third region without the "internal flash" interface in the example. Could you elaborate on why you saw the need to comment out the parameter initialization in the stack flash interface files?

  • Hi M-W,

    I read a post here by a TI employee stating that NVS_init() should only be called once in a project.

    Besides, I am having the same problem whether the code in flash_interface init is commented out or not.

    So, for the sake of clarity, let's pretend I have not touched anything but app code. All I intend to do is store some data in NVS from within an OAD-based project. 

    Any pointers where I should look next?

  • Hi MH,

    That is true for the NVS_init() function (for some reason, we did not add a guard for this but lets not focus on that). The NVS_Params_init() function however is a requirement to call before all the open calls. If you do not chances are that you are just opening up the driver with gibberish parameters. 

    I would verify that the handles are not mixed up for some reason (both being unique). Then I would put down a few breakpoints in the OAD part of the application to try capture the OAD events and see if they fail their NVS operation for some reason (check return statuses of these etc.). As it uses the "flash interface" files it should be rather easy to put breakpoints down to capture this. 

  • Hi M-W,

    I had already stepped through the flash-related code in OAD, and operations all returned 0 (SUCCESS). I had also tried only commenting out the NVS_init() line in flash_init(), with similar results.

    I will do this again and verify if the problem is the same at the collector and report back.

  • Hi M-W,

    confirming the exact same problem with:

    void flash_init(void)
    {
    //    NVS_init();
        NVS_Params_init(&nvsParams);
    }
    

    in flash_interface_int_rtos.c

    Reading from flash is successful just before the system reset:


  • Hi again M-W,

    in the last instance, I believe the device resets into the persistent FW as it should, but still fails to perform OAD. 

  • I built the simplest test case I could think of. Starting from the SDK 4.10 project

    sensor_oad_onchip_secure_CC1312R1_LAUNCHXL_tirtos_ccs

     

    I have added


    then in main.c main(), I have added basically the same NVS code:

    int main(void)
    {
        Task_Params taskParams;
    
    #ifndef USE_DEFAULT_USER_CFG
        macUser0Cfg[0].pAssertFP = assertHandler;
    #endif
    
        /*
         Initialization for board related stuff such as LEDs
         following TI-RTOS convention
         */
        Board_init();
    
        // test code below
    
        NVS_Params nvsParams;
    
        NVS_init();
        NVS_Params_init(&nvsParams);
        NVS_Handle nvsHandle = NVS_open(CONFIG_NVS_0, &nvsParams);
        char test[11] = {"Some string"};
        
        // uncommenting this line prevents OAD from working later on, it works otherwise
        // NVS_write(nvsHandle, 0, (void *)test, 11, NVS_WRITE_ERASE | NVS_WRITE_POST_VERIFY);
    

    Writing to NVS breaks OAD functionality, but the sensor keeps working. I have validated that the data is written correctly:

    and also commented out NVS_init(); from flash_interface.

    If you can please confirm my findings and provide a workaround, or maybe point out what I am doing wrong, it would be appreciated.

  • Hi MH,

    I would write this of as a "linker bug" where the linker file does not seem to setup constraints as one would expect it do in the OAD case. If you have a look at the flash layout for OAD:

    https://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_4_20_01_04/docs/ti154stack/html/oad-secure/flash-layout-on-chip-stack-library.html

    Here you will see that IMG_B (which is what you are compiling above) is located at start of FLASH followed by the IMG_A (or the persistent app). The latter starts at 0x2A000 and thus, your placement would be right into this image and the write you do simply corrupts the persistent app which means it will not be able to perform the OAD (my theory).

    The bug as such seems to be that the "FLASH_SIZE" used for IMG_B is not constraint to FLASH region it should span but instead allows placement in the whole range. I would expect it to give you a linker error when trying to place above 0x2A000.

    If this is correct, then you moving the new NVS region to be before 0x2A000 should "fix" it. 

  • Hi M-W,

    if I understand correctly, the linker file for OAD_IMG_B should have its FLASH_END at 0x2A000, right (at least in the TI project files)?

    Your diagnosis of memory corruption is correct, and the actual fix in my case was to make a bit more room for my app, such that I can use room between 0x2A000 and 0x2C000, and have the persistent app start at 0x2C000.

    Thanks for your help!

  • Hi MH,

    That is correct, you can see by looking at the linker file that "IMG_A" is placed from 0x2A000 -> (FLASH_END - ONE_PAGE) which means you get 0 -> 0x1FFFF as your application flash space.