2963 lines
114 KiB
C
2963 lines
114 KiB
C
/*******************************************************************************
|
||
Copyright (C) Marvell International Ltd. and its affiliates
|
||
|
||
********************************************************************************
|
||
Marvell GPL License Option
|
||
|
||
If you received this File from Marvell, you may opt to use, redistribute and/or
|
||
modify this File in accordance with the terms and conditions of the General
|
||
Public License Version 2, June 1991 (the "GPL License"), a copy of which is
|
||
available along with the File in the license.txt file or by writing to the Free
|
||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
|
||
on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
|
||
|
||
THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
|
||
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
|
||
DISCLAIMED. The GPL License provides additional details about this warranty
|
||
disclaimer.
|
||
|
||
*******************************************************************************/
|
||
#include <config.h>
|
||
#include <common.h>
|
||
#include <malloc.h>
|
||
#include <net.h>
|
||
#include <command.h>
|
||
|
||
#include "mvSysHwConfig.h"
|
||
#if defined(MV_INCLUDE_MONT_EXT) && defined (MV_INCLUDE_MONT_FFS)
|
||
|
||
#include "mvTypes.h"
|
||
#include "norflash/mvFlash.h"
|
||
#include "mvCpuIf.h"
|
||
/*#include "mv_mon.h"*/
|
||
#include "mv_fs.h"
|
||
|
||
#if CONFIG_COMMANDS & CFG_CMD_BSP
|
||
|
||
/* #define DEBUG */
|
||
#ifdef DEBUG
|
||
#define DB(x) x
|
||
#else
|
||
#define DB(x)
|
||
#endif
|
||
|
||
static MV_FLASH_INFO *mvFlashInfo;
|
||
|
||
/* File system data base variables */
|
||
/* FAT signature */
|
||
char FATsignature[] = "FAT024136764000";
|
||
unsigned int initializationFlag;
|
||
unsigned int mvFSTimeStamp;
|
||
unsigned int operationMode;
|
||
unsigned int mvFSOffset;
|
||
unsigned int mvFSTopOffset;
|
||
unsigned int nextFreeBlock;
|
||
FS_FILE_TABLE_ENTRY mvFSEntries[FS_MAX_NUM_OF_ENTRIES];
|
||
FS_FILE_CACHE_BLOCK mvFSCacheBlocks[FS_NUMBER_OF_BLOCKS_FOR_CACHE];
|
||
|
||
/* Functions */
|
||
extern void d_i_cache_clean(unsigned int Address, unsigned int byteCount);
|
||
extern int load_net(MV_U32 *loadnet_addr);
|
||
extern unsigned int VIRTUAL_TO_PHY(unsigned int address);
|
||
extern void mv_go(unsigned long addr,int argc, char *argv[]);
|
||
extern MV_FLASH_INFO* getMvFlashInfo(int index);
|
||
|
||
/*******************************************************************************
|
||
* mvFSFormat - Formats the mvFlash mvMemory for file system usage.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function formats the flash memory for file system usage. It
|
||
* allocates 10 blocks for FAT in a form of a linked list and write the
|
||
* signature (signature defind in mvFS.h) in each FAT header block
|
||
* within the flash. The format starts from the <20>offset<65> parameter value
|
||
* within the flash if the offset is aligned with one of the flash's
|
||
* sectors start address, otherwise it will be incremented to the nearest
|
||
* sector start address and then perform the format.The format can be
|
||
* accomplished in 2 modes as described below.
|
||
*
|
||
* INPUT:
|
||
* offset - Starting point of the format within the flash.
|
||
*
|
||
* mode - Defines whether an erasing counter will be enabled or not .
|
||
* When erasing counter is enabled , the function will allocate one
|
||
* block at the end of each sector to act as a counter for the
|
||
* number of erasures of that sector . The possible values :
|
||
* - ENABLE_ERASING_COUNTER
|
||
* - NO_ERASING_COUNTER
|
||
* OUTPUT:
|
||
* Initialized flash for file system usage.
|
||
*
|
||
* RETURN:
|
||
* The actual offset (after alignment to the nearest sector start address)
|
||
* or:
|
||
* FLASH_MEMORY_NOT_PRESENT - if no flash memory present .
|
||
* VALID_FILE_SYS_IN_LOWER_OFFSET - if a valid file system residing in a
|
||
* lower offset.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSFormat(unsigned int offset,unsigned int mode)
|
||
{
|
||
unsigned int i,sectorSize,tempOffset,limit,previousCount;
|
||
unsigned int erasingCounterWasEnabled = 0,status;
|
||
|
||
DB(printf("start mvFSFormat\n"));
|
||
DB(printf("Flash base addr 0x%x\n",mvFlashInfo->baseAddr));
|
||
|
||
if(offset != mvFlashSecOffsGet(mvFlashInfo, mvFlashInWhichSec(mvFlashInfo, offset)))
|
||
{
|
||
offset = mvFlashSecOffsGet(mvFlashInfo, mvFlashInWhichSec(mvFlashInfo, offset) + 1);
|
||
}
|
||
if(offset != 0xffffffff)
|
||
{
|
||
if(mode == FS_ENABLE_ERASING_COUNTER)
|
||
{
|
||
tempOffset = mvFSSearchForSignature();
|
||
if(tempOffset != FS_NO_VALID_FAT_STRING)
|
||
{
|
||
if(tempOffset < offset)
|
||
return FS_VALID_FILE_SYS_IN_LOWER_OFFSET;
|
||
if(mvFlash32Rd(mvFlashInfo, tempOffset + FS_ERSAING_COUNTER_FLAG_OFFSET)
|
||
== FS_ENABLE_ERASING_COUNTER)
|
||
{
|
||
erasingCounterWasEnabled = 1;
|
||
}
|
||
}
|
||
}
|
||
tempOffset = offset;
|
||
/* Eraseing the sectors dedicated for the file system */
|
||
while(mvFlashInWhichSec(mvFlashInfo, offset) != 0xffffffff)
|
||
{
|
||
if(mode == FS_NO_ERASING_COUNTER)
|
||
{
|
||
DB(printf("mvFSFormat - mode = FS_NO_ERASING_COUNTER\n"));
|
||
i = mvFlashInWhichSec(mvFlashInfo, offset);
|
||
sectorSize = mvFlashSecSizeGet(mvFlashInfo, i);
|
||
limit = offset + sectorSize;
|
||
for(; offset < limit ; offset+=4)
|
||
{
|
||
if(mvFlash32Rd(mvFlashInfo, offset) != 0xffffffff)
|
||
{
|
||
DB(printf("mvFSFormat - Erase flash sector 0x%x\n", mvFlashInWhichSec(mvFlashInfo, offset)));
|
||
status = mvFlashSecErase(mvFlashInfo, mvFlashInWhichSec(mvFlashInfo, offset));
|
||
if (status != MV_OK)
|
||
{
|
||
printf("mvFlashSecErase - FAIL!\n");
|
||
return status;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
offset += sectorSize;
|
||
}
|
||
else /* mode == FS_ENABLE_ERASING_COUNTER */
|
||
{
|
||
DB(printf("mvFSFormat - mode = FS_ENABLE_ERASING_COUNTER\n"));
|
||
i = mvFlashInWhichSec(mvFlashInfo, offset);
|
||
sectorSize = mvFlashSecSizeGet(mvFlashInfo, i);
|
||
limit = offset + sectorSize - FS_BLOCK_SIZE;
|
||
previousCount = mvFlash32Rd(mvFlashInfo, limit);
|
||
for(; offset <= (limit + 4) ; offset+=4)
|
||
{
|
||
if(mvFlash32Rd(mvFlashInfo, offset) != 0xffffffff)
|
||
{
|
||
mvFlashSecErase(mvFlashInfo, mvFlashInWhichSec(mvFlashInfo, offset));
|
||
if(erasingCounterWasEnabled)
|
||
{
|
||
/* Increment the counter */
|
||
mvFlash32Wr(mvFlashInfo, limit, previousCount + 1);
|
||
mvFlash8Wr(mvFlashInfo, limit+FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_USED_FOR_ERASING_COUNTER);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if(!erasingCounterWasEnabled)
|
||
{
|
||
/* Initialize the counter */
|
||
mvFlash32Wr(mvFlashInfo, limit, 0);
|
||
mvFlash8Wr(mvFlashInfo, limit + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_USED_FOR_ERASING_COUNTER);
|
||
}
|
||
offset = limit + FS_BLOCK_SIZE;
|
||
}
|
||
}
|
||
/* Fill the FAT's header */
|
||
offset = tempOffset;
|
||
/* Update the status flag */
|
||
mvFlash8Wr(mvFlashInfo, offset + FS_BLOCK_STATUS_FLAG_OFFSET,FS_FAT_BLOCK);
|
||
/* Write the FAT's signature */
|
||
mvFlashBlockWr(mvFlashInfo, offset + FS_SIGNATURE_OFFSET, FS_FAT_SIGNATURE_SIZE,
|
||
(MV_U8 *)FATsignature);
|
||
/* Check if we were able to burn the mvFlash */
|
||
for(i = 0 ; i < FS_FAT_SIGNATURE_SIZE ; i++)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, offset + FS_SIGNATURE_OFFSET + i) != FATsignature[i])
|
||
return FS_FLASH_MEMORY_NOT_PRESENT;
|
||
}
|
||
if(mode == FS_ENABLE_ERASING_COUNTER)
|
||
{
|
||
mvFlash32Wr(mvFlashInfo, offset + FS_ERSAING_COUNTER_FLAG_OFFSET,
|
||
FS_ENABLE_ERASING_COUNTER);
|
||
}
|
||
mvFlash32Wr(mvFlashInfo, offset, offset + FS_BLOCK_SIZE);
|
||
/* Alocate 9 more blocks for the FAT */
|
||
for(i = 1 ; i < (FS_MAX_NUM_OF_FAT_BLOCKS - 1) ; i++)
|
||
{
|
||
/* Next block pointer */
|
||
mvFlash32Wr(mvFlashInfo, offset+(FS_BLOCK_SIZE*(i)),offset+
|
||
(FS_BLOCK_SIZE*(i+1)));
|
||
/* Flag */
|
||
mvFlash8Wr(mvFlashInfo, offset+(FS_BLOCK_SIZE*(i)) +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET, FS_FAT_BLOCK);
|
||
}
|
||
/* The last block's next pointer is 0xffffffff since it is the last */
|
||
mvFlash8Wr(mvFlashInfo, offset + (FS_BLOCK_SIZE * i) +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET, FS_FAT_BLOCK);
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSInit - Initializes the flash system's data base variables.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function initializes the flash system's database variables residing
|
||
* in the systems dynamic memory (SDRAM) . It searches within the flash
|
||
* memory from the begining, for the first occurrence of a valid signature.
|
||
* If found, a valid file system is assumed to be exist starting from the
|
||
* sector the signature was found and all the database variables will than
|
||
* be initialized ,otherwise it returns NO_VALID_FAT_STRING or
|
||
* OFFSET_OUT_OF_RANGE to indicate that no valid file system was found
|
||
* within the flash .If a valid file system was found ,the function returns
|
||
* the number of files within the flash .The <20>mode<64> parameter delivered to
|
||
* the function is for future needs to support two cache modes(cache mode,
|
||
* non - cache mode) and currently this feature is not implemented in this
|
||
* current version of this function.
|
||
* NOTE!!!!:
|
||
* It is a MUST to call this function before any attempt to use file-system
|
||
* driver.
|
||
* INPUT:
|
||
* mode - For future needs to support cache or non-cache modes (currently
|
||
* not implemented).
|
||
*
|
||
* OUTPUT:
|
||
* Initialized data base for the file system.
|
||
*
|
||
* RETURN:
|
||
* Number of files currently on the system or:
|
||
* NO_VALID_FAT_STRING - if no file system was found (Try to use
|
||
* <20>fileSysFormat<61> function in this case).
|
||
* OFFSET_OUT_OF_RANGE - if there was an error finding a signature found is
|
||
* SYSTEM_ALREADY_INITIALIZED.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSInit(unsigned int mode)
|
||
{
|
||
/* Initially we are not going to support the FS_ENABLE_CACHE mode */
|
||
unsigned int offset = 0,i = 0,numOfFiles,nextBlockOffset;
|
||
unsigned int fileEntryOffset,tempOffset;
|
||
|
||
/* set the global flash info structure */
|
||
mvFlashInfo = getMvFlashInfo(MAIN_FLASH_INDEX);
|
||
|
||
/* Seek for the FAT signature */
|
||
offset = mvFSSearchForSignature();
|
||
if(offset == FS_NO_VALID_FAT_STRING)
|
||
return FS_NO_VALID_FAT_STRING;
|
||
if(offset >= mvFlashSizeGet(mvFlashInfo))
|
||
return FS_OFFSET_OUT_OF_RANGE;
|
||
mvFSTopOffset = mvFlashSizeGet(mvFlashInfo);
|
||
|
||
/* Check if the system is already initialized , if so we will not
|
||
re-initialize */
|
||
if(initializationFlag == FS_FILE_SYSTEM_INITIALIZED)
|
||
return FS_SYSTEM_ALREADY_INITIALIZED;
|
||
|
||
/* We found the FAT's signature, now we need to initialize the file system
|
||
data base and count the number of files */
|
||
mvFSTimeStamp = 0;
|
||
operationMode = mode;
|
||
mvFSOffset = offset;
|
||
nextFreeBlock = 0xffffffff - FS_BLOCK_SIZE;
|
||
/* Initialize the files entries */
|
||
for(i = 0 ; i < FS_MAX_NUM_OF_ENTRIES ; i++)
|
||
{
|
||
mvFSEntries[i].filePointer = 0;
|
||
mvFSEntries[i].statusFlag = FS_FREE_ENTRY;
|
||
mvFSEntries[i].mode[0] = '\0';
|
||
mvFSEntries[i].pointerToFAT = 0xffffffff;
|
||
mvFSEntries[i].EOFpointer = 0;
|
||
}
|
||
/* Initialize the cache blocks */
|
||
for(i = 0 ; i < FS_NUMBER_OF_BLOCKS_FOR_CACHE ; i++)
|
||
{
|
||
mvFSCacheBlocks[i].currentBlockAddress = 0xffffffff;
|
||
mvFSCacheBlocks[i].fileHandler = 0;
|
||
mvFSCacheBlocks[i].usageCounter = 0;
|
||
mvFSCacheBlocks[i].timeStamp = 0;
|
||
}
|
||
/* Count the number of files currently on the system */
|
||
numOfFiles = 0;
|
||
nextBlockOffset = mvFSOffset;
|
||
while(nextBlockOffset != 0xffffffff)
|
||
{
|
||
/* Skip the block's header */
|
||
fileEntryOffset = nextBlockOffset + FS_FAT_HEADER_SIZE;
|
||
for(i = 0 ; i < 15 ; i++)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, fileEntryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_USE)
|
||
numOfFiles++;
|
||
/* If we have files which were not properly closed we need to
|
||
to remove them from the system */
|
||
if(mvFlash8Rd(mvFlashInfo, fileEntryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_UPDATE)
|
||
{
|
||
mvFlash8Wr(mvFlashInfo, fileEntryOffset + FS_ENTRY_STATUS_FLAG_OFFSET,
|
||
FS_FREE_DIRTY_ENTRY);
|
||
/* Free the file's data blocks */
|
||
tempOffset = mvFlash32Rd(mvFlashInfo, fileEntryOffset);
|
||
while(tempOffset != 0xffffffff)
|
||
{
|
||
tempOffset = tempOffset & FS_BLOCK_OFFSET_MASK;
|
||
mvFlash8Wr(mvFlashInfo, tempOffset + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_FREE_DIRTY_BLOCK);
|
||
tempOffset = mvFlash32Rd(mvFlashInfo, tempOffset);
|
||
}
|
||
}
|
||
/* point to the next entry */
|
||
fileEntryOffset += FS_FAT_FILE_ENTRY_SIZE;
|
||
}
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, nextBlockOffset);
|
||
}
|
||
initializationFlag = FS_FILE_SYSTEM_INITIALIZED;
|
||
return numOfFiles;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSDelete - Deletes a file for the file system.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function deletes a file in the file-system. The function actually
|
||
* marks the file's entry status flag as FREE_DIRTY_ENTRY and the file's
|
||
* status flag of each data block with the value FREE_DIRTY_BLOCKs to
|
||
* indicate that this entery and all the file<6C>s data blocks are no longer
|
||
* associated by this file. If the file has valid handles associated with
|
||
* it the file will not be deleted .
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
*
|
||
* INPUT:
|
||
* fileName - A string containing the file name.
|
||
*
|
||
* OUTPUT:
|
||
* On success the file will be deleted..
|
||
*
|
||
* RETURN:
|
||
* On success - The return value will be FS_FILE_DELETED.
|
||
* On failure one of the following parameters:
|
||
* FS_FILE_NOT_FOUND - if the data base was initialized or file was not
|
||
* found.
|
||
* FS_FILE_IS_NOT_CLOSED - if the file has valid handles associated with
|
||
* it.
|
||
*******************************************************************************/
|
||
unsigned int mvFSDelete(char * fileName)
|
||
{
|
||
unsigned int fileOffset,numOfHandles,tempOffset;
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return FS_FILE_NOT_FOUND;
|
||
|
||
if((fileOffset = mvFSFileFind(fileName)) == FS_FILE_NOT_FOUND)
|
||
return FS_FILE_NOT_FOUND;
|
||
if((numOfHandles = mvFSNumOfHandles(fileName)) == FS_FILE_NOT_FOUND)
|
||
return FS_FILE_NOT_FOUND;
|
||
if(numOfHandles > 0)
|
||
return FS_FILE_IS_NOT_CLOSED;
|
||
|
||
mvFlash8Wr(mvFlashInfo, fileOffset + FS_ENTRY_STATUS_FLAG_OFFSET,
|
||
FS_FREE_DIRTY_ENTRY);
|
||
/* Free the file's data blocks */
|
||
tempOffset = mvFlash32Rd(mvFlashInfo, fileOffset);
|
||
while(tempOffset != 0xffffffff)
|
||
{
|
||
tempOffset = tempOffset & FS_BLOCK_OFFSET_MASK;
|
||
mvFlash8Wr(mvFlashInfo, tempOffset + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_FREE_DIRTY_BLOCK);
|
||
tempOffset = mvFlash32Rd(mvFlashInfo, tempOffset);
|
||
}
|
||
return FS_FILE_DELETED;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSFileFind - Check if a file exists in the file system.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function checks if the file <20>fileName<6D> exists in the file system.
|
||
* The function will search for the file with the matching name and
|
||
* extension and if found , the file's entry offset in the FAT is returned.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
*
|
||
* INPUT:
|
||
* fileName - A string containing the file name.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* FILE_NOT_FOUND or the file's entery offset in the FAT.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSFileFind(char * fileName)
|
||
{
|
||
unsigned int nextBlockOffset,fileEntryOffset,index;
|
||
char tempString[20];
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return FS_FILE_NOT_FOUND;
|
||
nextBlockOffset = mvFSOffset;
|
||
while(nextBlockOffset != 0xffffffff)
|
||
{
|
||
/* Skip the block's header */
|
||
for(fileEntryOffset = nextBlockOffset + FS_FAT_HEADER_SIZE;
|
||
fileEntryOffset < (nextBlockOffset + FS_BLOCK_SIZE);
|
||
fileEntryOffset += FS_FAT_FILE_ENTRY_SIZE)
|
||
{
|
||
index = 0;
|
||
if(mvFlash8Rd(mvFlashInfo, fileEntryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_USE)
|
||
{
|
||
/* Read the file's name */
|
||
mvFSReadFileNameFromFATentry(fileEntryOffset,tempString);
|
||
if(strcmp(tempString,fileName) == 0) return fileEntryOffset;
|
||
/* else , try the next entry */
|
||
}
|
||
}
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, nextBlockOffset);
|
||
}
|
||
return FS_FILE_NOT_FOUND;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSNumOfHandles - Counts the number of handles currently pointing to a file.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function counts the number of handles currently associated to the
|
||
* file <20>fileName<6D>.The entry table in the dynamic database is formed from
|
||
* an array of FILE_TABLE_ENTRY (structure defined in mvFS.h) and the
|
||
* file handler acts as the index of that array . The function counts each
|
||
* entry within the array that points to the file <20>fileName<6D> and return
|
||
* that value.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
*
|
||
* INPUT:
|
||
* fileName - A string containing the file name.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* on success , the Number of handlers currently associated to the file
|
||
* <20>fileName<6D>.
|
||
* on failure , FS_FILE_NOT_FOUND.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSNumOfHandles(char * fileName)
|
||
{
|
||
unsigned int fileEntryOffset,i,numOfHandles;
|
||
if((fileEntryOffset = mvFSFileFind(fileName)) == 0xffffffff)
|
||
return FS_FILE_NOT_FOUND;
|
||
|
||
numOfHandles = 0;
|
||
for(i = 0 ; i < FS_MAX_NUM_OF_ENTRIES ; i++)
|
||
{
|
||
if(fileEntryOffset == mvFSEntries[i].filePointer)
|
||
numOfHandles++;
|
||
}
|
||
return numOfHandles;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSSearchForSignature - Searches for the FAT's signature string, if the
|
||
* string is found we are assuming a valid file system.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function searches within the flash memory from the begining for the
|
||
* first occurrence of a valid signature .If found , it returns the sector
|
||
* offset on which the signature first occurred , otherwise it returns
|
||
* NO_VALID_FAT_STRING to indicate the flash is not formated , in that case
|
||
* you might want to use fileSysformat function.
|
||
*
|
||
* INPUT:
|
||
* None.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* The offset of the sector in which the signature was found,
|
||
* otherwise FS_NO_VALID_FAT_STRING .
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSSearchForSignature(void)
|
||
{
|
||
unsigned int offset = 0,i,sectorNumber;
|
||
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, offset);
|
||
while((offset = mvFlashSecOffsGet(mvFlashInfo, sectorNumber)) != 0xffffffff)
|
||
{
|
||
for(i = 0 ; i < FS_FAT_SIGNATURE_SIZE ; i++)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, offset + FS_SIGNATURE_OFFSET +
|
||
i) != FATsignature[i])
|
||
break;
|
||
}
|
||
if(i == FS_FAT_SIGNATURE_SIZE) break;
|
||
offset += mvFlashSecSizeGet(mvFlashInfo, sectorNumber);
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, offset);
|
||
if(sectorNumber == 0xffffffff) return FS_NO_VALID_FAT_STRING;
|
||
}
|
||
if(offset == 0xffffffff) return FS_NO_VALID_FAT_STRING;
|
||
return offset;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSOpen - Opens a file for read/write/append.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function opens a file for reading , writing or appending data .The
|
||
* function will act differantly upon each mode delivered by the parameter
|
||
* <20>mode<64>.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
*
|
||
* INPUT:
|
||
* mode - defines on which mode the file will be open .All possible values
|
||
* for <20>mode<64> parameter are described below:
|
||
*
|
||
<EFBFBD> "r" - Opens the file for reading only . If the file does not
|
||
* exist or cannot be found , the function fails . After the
|
||
* file has been found , the function searches for an empty
|
||
* entry within the dynamic data base entry table and if it
|
||
* found one , it associates the file <20>fileName<6D> to that
|
||
* entry and returns the handler of the file.
|
||
* "r+" - Opens the file for both reading and writing. If the file
|
||
* does not exist or cannot be found , the function fails.
|
||
* After the file has been found , the function searches
|
||
* for an empty entry within the dynamic data base entry
|
||
* table and if found , it associates the file <20>fileName<6D>
|
||
* to that entry and returns the handler of the file . When
|
||
* a file is opened with the <20>r+<2B> all write operations
|
||
* occur at the end of the file. The file pointer can be
|
||
* repositioned using fileSysSeek or fileSysRewind , but is
|
||
* always moved back to the end of the file before any write
|
||
* operation is carried out. Thus ,existing data cannot be
|
||
* overwritten.
|
||
* "w" - Opens an empty file for writing only. If the file does
|
||
* not exist the function will create it, otherwise if the
|
||
* given file exists the function will open it but its
|
||
* content will be destroyed . On both cases the function
|
||
* searches for an empty entry within the dynamic data base
|
||
* entry table and if found , it associates the file
|
||
* <20>fileName<6D> to that entry and returns the handler of the
|
||
* file .
|
||
* "w+" - Opens an empty file for both reading and writing data. If
|
||
* the given file exists, its contents is destroyed . When a
|
||
* file is opened with the "w+" access type , all write
|
||
* operations occur at the end of the file. The file pointer
|
||
* can be repositioned using fileSysSeek or fileSysRewind ,
|
||
* but is always moved back to the end of the file before any
|
||
* write operation is carried out. Thus ,existing data cannot
|
||
* be overwritten.
|
||
* "a+" - Opens a file for reading and appending data. If the given
|
||
* file exists ,its contents is destroyed .The appending
|
||
* operation includes the removal of the EOF marker before
|
||
* new data is written to the file and the EOF marker is
|
||
* restored after the writing has completed . When a file is
|
||
* opened with the "a+" access type ,all write operations
|
||
* occur at the end of the file. The file pointer can be
|
||
* repositioned using fileSysSeek or fileSysRewind , but is
|
||
* always moved back to the end of the file before any write
|
||
* operation is carried out .Thus , existing data cannot be
|
||
* overwritten.
|
||
* fileName - A string containing the file name.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* File handler on success or FILE_OPEN_ERROR in one of the following
|
||
* reasons:
|
||
* - File system not initialized.
|
||
* - In cases of the modes "r" or "r+" and the file is not found.
|
||
* - No free entries in the file system's data base.
|
||
* - In modes "w" and w+" if we try to open a file which already exists it
|
||
* must be deleted first , an error can occur at the delete function.
|
||
* - No more free entries on the flash memory.
|
||
* - Not supported mode.
|
||
*
|
||
*******************************************************************************/
|
||
FS_FILE_HANDLER mvFSOpen(char * fileName,char *mode)
|
||
{
|
||
unsigned int fileFAToffset,fh;
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
{
|
||
return FS_FILE_OPEN_ERROR;
|
||
}
|
||
/* Mode == "r" or "r+" - the file must exist */
|
||
if((mode[0] == 'r') &&
|
||
(mode[1] == '\0'|| (mode[1] == '+' && mode[2] == '\0')))
|
||
{
|
||
fileFAToffset = mvFSFileFind(fileName);
|
||
if(fileFAToffset == FS_FILE_NOT_FOUND)
|
||
return FS_FILE_OPEN_ERROR;
|
||
for(fh = 0 ; fh < FS_MAX_NUM_OF_ENTRIES ; fh++)
|
||
{
|
||
if(mvFSEntries[fh].statusFlag == FS_FREE_ENTRY)
|
||
{
|
||
mvFSEntries[fh].statusFlag = FS_ENTRY_IN_USE;
|
||
mvFSEntries[fh].filePointer = 0;
|
||
mvFSEntries[fh].mode[0] = mode[0];
|
||
mvFSEntries[fh].mode[1] = mode[1];
|
||
mvFSEntries[fh].mode[2] = mode[2];
|
||
mvFSEntries[fh].pointerToFAT = fileFAToffset;
|
||
mvFSEntries[fh].EOFpointer = mvFSGetEOFoffset(fileName);
|
||
return fh;
|
||
}
|
||
}
|
||
return FS_FILE_OPEN_ERROR;
|
||
}
|
||
/* Mode == "w" ,"w+" or "a+" */
|
||
if((mode[0] == 'w' || mode[0] == 'a') &&
|
||
(mode[1] == '\0'||(mode[1] == '+' && mode[2] == '\0')))
|
||
{
|
||
/* Check if the file exists on the system */
|
||
fileFAToffset = mvFSFileFind(fileName);
|
||
if(fileFAToffset != FS_FILE_NOT_FOUND)
|
||
{
|
||
if( mode[0] != 'a')
|
||
{
|
||
if(mvFSDelete(fileName) != FS_FILE_DELETED)
|
||
return FS_FILE_OPEN_ERROR;
|
||
/* Get a free entry on the FAT */
|
||
fileFAToffset = mvFSGetFreeEntry();
|
||
if(fileFAToffset == FS_NO_FREE_ENTRIES)
|
||
return FS_FILE_OPEN_ERROR;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Get a free entry on the FAT */
|
||
fileFAToffset = mvFSGetFreeEntry();
|
||
if(fileFAToffset == FS_NO_FREE_ENTRIES)
|
||
return FS_FILE_OPEN_ERROR;
|
||
}
|
||
/* Search for a free entry on the file system's data base */
|
||
for(fh = 0 ; fh < FS_MAX_NUM_OF_ENTRIES ; fh++)
|
||
{
|
||
if(mvFSEntries[fh].statusFlag == FS_FREE_ENTRY)
|
||
{
|
||
mvFSEntries[fh].statusFlag = FS_ENTRY_IN_USE;
|
||
mvFSEntries[fh].filePointer = 0;
|
||
mvFSEntries[fh].mode[0] = mode[0];
|
||
mvFSEntries[fh].mode[1] = mode[1];
|
||
mvFSEntries[fh].mode[2] = mode[2];
|
||
mvFSEntries[fh].pointerToFAT= fileFAToffset;
|
||
mvFSEntries[fh].EOFpointer = mvFSGetEOFoffset(fileName);
|
||
/* Update the entry on the FAT */
|
||
/* Write the file's name */
|
||
mvFSWriteFileNameToFATentry(fileFAToffset,fileName);
|
||
/* Update the status flag */
|
||
mvFlash8Wr(mvFlashInfo, fileFAToffset + FS_ENTRY_STATUS_FLAG_OFFSET,
|
||
FS_ENTRY_IN_UPDATE);
|
||
return fh;
|
||
}
|
||
}
|
||
return FS_FILE_OPEN_ERROR;
|
||
}
|
||
return FS_FILE_OPEN_ERROR; /* Has no meaning, just for the compiler */
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSClose - Closes a file.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function closes a file by removing the file's entry from the file
|
||
* system's data base , updating the file's FAT entry and data block's
|
||
* status flags and offset . After calling this function , the virtual EOF
|
||
* character is created by updating the last block<63>s 9 bits of the next
|
||
* block pointer if data was not appended to that block . If data was
|
||
* appended , the offset field of the last block of data will be updated
|
||
* (as described at the Introduction ).
|
||
*
|
||
* INPUT:
|
||
* fileName - A string containing the file name.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* The return value can be either FS_FILE_CLOSED on seccess or
|
||
* FILE_CLOSE_ERROR in one of the following reasons:
|
||
* - If the handler is out of range (bigger or equal to MAX_NUM_OF_ENTRIES
|
||
* defind in mvFS.h).
|
||
* - If the handler points to an entry with a FREE_ENTRY status.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSClose(FS_FILE_HANDLER fileHandler)
|
||
{
|
||
unsigned int FATentryOffset,nextBlockPointer,prevBlockPointer;
|
||
unsigned int offset;
|
||
|
||
if(fileHandler >= FS_MAX_NUM_OF_ENTRIES)
|
||
return FS_FILE_CLOSE_ERROR;
|
||
if(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY)
|
||
return FS_FILE_CLOSE_ERROR;
|
||
/* mode = "r" */
|
||
if(mvFSEntries[fileHandler].mode[0] == 'r' &&
|
||
mvFSEntries[fileHandler].mode[1] == '\0')
|
||
{
|
||
mvFSEntries[fileHandler].statusFlag = FS_FREE_ENTRY;
|
||
return FS_FILE_CLOSED;
|
||
}
|
||
/* mode = "r+","w","w+" or "a+" */
|
||
FATentryOffset = mvFSEntries[fileHandler].pointerToFAT;
|
||
/* Empty file => next block pointer == 0xFFFFFFFF */
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, FATentryOffset);
|
||
if(nextBlockPointer == 0xffffffff)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, FATentryOffset + FS_ENTRY_STATUS_FLAG_OFFSET) ==
|
||
FS_ENTRY_IN_UPDATE)
|
||
{
|
||
/* Update the file's entry status flag */
|
||
mvFlash8Wr(mvFlashInfo, FATentryOffset + FS_ENTRY_STATUS_FLAG_OFFSET,
|
||
FS_ENTRY_IN_USE);
|
||
}
|
||
mvFSEntries[fileHandler].statusFlag = FS_FREE_ENTRY;
|
||
return FS_FILE_CLOSED;
|
||
}
|
||
/* search for the last block */
|
||
prevBlockPointer = FATentryOffset;
|
||
while(mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK) != 0xffffffff)
|
||
{
|
||
prevBlockPointer = nextBlockPointer;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
}
|
||
|
||
if(mvFlash8Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_STATUS_FLAG_OFFSET) == FS_BLOCK_IN_USE)
|
||
{
|
||
/* Old block, need to use the offset field */
|
||
if(!((mvFlash8Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_FLAG_OFFSET) == FS_FULL_BLOCK) ||
|
||
(mvFlash16Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_OFFSET) != 0xffff)))
|
||
{
|
||
/* File was modified */
|
||
/* We need to update the offset field */
|
||
if(prevBlockPointer == FATentryOffset)
|
||
{
|
||
offset = mvFlash32Rd(mvFlashInfo, prevBlockPointer) & FS_BLOCK_OFFSET;
|
||
}
|
||
else
|
||
{
|
||
offset = mvFlash32Rd(mvFlashInfo, prevBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK) & FS_BLOCK_OFFSET;
|
||
}
|
||
offset = (mvFSEntries[fileHandler].EOFpointer
|
||
& FS_BLOCK_OFFSET) - offset;
|
||
mvFlash16Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_OFFSET,offset);
|
||
}
|
||
/* else - File not modified */
|
||
mvFSEntries[fileHandler].statusFlag = FS_FREE_ENTRY;
|
||
return FS_FILE_CLOSED;
|
||
}
|
||
else
|
||
{
|
||
/* Update the block's status flag */
|
||
mvFlash8Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET,FS_BLOCK_IN_USE);
|
||
/* Update the offset at the previous block's next block pointer */
|
||
offset = mvFSEntries[fileHandler].EOFpointer & FS_BLOCK_OFFSET;
|
||
if(prevBlockPointer != FATentryOffset)
|
||
{
|
||
offset = (mvFlash32Rd(mvFlashInfo, prevBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
& FS_BLOCK_OFFSET_MASK) | offset;
|
||
mvFlash32Wr(mvFlashInfo, prevBlockPointer & FS_BLOCK_OFFSET_MASK,offset);
|
||
}
|
||
else /* prevBlockPointer == FATentryOffset */
|
||
{
|
||
offset = (mvFlash32Rd(mvFlashInfo, prevBlockPointer) & FS_BLOCK_OFFSET_MASK)
|
||
| offset;
|
||
mvFlash32Wr(mvFlashInfo, prevBlockPointer, offset);
|
||
}
|
||
mvFSEntries[fileHandler].statusFlag = FS_FREE_ENTRY;
|
||
}
|
||
return FS_FILE_CLOSED;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSFileSize - Counts the number of bytes the file consist of.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function counts and return the number of bytes the file consist of.
|
||
* If the file handler delivered to the function is erroneous the function
|
||
* will return the value 0xFFFFFFFF.
|
||
*
|
||
* INPUT:
|
||
* fileHandler - The file handler to count its bytes.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* The file's number of bytes of the on success or 0xFFFFFFFF on failier.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSFileSize(FS_FILE_HANDLER fileHandler)
|
||
{
|
||
unsigned int numOfBytes = 0,nextBlockPointer;
|
||
|
||
if((fileHandler >= FS_MAX_NUM_OF_ENTRIES) ||
|
||
(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY))
|
||
return 0xffffffff;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
if(nextBlockPointer == 0xffffffff)
|
||
return 0;
|
||
while(nextBlockPointer != 0xffffffff)
|
||
{
|
||
if(((nextBlockPointer & FS_BLOCK_OFFSET) + 1) != FS_BLOCK_SIZE)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_FLAG_OFFSET) == FS_FULL_BLOCK)
|
||
{
|
||
numOfBytes += (FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE);
|
||
}
|
||
else
|
||
{
|
||
if(mvFlash16Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_OFFSET) != 0xffff)
|
||
{
|
||
numOfBytes += ((nextBlockPointer & FS_BLOCK_OFFSET) +
|
||
mvFlash16Rd(mvFlashInfo, (nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_OFFSET) -
|
||
FS_BLOCK_HEADER_SIZE + 1);
|
||
}
|
||
else
|
||
{
|
||
numOfBytes += ((nextBlockPointer & FS_BLOCK_OFFSET) -
|
||
FS_BLOCK_HEADER_SIZE + 1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if((mvFSEntries[fileHandler].EOFpointer & FS_BLOCK_OFFSET_MASK) ==
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK)) /* Last block */
|
||
{
|
||
numOfBytes += ((mvFSEntries[fileHandler].EOFpointer
|
||
& FS_BLOCK_OFFSET)- FS_BLOCK_HEADER_SIZE + 1);
|
||
}
|
||
else
|
||
{
|
||
numOfBytes += (FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE);
|
||
}
|
||
}
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
}
|
||
if(numOfBytes == 0)
|
||
return 0;
|
||
return numOfBytes;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetEOFoffset - Gets the file's EOF offset in the flash memory.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function searches for the file<6C>s EOF offset relatively to the
|
||
* begining of the last block offset . The EOF offset could be either the 9
|
||
* least significant bits of the next block pointer or , if data was
|
||
* appended to last block , the offset field within that block .
|
||
*
|
||
* INPUT:
|
||
* fileName - The file name to get its EOF offset .
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* The file's EOF offset or FILE_NOT_FOUND.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetEOFoffset(char * fileName)
|
||
{
|
||
unsigned int EOFoffset = 0,fileFAToffset,nextBlockOffset;
|
||
|
||
fileFAToffset = mvFSFileFind(fileName);
|
||
if(fileFAToffset == FS_FILE_NOT_FOUND)
|
||
return FS_FILE_NOT_FOUND;
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, fileFAToffset);
|
||
if(nextBlockOffset == 0xffffffff)
|
||
return 0;
|
||
while(nextBlockOffset != 0xffffffff)
|
||
{
|
||
EOFoffset = nextBlockOffset;
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, nextBlockOffset &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
}
|
||
nextBlockOffset = EOFoffset & FS_BLOCK_OFFSET_MASK;
|
||
if(mvFlash8Rd(mvFlashInfo, nextBlockOffset + FS_BLOCK_OFFSET_FLAG_OFFSET) ==
|
||
FS_FULL_BLOCK)
|
||
{
|
||
EOFoffset = nextBlockOffset + (FS_BLOCK_SIZE -
|
||
FS_BLOCK_HEADER_SIZE - 1);
|
||
}
|
||
else
|
||
{
|
||
if(mvFlash16Rd(mvFlashInfo, nextBlockOffset + FS_BLOCK_OFFSET_OFFSET)
|
||
!= 0xffff)
|
||
{
|
||
EOFoffset = EOFoffset + mvFlash16Rd(mvFlashInfo, nextBlockOffset +
|
||
FS_BLOCK_OFFSET_OFFSET);
|
||
}
|
||
else
|
||
{
|
||
return EOFoffset; /* Not necessary - just for readability */
|
||
}
|
||
}
|
||
return EOFoffset;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetFreeBlockForWrite - Returns the offset of a free block (if found).
|
||
*
|
||
* DESCRIPTION:
|
||
* This function searches for a free block in more efficient way than
|
||
* <20>fileSysGetFreeBlock<63> function by saving the last free block offset
|
||
* that was found in the previous search and searches from that point. In
|
||
* case it couldnt find a free block , it uses the function
|
||
* <20>fileSysGetFreeBlock<63>.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
* If during the copying of the sector containing the most free dirty block
|
||
* to the dynamic memory the system will loose power the file system will
|
||
* crash.
|
||
*
|
||
* INPUT:
|
||
* None.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Offset to a free block , FS_NO_FREE_BLOCKS if there are no more free
|
||
* blocks or the file system was not initilized (use <20>fileSysInit<69> before
|
||
* using this function in that case).
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetFreeBlockForWrite()
|
||
{
|
||
unsigned char status;
|
||
|
||
nextFreeBlock += FS_BLOCK_SIZE;
|
||
if((nextFreeBlock == 0xffffffff) ||
|
||
((nextFreeBlock != 0xffffffff) && (nextFreeBlock >= mvFSTopOffset)))
|
||
{
|
||
nextFreeBlock = mvFSGetFreeBlock();
|
||
return nextFreeBlock;
|
||
}
|
||
else
|
||
{
|
||
while(1)
|
||
{
|
||
status = mvFlash8Rd(mvFlashInfo, nextFreeBlock +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET);
|
||
if(status == FS_FREE_BLOCK)
|
||
{
|
||
return nextFreeBlock;
|
||
}
|
||
nextFreeBlock += FS_BLOCK_SIZE;
|
||
if(nextFreeBlock >= mvFSTopOffset || status == FS_FREE_DIRTY_BLOCK)
|
||
{
|
||
nextFreeBlock = mvFSGetFreeBlock();
|
||
return nextFreeBlock;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetFreeBlock - Returns the offset of a free block (if found).
|
||
*
|
||
* DESCRIPTION:
|
||
* This function searches for a free block from the begining of the file
|
||
* system ( from <20>fileSysOffset<65> parameter initialized by <20>fileSysInit<69>
|
||
* function ) to the last sector and return its offset in case it found
|
||
* one .While the function perform the search for a free block within each
|
||
* sector it also searches for the sector containing the most free dirty
|
||
* block in case a free block will not be found .If indeed a free block was
|
||
* not found ,the function erases that sector ( the one with the most free
|
||
* dirty blocks ) after copying it to a temporary buffer in the dynamic
|
||
* memory (SDRAM) and write back only the valid blocks to it .In that way
|
||
* the function free blocks from the sector containing the most free dirty
|
||
* blocks and return the next free block within that sector.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
* If during the copying of the sector containing the most free dirty block
|
||
* to the dynamic memory the system will loose power the file system will
|
||
* crash.
|
||
*
|
||
* INPUT:
|
||
* None.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Offset to a free block , NO_FREE_BLOCKS if there are no more free blocks
|
||
* or the file system was not initilized (use <20>fileSysInit<69> before using
|
||
* this function in that case).
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetFreeBlock()
|
||
{
|
||
unsigned int freeBlockOffset,sectorTopOffset,i;
|
||
unsigned int maxFreeDirtyBlocks = 0,sectorNumber,lastSector;
|
||
unsigned int dirtyBlocksCounter = 0,dirtyBlocksSector,blockSize;
|
||
unsigned int sectorBaseOffset,previousCounter,counterOffset;
|
||
char * rmwBlockPointer,* tempBlockPointer;
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return FS_NO_FREE_BLOCKS;
|
||
freeBlockOffset = mvFSOffset + FS_BLOCK_SIZE;
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, freeBlockOffset);
|
||
lastSector = mvFlashNumOfSecsGet(mvFlashInfo);
|
||
dirtyBlocksSector = sectorNumber;
|
||
/* Search for a free block, while doing that I am searching for the sector
|
||
with the most dirty free blocks in case I will not find a free block */
|
||
for(i = sectorNumber ; i < lastSector ; i++)
|
||
{
|
||
sectorTopOffset = mvFlashSecOffsGet(mvFlashInfo, sectorNumber) +
|
||
mvFlashSecSizeGet(mvFlashInfo, sectorNumber) - 1;
|
||
dirtyBlocksCounter = 0;
|
||
while(freeBlockOffset < sectorTopOffset)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, freeBlockOffset + FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_BLOCK)
|
||
{
|
||
return freeBlockOffset;
|
||
}
|
||
if(mvFlash8Rd(mvFlashInfo, freeBlockOffset + FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_DIRTY_BLOCK) dirtyBlocksCounter++;
|
||
freeBlockOffset += FS_BLOCK_SIZE;
|
||
}
|
||
if(dirtyBlocksCounter > maxFreeDirtyBlocks)
|
||
{
|
||
maxFreeDirtyBlocks = dirtyBlocksCounter;
|
||
dirtyBlocksSector = sectorNumber;
|
||
}
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, freeBlockOffset);
|
||
}
|
||
/* We are here since we have'nt found a free block */
|
||
/* Lets check if we have a free dirty block */
|
||
if(maxFreeDirtyBlocks > 0)
|
||
{
|
||
/* Now we need to perform the read modify write dispensing the free
|
||
dirty blocks */
|
||
blockSize = mvFlashSecSizeGet(mvFlashInfo, dirtyBlocksSector);
|
||
sectorBaseOffset = mvFlashSecOffsGet(mvFlashInfo, dirtyBlocksSector);
|
||
rmwBlockPointer = (char *)malloc(blockSize);
|
||
if(rmwBlockPointer == NULL) return FS_NO_FREE_BLOCKS;
|
||
/* Read the block */
|
||
for(i = 0 ; i < blockSize ; i++)
|
||
{
|
||
rmwBlockPointer[i] = mvFlash8Rd(mvFlashInfo, sectorBaseOffset + i);
|
||
}
|
||
/* Erase the sector */
|
||
if(mvFlash32Rd(mvFlashInfo, mvFSOffset + FS_ERSAING_COUNTER_FLAG_OFFSET)
|
||
== FS_ENABLE_ERASING_COUNTER)
|
||
{
|
||
counterOffset = sectorBaseOffset + blockSize - FS_BLOCK_SIZE;
|
||
previousCounter = mvFlash32Rd(mvFlashInfo, counterOffset);
|
||
mvFlashSecErase(mvFlashInfo, dirtyBlocksSector);
|
||
mvFlash32Wr(mvFlashInfo, counterOffset, previousCounter + 1);
|
||
mvFlash8Wr(mvFlashInfo, counterOffset + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_USED_FOR_ERASING_COUNTER);
|
||
blockSize -= FS_BLOCK_SIZE;
|
||
}
|
||
else
|
||
{
|
||
mvFlashSecErase(mvFlashInfo, dirtyBlocksSector);
|
||
}
|
||
/* Write back only the valid blocks */
|
||
for(i = 0 ; i < blockSize ; i += FS_BLOCK_SIZE)
|
||
{
|
||
if(rmwBlockPointer[i + FS_BLOCK_STATUS_FLAG_OFFSET] ==
|
||
FS_BLOCK_IN_USE || rmwBlockPointer[i +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET] == FS_BLOCK_IN_UPDATE ||
|
||
rmwBlockPointer[i + FS_BLOCK_STATUS_FLAG_OFFSET] == FS_FAT_BLOCK)
|
||
{
|
||
tempBlockPointer = rmwBlockPointer + i;
|
||
mvFlashBlockWr(mvFlashInfo, sectorBaseOffset + i, FS_BLOCK_SIZE,
|
||
(MV_U8 *)tempBlockPointer);
|
||
}
|
||
}
|
||
free(rmwBlockPointer);
|
||
for(i = 0 ; i < blockSize ; i += FS_BLOCK_SIZE)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, sectorBaseOffset + i +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_BLOCK)
|
||
return (sectorBaseOffset + i);
|
||
}
|
||
}
|
||
return FS_NO_FREE_BLOCKS;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetFreeEntry - Finds a free entry in the FAT and returns its offset.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function finds a free entry in the FAT and returns its offset.
|
||
* During the search for a free entry the function also finds the sector
|
||
* containing the most free dirty entries . If the fuction cant find any
|
||
* free entry within the FAT it copies the sector containing the most free
|
||
* dirty entries to the dynamic memory (SDRAM), erase that sector and write
|
||
* back only the valid entries. In that way the function free space for
|
||
* new entries and return the next free entry offset.
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
* If during the copying of the sector containing the most free dirty
|
||
* enrties to the dynamic memory the system will loose power the file
|
||
* system will crash.
|
||
*
|
||
* INPUT:
|
||
* None.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Offset to a free entry , NO_FREE_ENTRIES if there are no more free
|
||
* entries in the file system`s FAT or the file system was not initialized
|
||
* (use <20>fileSysInit<69> before using this function in that case).
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetFreeEntry()
|
||
{
|
||
unsigned int nextBlockOffset,sectorNumber,i,previousSector;
|
||
unsigned int dirtyEntriesCounter = 0,dirtyEntriesSector,blockSize,j;
|
||
unsigned int maxFreeDirtyBlocks = 0;
|
||
unsigned int sectorBaseOffset,previousCounter,counterOffset;
|
||
char * rmwBlockPointer,* tempBlockPointer;
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return FS_NO_FREE_ENTRIES;
|
||
/* First FAT block */
|
||
nextBlockOffset = mvFSOffset;
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, nextBlockOffset);
|
||
dirtyEntriesSector = sectorNumber;
|
||
previousSector = sectorNumber;
|
||
while(nextBlockOffset != 0xffffffff)
|
||
{
|
||
if(previousSector != sectorNumber)
|
||
{
|
||
if(dirtyEntriesSector > maxFreeDirtyBlocks)
|
||
{
|
||
maxFreeDirtyBlocks = dirtyEntriesSector;
|
||
dirtyEntriesSector = sectorNumber;
|
||
}
|
||
previousSector = sectorNumber;
|
||
dirtyEntriesSector = 0;
|
||
}
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, nextBlockOffset);
|
||
for(i = 0 ; i < FS_BLOCK_SIZE ; i += FS_FAT_FILE_ENTRY_SIZE)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, nextBlockOffset +i+ FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_ENTRY)
|
||
return (nextBlockOffset + i);
|
||
if(mvFlash8Rd(mvFlashInfo, nextBlockOffset +i+ FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_DIRTY_ENTRY)
|
||
dirtyEntriesCounter++;
|
||
}
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, nextBlockOffset);
|
||
}
|
||
/* Now we need to perform the read modify write dispensing the free
|
||
dirty entries and blocks */
|
||
blockSize = mvFlashSecSizeGet(mvFlashInfo, dirtyEntriesSector);
|
||
sectorBaseOffset = mvFlashSecOffsGet(mvFlashInfo, dirtyEntriesSector);
|
||
rmwBlockPointer = (char *)malloc(blockSize);
|
||
if(rmwBlockPointer == NULL) return FS_NO_FREE_ENTRIES;
|
||
/* Read the block */
|
||
for(i = 0 ; i < blockSize ; i++)
|
||
{
|
||
rmwBlockPointer[i] = mvFlash8Rd(mvFlashInfo, sectorBaseOffset + i);
|
||
}
|
||
/* Erase the sector */
|
||
if(mvFlash32Rd(mvFlashInfo, mvFSOffset + 20) == FS_ENABLE_ERASING_COUNTER)
|
||
{
|
||
counterOffset = sectorBaseOffset + blockSize - FS_BLOCK_SIZE;
|
||
previousCounter = mvFlash32Rd(mvFlashInfo, counterOffset);
|
||
mvFlashSecErase(mvFlashInfo, dirtyEntriesSector);
|
||
mvFlash32Wr(mvFlashInfo, counterOffset,previousCounter + 1);
|
||
mvFlash8Wr(mvFlashInfo, counterOffset + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_USED_FOR_ERASING_COUNTER);
|
||
blockSize -= FS_BLOCK_SIZE;
|
||
}
|
||
else
|
||
{
|
||
mvFlashSecErase(mvFlashInfo, dirtyEntriesSector);
|
||
}
|
||
/* Write back only the valid blocks */
|
||
for(i = 0 ; i < blockSize ; i += FS_BLOCK_SIZE)
|
||
{
|
||
if(rmwBlockPointer[i + FS_BLOCK_STATUS_FLAG_OFFSET] ==
|
||
FS_BLOCK_IN_USE || rmwBlockPointer[i + FS_BLOCK_STATUS_FLAG_OFFSET]
|
||
== FS_BLOCK_IN_UPDATE)
|
||
{
|
||
tempBlockPointer = rmwBlockPointer + i;
|
||
mvFlashBlockWr(mvFlashInfo, sectorBaseOffset + i, FS_BLOCK_SIZE,
|
||
(MV_U8 *)tempBlockPointer);
|
||
}
|
||
if(rmwBlockPointer[i + FS_BLOCK_STATUS_FLAG_OFFSET] == FS_FAT_BLOCK)
|
||
{
|
||
for(j = FS_FAT_FILE_ENTRY_SIZE ; j < FS_BLOCK_SIZE ;
|
||
j+= FS_FAT_FILE_ENTRY_SIZE)
|
||
{
|
||
if(rmwBlockPointer[j + FS_ENTRY_STATUS_FLAG_OFFSET]
|
||
== FS_ENTRY_IN_USE ||
|
||
rmwBlockPointer[j + FS_ENTRY_STATUS_FLAG_OFFSET]
|
||
== FS_ENTRY_IN_UPDATE)
|
||
{
|
||
tempBlockPointer = rmwBlockPointer + j;
|
||
mvFlashBlockWr(mvFlashInfo, sectorBaseOffset + j,
|
||
FS_FAT_FILE_ENTRY_SIZE, (MV_U8 *)tempBlockPointer);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
free(rmwBlockPointer);
|
||
for(i = 0 ; i < blockSize ; i += FS_BLOCK_SIZE)
|
||
{
|
||
if(mvFlash32Rd(mvFlashInfo, sectorBaseOffset + i + FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FAT_BLOCK)
|
||
{
|
||
for(j = i + FS_FAT_FILE_ENTRY_SIZE ; j < (i + FS_BLOCK_SIZE) ;
|
||
j+= FS_FAT_FILE_ENTRY_SIZE)
|
||
{
|
||
if(mvFlash32Rd(mvFlashInfo, sectorBaseOffset +j+
|
||
FS_ENTRY_STATUS_FLAG_OFFSET) == FS_FREE_ENTRY)
|
||
return (sectorBaseOffset + j);
|
||
}
|
||
}
|
||
}
|
||
return FS_NO_FREE_ENTRIES;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSWriteFileNameToFATentry - Write the file name to an entry in the FAT .
|
||
*
|
||
* DESCRIPTION:
|
||
* This function writes the file name to an entry in the FAT.The function
|
||
* extarcts the file name and extention and write it to the entry at
|
||
* <20>entryOffset<65> within the FAT.
|
||
*
|
||
* INPUT:
|
||
* entryOffset - Pointer to the desired entry to write the file name at.
|
||
* fileName - The file name and extention.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* 0 for invalid file name, 1 for success.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSWriteFileNameToFATentry(unsigned int entryOffset,
|
||
char * fileName)
|
||
{
|
||
char name[FS_FILE_NAME_LENGTH];
|
||
char ext[FS_FILE_EXT_LENGTH];
|
||
unsigned int index,extIndex;
|
||
|
||
/* Extract the name */
|
||
for(index = 0 ; index < FS_FILE_NAME_LENGTH ; index++)
|
||
{
|
||
if(fileName[index] == '.' || fileName[index] == '\0')
|
||
{
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
name[index] = fileName[index];
|
||
}
|
||
}
|
||
/* Write the name */
|
||
if(index != 0)
|
||
mvFlashBlockWr(mvFlashInfo, entryOffset + FS_FILE_NAME_OFFSET, index, (MV_U8 *)name);
|
||
if(index == 0 && fileName[index] == '\0') /* Not a valid name */
|
||
return 0;
|
||
if(fileName[index] == '\0') /* No extension */
|
||
return 1;
|
||
/* Extract the extension */
|
||
index++; /* Skip the dot */
|
||
for(extIndex = 0 ; extIndex < FS_FILE_EXT_LENGTH ; extIndex++)
|
||
{
|
||
if(fileName[index + extIndex] == '\0')
|
||
{
|
||
// ronen fix a bug ---> extIndex++;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
ext[extIndex] = fileName[index + extIndex];
|
||
}
|
||
}
|
||
/* Write the extension */
|
||
if(extIndex != 0)
|
||
mvFlashBlockWr(mvFlashInfo, entryOffset + FS_FILE_EXT_OFFSET, extIndex, (MV_U8 *)ext);
|
||
return 1;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSReadFileNameFromFATentry - Read the file name from an entry in the FAT.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function reads the file name from an entry in the FAT. If the given
|
||
* entry is not used by any file , the function will return 0 to remark a
|
||
* failier.
|
||
*
|
||
* INPUT:
|
||
* entryOffset - Pointer to the desired entry to read the file name from.
|
||
* fileName - pointer to an empty array to be filled by this functoin with
|
||
* the file name and extention.
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* 0 for failure, 1 for success.
|
||
*
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSReadFileNameFromFATentry(unsigned int entryOffset,
|
||
char * fileName)
|
||
{
|
||
unsigned int index = 0,offset;
|
||
unsigned char c;
|
||
|
||
if( (mvFlash8Rd(mvFlashInfo, entryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_USE) ||
|
||
(mvFlash8Rd(mvFlashInfo, entryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_UPDATE) )
|
||
{
|
||
for(offset = 0 ; offset < FS_FILE_NAME_LENGTH ; offset++)
|
||
{
|
||
c = mvFlash8Rd(mvFlashInfo, entryOffset + FS_FILE_NAME_OFFSET + offset);
|
||
if(c == 0xff)
|
||
break;
|
||
fileName[index++] = c;
|
||
}
|
||
if(mvFlash8Rd(mvFlashInfo, entryOffset + FS_FILE_EXT_OFFSET) != 0xff)
|
||
{
|
||
fileName[index++] = '.';
|
||
for(offset = 0 ; offset < FS_FILE_EXT_LENGTH ; offset++)
|
||
{
|
||
c = mvFlash8Rd(mvFlashInfo, entryOffset + FS_FILE_EXT_OFFSET + offset);
|
||
if(c == 0xff) break;
|
||
fileName[index++] = c;
|
||
}
|
||
}
|
||
fileName[index++] = '\0';
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSWrite - Writes a block of data to an opened file.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function writes a block of data to a file opened by all modes
|
||
* except mode <20>r<EFBFBD> indicating the file is a read only file. The function
|
||
* will append the data to the last block ( if the offset flag is not set
|
||
* yet ) or to a new block if this is a new file , the function also takes
|
||
* care of updating the EOF pointer , updating the file's entry and data
|
||
* blocks status flags. During the write attempt , the function will
|
||
* return 0 value in the following cases:
|
||
* - if the given file handler is invalid that is , grater or equal to
|
||
* MAX_NUM_OF_ENTRIES (defined in mvFS.h).
|
||
* - if the entry of the file handler holds the status FREE_ENTRY.
|
||
* - if the <20>numberOfBytes<65> parameter is 0.
|
||
* - if this is the first write attempt to the file ( new file ) , the
|
||
* function will allocate a new block for the data , in this case a
|
||
* failier can occur resulting from lack of free blocks. In all other
|
||
* cases the function will return the number of bytes actually written.
|
||
* Note that the number of bytes actually written returned by this
|
||
* function may not be equal to the <20>numberOfBytes<65> parameter , in that
|
||
* case consider the write action as a fatal error and do not try to
|
||
* re-write the data.
|
||
*
|
||
* INPUT:
|
||
* fileHandler - The file handler of the file to be written.
|
||
* numOfBytes - The number of bytes to be written from the data array.
|
||
* block - The data array to write to the file.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Returns the number of bytes actually written, if the number of
|
||
* bytes actually written is not equal to the numberOfBytes consider it as
|
||
* a fatal error, do not try to re-write the data.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSWrite(FS_FILE_HANDLER fileHandler,
|
||
unsigned int numberOfBytes,char * block)
|
||
{
|
||
unsigned int remainingBytes,nextBlockPointer,newBlockPointer,blockSize;
|
||
unsigned int freeBytesInBlock,writtenBytes,blockIndex = 0;
|
||
unsigned int totalWrittenBytes = 0,numberOfBlocks,i;
|
||
|
||
blockSize = FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE;
|
||
if((fileHandler >= FS_MAX_NUM_OF_ENTRIES) ||
|
||
(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY) ||
|
||
numberOfBytes == 0)
|
||
return 0;
|
||
if(mvFSEntries[fileHandler].mode[0] == 'r' &&
|
||
mvFSEntries[fileHandler].mode[1] == '\0')
|
||
return 0; /* File was opened as read only */
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
remainingBytes = numberOfBytes;
|
||
if(nextBlockPointer == 0xffffffff)
|
||
{
|
||
/* New file, no blocks allocated yet */
|
||
newBlockPointer = mvFSGetFreeBlock();
|
||
mvFSEntries[fileHandler].blockPointer = newBlockPointer;
|
||
if(newBlockPointer == FS_NO_FREE_BLOCKS)
|
||
return 0;
|
||
/* Update the entry's status flag and next block pointer */
|
||
mvFlash32Wr(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT,
|
||
newBlockPointer | FS_BLOCK_OFFSET);
|
||
mvFlash8Wr(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT +
|
||
FS_ENTRY_STATUS_FLAG_OFFSET, FS_ENTRY_IN_USE);
|
||
/* Start writing the data */
|
||
if(numberOfBytes <= blockSize)
|
||
{
|
||
/* Only one block needed */
|
||
/* Update the blocks status flag */
|
||
mvFlash8Wr(mvFlashInfo, newBlockPointer + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_IN_UPDATE);
|
||
/* Update the EOFpointer */
|
||
mvFSEntries[fileHandler].EOFpointer = newBlockPointer
|
||
+ numberOfBytes + FS_BLOCK_HEADER_SIZE - 1;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
/* Write the data */
|
||
return
|
||
mvFlashBlockWr(mvFlashInfo, newBlockPointer + FS_BLOCK_HEADER_SIZE,
|
||
numberOfBytes, (MV_U8 *)block);
|
||
}
|
||
else /* More than one block is needed */
|
||
{
|
||
/* I will take care of the first block in here, the rest
|
||
will be handled later in the fuction */
|
||
/* Update the block's status flag */
|
||
mvFlash8Wr(mvFlashInfo, newBlockPointer + FS_BLOCK_STATUS_FLAG_OFFSET,
|
||
FS_BLOCK_IN_USE);/* Fully exploited block */
|
||
/* Write the data */
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo, newBlockPointer +
|
||
FS_BLOCK_HEADER_SIZE, blockSize, (MV_U8 *)block);
|
||
/* Update the EOFpointer */
|
||
mvFSEntries[fileHandler].EOFpointer = newBlockPointer
|
||
+ writtenBytes + FS_BLOCK_HEADER_SIZE - 1;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
if(writtenBytes != blockSize)
|
||
return writtenBytes; /* Write operation failed */
|
||
totalWrittenBytes += writtenBytes;
|
||
remainingBytes = numberOfBytes - blockSize;
|
||
nextBlockPointer = newBlockPointer;
|
||
blockIndex += blockSize;
|
||
}
|
||
}
|
||
/* Search for the last block */
|
||
while(mvFlash32Rd(mvFlashInfo, nextBlockPointer & FS_BLOCK_OFFSET_MASK) !=
|
||
0xffffffff)
|
||
{
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
}
|
||
freeBytesInBlock = FS_BLOCK_SIZE - 1 -
|
||
(mvFSEntries[fileHandler].EOFpointer & FS_BLOCK_OFFSET);
|
||
if(mvFlash8Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_STATUS_FLAG_OFFSET) == FS_BLOCK_IN_USE)
|
||
{
|
||
/* We can use the offset flag to append data, or the FS_FULL_BLOCK
|
||
flag in case the block will be fully exploited */
|
||
if(freeBytesInBlock != 0)
|
||
{
|
||
if((remainingBytes < freeBytesInBlock) &&
|
||
mvFlash16Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_OFFSET) == 0xffff)
|
||
{
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo,
|
||
mvFSEntries[fileHandler].EOFpointer + 1,
|
||
remainingBytes, (MV_U8 *)&block[blockIndex]);
|
||
mvFSEntries[fileHandler].EOFpointer += writtenBytes;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
if(remainingBytes == freeBytesInBlock)
|
||
{
|
||
mvFlash8Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_FLAG_OFFSET, FS_FULL_BLOCK);
|
||
}
|
||
/* else the OFFSET will be updated by mvFSClose */
|
||
return writtenBytes;
|
||
}
|
||
else
|
||
{
|
||
if(remainingBytes >= freeBytesInBlock)
|
||
{
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo,
|
||
mvFSEntries[fileHandler].EOFpointer + 1,
|
||
freeBytesInBlock, (MV_U8 *)&block[blockIndex]);
|
||
mvFSEntries[fileHandler].EOFpointer += freeBytesInBlock;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
totalWrittenBytes += writtenBytes;
|
||
if(writtenBytes != freeBytesInBlock) /* error */
|
||
return totalWrittenBytes;
|
||
mvFlash8Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_OFFSET_FLAG_OFFSET, FS_FULL_BLOCK);
|
||
remainingBytes -= freeBytesInBlock;
|
||
blockIndex += freeBytesInBlock;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else /* The block is not sealed yet, we can simply append the data */
|
||
{
|
||
if(remainingBytes <= freeBytesInBlock)
|
||
{
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo,
|
||
mvFSEntries[fileHandler].EOFpointer + 1,
|
||
remainingBytes, (MV_U8 *)&block[blockIndex]);
|
||
mvFSEntries[fileHandler].EOFpointer += writtenBytes;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
if(remainingBytes == freeBytesInBlock)
|
||
{
|
||
mvFlash8Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_STATUS_FLAG_OFFSET, FS_BLOCK_IN_USE);
|
||
}
|
||
return writtenBytes;
|
||
}
|
||
else /* More blocks are needed */
|
||
{
|
||
/* Fill the current block */
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo,
|
||
mvFSEntries[fileHandler].EOFpointer + 1,
|
||
freeBytesInBlock, (MV_U8 *)&block[blockIndex]);
|
||
mvFSEntries[fileHandler].EOFpointer += writtenBytes;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
totalWrittenBytes += writtenBytes;
|
||
if(writtenBytes != freeBytesInBlock) /* error */
|
||
return totalWrittenBytes;
|
||
mvFlash8Wr(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_STATUS_FLAG_OFFSET, FS_BLOCK_IN_USE);
|
||
remainingBytes -= freeBytesInBlock;
|
||
blockIndex += freeBytesInBlock;
|
||
}
|
||
}
|
||
numberOfBlocks = remainingBytes / blockSize;
|
||
for(i = 0 ; i < numberOfBlocks ; i++)
|
||
{
|
||
/* All the blocks in this loop will be fully exploited */
|
||
newBlockPointer = mvFSGetFreeBlockForWrite();
|
||
if(newBlockPointer == FS_NO_FREE_BLOCKS)
|
||
return totalWrittenBytes;
|
||
/* Update the nextBlockPointer */
|
||
mvFlash32Wr(mvFlashInfo, nextBlockPointer & FS_BLOCK_OFFSET_MASK,
|
||
newBlockPointer | FS_BLOCK_OFFSET);
|
||
/* Update the status flag */
|
||
mvFlash8Wr(mvFlashInfo, (newBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET, FS_BLOCK_IN_USE);
|
||
/* Write The Data */
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo, (newBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_HEADER_SIZE, blockSize,
|
||
(MV_U8 *)&block[blockIndex]);
|
||
blockIndex += blockSize;
|
||
totalWrittenBytes += writtenBytes;
|
||
/* Make sure the EOFpointer is set for error handling */
|
||
mvFSEntries[fileHandler].EOFpointer = (newBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) + FS_BLOCK_HEADER_SIZE + writtenBytes - 1;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
if(writtenBytes != blockSize)/* Error */
|
||
return totalWrittenBytes;
|
||
remainingBytes -= blockSize;
|
||
nextBlockPointer = newBlockPointer;
|
||
}
|
||
if(remainingBytes == 0)
|
||
return totalWrittenBytes;
|
||
/* Allocate a new block for the remaining bytes */
|
||
newBlockPointer = mvFSGetFreeBlockForWrite();
|
||
if(newBlockPointer == FS_NO_FREE_BLOCKS)
|
||
return totalWrittenBytes;
|
||
/* Update the nextBlockPointer */
|
||
mvFlash32Wr(mvFlashInfo, nextBlockPointer & FS_BLOCK_OFFSET_MASK,
|
||
newBlockPointer | FS_BLOCK_OFFSET);
|
||
/* Update the status flag */
|
||
mvFlash8Wr(mvFlashInfo, (newBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_STATUS_FLAG_OFFSET, FS_BLOCK_IN_UPDATE);
|
||
/* Write The Data */
|
||
writtenBytes = mvFlashBlockWr(mvFlashInfo, (newBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_HEADER_SIZE, remainingBytes,
|
||
(MV_U8 *)&block[blockIndex]);
|
||
mvFSEntries[fileHandler].EOFpointer = (newBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) + FS_BLOCK_HEADER_SIZE + writtenBytes - 1;
|
||
/* Update the File pointer */
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
totalWrittenBytes += writtenBytes;
|
||
return totalWrittenBytes;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetNumOfValidBytes - Return the number of valid bytes from
|
||
* blockOffsetPointer to the end of the block.
|
||
*
|
||
* DESCRIPTION:
|
||
* None.
|
||
*
|
||
* INPUT:
|
||
* blockPointer - The offset of the block to read its valid bytes.
|
||
* blockOffsetPointer - The offset within the block to read the valid
|
||
* bytes from.
|
||
* EOFpointer - The EOF offset.
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Number of valid bytes.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetNumOfValidBytes(unsigned int blockPointer,
|
||
unsigned int blockOffsetPointer,
|
||
unsigned int EOFpointer)
|
||
{
|
||
if((blockOffsetPointer & FS_BLOCK_OFFSET_MASK) ==
|
||
(EOFpointer & FS_BLOCK_OFFSET_MASK))
|
||
{
|
||
/* This is the last block */
|
||
if(EOFpointer > blockOffsetPointer)
|
||
return (EOFpointer - blockOffsetPointer);
|
||
else
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
if((mvFlash8Rd(mvFlashInfo, (blockOffsetPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_FLAG_OFFSET) == FS_FULL_BLOCK)
|
||
|| ((blockPointer & FS_BLOCK_OFFSET) == FS_BLOCK_OFFSET))
|
||
{
|
||
return (FS_BLOCK_SIZE - 1 - (blockOffsetPointer & FS_BLOCK_OFFSET));
|
||
}
|
||
else /* offset field is used */
|
||
{
|
||
return ((blockPointer & FS_BLOCK_OFFSET) + mvFlash16Rd(mvFlashInfo,
|
||
(blockPointer & FS_BLOCK_OFFSET_MASK) + FS_BLOCK_OFFSET_OFFSET)
|
||
- (blockOffsetPointer & FS_BLOCK_OFFSET));
|
||
}
|
||
}
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSRead - Read a block of data into block from a file.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function reads a block of data from a file opened by all modes
|
||
* except <20> w <20> mode , into a given block (<28>block<63> parameter ) .While the
|
||
* file is opened , the function will start reading the file from the
|
||
* begining if its the first read attempt after opening the file or from
|
||
* the last point within the block of data were the previous read action
|
||
* ended .The read action will not exceed the EOF pointer if the
|
||
* <20>numberOfBytes<65> parameter is larger than the whole file or the number of
|
||
* bytes left from the previous read action . During the read attempt , the
|
||
* function will return an error code or 0 in the following cases:
|
||
*
|
||
* - if the given file handler is invalid that is , grater or equal to
|
||
* MAX_NUM_OF_ENTRIES (defined in fileSys.h).
|
||
* - if the entry of the file handler within the dynamic database holds the
|
||
* status FREE_ENTRY .
|
||
* - if the mode of the opened file is write only - <20> w<> .
|
||
* - if the EOF pointer is equal to the file pointer that indicates the
|
||
* curruent position within the file.
|
||
* - if the <20>nextBlockPointer<65> field within the entry in the FAT is equal
|
||
* to 0xFFFFFFFF indicating the file is empty.
|
||
* In a successfull read operation the function will return the number of
|
||
* bytes read , if this value is not equal to the <20>numberOfBytes<65>
|
||
* parameter delivered to the function , the read action reached EOF.
|
||
*
|
||
* INPUT:
|
||
* fileHandler - The file handler of the file to be read.
|
||
* numOfBytes - The number of bytes to be read from the file to the data
|
||
* array.
|
||
* block - The data array to hold the read data from the file.
|
||
*
|
||
* OUTPUT:
|
||
* block filled with data from the file.
|
||
*
|
||
* RETURN:
|
||
* The number of bytes actually read . If this value is not equal to the
|
||
* <20>numberOfBytes<65> parameter delivered to the function , the read action
|
||
* reached EOF.The function can also return the following values in case of
|
||
* an error :
|
||
* - FILE_READ_ERROR if the fileHandler is larger or equal to
|
||
* MAX_NUM_OF_ENTRIES defined in fileSys.h or if the status flag of the
|
||
* file entry in the dynamic database holds the value FREE_ENTRY.
|
||
* - 0 if the file was opened as write only , the EOF pointer is equal to
|
||
* the file pointer indicating the current loaction within the file or
|
||
* the <20>nextBlockPointer<65> field within the file entry in the flash is
|
||
* equal to 0xFFFFFFFF (empty file).
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSRead(FS_FILE_HANDLER fileHandler,
|
||
unsigned int numberOfBytes,char * block)
|
||
{
|
||
unsigned int blockIndex = 0,nextBlockPointer,EOFpointer;
|
||
unsigned int remainingBytes,freeBytesInBlock,bytesRead;
|
||
unsigned int totalBytesRead = 0,blockSize;
|
||
|
||
if((fileHandler >= FS_MAX_NUM_OF_ENTRIES) ||
|
||
(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY) ||
|
||
numberOfBytes == 0)
|
||
return FS_FILE_READ_ERROR;
|
||
if(mvFSEntries[fileHandler].mode[0] == 'w' &&
|
||
mvFSEntries[fileHandler].mode[1] == '\0')
|
||
return 0; /* File was opened as write only */
|
||
if(mvFSEntries[fileHandler].EOFpointer ==
|
||
mvFSEntries[fileHandler].filePointer)
|
||
return 0;
|
||
blockSize = FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE;
|
||
EOFpointer = mvFSEntries[fileHandler].EOFpointer;
|
||
remainingBytes = numberOfBytes;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
if(nextBlockPointer == 0xffffffff)
|
||
return 0; /* An empty file */
|
||
if(mvFSEntries[fileHandler].filePointer == 0)
|
||
{
|
||
/* Read one byte and set the filePointer to the first block */
|
||
block[blockIndex] = mvFlash8Rd(mvFlashInfo, (nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) + FS_BLOCK_HEADER_SIZE);
|
||
remainingBytes--;
|
||
totalBytesRead++;
|
||
mvFSEntries[fileHandler].filePointer = (nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_HEADER_SIZE;
|
||
blockIndex++;
|
||
mvFSEntries[fileHandler].blockPointer= nextBlockPointer;
|
||
}
|
||
else
|
||
{
|
||
/* update the block's file pointer */
|
||
nextBlockPointer = mvFSEntries[fileHandler].blockPointer;
|
||
}
|
||
while(1)
|
||
{
|
||
if((mvFSEntries[fileHandler].filePointer & FS_BLOCK_OFFSET_MASK) !=
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK))
|
||
{ /* Forward the file pointer to the current block */
|
||
block[blockIndex] = mvFlash8Rd(mvFlashInfo, (nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_HEADER_SIZE);
|
||
remainingBytes--;
|
||
totalBytesRead++;
|
||
mvFSEntries[fileHandler].filePointer = (nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_HEADER_SIZE;
|
||
blockIndex++;
|
||
}
|
||
freeBytesInBlock = mvFSGetNumOfValidBytes(nextBlockPointer,
|
||
mvFSEntries[fileHandler].filePointer,
|
||
EOFpointer);
|
||
if(freeBytesInBlock <= remainingBytes)
|
||
{
|
||
bytesRead = mvFlashBlockRd(mvFlashInfo, mvFSEntries[fileHandler].filePointer
|
||
+1,freeBytesInBlock, (MV_U8 *)&block[blockIndex]);
|
||
remainingBytes -= bytesRead;
|
||
totalBytesRead += bytesRead;
|
||
mvFSEntries[fileHandler].filePointer += bytesRead;
|
||
blockIndex += bytesRead;
|
||
if(bytesRead != freeBytesInBlock) /* Fatal error */
|
||
{
|
||
return totalBytesRead;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bytesRead = mvFlashBlockRd(mvFlashInfo, mvFSEntries[fileHandler].filePointer
|
||
+1,remainingBytes,(MV_U8 *)&block[blockIndex]);
|
||
totalBytesRead += bytesRead;
|
||
mvFSEntries[fileHandler].filePointer += bytesRead;
|
||
blockIndex += bytesRead;
|
||
if(bytesRead != remainingBytes) /* Fatal error */
|
||
{
|
||
return totalBytesRead;
|
||
}
|
||
remainingBytes -= bytesRead;
|
||
}
|
||
if(((nextBlockPointer & FS_BLOCK_OFFSET_MASK) ==
|
||
(EOFpointer & FS_BLOCK_OFFSET_MASK)) || remainingBytes == 0)
|
||
{ /* Last valid block */
|
||
return totalBytesRead;
|
||
}
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
}
|
||
return totalBytesRead;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSRewind - Set the file pointer the beginning of the file.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function set the file pointer the beginning of the given file.
|
||
*
|
||
* INPUT:
|
||
* fileHandler - The file handler of the file to rewind its pointer.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* 0 on succes otherwise 0xffffffff.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSRewind(FS_FILE_HANDLER fileHandler)
|
||
{
|
||
if((fileHandler >= FS_MAX_NUM_OF_ENTRIES) ||
|
||
(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY))
|
||
return 0xffffffff;
|
||
mvFSEntries[fileHandler].filePointer = 0;
|
||
return 0;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSSeek - Move the file pointer from the origin specified.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function move<76>s the file-pointer associated with <20>filehandler<65> to a
|
||
* new location that is <20>offset<65> bytes from <20>origin<69>.The argument <20>origin<69>
|
||
* must be one of the following constants , defined in mvFS.h :
|
||
*
|
||
* SEEK_CUR - Current position of file pointer.
|
||
* SEEK_END - End of file.
|
||
* SEEK_SET - Beginning of file.
|
||
*
|
||
* The <20>offset<65> argument indicates the number of bytes to move relatively
|
||
* to <20>origin<69>.
|
||
*
|
||
* INPUT:
|
||
* fileHandler - The file-handler of the file to reposition its
|
||
* file-pointer.
|
||
* Offset - The number of bytes to move the file pointer from <20>origin<69>.
|
||
* Origin - The relative point within the file to move the file-pointer
|
||
* <20>offset<65> bytes from it.Must be one of the three values
|
||
* described above.
|
||
*
|
||
* OUTPUT:
|
||
* File-pointer located on its new place ( on success ).
|
||
*
|
||
* RETURN:
|
||
* true on succes, 0xffffffff otherwise.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSSeek(FS_FILE_HANDLER fileHandler,int offset,int origin)
|
||
{
|
||
unsigned int nextBlockPointer,fileSize;
|
||
unsigned int validBytes,temp;
|
||
int tempSize = 0,tempOffset = 0;
|
||
|
||
if((fileHandler >= FS_MAX_NUM_OF_ENTRIES) ||
|
||
(mvFSEntries[fileHandler].statusFlag == FS_FREE_ENTRY))
|
||
return 0xffffffff;
|
||
fileSize = mvFSFileSize(fileHandler);
|
||
if(fileSize == 0xffffffff || fileSize == 0)
|
||
return 0xffffffff;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
switch(origin)
|
||
{
|
||
case FS_SEEK_END:
|
||
if(offset <= 0)
|
||
return 1/*true*/;
|
||
if((unsigned int)offset >= fileSize)
|
||
{
|
||
mvFSEntries[fileHandler].filePointer = 0;
|
||
return 1/*true*/;
|
||
}
|
||
offset = fileSize - offset;
|
||
break;
|
||
case FS_SEEK_SET:
|
||
if(offset <= 0)
|
||
{
|
||
mvFSEntries[fileHandler].filePointer = 0;
|
||
return 1/*true*/;
|
||
}
|
||
if((unsigned int)offset >= fileSize)
|
||
{
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
return 1/*true*/;
|
||
}
|
||
while(tempOffset < offset)
|
||
{
|
||
validBytes = mvFSGetNumOfValidBytes(nextBlockPointer,
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_HEADER_SIZE,
|
||
mvFSEntries[fileHandler].EOFpointer);
|
||
if((tempOffset + (int)validBytes) >= offset)
|
||
break;
|
||
tempOffset += validBytes;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
}
|
||
mvFSEntries[fileHandler].filePointer =
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
(offset - tempOffset) + FS_BLOCK_HEADER_SIZE - 1;
|
||
return 1/*true*/;
|
||
case FS_SEEK_CUR: /* In this case offset can be negative */
|
||
if(offset == 0)
|
||
return 1/*true*/;
|
||
/* tempSize = Size in bytes up-to filePointer */
|
||
temp = nextBlockPointer;
|
||
nextBlockPointer =
|
||
mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
while(nextBlockPointer != 0xffffffff)
|
||
{
|
||
if(mvFSEntries[fileHandler].filePointer == 0)
|
||
break;
|
||
if((mvFSEntries[fileHandler].filePointer & FS_BLOCK_OFFSET_MASK) ==
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK)) /* Last block for us*/
|
||
{
|
||
tempSize += (mvFSEntries[fileHandler].filePointer
|
||
& FS_BLOCK_OFFSET) - FS_BLOCK_HEADER_SIZE + 1;
|
||
break;
|
||
}
|
||
if(((nextBlockPointer & FS_BLOCK_OFFSET) + 1) != FS_BLOCK_SIZE)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, (nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_FLAG_OFFSET) == FS_FULL_BLOCK)
|
||
{
|
||
tempSize += (FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE);
|
||
}
|
||
else
|
||
{
|
||
if(mvFlash16Rd(mvFlashInfo, (nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_OFFSET) != 0xffff)
|
||
{
|
||
tempSize += ((nextBlockPointer & FS_BLOCK_OFFSET) +
|
||
mvFlash16Rd(mvFlashInfo, (nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK) +
|
||
FS_BLOCK_OFFSET_OFFSET) -
|
||
FS_BLOCK_HEADER_SIZE + 1);
|
||
}
|
||
else
|
||
{
|
||
tempSize += ((nextBlockPointer & FS_BLOCK_OFFSET) -
|
||
FS_BLOCK_HEADER_SIZE + 1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tempSize += (FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE);
|
||
}
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer &
|
||
FS_BLOCK_OFFSET_MASK);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
}
|
||
nextBlockPointer = temp;
|
||
offset = tempSize + offset;
|
||
if(offset >= (int)fileSize)
|
||
{
|
||
mvFSEntries[fileHandler].filePointer =
|
||
mvFSEntries[fileHandler].EOFpointer;
|
||
return 1/*true*/;
|
||
}
|
||
if(offset <= (int)0)
|
||
{
|
||
mvFSEntries[fileHandler].filePointer = 0;
|
||
return 1/*true*/;
|
||
}
|
||
while(tempOffset < offset)
|
||
{
|
||
validBytes = mvFSGetNumOfValidBytes(nextBlockPointer,
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK)
|
||
+ FS_BLOCK_HEADER_SIZE,
|
||
mvFSEntries[fileHandler].EOFpointer);
|
||
if((tempOffset + (int)validBytes) >= offset)
|
||
break;
|
||
tempOffset += validBytes;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer
|
||
& FS_BLOCK_OFFSET_MASK);
|
||
mvFSEntries[fileHandler].blockPointer = nextBlockPointer;
|
||
}
|
||
mvFSEntries[fileHandler].filePointer =
|
||
(nextBlockPointer & FS_BLOCK_OFFSET_MASK) +
|
||
(offset - tempOffset) + FS_BLOCK_HEADER_SIZE - 1;
|
||
return 1/*true*/;
|
||
default:
|
||
return 0xffffffff;
|
||
}
|
||
return 0xffffffff;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSReadErasingCounter - Reads the value of the erasing counter (if
|
||
* implemented).
|
||
*
|
||
* DESCRIPTION:
|
||
* This function reads the value of the erasing counter ( if implemented )
|
||
* of the given sector .The erasing counter is enabled by the function
|
||
* <20>fileSysFormat<61> (by the <20>mode<64> parameter) . It is implimented by
|
||
* allocating one block at the end of each sector and it helps monitoring
|
||
* the number of erasures of the sector the counter is at .
|
||
* NOTE:
|
||
* he file system's data base must be initialized by <20>fileSysInit<69> function
|
||
* before using this function .
|
||
*
|
||
* INPUT:
|
||
* sectorNumber - The sector number to read its erasing counter
|
||
* (if implemented).
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* The vlaue of the erasing counter, 0xffffffff in case the erasing
|
||
* counter was not implemented or the sector number is not valid.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSReadErasingCounter(unsigned int sectorNumber)
|
||
{
|
||
unsigned int counterValue,sectorBaseAddr,sectorSize;
|
||
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return 0xffffffff;
|
||
if(mvFlash32Rd(mvFlashInfo, mvFSOffset + FS_ERSAING_COUNTER_FLAG_OFFSET) !=
|
||
FS_ENABLE_ERASING_COUNTER)
|
||
return 0xffffffff;
|
||
if((sectorBaseAddr = mvFlashSecOffsGet(mvFlashInfo, sectorNumber)) == 0xffffffff)
|
||
return 0xffffffff;
|
||
if(sectorBaseAddr < mvFSOffset)
|
||
return 0xffffffff;
|
||
sectorSize = mvFlashSecSizeGet(mvFlashInfo, sectorNumber);
|
||
counterValue = mvFlash32Rd(mvFlashInfo, sectorBaseAddr + sectorSize - FS_BLOCK_SIZE);
|
||
return counterValue;
|
||
}
|
||
|
||
/*******************************************************************************
|
||
* mvFSGetFreeSize - Returns the number of free bytes in the file system.
|
||
*
|
||
* DESCRIPTION:
|
||
* This function returns the number of free bytes in the entire file
|
||
* system. It counts the number of free blocks and dirty blocks ( blocks
|
||
* that are no longer in use by any file ) from the begining of the
|
||
* file-system to the end , and return that value multiply by block size
|
||
* (in bytes).
|
||
* NOTE:
|
||
* The file system's data base must be initialized by <20>fileSysInit<69>
|
||
* function before using this function .
|
||
* INPUT:
|
||
* None.
|
||
*
|
||
* OUTPUT:
|
||
* None.
|
||
*
|
||
* RETURN:
|
||
* Number of free bytes in the entire file-system on success, 0xFFFFFFFF
|
||
* otherwise.
|
||
*
|
||
*******************************************************************************/
|
||
unsigned int mvFSGetFreeSize()
|
||
{
|
||
unsigned int freeBlockOffset,sectorTopOffset,i;
|
||
unsigned int sectorNumber,lastSector;
|
||
unsigned int dirtyBlocksCounter = 0,dirtyBlocksSector;
|
||
unsigned int freeBlocksCounter = 0;
|
||
|
||
/* Check if the file system's data base was initialized */
|
||
if(initializationFlag != FS_FILE_SYSTEM_INITIALIZED)
|
||
return 0xffffffff;
|
||
freeBlockOffset = mvFSOffset + FS_BLOCK_SIZE;
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, freeBlockOffset);
|
||
lastSector = mvFlashNumOfSecsGet(mvFlashInfo);
|
||
dirtyBlocksSector = sectorNumber;
|
||
for(i = sectorNumber ; i < lastSector ; i++)
|
||
{
|
||
sectorTopOffset = mvFlashSecOffsGet(mvFlashInfo, sectorNumber) +
|
||
mvFlashSecSizeGet(mvFlashInfo, sectorNumber) - 1;
|
||
while(freeBlockOffset < sectorTopOffset)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, freeBlockOffset + FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_BLOCK) freeBlocksCounter++;
|
||
if(mvFlash8Rd(mvFlashInfo, freeBlockOffset + FS_BLOCK_STATUS_FLAG_OFFSET)
|
||
== FS_FREE_DIRTY_BLOCK) dirtyBlocksCounter++;
|
||
freeBlockOffset += FS_BLOCK_SIZE;
|
||
}
|
||
sectorNumber = mvFlashInWhichSec(mvFlashInfo, freeBlockOffset);
|
||
}
|
||
return (freeBlocksCounter + dirtyBlocksCounter) *
|
||
(FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE);
|
||
}
|
||
|
||
/********************************************************************************/
|
||
/********************************************************************************/
|
||
/********************************************************************************/
|
||
|
||
/***********************************************************************/
|
||
/* ask the user to give a file name and chck if the file already exist.*/
|
||
/***********************************************************************/
|
||
MV_VOID get_filename(MV_8 *fileName, MV_BOOL exeType)
|
||
{
|
||
int i;
|
||
extern MV_8 console_buffer[];
|
||
|
||
while(1)
|
||
{
|
||
i = 0;
|
||
printf("Enter name & extension for the file (maximum %d characters for the name)\n",
|
||
FS_FILE_NAME_LENGTH);
|
||
readline(" # ");
|
||
|
||
strcpy(fileName, console_buffer);
|
||
while( i < FS_FILE_NAME_LENGTH &&
|
||
fileName[i] != '\0' && fileName[i] != ' ') i++;
|
||
fileName[i] = '\0';
|
||
if(i == 0)
|
||
{
|
||
strcpy(fileName,"NoName");
|
||
i = 6;
|
||
fileName[i] = '\0';
|
||
}
|
||
/* if exe file type */
|
||
if(exeType == MV_TRUE){
|
||
i = 0;
|
||
while(fileName[i] != '.' && i < FS_FILE_NAME_LENGTH &&
|
||
fileName[i] != '\0') i++;
|
||
fileName[i] = '.';
|
||
fileName[i+1] = 'e';
|
||
fileName[i+2] = 'x';
|
||
fileName[i+3] = 'e';
|
||
fileName[i+4] = '\0';
|
||
}
|
||
|
||
if (mvFSFileFind(fileName) != FS_FILE_NOT_FOUND)
|
||
{
|
||
printf("File already exists, overwrite? (Y/N)\n");
|
||
readline(" ? ");
|
||
if(strcmp(console_buffer,"N") == 0 || strcmp(console_buffer,"no") == 0 ||
|
||
strcmp(console_buffer,"n") == 0)
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
if(mvFSDelete(fileName) != FS_FILE_DELETED)
|
||
{
|
||
printf("File could not be deleted!\n");
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
/***********************************************/
|
||
/* load a file to the flash FS using the tftp. */
|
||
/***********************************************/
|
||
int
|
||
tftpfs_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
int filesize;
|
||
MV_8 fileName[CFG_CBSIZE];
|
||
MV_U32 status;
|
||
FS_FILE_HANDLER fileHandler;
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
load_addr = 0x400000;
|
||
if(argc == 2) {
|
||
copy_filename (BootFile, argv[1], sizeof(BootFile));
|
||
|
||
}else{ printf ("Usage:\n%s\n", cmdtp->usage);
|
||
return 0;
|
||
}
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
|
||
if ((filesize = NetLoop(TFTP)) < 0)
|
||
return 0;
|
||
|
||
/* done if no file was loaded (no errors though) */
|
||
if (filesize <= 0)
|
||
return 0;
|
||
|
||
/* get a file name from the user */
|
||
get_filename(fileName,MV_FALSE);
|
||
|
||
fileHandler = mvFSOpen(fileName,"w");
|
||
if(fileHandler == FS_FILE_OPEN_ERROR)
|
||
{
|
||
printf("ERROR: Can't open file!\n");
|
||
return 0;
|
||
}
|
||
if(mvFSWrite(fileHandler,filesize,(MV_8 *)load_addr) != filesize)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
printf("File loaded to file system successfully...\n");
|
||
mvFSClose(fileHandler);
|
||
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FStftp, 2, 1, tftpfs_cmd,
|
||
"FStftp - tftp a file to the Flash MV FS\n",
|
||
" filename.\n"
|
||
"\tDownload a file through the network interface to the DRAM(0x400000) using\n"
|
||
"\ttftp, and copy the file to the MV Flash FS.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
/***********************************************/
|
||
/* load a file to the flash FS using the tftp. */
|
||
/***********************************************/
|
||
int
|
||
tftpefs_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||
{
|
||
int filesize;
|
||
char fileName[CFG_CBSIZE],c;
|
||
unsigned int status, entryAddress;
|
||
FS_FILE_HANDLER fileHandler;
|
||
unsigned char addressBuffer[8];
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
if(argc == 3) {
|
||
entryAddress = simple_strtoul(argv[1], NULL, 16);
|
||
load_addr = entryAddress;
|
||
copy_filename (BootFile, argv[2], sizeof(BootFile));
|
||
|
||
}else{
|
||
printf ("Usage:\n%s %d\n", cmdtp->usage,argc);
|
||
return 0;
|
||
}
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
|
||
if ((filesize = NetLoop(TFTP)) < 0)
|
||
return 0;
|
||
|
||
/* done if no file was loaded (no errors though) */
|
||
if (filesize <= 0)
|
||
return 0;
|
||
|
||
/* get a file name from the user */
|
||
get_filename(fileName,MV_TRUE);
|
||
|
||
fileHandler = mvFSOpen(fileName,"w");
|
||
if(fileHandler == FS_FILE_OPEN_ERROR)
|
||
{
|
||
printf("ERROR: Can't open file!\n");
|
||
return 0;
|
||
}
|
||
|
||
/* Set the entry address for the file */
|
||
c = (entryAddress >> 28) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[0] = c + '0';
|
||
else
|
||
addressBuffer[0] = c + 'A' - 10;
|
||
c = (entryAddress >> 24) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[1] = c + '0';
|
||
else
|
||
addressBuffer[1] = c + 'A' - 10;
|
||
c = (entryAddress >> 20) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[2] = c + '0';
|
||
else
|
||
addressBuffer[2] = c + 'A' - 10;
|
||
c = (entryAddress >> 16) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[3] = c + '0';
|
||
else
|
||
addressBuffer[3] = c + 'A' - 10;
|
||
c = (entryAddress >> 12) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[4] = c + '0';
|
||
else
|
||
addressBuffer[4] = c + 'A' - 10;
|
||
c = (entryAddress >> 8) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[5] = c + '0';
|
||
else
|
||
addressBuffer[5] = c + 'A' - 10;
|
||
c = (entryAddress >> 4) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[6] = c + '0';
|
||
else
|
||
addressBuffer[6] = c + 'A' - 10;
|
||
c = (entryAddress) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[7] = c + '0';
|
||
else
|
||
addressBuffer[7] = c + 'A' - 10;
|
||
|
||
if(mvFSWrite(fileHandler,8,(char *)addressBuffer)!= 8)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
|
||
if(mvFSWrite(fileHandler,filesize,(char *)load_addr) != filesize)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
printf("File loaded to file system successfully...\n");
|
||
mvFSClose(fileHandler);
|
||
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FStftpe, 3, 1, tftpefs_cmd,
|
||
"FStftpe - tftp an exe file to the Flash MV FS\n",
|
||
" entry_address filename.\n"
|
||
"\tDownload a file through the network interface to entry_address using\n"
|
||
"\ttftp, and copy the file to the MV Flash FS.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
/**************************************************/
|
||
/* load a file to the flash FS using the loadnet. */
|
||
/**************************************************/
|
||
#if 0
|
||
int
|
||
loadfs_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
int filesize;
|
||
MV_8 fileName[CFG_CBSIZE];
|
||
MV_U32 status,addr = 0x20000;
|
||
FS_FILE_HANDLER fileHandler;
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
|
||
filesize = load_net(&addr);
|
||
printf("\nFile loaded successfully...\n");
|
||
printf("File size: %d bytes.\n",filesize);
|
||
|
||
|
||
/* done if no file was loaded (no errors though) */
|
||
if (filesize <= 0)
|
||
return 0;
|
||
|
||
/* get a file name from the user */
|
||
get_filename(fileName, MV_FALSE);
|
||
|
||
fileHandler = mvFSOpen(fileName,"w");
|
||
if(fileHandler == FS_FILE_OPEN_ERROR)
|
||
{
|
||
printf("ERROR: Can't open file!\n");
|
||
return 0;
|
||
}
|
||
if(mvFSWrite(fileHandler,filesize,(MV_8 *)addr) != filesize)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
printf("File loaded to file system successfully...\n");
|
||
mvFSClose(fileHandler);
|
||
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FSlf, 1, 1, loadfs_cmd,
|
||
"FSlf - Load a file to the Flash MV FS\n",
|
||
" \n"
|
||
"\tLoad S-Record file via the first available ethernet port, to the DRAM\n"
|
||
"\t(0x200000) and copy it to the MV Flash FS.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
#endif
|
||
|
||
/*******************************************************/
|
||
/* load an exe file to the flash FS using the loadnet. */
|
||
/*******************************************************/
|
||
#if 0
|
||
int
|
||
loadexefs_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
int filesize;
|
||
MV_8 fileName[CFG_CBSIZE],c;
|
||
MV_U32 status,entryAddress = 0x0;
|
||
FS_FILE_HANDLER fileHandler;
|
||
MV_U8 addressBuffer[8];
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
|
||
filesize = load_net(&entryAddress);
|
||
printf("\nFile loaded successfully...\n");
|
||
printf("File size: %d bytes.\n",filesize);
|
||
|
||
|
||
/* done if no file was loaded (no errors though) */
|
||
if (filesize <= 0)
|
||
return 0;
|
||
|
||
/* get a file name from the user */
|
||
get_filename(fileName, MV_TRUE);
|
||
|
||
fileHandler = mvFSOpen(fileName,"w");
|
||
if(fileHandler == FS_FILE_OPEN_ERROR)
|
||
{
|
||
printf("ERROR: Can't open file!\n");
|
||
return 0;
|
||
}
|
||
/* Set the entry address for the file */
|
||
c = (entryAddress >> 28) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[0] = c + '0';
|
||
else
|
||
addressBuffer[0] = c + 'A' - 10;
|
||
c = (entryAddress >> 24) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[1] = c + '0';
|
||
else
|
||
addressBuffer[1] = c + 'A' - 10;
|
||
c = (entryAddress >> 20) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[2] = c + '0';
|
||
else
|
||
addressBuffer[2] = c + 'A' - 10;
|
||
c = (entryAddress >> 16) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[3] = c + '0';
|
||
else
|
||
addressBuffer[3] = c + 'A' - 10;
|
||
c = (entryAddress >> 12) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[4] = c + '0';
|
||
else
|
||
addressBuffer[4] = c + 'A' - 10;
|
||
c = (entryAddress >> 8) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[5] = c + '0';
|
||
else
|
||
addressBuffer[5] = c + 'A' - 10;
|
||
c = (entryAddress >> 4) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[6] = c + '0';
|
||
else
|
||
addressBuffer[6] = c + 'A' - 10;
|
||
c = (entryAddress) & 0x0f;
|
||
if(c < 10)
|
||
addressBuffer[7] = c + '0';
|
||
else
|
||
addressBuffer[7] = c + 'A' - 10;
|
||
|
||
if(mvFSWrite(fileHandler,8,(MV_8 *)addressBuffer)!= 8)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
|
||
if(mvFSWrite(fileHandler,filesize,(MV_8 *)entryAddress)!= filesize)
|
||
{
|
||
printf("ERROR: Writing data to file.\n");
|
||
return 0;
|
||
}
|
||
printf("File loaded to file system successfully...\n");
|
||
mvFSClose(fileHandler);
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FSlef, 1, 1, loadexefs_cmd,
|
||
"FSlef - Load an exe file to the Flash MV FS\n",
|
||
" \n"
|
||
"\tLoad S-Record EXE file via the first available ethernet port to the DRAM\n"
|
||
"\t(0x200000) and copy it to the MV Flash FS.\n"
|
||
"\tAfter load is complete the EXE file can be run by using: FSrun filename.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
#endif
|
||
|
||
/*********************************************************************************
|
||
* Load Exe file from the Flash FS.
|
||
*********************************************************************************/
|
||
MV_U32 loadExe(MV_8 * fname)
|
||
{
|
||
register MV_U32 byteCount;
|
||
register MV_U32 entryAddress = 0xffffffff;
|
||
MV_8 addressBuffer[9];
|
||
FS_FILE_HANDLER fileHandler;
|
||
MV_U32 nextBlockPointer, sourceAddress, destAddress, status;
|
||
MV_U32 mvFlashBaseAddress;
|
||
|
||
mvFlashBaseAddress = MV_BOARD_FLASH_BASE_ADRS;
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return entryAddress;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return entryAddress;
|
||
}
|
||
if((fileHandler = mvFSOpen(fname,"r")) == FS_FILE_OPEN_ERROR)
|
||
{
|
||
printf("ERROR in file open\n");
|
||
return entryAddress;
|
||
}
|
||
|
||
/* Extract the file's entry address */
|
||
mvFSRead(fileHandler,8,addressBuffer);
|
||
addressBuffer[8]='\0';
|
||
entryAddress = simple_strtoul(addressBuffer, NULL, 16);
|
||
debug("entryAddress = %x \n",entryAddress);
|
||
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, mvFSEntries[fileHandler].pointerToFAT);
|
||
/* The First block contain the address, thus treated differently */
|
||
byteCount = FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE - 8 /* Address size */ ;
|
||
destAddress = entryAddress;
|
||
sourceAddress = (nextBlockPointer & FS_BLOCK_OFFSET_MASK) + mvFlashBaseAddress
|
||
+ FS_BLOCK_HEADER_SIZE + 8/* Address size */;
|
||
|
||
/* Flush the block from the cache before executing it */
|
||
debug("memcpy transfer src %x dst %x bytecnt %x\n",\
|
||
sourceAddress,destAddress,byteCount);
|
||
memcpy((void *)destAddress, (void *)sourceAddress, byteCount);
|
||
destAddress += byteCount;
|
||
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer & FS_BLOCK_OFFSET_MASK);
|
||
byteCount = FS_BLOCK_SIZE - FS_BLOCK_HEADER_SIZE;
|
||
|
||
while(nextBlockPointer != 0xffffffff)
|
||
{
|
||
sourceAddress = (nextBlockPointer & FS_BLOCK_OFFSET_MASK) + mvFlashBaseAddress
|
||
+ FS_BLOCK_HEADER_SIZE;
|
||
|
||
memcpy((MV_U32*)destAddress,(MV_U32*)sourceAddress,byteCount);
|
||
|
||
destAddress += byteCount;
|
||
nextBlockPointer = mvFlash32Rd(mvFlashInfo, nextBlockPointer & FS_BLOCK_OFFSET_MASK);
|
||
}
|
||
mvFSClose(fileHandler);
|
||
return entryAddress;
|
||
}
|
||
|
||
int runexeFS_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
MV_8 fileName[CFG_CBSIZE];
|
||
MV_U32 i,entryAddress;
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
if(argc >= 2) {
|
||
copy_filename(fileName, argv[1], sizeof(fileName));
|
||
|
||
}else{ printf ("Usage:\n%s\n", cmdtp->usage);
|
||
return 0;
|
||
}
|
||
|
||
for(i = 0 ; i < FS_FILE_NAME_LENGTH; i++)
|
||
{
|
||
if(fileName[i] == '.')
|
||
break;
|
||
if(fileName[i] == '\0')
|
||
{
|
||
fileName[i] = '.';
|
||
fileName[i+1] = 'e';
|
||
fileName[i+2] = 'x';
|
||
fileName[i+3] = 'e';
|
||
fileName[i+4] = 0;
|
||
break;
|
||
}
|
||
}
|
||
if((entryAddress = loadExe(fileName)) == 0xffffffff)
|
||
{
|
||
printf ("%s: Command not found.\n", fileName);
|
||
return 0;
|
||
}
|
||
mv_go(entryAddress, --argc, &argv[1]);
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FSrun, CFG_MAXARGS, 1, runexeFS_cmd,
|
||
"FSrun - Load an exe file from the Flash MV FS and run it\n",
|
||
" filename\n"
|
||
"\tLoad an exe file 'filename' from the Flash MV FS and run it.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
|
||
/******************************************************************************
|
||
* Functionality- The commands allows the user to view the contents of a file
|
||
* located in the file system.
|
||
*****************************************************************************/
|
||
int type_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
MV_8 fileName[128]={},readBuffer[101],key;
|
||
FS_FILE_HANDLER fileHandler;
|
||
MV_U32 readCount=0, newLineCount=0, flagm,readCounttmp, lineCount=0,i;
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
if(argc == 2) {
|
||
copy_filename(fileName, argv[1], sizeof(fileName));
|
||
}else{ printf ("Usage:\n%s\n", cmdtp->usage);
|
||
return 0;
|
||
}
|
||
fileHandler = mvFSOpen(fileName,"r");
|
||
if(fileHandler != FS_FILE_OPEN_ERROR)
|
||
{
|
||
while(readCount < mvFSFileSize(fileHandler))
|
||
{
|
||
readCounttmp = mvFSRead(fileHandler,100,readBuffer);
|
||
readBuffer[100] = '\0';
|
||
if(readCounttmp < 100)
|
||
readBuffer[readCounttmp] = '\0';
|
||
readCount += readCounttmp;
|
||
lineCount += readCounttmp;
|
||
for(i = 0 ; i <= readCounttmp ; i++)
|
||
if(readBuffer[i] == '\n')
|
||
newLineCount++;
|
||
printf("%s",readBuffer);
|
||
if(newLineCount >= 20 || lineCount > 1600)
|
||
{
|
||
flagm = 0;
|
||
while(1)
|
||
{
|
||
key = getc();
|
||
switch(key)
|
||
{
|
||
case ' ':
|
||
flagm = 1;
|
||
newLineCount = 0;
|
||
lineCount = 0;
|
||
break;
|
||
case 'x':
|
||
mvFSClose(fileHandler);
|
||
printf("\n");
|
||
return 1;
|
||
}
|
||
if(flagm == 1)
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
mvFSClose(fileHandler);
|
||
printf("\n");
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FStype, CFG_MAXARGS, 1, type_cmd,
|
||
"FStype - cat file from the Flash MV FS\n",
|
||
" filename \n"
|
||
"\tDisplay an ascii file 'filename' found on the MV Flash FS.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
|
||
|
||
/******************************************************************************
|
||
* Functionality- Formats the mvFlash mvMemory at a given offset
|
||
*****************************************************************************/
|
||
int format_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
MV_U32 offset =0,result;
|
||
extern MV_8 console_buffer[];
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
if(argc == 2) {
|
||
offset = simple_strtoul(argv[1], NULL, 16);
|
||
}else{ printf ("Usage:\n%s\n", cmdtp->usage);
|
||
return 0;
|
||
}
|
||
|
||
printf("\a\a\aThis action will erase the FLASH Memory!!!\n");
|
||
printf("Are you sure (y/n) ");
|
||
readline(" ? ");
|
||
|
||
if(strcmp(console_buffer,"y") == 0 || strcmp(console_buffer,"yes") == 0 || strcmp(console_buffer,"Y") == 0)
|
||
{
|
||
if(offset == 0xffffffff)
|
||
{
|
||
printf("Bad offset!\n");
|
||
}
|
||
result = mvFSFormat(offset,FS_NO_ERASING_COUNTER);
|
||
if(result == FS_VALID_FILE_SYS_IN_LOWER_OFFSET)
|
||
{
|
||
printf("ERROR: FS_VALID_FILE_SYS_IN_LOWER_OFFSET\n");
|
||
return 0;
|
||
}
|
||
if(result == FS_FLASH_MEMORY_NOT_PRESENT)
|
||
{
|
||
printf("ERROR: FS_FLASH_MEMORY_NOT_PRESENT\n");
|
||
return 1;
|
||
}
|
||
printf("Flash Memory formated successfully, actual offset is: %x\n"
|
||
,result);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FSformat, 2, 1, format_cmd,
|
||
"FSformat- format the Flash MV FS\n",
|
||
" address \n"
|
||
"\tInitialize the MV Flash FS starting at offset 'address' in the Flash.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
|
||
/******************************************************************************
|
||
* Functionality- Display the list of files currently on the system (file name + size)
|
||
*****************************************************************************/
|
||
int dir_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
MV_U32 fileEntryOffset,nextBlockOffset,mvFSOffset;
|
||
MV_U32 status,i,j,spaces = 20;
|
||
FS_FILE_HANDLER fileHandler;
|
||
MV_8 fileName[20];
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
if(status != FS_SYSTEM_ALREADY_INITIALIZED)
|
||
{
|
||
printf("Number of files in system: %d\n",status);
|
||
}
|
||
|
||
mvFSOffset = mvFSSearchForSignature();
|
||
nextBlockOffset = mvFSOffset;
|
||
while(nextBlockOffset != 0xffffffff)
|
||
{
|
||
/* Skip the block's header */
|
||
fileEntryOffset = nextBlockOffset + FS_FAT_HEADER_SIZE;
|
||
for(i = 0 ; i < 15 ; i++)
|
||
{
|
||
if(mvFlash8Rd(mvFlashInfo, fileEntryOffset + FS_ENTRY_STATUS_FLAG_OFFSET)
|
||
== FS_ENTRY_IN_USE)
|
||
{
|
||
mvFSReadFileNameFromFATentry(fileEntryOffset,fileName);
|
||
fileHandler = mvFSOpen(fileName,"r");
|
||
printf("%s",fileName);
|
||
spaces = 22 - strlen(fileName);
|
||
for(j = 0 ; j < spaces ; j++)
|
||
printf(" ");
|
||
printf("size: %d bytes\n",mvFSFileSize(fileHandler));
|
||
mvFSClose(fileHandler);
|
||
}
|
||
/* point to the next entry */
|
||
fileEntryOffset += FS_FAT_FILE_ENTRY_SIZE;
|
||
}
|
||
nextBlockOffset = mvFlash32Rd(mvFlashInfo, nextBlockOffset);
|
||
}
|
||
printf("\n %d free bytes\n",
|
||
mvFSGetFreeSize());
|
||
return 1;
|
||
}
|
||
|
||
|
||
U_BOOT_CMD(
|
||
FSdir, 1, 1, dir_cmd,
|
||
"FSdir - ls the Flash MV FS\n",
|
||
" \n"
|
||
"\tDisplay the MV Flash FS contents.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
/******************************************************************************
|
||
* Functionality- Deletes a file from the system
|
||
*****************************************************************************/
|
||
int del_cmd(cmd_tbl_t *cmdtp, int flag, int argc, MV_8 *argv[])
|
||
{
|
||
MV_U32 status;
|
||
MV_8 cmd[30];
|
||
|
||
if(!enaMonExt()){
|
||
printf("This command can be used only if enaMonExt is set!\n");
|
||
return 0;}
|
||
|
||
if(argc == 2) {
|
||
copy_filename (cmd, argv[1], sizeof(cmd));
|
||
}else{ printf ("Usage:\n%s\n", cmdtp->usage);
|
||
return 0;
|
||
}
|
||
status = mvFSInit(FS_NO_CACHE);
|
||
if(status == FS_NO_VALID_FAT_STRING)
|
||
{
|
||
printf("ERROR: FS_NO_VALID_FAT_STRING\n");
|
||
return 0;
|
||
}
|
||
if(status == FS_OFFSET_OUT_OF_RANGE)
|
||
{
|
||
printf("ERROR: FS_OFFSET_OUT_OF_RANGE\n");
|
||
return 0;
|
||
}
|
||
if(mvFSFileFind(cmd) != FS_FILE_NOT_FOUND)
|
||
{
|
||
if(mvFSDelete(cmd) == FS_FILE_DELETED)
|
||
{
|
||
printf("File deleted\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
printf("%s:No such file\n",cmd);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
U_BOOT_CMD(
|
||
FSdel, 2, 1, del_cmd,
|
||
"FSdel - del a file from the Flash MV FS\n",
|
||
" filename \n"
|
||
"\tDelete a file 'filename' from the MV Flash FS.\n"
|
||
"\t(This command can be used only if enaMonExt is set!)\n"
|
||
);
|
||
|
||
|
||
#endif /* CONFIG_COMMANDS & CFG_CMD_BSP */
|
||
|
||
#endif /* MV_INC_BOARD_NOR_FLASH */
|