I've used the last blocks of the EPCS memory for user data.
The address of the EPCS controller comes from SOPC builder and from your BSP's system.h include file (i.e. it varies in every system). But if you use alt_flash_open_dev(), you don't have to know the address of the EPCS controller in but Avalon bus.
Here's some example what I've used:
# define BOARD_DATA_BLOCK_FROM_END 1 /* Last block for my own use */
alt_flash_dev *pFlash;
flash_region *flash_info_ptr;
int number_of_regions;
unsigned int addr;
pFlash = alt_flash_open_dev( EPCS_CONTROLLER_NAME );
if ( pFlash ) {
alt_get_flash_info( pFlash, &flash_info_ptr, &number_of_regions );
//printf( "Flash offset=0x%X, region_size=0x%X, number_of_block=%d, block_size=0x%X\n",
// flash_info_ptr->offset,
// flash_info_ptr->region_size,
// flash_info_ptr->number_of_blocks,
// flash_info_ptr->block_size );
//printf( "Flash number_of_regions=%d\n", number_of_regions );
addr = (flash_info_ptr->number_of_blocks-BOARD_DATA_BLOCK_FROM_END) * flash_info_ptr->block_size;
alt_read_flash( pFlash, addr, &g_BoardData, sizeof(g_BoardData) );
alt_flash_close_dev( pFlash );
// Verify tag ...
if ( (g_BoardData.MagicTag & 0xFFFF0000) != (BOARD_DATA_TAG_V1 & 0xFFFF0000) ) {
// Bad tag, ignore data and clear buffer
memset( &g_BoardData, 0, sizeof(g_BoardData) );
}
}