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 <EFBFBD>offset<EFBFBD> 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 <EFBFBD>mode<EFBFBD> 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
|
|||
|
* <EFBFBD>fileSysFormat<EFBFBD> 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<EFBFBD>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 <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileName<EFBFBD> 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 <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileName<EFBFBD>.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 <EFBFBD>fileName<EFBFBD> and return
|
|||
|
* that value.
|
|||
|
* NOTE:
|
|||
|
* The file system's data base must be initialized by <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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
|
|||
|
* <EFBFBD>fileName<EFBFBD>.
|
|||
|
* 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
|
|||
|
* <EFBFBD>mode<EFBFBD>.
|
|||
|
* NOTE:
|
|||
|
* The file system's data base must be initialized by <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* function before using this function .
|
|||
|
*
|
|||
|
* INPUT:
|
|||
|
* mode - defines on which mode the file will be open .All possible values
|
|||
|
* for <EFBFBD>mode<EFBFBD> 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 <EFBFBD>fileName<EFBFBD> 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 <EFBFBD>fileName<EFBFBD>
|
|||
|
* to that entry and returns the handler of the file . When
|
|||
|
* a file is opened with the <EFBFBD>r+<EFBFBD> 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
|
|||
|
* <EFBFBD>fileName<EFBFBD> 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<EFBFBD>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<EFBFBD>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
|
|||
|
* <EFBFBD>fileSysGetFreeBlock<EFBFBD> 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
|
|||
|
* <EFBFBD>fileSysGetFreeBlock<EFBFBD>.
|
|||
|
* NOTE:
|
|||
|
* The file system's data base must be initialized by <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileSysInit<EFBFBD> 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 <EFBFBD>fileSysOffset<EFBFBD> parameter initialized by <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileSysInit<EFBFBD> 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 <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 <EFBFBD>fileSysInit<EFBFBD> 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
|
|||
|
* <EFBFBD>entryOffset<EFBFBD> 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 <EFBFBD>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 <EFBFBD>numberOfBytes<EFBFBD> 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 <EFBFBD>numberOfBytes<EFBFBD> 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 <EFBFBD> w <EFBFBD> mode , into a given block (<EFBFBD>block<EFBFBD> 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
|
|||
|
* <EFBFBD>numberOfBytes<EFBFBD> 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 - <EFBFBD> w<EFBFBD> .
|
|||
|
* - if the EOF pointer is equal to the file pointer that indicates the
|
|||
|
* curruent position within the file.
|
|||
|
* - if the <EFBFBD>nextBlockPointer<EFBFBD> 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 <EFBFBD>numberOfBytes<EFBFBD>
|
|||
|
* 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
|
|||
|
* <EFBFBD>numberOfBytes<EFBFBD> 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 <EFBFBD>nextBlockPointer<EFBFBD> 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<EFBFBD>s the file-pointer associated with <EFBFBD>filehandler<EFBFBD> to a
|
|||
|
* new location that is <EFBFBD>offset<EFBFBD> bytes from <EFBFBD>origin<EFBFBD>.The argument <EFBFBD>origin<EFBFBD>
|
|||
|
* 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 <EFBFBD>offset<EFBFBD> argument indicates the number of bytes to move relatively
|
|||
|
* to <EFBFBD>origin<EFBFBD>.
|
|||
|
*
|
|||
|
* INPUT:
|
|||
|
* fileHandler - The file-handler of the file to reposition its
|
|||
|
* file-pointer.
|
|||
|
* Offset - The number of bytes to move the file pointer from <EFBFBD>origin<EFBFBD>.
|
|||
|
* Origin - The relative point within the file to move the file-pointer
|
|||
|
* <EFBFBD>offset<EFBFBD> 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
|
|||
|
* <EFBFBD>fileSysFormat<EFBFBD> (by the <EFBFBD>mode<EFBFBD> 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 <EFBFBD>fileSysInit<EFBFBD> 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 <EFBFBD>fileSysInit<EFBFBD>
|
|||
|
* 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 */
|