Here is the code I use to store configuration information in the flash.
Just define a C structure called FlashConfigStruct that holds all your configuration parameters. It must contain an unsigned int called Magic, and you should define a constant called FLASH_MAGIC containing any value you want.
The routine will use this to report if it read a valid configuration or not.
# include "sys/alt_flash.h"
# include "system.h"
FlashConfigStruct FlashConfig;
int DoReadFlash()
{
alt_flash_fd* Fd;
flash_region* Regions;
unsigned int NumberOfRegions;
unsigned char *Buffer;
Fd = alt_flash_open_dev(EPCS_FLASH_CONTROLLER_NAME);
if (!Fd)
{
printf("Flash not found\n");
return 0;
}
if (alt_get_flash_info(Fd, &Regions, (int*) &NumberOfRegions) != 0)
{
// error while retreiving the flash information
printf("Couldn't retreive flash information\n");
alt_flash_close_dev(Fd);
return 0;
}
// allocate a bloc
Buffer = malloc(Regions->block_size);
if (!Buffer)
{
printf("Not enough memory\n");
alt_flash_close_dev(Fd);
return 0;
}
// read flash last block
if (alt_read_flash(Fd,
Regions->offset+(Regions->number_of_blocks-1)*Regions->block_size,
Buffer, Regions->block_size))
{
printf("Error while reading flash block\n");
free(Buffer);
alt_flash_close_dev(Fd);
return 0;
}
// copy into the structure
memcpy(&FlashConfig,Buffer,sizeof(FlashConfigStruct));
free(Buffer);
alt_flash_close_dev(Fd);
// check block contents
if (FlashConfig.Magic != FLASH_MAGIC)
{
printf("Flash contents invalid\n");
return 0;
}
return -1;
}
void ReadFlash()
{
if (!DoReadFlash())
{
printf("Taking default configuration.\n");
FlashConfig.Magic=FLASH_MAGIC;
// fill here the other members of FlashConfig with defaults values
}
}
int WriteFlash()
{
alt_flash_fd* Fd;
flash_region* Regions;
unsigned int NumberOfRegions;
unsigned char *Buffer;
Fd = alt_flash_open_dev(EPCS_FLASH_CONTROLLER_NAME);
if (!Fd)
{
printf("Flash not found\n");
return 0;
}
if (alt_get_flash_info(Fd, &Regions, (int*) &NumberOfRegions) != 0)
{
// error while retreiving the flash information
printf("Couldn't retreive flash information\n");
alt_flash_close_dev(Fd);
return 0;
}
// allocate a bloc
Buffer = calloc(Regions->block_size,1);
if (!Buffer)
{
printf("Not enough memory\n");
alt_flash_close_dev(Fd);
return 0;
}
// copy into the buffer
memcpy(Buffer,&FlashConfig,sizeof(FlashConfigStruct));
// write flash last block
if (alt_write_flash(Fd,
Regions->offset+(Regions->number_of_blocks-1)*Regions->block_size,
Buffer, Regions->block_size))
{
printf("Error while writing flash block\n");
free(Buffer);
alt_flash_close_dev(Fd);
return 0;
}
free(Buffer);
alt_flash_close_dev(Fd);
return -1;
}
Call ReadFlash() from your application init, and WriteFlash when you updated the FlashConfig structure and want to store it to flash.
The code will use the last block of the first region. Every EPCS I encountered until now has only one region, so the block used is the last one in the flash.