📄 nandfile.424
字号:
/*************************************************************
File Name: NANDFILE.C
Last Modified Date: 2001/03/21
Programmer: MSC
Compiler:
Platform:
Usage:
File API for NAND FFS
Other Information:
**************************************************************/
#include <sys/syscall.h>
#include <ansi_c/stdio.h>
/**** added by chilong 01/19/2002 ****/
//#include "nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif
/**** added by chilong 01/19/2002 ****/
//#include "../../rDebug/rdebug.h"
//#include "../../rDebug/include/rdebug.h"
#include "ffs_nand/include/FFS_NAND.h"
#include "ffs_nand/include/NANDfblk.h"
#include "ffs_nand/include/NANDlump.h"
//**************************** jason
#define FILE_COU 30
#define FILE_LEN 30
extern unsigned char dir_file[FILE_COU][FILE_LEN] ;
extern unsigned short file_index ;
extern unsigned short file_end ;
//********************************************* jason
#define ERROR_FILE_SYSTEM_NOT_INIT 0x90
#define ERROR_ALLOC_MEM 0x91
#define ERROR_NO_HANDLE_AVAIL 0x92
#define ERROR_DIR_ALREADY_EXIST 0x93
#define ERROR_FILE_SYSTEM_NOT_INIT 0x94
#define ERROR_INVALID_HANDLE 0x95
#define ERROR_DIR_NOT_EXIST 0x96
#define ERROR_FILE_NOT_EXIST 0x97
#define ERROR_DIR_NOT_EMPTY 0x98
#define ERROR_PATHNAME_TOO_LONG 0x99
#define ERROR_WAIT_SEMAPHORE 0xa0
#define ERROR_ALLOC_LUMP 0xa1
#define ERROR_FILE_FLAG 0xa2
//*********************************************
#ifdef NAND_FLASH_DISK_ID
struct NAND_FFS_FILE **NAND_FFS_HandleTable;
int NAND_FFS_CurrentHandle;
/* marked by chilong 01/25/2002
unsigned char *NAND_LumpBuf1;
unsigned char *NAND_LumpBuf2;
marked by chilong 01/25/2002 */
extern unsigned long real_flash_block_num ;
// FFS_NAND.c
extern char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];
extern int NAND_FFS_SemaphoreID;
extern int NAND_FFS_Init_OK;
/**** added by chilong 01/18/2002 ****/
extern int NAND_FFS_rootLumpNo;
/**** added by chilong 01/18/2002 ****/
/**** added by chilong 01/19/2002 ****/
extern char NAND_FFS_lumpMapTable[NAND_FFS_BLOCK_NUM * NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE / 8];
/**** added by chilong 01/19/2002 ****/
#ifdef NAND_FFS_USE_CACHE
extern unsigned char *NAND_FFS_BlockCache[NAND_FFS_CACHE_BLOCK_NUM];
#endif
// NANDlump.c
extern unsigned long NAND_LumpNum;
extern unsigned long NAND_TotalLumpNum;
/**** added by chilong 12/24/2001 ****/
//char NAND_FFS_DebugString[80];
/**** added by chilong 12/24/2001 ****/
/*************************************************************
External functions
*************************************************************/
#ifndef __WIN32__
extern void memoryZero(void *source, unsigned int size);
#endif
extern struct dLinkList *tcbSearch(threadID searchID);
/*************************************************************
Function: NAND_FFS_open
Description:
open an existing file in the simple flash storage system
Input:
name the target file
flag open flags
Output:
file handle
-1 failure
**************************************************************/
int NAND_FFS_open(unsigned char *name, int flag)
{
int returnValue;
if (NAND_FFS_Init_OK == FALSE)
{
NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
return -1;
}
NAND_FFS_Errno = 0;
sc_waitSemaphore(NAND_FFS_SemaphoreID);
returnValue = NAND_FFS_open_r(name, flag);
sc_signalSemaphore(NAND_FFS_SemaphoreID);
return returnValue;
}
int NAND_FFS_open_r(unsigned char *string, int flag)
{
struct NAND_FFS_FILE *pfile;
int result;
int availHandler;
unsigned char attrib;
/*
#ifdef NAND_FFS_DEBUG
struct NAND_diskLump *curLump;
unsigned char *pData;
int i;
#endif
*/
// initialize the file's structure
pfile = (struct NAND_FFS_FILE *)ap_malloc(sizeof(struct NAND_FFS_FILE));
if (pfile == NULL)
{
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
memoryZero((void *)pfile, (unsigned int)sizeof(struct NAND_FFS_FILE));
availHandler = findFreeHandle();
pfile->handle = availHandler;
NAND_FFS_HandleTable[availHandler] = pfile;
if (availHandler == -1)
{
ap_free(pfile);
NAND_FFS_Errno = ERROR_NO_HANDLE_AVAIL;
return -1;
}
// initialize some values before searching the file
pfile->subDirLumpNo = NAND_END_LUMP;
pfile->nThDirEntry = NAND_END_LUMP;
result = NAND_FFS_fileSearch(pfile, string);
pfile->fileFlag = flag;
// If the file does not exist, create it if O_CREATE is set
if (result == -1)
{
if ((flag & O_CREATE) != O_CREATE)
{
// file not found and the O_CREATE flag is off
ap_free(pfile);
NAND_FFS_HandleTable[availHandler] = NULL;
return -1;
}
else
{
attrib = DA_ARCHIVE;
result = NAND_FFS_fileCreate(pfile, string, attrib);
if (result == -1)
{
ap_free(pfile);
NAND_FFS_HandleTable[availHandler] = NULL;
return -1;
}
}
}
else
{
// name found, check if it is a file
if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
{
// this is a directory, cannot open
NAND_FFS_Errno = ERROR_DIR_ALREADY_EXIST;
ap_free(pfile);
NAND_FFS_HandleTable[availHandler] = NULL;
return -1;
}
// file found, open it
if ((flag & O_TRUNC) == O_TRUNC)
{
// truncate the file
(pfile->dirEntry).fsize = 0;
NAND_FFS_freeCurrentLumps(pfile->dirEntry.startLump);
NAND_FFS_freeLumpLink(pfile->dirEntry.startLump);
pfile->dirEntry.startLump = NAND_END_LUMP;
}
else if ((flag & O_APPEND) == O_APPEND)
pfile->fpos = (pfile->dirEntry).fsize;
}
pfile->deviceID = NAND_FLASH_DISK_ID;
pfile->currentLump = NAND_END_LUMP;
pfile->ownerID = sc_getThreadID();
pfile->fDupFromHandle = -1;
return(availHandler);
}
/*************************************************************
Function: NAND_FFS_close
Description:
close a file in the simple flash storage system
Input:
handle the target file handle
Output:
0 no error
-1 error
**************************************************************/
int NAND_FFS_close(int handle)
{
if (NAND_FFS_Init_OK == FALSE)
{
NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
return -1;
}
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_close] handle=%d, *handle=%d", handle, *((int *)NAND_FFS_HandleTable[handle]));
SprintStringLn(NAND_FFS_DebugString);
#endif
if ((handle < 0) || (handle >= MAX_OPEN_FILE) || (NAND_FFS_HandleTable[handle] == NULL))
{
NAND_FFS_Errno = ERROR_INVALID_HANDLE;
return -1;
}
if (NAND_FFS_HandleTable[handle]->deviceID != NAND_FLASH_DISK_ID)
{
NAND_FFS_Errno = ERROR_INVALID_DEVICE;
return -1;
}
NAND_FFS_Errno = 0;
sc_waitSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_close_r(NAND_FFS_HandleTable[handle]);
NAND_FFS_HandleTable[handle] = NULL;
sc_signalSemaphore(NAND_FFS_SemaphoreID);
return 0;
}
void NAND_FFS_close_r(struct NAND_FFS_FILE *pfile)
{
#ifdef NAND_FFS_DEBUG
#ifdef NAND_FFS_USE_CACHE
NAND_FFS_showCacheStatus();
#endif
#endif
#ifdef NAND_FFS_USE_CACHE
#ifdef NAND_FFS_DEBUG
// if (NAND_FFS_flushCacheByHandle(pfile->handle) == -1)
if (NAND_FFS_flushAllCache() == -1)
{
sprintf(NAND_FFS_DebugString, " flush failed! NAND_FFS_Errno=0x%x", NAND_FFS_Errno);
SprintStringLn(NAND_FFS_DebugString);
}
#else
// NAND_FFS_flushCacheByHandle(pfile->handle);
NAND_FFS_flushAllCache();
#endif
#endif
sc_free(pfile);
return;
}
/*************************************************************
Function: NAND_FFS_remove
Description:
delete an existing file
Input:
dirname - full path name
Output:
0: Success
-1: Failure
**************************************************************/
int NAND_FFS_remove(unsigned char *dirname)
{
int status;
if (NAND_FFS_Init_OK == FALSE)
{
NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
return -1;
}
NAND_FFS_Errno = 0;
sc_waitSemaphore(NAND_FFS_SemaphoreID);
status = NAND_FFS_killEntry(dirname, 0);
sc_signalSemaphore(NAND_FFS_SemaphoreID);
return status;
}
int NAND_FFS_killEntry(unsigned char *dirname, unsigned char attribute)
{
struct NAND_FFS_FILE *pfile;
struct NAND_diskLump *curLump;
struct NAND_directory *curEntry;
int result;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_killEntry] dirname: %s, attribute: %x",
dirname, attribute);
SprintString(NAND_FFS_DebugString);
#endif
// initialize the file's structure
pfile = (struct NAND_FFS_FILE *)ap_malloc(sizeof(struct NAND_FFS_FILE));
if (pfile == NULL)
{
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
memoryZero((void *)pfile, (unsigned int)sizeof(struct NAND_FFS_FILE));
// initialize some values before searching the file
pfile->subDirLumpNo = NAND_END_LUMP;
pfile->nThDirEntry = NAND_END_LUMP;
result = NAND_FFS_fileSearch(pfile, dirname);
if (result == 0)
{
// name found, check attribute (file or directory)
if (attribute == DA_DIR)
{
// trying to rmdir, check the attribute of the entry
if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
{
// the entry is actually a directory, check if it is empty
if (NAND_FFS_isDirEmpty((pfile->dirEntry).startLump) != 0)
{
#ifdef NAND_FFS_DEBUG
SprintStringLn("[NAND_FFS_killEntry]: pfile->Entry is not empty");
#endif
// not empty, can't remove
NAND_FFS_Errno = ERROR_DIR_NOT_EMPTY;
ap_free(pfile);
result = -1;
}
}
else
{
#ifdef NAND_FFS_DEBUG
SprintStringLn("[NAND_FFS_killEntry]: pfile->Entry is not a dir");
#endif
// the entry is a file, it is not a directory!
NAND_FFS_Errno = ERROR_DIR_NOT_EXIST;
ap_free(pfile);
result = -1;
}
}
else
{
// trying to remove a file, check the attribute of the entry
if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
{
// the entry is a directory, it is not a file!
NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
ap_free(pfile);
result = -1;
}
// we can't remove the file if it's being open by another user
if (NAND_FFS_isFileOpened(pfile) == 1)
{
// NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
ap_free(pfile);
result = -1;
}
}
if (result == 0)
{
// no problem found, delete the entry
printf("{Free Lump=%d}",(pfile->dirEntry).startLump); // jason
NAND_FFS_freeLumpLink((pfile->dirEntry).startLump);
if (NAND_FFS_readLump(pfile->subDirLumpNo, (unsigned char**)&curLump) == -1)
{
ap_free(pfile);
return -1;
}
curEntry = (struct NAND_directory *) ((unsigned long) curLump +
sizeof(struct NAND_diskLump) +
pfile->nThDirEntry * sizeof(struct NAND_directory));
curEntry->name[0] = DELETED_ENTRY;
printf("{Sub Lump=%d}", pfile->subDirLumpNo);
if (NAND_FFS_writeLump(pfile->subDirLumpNo, (unsigned char*)curLump) == -1)
{
ap_free(pfile);
return -1;
}
NAND_FFS_Errno = 0;
}
}
else
{
if (attribute == DA_DIR)
NAND_FFS_Errno = ERROR_DIR_NOT_EXIST;
else
NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
}
ap_free(pfile);
return result;
}
/*************************************************************
Function: NAND_FFS_isDirEmpty
Description:
check if a directory is empty
Input:
startBlock - the starting block of the directory
Output:
0: empty
-1: not empty
**************************************************************/
int NAND_FFS_isDirEmpty(int startLumpNo)
{
struct NAND_diskLump *curLump;
struct NAND_directory *curEntry;
long i;
int curLumpNo;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_isDirEmpty] startLumpNo: %d", startLumpNo);
SprintStringLn(NAND_FFS_DebugString);
#endif
curLumpNo = startLumpNo;
if (NAND_checkLump(curLumpNo) == -1)
{
// invalid block location
NAND_FFS_Errno = ERROR_FILE_SYSTEM;
return -1;
}
if (NAND_FFS_readLump(curLumpNo, (unsigned char**)&curLump) == -1)
return -1;
for (;;)
{
curEntry = (struct NAND_directory *)((unsigned long)curLump + sizeof(struct NAND_diskLump));
// compare the entries in this cluster
for (i = 0; i < NAND_LUMP_SIZE; i += sizeof(struct NAND_directory))
{
if (curEntry->name[0] == NAND_FREE_ENTRY)
{
// it is a free entry, the end has been reached and nothing in this dir
return 0;
}
if ((unsigned char)(curEntry->name[0]) != (unsigned char)DELETED_ENTRY)
{
// not deleted entry nor free entry ==> not empty
return -1;
}
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_isDirEmtry] curEntry->name: %s", curEntry->name);
SprintStringLn(NAND_FFS_DebugString);
#endif
curEntry = (struct NAND_directory *)((unsigned long)curEntry + sizeof(struct NAND_directory));
}
curLumpNo = curLump->nextLump;
if (curLumpNo == NAND_END_LUMP)
return 0;
if (NAND_checkLump(curLumpNo) == -1)
{
// invalid block location
NAND_FFS_Errno = ERROR_FILE_SYSTEM;
return -1;
}
if (NAND_FFS_readLump(curLumpNo, (unsigned char**)&curLump) == -1)
return -1;
}
return 0;
}
/*************************************************************
Function: NAND_FFS_isFileOpened
Description:
check if the file is being opened above twice
Input:
pfile
Output:
1: open
0: not open
**************************************************************/
int NAND_FFS_isFileOpened(struct NAND_FFS_FILE *pfile)
{
int i;
if (pfile == NULL)
return 0;
if (pfile->deviceID != NAND_FLASH_DISK_ID)
return 0;
for (i = 0; i < MAX_OPEN_FILE; i++)
{
if (NAND_FFS_HandleTable[i] != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -