Continuous Writes to NVS and Storage Space Management

We are currently working on a Zigbee-based network coordinator using the nRF52840. I have a function, dfu_multi_image_write, that writes data to NVS in chunks. The function writes continuously to NVS, and I'm unsure if this is acceptable or if the SDK automatically manages storage availability.

See the dfu_multi_image_write function:

int dfu_multi_image_write(size_t offset, const uint8_t *chunk, size_t chunk_size)
{
    int result;
    size_t chunk_offset = 0;

    if (offset > ctx.cur_offset) {
        /* Unexpected data gap */
        return -ESPIPE;
    }

    while (1) {
        /* Skip ahead to the current write offset */
        chunk_offset += (ctx.cur_offset - offset);

        if (chunk_offset >= chunk_size) {
            break;
        }

        result = process_current_item(chunk + chunk_offset, chunk_size - chunk_offset);

        if (result <= 0) {
            return result;
        }

        chunk_offset += (size_t)result;
        offset += (size_t)result;
    }

    return 0;
}


See the process_current_item function:

static int process_current_item(const uint8_t *chunk, size_t chunk_size)
{
	int err = 0;

	/* Process only remaining bytes of the current item (header or image) */
	chunk_size = MIN(chunk_size, ctx.cur_item_size - ctx.cur_item_offset);

	if (ctx.cur_image_no < 0) {
		memcpy(ctx.buffer + ctx.cur_item_offset, chunk, chunk_size);

		if (ctx.cur_item_offset + chunk_size == ctx.cur_item_size) {
			if (ctx.cur_image_no == IMAGE_NO_FIXED_HEADER) {
				err = parse_fixed_header();
			} else {
				err = parse_cbor_header();
			}
		}
	} else {
		/* Image data */
		const struct dfu_image_writer *writer = current_image_writer();

		if (!writer) {
			err = -ESPIPE;
		}

		if (!err && ctx.cur_item_offset == 0) {
			err = writer->open(writer->image_id,
					   ctx.header.images[ctx.cur_image_no].size);
		}

		if (!err) {
			err = writer->write(chunk, chunk_size);
		}

		if (!err && ctx.cur_item_offset + chunk_size == ctx.cur_item_size) {
			err = writer->close(true);
		}
	}

	if (err) {
		return err;
	}

	ctx.cur_offset += chunk_size;
	ctx.cur_item_offset += chunk_size;

	if (ctx.cur_item_offset == ctx.cur_item_size) {
		select_next_image();
	}

	return chunk_size;
}


Can you please clarify the following questions?

1. Is it acceptable to continuously write to NVS as shown in the code snippet? Are there any procedures to follow to avoid potential issues?
2. How can I check if the previous write was completed and verify the busy status of the writer?
3. What will happen if the writer is busy, and how is it handled?

Hardware: Custom hardware with nRF52840
SDK: nRF Connect SDK version 2.1.0

Thanks, and regards,
Kavitha

Parents
  • Hi, 

    I don't understand the questions. It looks like dfu_multi_image_write() is located in nrf/subsys/dfu/dfu_multi_image/src/dfu_multi_image.c in NCS.

    Are you implementing your own writer to store the image in a custom (as in "not-supported-out-of-the-box") place?

  • Hi  ,

    No, we are not trying to implement our own writer. In the dfu_multi_image_write function, due to the while(1) loop, it seems like the writing process happens continuously. If the chunk size is increased, is there a chance it could affect Zigbee network functions, or will it be able to handle it? I just need this clarification as usually, the write to flash take more time than most other operations and would like to know if this is handled inside the writer functions or there is any limitations to it.

    We are occasionally getting hardfault when using this image write, though we are not sure its because of dfu_multi_image_write, we just want to make sure there are no limitations to using this function.

Reply
  • Hi  ,

    No, we are not trying to implement our own writer. In the dfu_multi_image_write function, due to the while(1) loop, it seems like the writing process happens continuously. If the chunk size is increased, is there a chance it could affect Zigbee network functions, or will it be able to handle it? I just need this clarification as usually, the write to flash take more time than most other operations and would like to know if this is handled inside the writer functions or there is any limitations to it.

    We are occasionally getting hardfault when using this image write, though we are not sure its because of dfu_multi_image_write, we just want to make sure there are no limitations to using this function.

Children
  • Hi, 

    Note that the while(1) loop is exited when if (chunk_offset >= chunk_size). And the following code makes sure that chunk_offset is advanced in each iteration:

            result = process_current_item(chunk + chunk_offset, chunk_size - chunk_offset);
            if (result <= 0) {
            return result;
            }
            
            chunk_offset += (size_t)result;
            offset += (size_t)result;
     

    Thus, I can't see anything wrong in this code. This library is just for unpacking a multi-image package, and it requires that a user provides custom writers for storing the separate images (normally DFU target library is used for that). The question is how you implement the writers and why NVS is mentioned here at all.

    -Amanda H.

  • Hi  ,

    Sorry for the confusion. I mistakenly mentioned NVS. I just want to rephrase my question.

    My question is: If the chunk size is increased, is there a chance it could affect Zigbee network functions, or will the system be able to handle it? Based on your previous response, I understand that since the writer is inside a while(1) loop, it should not affect Zigbee network functions, even if writing to flash takes more time or if the chunk size is increased. Please let me know if my understanding is incorrect.

  • Kavitha said:
    If the chunk size is increased, is there a chance it could affect Zigbee network functions, or will the system be able to handle it?

    No, as is the explanation in the previous reply. 

Related