This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Using the Zephyr NVS library with External Flash Storage on the nRF9160

Hi, 

I am using the MX25R64 NOR Flash chip on my own PCB with the nRF9160 package. With the help of this thread I have managed to get the NVS library to work with it. I don't necessarily have a problem to solve, but I would like to understand a few things because to be honest I'm quite confused as to how this is working. 

Firstly, here is a segment from the overlay file. 

&spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	sck-pin = < 2 >;
	mosi-pin = < 3 >;
	miso-pin = < 4 >;
	label = "SPI_1";
	cs-gpios = < &gpio0 1 GPIO_ACTIVE_LOW >;
	mx25r64: mx25r6435f@0 {
		compatible = "jedec,spi-nor";
		reg = < 0x0 >;
		spi-max-frequency = < 8000000 >;
		label = "MX25R64";
		jedec-id = [ C2 28 17 ];
		size = < 0x4000000 >;
		has-dpd;
		t-enter-dpd = < 0x2710 >;
		t-exit-dpd = < 0x88b8 >;
		partitions {
			compatible = "fixed-partitions";
			#address-cells = < 0x1 >;
			#size-cells = < 0x1 >;
			lfs1_part: partition@0 {
				label = "ext_storage";
				reg = < 0x0 0x10000 >;
				phandle = < 0x5 >;
			};
		};
	};
};

Here are the relevant macros in the conf file 

CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_PM_EXTERNAL_FLASH=y
CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R64"
CONFIG_PM_EXTERNAL_FLASH_BASE=0x0
CONFIG_SPI_NOR_IDLE_IN_DPD=y
CONFIG_PM_EXTERNAL_FLASH_SIZE=0x4000000

And this is what I am doing in main to initalise the flash (This was originally linked to the internal flash storage so I basically just changed the first line and the sector size/count)

	flash_dev = DEVICE_DT_GET(DT_N_NODELABEL_mx25r64);
	if (!device_is_ready(flash_dev)){
		printk("Internal Flash ERROR");
	}

	fs.offset = 0x00;
	err = flash_get_page_info_by_offs(flash_dev, fs.offset, &info);
	if (err) {
		printk("Unable to get page info...");
	}
	fs.sector_size = 32768;
	fs.sector_count = 256;

	err = nvs_init(&fs, flash_dev->name);
	if (err) {
		printk("Internal Flash Initialisation Failed");
	}
	else{
		printk("Internal Flash Initialisation Passed");
	}

After this I can use nvs libraries to read and write to the flash - great!

What I cannot understand though...

1. Do all SPI NOR Flash chips have the same protocol to read and write? (By protocol I don't mean SPI - I mean the command set that you send over SPI to read/write)

If so, does that mean to use a different SPI NOR chip, you would just have to change the JEDEC ID in the overlay?

Or if not, where is the driver that is allowing me to read and write to the MX25R64, and how was it invoked from the overlay?

2. What is happening when I write an 8 byte array to the flash using nvs_write() ? 

From my understanding, the minimum amount of data that can be written to flash is one "page" which the smallest page size I can define is 4096 bytes, so if I write 8 bytes, am I actually writing 8 bytes (+8 bytes header that NVS uses) followed by 4080 NULL bytes to write one page? If so, then the second time I write, am I copying the page, adding a further 8 bytes and writing over the same page?

This is important as I am aware of flash ware, and I don't want to rewrite over the same page 256 times (in this example setup) when I could store that data in RAM until I have filled a page worth of data. 

Thanks, 

Damien

Parents
  • 1. Do all SPI NOR Flash chips have the same protocol to read and write? (By protocol I don't mean SPI - I mean the command set that you send over SPI to read/write)

    most have the same OP codes, any deviation should be noted in the datasheet of the product of choice. So changing JEDEC ID, size and page size should be enough. 


    What is happening when I write an 8 byte array to the flash using nvs_write() ? 

    It should be possible to write less than one page at the time. as long as it is word-aligned. 


    Do you need to use QSPI and external memory to store 8 bytes?

    Regards,
    Jonathan

  • Hi Jonathon, 

    Thanks for your reply, that's useful to know.

    Do you need to use QSPI and external memory to store 8 bytes?

    To be clear, I don't mean that's all I'm going to write. I am working on a data-logger, so every X amount of time, I am reading a sensor and saving that data in flash. I am trying to generalize all the possible things I might save in flash - 8 Bytes should be enough in each case to save a timestamp, type and value - (Obviously encoded)

    Due to it being a case where I need flash memory for a long period of time (Minimum 6 months log) I just want to make sure I am doing it right. Ideally I will save data every time it is read, in case of reset, but if I have to fill a page worth in RAM before it is written I can deal with that, just need to know!

    Also I believe its not QSPI as it's the nRF9160.

    Thanks for your help. 

    Damien

Reply
  • Hi Jonathon, 

    Thanks for your reply, that's useful to know.

    Do you need to use QSPI and external memory to store 8 bytes?

    To be clear, I don't mean that's all I'm going to write. I am working on a data-logger, so every X amount of time, I am reading a sensor and saving that data in flash. I am trying to generalize all the possible things I might save in flash - 8 Bytes should be enough in each case to save a timestamp, type and value - (Obviously encoded)

    Due to it being a case where I need flash memory for a long period of time (Minimum 6 months log) I just want to make sure I am doing it right. Ideally I will save data every time it is read, in case of reset, but if I have to fill a page worth in RAM before it is written I can deal with that, just need to know!

    Also I believe its not QSPI as it's the nRF9160.

    Thanks for your help. 

    Damien

Children
  • DamoL said:
    Also I believe its not QSPI as it's the nRF9160.

    Yes, no QSPI for the nRF9160, sorry for the confusion. 


    Time is not the main factored, but he write/erase cycles. So reducing the amount of write/erase will prolong the life of the flash. 

    Regards,
    Jonathan

  • Yes absolutely, I probably wasn't clear, when I say 6 months, I mean 6 months worth or readings, which if I am logging every minute is 262800 readings in flash. So obviously cant get this wrong and ware the flash out in the few months. I guess I will have to store in RAM and only write in blocks every x amount of readings to be sure. 

    Thanks for your help. 

    Damien

Related