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

BLE does not work after writing a value to UICR

Hi, Everyone

My Environment: nRF52840, SDK15.3, Keil

My code is:

err_code = nrf_sdh_disable_request();
APP_ERROR_CHECK(err_code);

NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};

NRF_UICR->CUSTOMER[AES_KEY0] = aes_key0;

NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};

err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);

BLE works before writing data to UICR

However, after writing data to UICR, the name does not appear when scanning from nRFconnect.

Please advise.

Parents
  • Hi,

    I do not see anything wrong in this code snippet, so it should not cause problems:

    A few questions:

    • What is the value of AES_KEY0?
    • Have you tried to debug to see what is going on on the nRF side? Is an error check hit? Or something else? Which state is the nRF in (observed from a debugger)?
  • Hi, 

    I'm using UICR to preserve system configuration data.

    The setting data can be changed frequently.

    Data should be preserved after the OTA.

    What is the value of AES_KEY0?

    -> #define AES_KEY0 0x07

    err_code = nrf_sdh_enable_request();

    -> err_code is 0x00

    Which state is the nRF in (observed from a debugger)?

    -> I am using keil Compiler.

       How can I debug the state of nRF?

    Best regards,

    Alex

  • Hi Einar,

    Thank you for your answer.

    We will change the encryption key every hour.

    The encryption key value should be saved even after reset.

    Your advice seems to be inconvenient to store data that changes frequently in UICR.

    I'll find another way to use it.

    Best regards,

    Alex

  • Hi Alex,

    Yes, it is definitely inconvenient to store data that changes frequently in UICR. In fact, it is practically impossible, since you normally don't want to erase the UICR page, and a page erase is needed whenever you want to overwrite data in the same address with new data. I suggest you look into FDS for this, which is perfect for frequently changing data.

  • Hi, sorry to hijack the thread but we have a similar design issue regarding optimal frequency of the key exchange. As I understand the max no of writes to flash-mem is about 10 000. That means the life expectancy using one hour key exchange is about 1 year and 51 days. Correct?

    One solution is to just increase frequency of the key exchange to meet the expected life span of the product but I've got a couple of follow upp questions before we can make any decisions:

    1. Are 10000 max-writes the same for all socs?
    2. Are there any other storage options with static ram or similar that fits 16 bytes with no limitation regarding number of writes?

    --

    Br, Lars.

  • Hi Lars,

    LarsH said:
    1. Are 10000 max-writes the same for all socs?

    That is the typical number for all nRF52 devices I believe.

    LarsH said:
    2. Are there any other storage options with static ram or similar that fits 16 bytes with no limitation regarding number of writes?

    You can use GPREGRET if you don't need the data to be persistent across power-on-reset. However, if you need truly persistent storage, then you probably need to use the flash.

    The SDK includes the FDS library, which is essentially a very simple file system. It implements basic wear leveling, which is very sensible in this case. Essentially you set aside a few flash pages (minimum 2, since there must be one swap page), and the data is moved around whenever you update it, spreading the wear across all the flash pages that are allocated for this. Most BLE examples already use this since it is used by the Peer manager for storing bonding information.

    Einar

  • Thanks! 

    Essentially you set aside a few flash pages (minimum 2, since there must be one swap page), and the data is moved around whenever you update it, spreading the wear across all the flash pages that are allocated for this
    1. Does this mean that if you allocate 5 pages you can perform 50 000 writes?
    2. What's the minimal page size (since we only need room for 16 bytes)?

    Lars.

Reply Children
  • LarsH said:
    Does this mean that if you allocate 5 pages you can perform 50 000 writes?

     No, much more than that, depending on how large sections of data you write. You will continue to fill up a flash page with every update. Data will not be overwritten until you do a garbage collection, which is typically after you have written to all reserved flash pages. You can calculate this yourself, just remember that there is a flash page tag of 2 words (8 bytes) and a record header of 3 words (12 bytes).

    For example, a page is 1024 words (4096 bytes), so if you are writing data that is 16 bytes that is 4 words, this means that you can write (1024-2)/(3+4) = 146 times to each page without overwriting anything. And so on, until you do a garbage collection. And when you do a garbage collection, data is shuffled so that you can delete pages. And so on. You can read up on the detail in the FDS documentation, but the key here is that you can significantly increase the life span of the flash by this approach.

  • Thus, you get a lifetime of 1.46 million updates (ie 166 years) on a single flash-page with one hour key exchange.

    That should be sufficient, I think! :-)

Related