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

How to find the start address for writing to flash

There are two central sd_* methods for writing to flash - write and erase. The problem is I need to know where I can put my data without trashing something else that is already there and without reading every memory location and looking for the 'magic value'.

The examples do not help a bit, as they simply use the address of the last page. What if I need more than 1024 bytes?

Yes I know how to get the end of the memory. But that is a pretty stupid place to begin writing unless one writes backwards.

Clearly what the application writer wants is to find the start of free flash, so there is a maximum amount of flash available. 

How does one do this???

Why isn't there a method sd_get_start_address_of_free_flash()?  I think that was first suggested some six years ago.

  • For the moment I am using the last code page so I don't have to search for a start address. Since I am only storing 0x34 bytes, this is not a problem. I want to get basic writes/reads working first, then I will worry about finding the start location.

    I read from flash before any Bluetooth activity takes place, and write when all Bluetooth activity is finished. I don't need to worry about radio/flash conflicts.

    That being said, I am having issues writing. I am not getting back the keys I have written. 

    So first addition is to add sd_softdevice_disable() as it would be a nightmare to handle events in a loop - there is no semaphore support here. So now I am wondering about NRF_BUSY  responses. Would the proper way to handle that be (for both erase and write)

        while(true)
        {
            err_code = sd_flash_page_erase(pg_num);
            if (err_code == NRF_SUCCESS)
            {
                break;
            }
            if (err_code != NRF_ERROR_BUSY)
            {
                APP_ERROR_CHECK(err_code);
            }
        }
        i = (size >= pg_size) ? (pg_size >> 2) : (size >> 2);     // four-byte hunks to write; size is evenly divisible by four
        while(true)
        {
            err_code = sd_flash_write(addr, ptr32, i);
            if (err_code == NRF_SUCCESS)
            {
                break;
            }
            if (err_code != NRF_ERROR_BUSY)
            {
                APP_ERROR_CHECK(err_code);
            }
        }

    What! I get a NRF_ERROR_SOFTDEVICE_NOT_ENABLED error! That does NOT jive with the documentation.

    Docs say

    If the SoftDevice is not enabled no event will be generated, and this call will return NRF_SUCCESS when the write has been completed

    And the NRF_ERROR_SOFTDEVICE_NOT_ENABLED is NOT one of the listed return values. What is going here?

    If I step through the above code using the debugger, it works. When I run it and stop at the end of the writing, it does not work. Any idea why?

Related