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

sd_flash_write halts

Hi,

On SDK12.3 when using sd_flash_write at any memory location causes the device to halt and restart.
On SDK11 I've been using flash_word_write and flash_page_erase using the NRF_NVMC registers, and it worked flawlessly.
But I can't seem to figure out what is the issue with SDK12.3.
I've read that using NRF_NVMC with the softdevice is not allowed.
I've been writing to NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1) previously and that always worked.
But is there a way to reserve a page of flash to which I can store my custom data structure and modify it in the firmware without using fds?
I've tried making a const char array of a size and then writing to its pointer, but that didn't work. If I know my application code is less than 32k, can't I just write anything after the 32k mark?
I also have a softdevice and bootloader.

Edit:
I'm currently using SDK12.3 and I can't migrate it to a newer version, but the question applies for newer SDK too.

  • I'm trying out fstorage and it seems to work, but I'm having a problem I had a long time ago, and I don't remember what was the fix.
    When using fstorage I can read the data properly, but when it comes to erasing and writing it it gets weird.
    I either can have it erase, or have it write data. Both functions don't work at the same time. Sometimes it will only erase, sometimes only write. I trigger the functions by hand.
    I am also using the address 0x00040000 for testing which I found to be unused.

  • Do you use the Softdevice along with your fstorage code? In that case, you are trying to write to the softdevice region. 

    Another thing that may be the issue, if you are able to read, but write and erase works a bit weird, it may be that you are not waiting for the operations to finish. These kinds of issues are only visible when you are trying to change the values (write/erase).

    Use the events that are generated to tell the application that a write or erase is done:

    my_write_function():

    while (!write_done){};

    write_done = false;

    continue();

    You should look at the SDK\examples\peripheral\flashwrite example, to see an example for how to wait. In SDK12.3.0 it is done like this:

    NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);

    while (NRF_NVMC->READY == NVMC_READY_READY_Busy)

    {

        // Do nothing

    }

  • Yes, I have both the softdevice and bootloader, but I'm not using up all the program code(keil licence 32k limit) so there has to be empty space left for one page of user data somewhere. I came up with 40000 by looking for a region that was always FF. I though too it might be a timing problem, so that is why I trigger all of the operations manually, but still it works randomly. Sometimes write works, sometimes erase works, sometime neither work. Its much like the scenario where a variable would not be volatile and would be read incorrectly from another side, but there is nothing to be cached in this case.

  • I am not sure how Keil calculates this limit. I believe it is just the source code that has to be below 32k, and you can write to any place in the flash.

    However, if you are bothered with the 32k limit, I really recommend you to move to SDK14.0.0 or later, which has Segger Embedded Studio projects, which are free of charge and no limits when you develop for Nordic Semiconductor products.

    Regarding your issues. You can't write several times to the same place in flash. You must erase it in between two writes to the same address. 

    Best regards,

    Edvin

  • I know about the licenced not being limited in the new sdk, but I'm stuck with sdk12 for now.
    I did a bit more investigation, and not sure why I did not see this before, but I'm actually getting FS_ERR_INVALID_ADDR  on fstorage operations. I found a map of the address space:
    https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk52.v0.9.1%2Fbledfu_memory.html
    And I should be able to write inside the application/user space.

    I tried writing to places like 0x27000, 0x1F000 and 0x7E000, but I always get that error.
    The example uses fs_config.p_start_addr but when I read that value its 0x7F000 which is already inside the DFU area which I can't use since I have a bootloader.

    Edit:
    I also don't see the fs_evt_handler ever being called, and after poking a bit I got it to return success at 0x7F000 and after a while I got FS_ERR_QUEUE_FULL  which means fstorage is just piling up tasks.

Related