This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Is it possibl that re-write UICR when application is running? if yes, how to do this.

SDK 15.3.0

I want to save some user data in UICR , this data will change when application runing. How to re-write the data into UICR.

I assume that the UICR will not be erased by DFU, am I right ?

Parents Reply Children
  • Thanks,

    I found a DEFINE named "DFU_APP_DATA_RESERVED" in bootloader code, according to the code comments, seems this flash area is for saving application data.

    this area is 8k byes, the bootloader is start from 0x28000, therefor, this DFU_APP_DATA is from 0x26000 to 0x27FFF.

    I assumed that all I have to is just use nrf_fstorage.c 's function to write my user data to 0x26000.

     I added a button event to run below code, but it seems the system is stucked when run it.

     Please help !

    ;----------------------------------------------------------------------------------------------------------------------

    NRF_LOG_INFO("FLASH WRITE START");
    pairKey = (rcvData[1] << 24) | (rcvData[2] << 16) | (rcvData[3] << 8) | (rcvData[1]);
    nrf_fstorage_api_t * p_fs_api;
    p_fs_api = &nrf_fstorage_sd;
    err_code = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
    APP_ERROR_CHECK(err_code);
    (void) nrf5_flash_end_addr_get();
    err_code = nrf_fstorage_write(&fstorage, 0x26000, &pairKey, sizeof(pairKey), NULL);
    APP_ERROR_CHECK(err_code);
    wait_for_flash_ready(&fstorage);
    NRF_LOG_INFO("FLASH WRITE DONE");

    ;---------------------------------------------------------------------------------------------------------------------------

    BELOW LINES ARE related define.

    static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);


    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
    {
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
    * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
    * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
    * last page of flash available to write data. */
    .start_addr = 0x26000,
    .end_addr = 0x27FFF,
    };

    /* Dummy data to write to flash. */
    static uint32_t pairKey;

    static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
    {
    if (p_evt->result != NRF_SUCCESS)
    {
    NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
    return;
    }

    switch (p_evt->id)
    {
    case NRF_FSTORAGE_EVT_WRITE_RESULT:
    {
    NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.",
    p_evt->len, p_evt->addr);
    } break;

    case NRF_FSTORAGE_EVT_ERASE_RESULT:
    {
    NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.",
    p_evt->len, p_evt->addr);
    } break;

    default:
    break;
    }
    }

    static uint32_t nrf5_flash_end_addr_get()
    {
    uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
    uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
    uint32_t const code_sz = NRF_FICR->CODESIZE;

    return (bootloader_addr != 0xFFFFFFFF ?
    bootloader_addr : (code_sz * page_sz));
    }

    void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
    {
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {
    sd_app_evt_wait();
    }
    }

  • Thanks

    I found there is DEFINE named "DFU_APP_DATA_RESERED" in bootloader example code, according to the comments, seems this flash area is for saving application's data. 

    all I have to do is write my user data to this flash area. this area is 8k size, the bootloader rom is from 0x28000, therefor this DFU_APP_DATA area is from 0x26000 to 0x27FFF.

    I used nrf_storage function to write data to 0x26000, but when I called  the flash write, the system got stucked.

    I added a Button Event to run below code:

    ;-----------------------------------------------------------------------------------------------------------------------

    NRF_LOG_INFO("FLASH WRITE START");
    pairKey = (rcvData[1] << 24) | (rcvData[2] << 16) | (rcvData[3] << 8) | (rcvData[1]);
    nrf_fstorage_api_t * p_fs_api;
    p_fs_api = &nrf_fstorage_sd;
    err_code = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
    APP_ERROR_CHECK(err_code);
    (void) nrf5_flash_end_addr_get();
    err_code = nrf_fstorage_write(&fstorage, 0x26000, &pairKey, sizeof(pairKey), NULL);
    APP_ERROR_CHECK(err_code);
    wait_for_flash_ready(&fstorage);
    NRF_LOG_INFO("FLASH WRITE DONE");

    ;------------------------------------------------------------------------------------------------------------------------------

    Related define for above code:

    static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);


    NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
    {
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
    * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
    * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
    * last page of flash available to write data. */
    .start_addr = 0x26000,
    .end_addr = 0x27FFF,
    };

    /* Dummy data to write to flash. */
    static uint32_t pairKey;

    static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
    {
    if (p_evt->result != NRF_SUCCESS)
    {
    NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
    return;
    }

    switch (p_evt->id)
    {
    case NRF_FSTORAGE_EVT_WRITE_RESULT:
    {
    NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.",
    p_evt->len, p_evt->addr);
    } break;

    case NRF_FSTORAGE_EVT_ERASE_RESULT:
    {
    NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.",
    p_evt->len, p_evt->addr);
    } break;

    default:
    break;
    }
    }

    static uint32_t nrf5_flash_end_addr_get()
    {
    uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
    uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
    uint32_t const code_sz = NRF_FICR->CODESIZE;

    return (bootloader_addr != 0xFFFFFFFF ?
    bootloader_addr : (code_sz * page_sz));
    }

    void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
    {
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {
    sd_app_evt_wait();
    }
    }

  • As I said, take a look at the FDS library. It implements a very simple file system that already takes care of load balancing, identification and deletion for you. The fstorage library is a simple API to access RAW data in flash, it doesn't cut it to constantly update a single uint32 in flash.

  • I took a look at the FDS, seems it is beyond my understanding, but I found a example to write flash.

    my concern is " how to make sure the data won't be erased by DFU?"

Related