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

Smallest Flash-write operation possible and what is to consider when using BLE and Flash at the same time?

I'm developing for the NRF52 DK (nRF52832) using VisualGDB (which uses SDK v11.0.0).

When completed my program is supposed to read data from sensor (via I2C), store it in the internal flash and if enough data is accumulated send it to a phone via BLE.

I've searched through all the datasheets and documentation but could not find clear statements to my questions.

While developing 3 questions came up:

  1. Is it possible to write less than 4 Bytes to the flash at one time?

    I'd like to write only 1 Byte at a time (right now I'm writing 4 Bytes, see code below).
  2. If not, is it possible to add data to places where there is already data stored?

    If there is a limit to how small a writing operation is wouldn't it be possible to write the same data to the flash storage with new data attached to it?
    To my knowledge when erasing all bits are set to 1 and when writing the 0's are set. So writing the same data to the same address shouldn't change anything.
    One thing that does worry me about this is wear. According to the Absolute Maximum Ratings 10000 write /erase cycles are possible; would writing the same data over and over again wear down the flash?
  3. What is to be considered when using BLE and Flash-operations?

    While searching through forums and other questions I found out that using both apparently can cause problems. Again I could not find a official statement to that. Is it only while advertising, while sending data? Do I have to take into consideration that the SoftDevice has the highest priority?

Function used to write to flash:

bool  flash_byte_write(uint32_t* pAddress, uint8_t uiValue)
{
	// Turn on flash write enable and wait until the NVMC is ready:
	NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);

	while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
	{//waiting
	}

	*pAddress = uiValue;

	while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
	{//waiting
	}

	// Turn off flash write enable and wait until the NVMC is ready:
	NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);

	while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
	{//waiting
	}
}

Function used to read from flash:

uint8_t flash_byte_read(uint32_t* pAddress)
{
	uint8_t data = (uint8_t)*(pAddress);
	return data;
}

Thanks in advance.

Parents
  • Hi,

    First I want to give you my general advice which is what I would do if I understand your system correctly: Use a small buffer to receive 4 bytes of data before writing to flash 32 bit at a time.

    Is it possible to write less than 4 Bytes to the flash at one time?

    Yes, you can write 1 byte at a time by setting all bits you do not want to affect to '1'. Write operations are only flipping '1' bits to '0' when you perform a write operation.

    But there are limitations to this. You may only write 181 times to each block. A block is 1/8th of a flash page (512 byte or 128 words).

    This essentially means that you can write 1 byte at a time, but then you can only write to the first 181 bytes of the 512 bytes in the flash page. Based on the fact that you are worried about flash lifetime this sounds like a bad solution for you.

    One thing that does worry me about this is wear. According to the Absolute Maximum Ratings 10000 write /erase cycles are possible; would writing the same data over and over again wear down the flash?

    The first thing I want to say about this topic is that 10000 cycles is an absolute maximum rating which is really just a worst case for chips operating in extreme environments. This number applies to chips operating with a heavy load in extreme environments with parameters like temperature swinging between  -40°C and 85°C. A chip operating at room temperature most of the time with a normal workload will typically hold at least 50000 cycles. (This is not an official guaranteed rating from Nordic Semiconductor, but rather a number observed by testing.)

    The rating is for full cycles of writing to and then erasing the flash. You are capped by the 181 write limit, so as long as you keep within this limitation you should be doing fine. I can't find any data available on the impact of writing compared to the impact of erasing.

    What is to be considered when using BLE and Flash-operations?

    It's not a problem performing flash operations while the SoftDevice is enabled, but you have to send the flash operations to the SoftDevice and not directly to the hardware. The SoftDevice has a series of API calls "sd_flash... " which allow you to use the flash. When you use these API calls the SoftDevice will queue the operation, find a timeslot in between the scheduled radio operations and send you an event when it's done.

    Function used to read from flash:

    This code is fine I, but you don't really need it. You can read data directly from flash without this function.

    Best regards,
    Rune Holmgren

  • Edit: Figured it out read reply below if anybody has the same problem.

    After further testing it seems that the sd_flash.. calls do not work while the SoftDevice is running.
    I'm using them in my program and as soon as I start using BLE it completely stops working. 
    There is an event Queue running, everything else works fine (I2C communication etc). If I disable the BLE initialization the write functions work fine, if it is enabled again it stops working. 
    The program does not crash, the write functions simply write wrong values like if it is supposed to write 0xFFFF47C it reads 0x2000FF80. The write functions are getting called with eventQueue->call(<function>); Am I supposed to do it differently?

  • The sd_flash_write function does not keep the data pointer alive, the variable needs to be static. Now it does work fine. 

Reply Children
No Data
Related