Using Non-Volatile Memory in Embedded Systems

nandIn the previous post we have started a series about creating a custom bootloader for MSP430 family. In our bootloader we will use a non-volatile memory for storing the new firmware image file. So maybe it will be good to talk about non-volatile memory types, mainly NOR and NAND flash memories  and how to use them first. Both nor and nand flash memories are easy to interface with a micro-controller with small number of pins with easy/lightweight protocols which is very important in applications like boot-loader and ram-loader due to the small available memory.

Most flash memories guarantee a number of erase and re-write cycles for each sector, (i.e, 100.000 cycles per sector) and a data retention of 10 to 20 years.  So using the flash memory smartly is important. Using the same sector over and over or storing or changing a data in a sector every second will break the device. So use the flash memory for data that will not change frequently such as data logs, user configuration options, calibration values, big files such as jpeg, or html text for an embedded web server, etc… Another disadvantage is you can not erase/modify a single byte, most devices are page erasable or sector erasable, so to modify even a single byte you must read the minimum erasable size(page or sector) to a buffer modify it there, erase the page/sector and write it again, so available buffer size in you micro is another concern.

 

So here is an example about how to use any type of non-volatile memory to get application options, remember we must read our configuration options from the memory if available(not first time) if not we must fill the device with default options or ask user about it. To understand if it is the first boot, we use a MAGIC word/number, changing the magic word will format the device with default values again, so I usually use a statement like this Magicword= 0XABCD+SOFTWARE_VERSION; which guarantees the device will be formatted with default values in the first boot.

 

typedef struct _FLASH_SETTINGS
{
	uint_32		server_ip;
	uint_32		server_port;
	uint_32		own_ip;
	uint_32		own_ip_mask;
	uint_32		own_ip_gateaway;
	uint_32		total_boot;
        uint_8          serial_number[6];
		
}
FLASH_SETTINGS;


#define SOFTWARE_VERSION 2
#define MAGIC_WORD 0XABCD+ SOFTWARE_VERSION
void Load_Conf_Flash(FLASH_SETTINGS* f_set)
{
	//read to buffer
	N25Q16_read(0x0000 ,  (unsigned char*) f_set, sizeof(FLASH_SETTINGS));

        //cheack magic word
	if(f_set->magic_word==MAGIC_WORD)	//not first time
	{
		f_set->total_boot++;

		Update_Flash(f_set); //Erasing and writing
	}
	else //first time
	{
                //write default values
		f_set->magic_word = MAGIC_WORD;

		f_set->serial_number[0]=myID[0];
		f_set->serial_number[1]=myID[1];
		f_set->serial_number[2]=myID[2];
		f_set->serial_number[3]=myID[3];
		f_set->serial_number[4]=myID[4];
		f_set->serial_number[5]=myID[5];

		f_set->total_boot=1;
		f_set->PT100_calibration_first_value = CALIBRATION_CONSTANT;
		

		Update_Flash(f_set);

	}

}

Leave a Reply

Your email address will not be published. Required fields are marked *