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

nRF51822 The access to the flash memory cause the program to fail.

Hi, everyone,

I am developing the project on nRF518522 and I must use the flash memory to save the data. The data must be saved while the device is conncted via BT with the master. For this purpose I use the procedure ble_flash_page_write(PG_NUM, p_out_array, p_word_count); where: the variables and constants are defined so:

#define PG_SIZE (NRF_FICR->CODEPAGESIZE)
#define PG_NUM  (BLE_FLASH_PAGE_END - 1)

uint32_t p_out_array[PG_SIZE];

in my case the p_word_count=7;

If I try to pass the code by step by step, the procedure (ble_flash_page_write) passes successfully, but during the running it caus the device to stop working and nothing in the flash is saved.

What is it possible to do?

  • Hi,

    Did you read the warning in the API documentation for ble_flash_page_write()?

    Warning

    This operation blocks the CPU. DO NOT use while in a connection!

    You will have to erase the pages you want to write before initializing the BLE stack, for instance using ble_flash_page_erase(), and use ble_flash_word_write() to write to flash. You can also check out the FDS library, which can be used for writing data to flash. An example can be found on this GitHub page.

    Best regards,

    Jørgen

  • Hi, Jorgen, Yes, I have read this warning and understand that it cannot be used with radio communication. BUT ...

    1. I need to write to the flash and in the needed cases to erase it exactly when the radio communication exists.
    2. In the warning is written that this procedure blocks the CPU but there is not written that it hungs it until the reset. And practically It blocked me the CPU at all.
    3. During the debugging by trying to do this step bu step the blocking was hapening not only during the flash erasing, but during the writing the new data to it too.

    In addinion when I tried to find the decision, I saw that in the "ble_flash.h" library exists the special event procedure "void ble_flash_on_radio_active_evt(bool radio_active);". In the certain examples was written that it it's address must be given as the handler to the "ble_radio_notification_init()" function. According to documentation these procedures must solve this problem, but practically I couldn't solve this problem due to next problems:

    1. In the example this function "ble_radio_notification_init()" was given by this line: err_code = ble_radio_notification_init(NRF_APP_PRIORITY_LOW, NRF_RADIO_NOTIFICATION_DISTANCE_800US, ble_flash_on_radio_active_evt);
      where the constant/definition "NRF_APP_PRIORITY_LOW" I couldn't find at all.
    2. For using this function I had to include the "ble_radio_notification.h" and "ble_radio_notification.c" files to my project that gave me the error of multiple interrupt definition.
    3. The event procedure "ble_flash_on_radio_active_evt()" had to cause to wait only to the procedure "flash_word_write()", but not to the "ble_flash_page_write()" function that I needed and even not to "ble_flash_page_erase()" function.

    To solve in this case the third reason would be possible, but due to the first two reasons the function "ble_radio_notification_init()" couldn't be implemented at all.

    In conclusion, My question is how to write/erase the flash even when the BlueTooth communication is active?

    Thank you for pauing attention.

    Best regards Boris Fridman

  • If the softdevice is blocked from handling the incoming events immeadiately, it will hardfault. When you single step the code when the softdevice is enabled, you will also get a hardfault, as the softdevice will not be able to process the events. The only recovery from the hardfault is a reset.

    Why do you need to perform the erase while in a connection? Can't you do the erase first and store new values in new locations? FDS implements this handling for you, allowing you to update/invalidate records when in a connection, and run garbage collection/flash erase when idle. Which SDK version are you using, and what API documentation/guide are you following? Newer SDK version use the priorities defined in app_irq_priority_t in app_util_platform library.

  • Of corse it is possible to prepair the block writings and erase the page only when it is full. During the connection it will solve the problem partialy because in this case during the connection will be only writings. BUT! When the page will be full, for writing the next block it will be needed to erase it for freeing the place. And independently if the module is connected or not, The page will have to be erased in any case. We are using the SDK version 12.3.0 because the newest one doesn't support the nrf51822 chip.

  • If you do not want to use fstorage/FDS, please have a look at the Flash Memory API that can be used when the softdevice is enabled.

Related