📄 ffs_nand.c
字号:
/*************************************************************
File Name: FFS_NAND.C
Last Modified Date: 2001/03/20
Programmer: MSC
Compiler:
Platform:
Usage:
NAND Flash File System
Unfinished functions:
NAND_FFS_scanDisk()
NAND_FFS_defrag()
**************************************************************/
#include <sys/syscall.h>
//#include "../../rDebug/rdebug.h"
//#include "../../rDebug/include/rdebug.h"
//#include "../../nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif
#include "../include/FFS_NAND.h"
#include "../include/NANDfblk.h"
#include "../include/NANDLump.h"
#ifdef NAND_FLASH_DISK_ID
#ifdef NAND_FFS_DEBUG
#ifdef __WIN32__
#include <stdio.h>
#else
#include <ansi_c/stdio.h>
#endif
#endif
// the block map
// 0 = cannot be used by FFS
// 1 = free flash block
// 2 = allocated flash block
char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];
//#ifdef __WIN32__
unsigned char pNandFSSCacheBaseAddr[16*16384+16*20];
//#endif
/**** added by chilong 01/18/2002 ****/
char NAND_FFS_lumpMapTable[NAND_FFS_BLOCK_NUM * NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE / 8];
int NAND_FFS_rootLumpNo;
int NAND_FFS_curFreeLumpNo = NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE;
/**** added by chilong 01/18/2002 ****/
// read counts for the flash blocks
unsigned long *NAND_FFS_ReadCount;
// erase counts for the flash blocks
// this counter also use to indicate whether a block is full
// if the block full bit of the count is 1, the block is full.
unsigned long *NAND_FFS_EraseCount;
// program counts for the flash blocks
unsigned long *NAND_FFS_ProgramCount;
//int FFS_FreeBegin = NAND_FFS_START_BLOCK;
// semaphore to serialize FFS accesses
int NAND_FFS_SemaphoreID;
int NAND_FFS_Init_OK = FALSE;
int NAND_FFS_Errno;
// marked by chilong 01/14/2002
//unsigned char *NAND_FlashAccessBuffer;
/**** added by chilong 01/14/2002 ****/
unsigned char *NAND_FlashAccessBuffer1;
unsigned char *NAND_FlashAccessBuffer2;
/**** added by chilong 01/14/2002 ****/
#ifdef NAND_FFS_USE_CACHE
// cache info
// struct NAND_FFS_cacheInfo *NAND_FFS_CacheStatus[NAND_FFS_CACHE_BLOCK_NUM];
// unsigned char *NAND_FFS_BlockCache[NAND_FFS_CACHE_BLOCK_NUM];
struct NAND_FFS_cacheInfo **NAND_FFS_CacheStatus;
unsigned char **NAND_FFS_BlockCache;
#endif
/*
// location of flash erase and program function in RAM
NAND_readFun NAND_FFS_read; // function pointer to the flash sector read function in RAM
NAND_eraseFun NAND_FFS_erase; // function pointer to the flash sector erase function in RAM
NAND_programFun NAND_FFS_program; // function pointer to the flash sector program function in RAM
*/
// FileSys.c
//extern short *FileSysHandleTable[MAX_OPEN_FILE];
extern short **FileSysHandleTable;
// NANDfile.c
extern struct NAND_FFS_FILE **NAND_FFS_HandleTable;
extern int NAND_FFS_CurrentHandle;
/* marked by chilong 01/25/2002
extern unsigned char *NAND_LumpBuf1;
extern unsigned char *NAND_LumpBuf2;
marked by chilong 01/25/2002 */
// NANDlump.c
extern unsigned long NAND_LumpNum;
extern unsigned long NAND_TotalLumpNum;
// jason define
unsigned long real_flash_block_num ;
/*************************************************************
Function: NAND_FFS_init
Description:
initialize the simple flash storage system
Input:
Output:
0 SUCCESS
-1 FAILURE
**************************************************************/
int NAND_FFS_init(void)
{
int i;
struct NAND_diskLump *rootLump;
int j;
#ifdef NAND_FFS_CACHE_DEBUG
long begin, end;
#endif
// unsigned long rdFuncSize, erFuncSize, prFuncSize;
// int *src;
// int *des;
// unsigned short *bootStatus;
#ifdef NAND_FFS_USE_CACHE
unsigned long base;
#endif
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_init] NAND_FFS_Init_OK=%d", NAND_FFS_Init_OK);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (NAND_FFS_Init_OK == TRUE)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " Flash disk already initialized");
SprintStringLn(NAND_FFS_DebugString);
#endif
return 0;
}
// set the flash block map
for (i = 0; i < NAND_FFS_BLOCK_NUM; i++)
NAND_FFS_Block[i] = NAND_FB_OK; // all blocks are usable and free
// set parameters
NAND_FFS_Init_OK = TRUE;
// create a semaphore for NAND FFS
NAND_FFS_SemaphoreID = sc_createSemaphore(1, 1);
if (NAND_FFS_SemaphoreID == -1)
{
NAND_FFS_Init_OK = FALSE;
NAND_FFS_Errno = ERROR_CREATE_SEMAPHORE;
return -1;
}
// prepare the access counts
NAND_FFS_ReadCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
if (NAND_FFS_ReadCount == NULL)
{
NAND_FFS_Init_OK = FALSE;
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
memoryZero(NAND_FFS_ReadCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
NAND_FFS_EraseCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
if (NAND_FFS_EraseCount == NULL)
{
sc_free(NAND_FFS_ReadCount);
NAND_FFS_Init_OK = FALSE;
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
memoryZero(NAND_FFS_EraseCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
NAND_FFS_ProgramCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
if (NAND_FFS_ProgramCount == NULL)
{
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
NAND_FFS_Init_OK = FALSE;
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
memoryZero(NAND_FFS_ProgramCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
// set the file handle table
NAND_FFS_HandleTable = (struct NAND_FFS_FILE **)FileSysHandleTable;
NAND_FFS_CurrentHandle = -1;
// initialize lump parameters
NAND_initLump();
/*
// load the erase and program functions into RAM
rdFuncSize = (unsigned long)NAND_FFS_fshBlockErase - (unsigned long)NAND_FFS_fshBlockRead;
erFuncSize = (unsigned long)NAND_FFS_fshBlockProgram - (unsigned long)NAND_FFS_fshBlockErase;
prFuncSize = (unsigned long)NAND_FFS_fshDummy - (unsigned long)NAND_FFS_fshBlockProgram;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read: %d; erase: %d; program: %d", rdFuncSize, erFuncSize, prFuncSize);
SprintStringLn(NAND_FFS_DebugString);
#endif
rdFuncSize = (((rdFuncSize - 1) >> 2) + 1) << 2;
erFuncSize = (((erFuncSize - 1) >> 2) + 1) << 2;
prFuncSize = (((prFuncSize - 1) >> 2) + 1) << 2;
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, " read: %d; erase: %d; program: %d", rdFuncSize, erFuncSize, prFuncSize);
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_erase = (NAND_eraseFun)sc_malloc(erFuncSize);
if (NAND_FFS_erase == NULL)
{
NAND_FFS_Init_OK = FALSE;
sc_free(NAND_FFS_EraseCount);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
NAND_FFS_program = (NAND_programFun)sc_malloc(prFuncSize);
if (NAND_FFS_program == NULL)
{
NAND_FFS_Init_OK = FALSE;
sc_free((void *)NAND_FFS_erase);
sc_free(NAND_FFS_EraseCount);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
// copy erase function to RAM
src = (int *)NOR_FFS_fshSectorErase;
des = (int *)NAND_FFS_erase;
for (i = 0; i < erFuncSize; i += sizeof(int))
*des++ = *src++;
// copy program function to RAM
src = (int *)NOR_FFS_fshSectorProgram;
des = (int *)NAND_FFS_program;
for (i = 0; i < prFuncSize; i += sizeof(int))
*des++ = *src++;
*/
// setup the cache
#ifdef NAND_FFS_USE_CACHE
NAND_FFS_CacheStatus = (struct NAND_FFS_cacheInfo **)sc_malloc(NAND_FFS_CACHE_BLOCK_NUM * sizeof(struct NAND_FFS_cacheInfo *));
if (NAND_FFS_CacheStatus == NULL)
{
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
NAND_FFS_Init_OK = FALSE;
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
NAND_FFS_BlockCache = (unsigned char **)sc_malloc(NAND_FFS_CACHE_BLOCK_NUM * sizeof(unsigned char *));
if (NAND_FFS_BlockCache == NULL)
{
sc_free(NAND_FFS_CacheStatus);
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
NAND_FFS_Init_OK = FALSE;
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
NAND_FFS_CacheStatus[i] = (struct NAND_FFS_cacheInfo *)(NAND_FFS_CACHE_BASE_ADDRESS + i * sizeof(struct NAND_FFS_cacheInfo));
//memset(NAND_FFS_CacheStatus[i], 0xff, sizeof(struct NAND_FFS_cacheInfo));
memoryZero(NAND_FFS_CacheStatus[i], sizeof(struct NAND_FFS_cacheInfo));
}
base = NAND_FFS_CACHE_BASE_ADDRESS + NAND_FFS_CACHE_BLOCK_NUM * sizeof(struct NAND_FFS_cacheInfo);
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
NAND_FFS_BlockCache[i] = (unsigned char *)(base + i * NAND_FLASH_BLOCK_SIZE);
//memset(NAND_FFS_BlockCache[i], 0xff, NAND_FLASH_BLOCK_SIZE);
memoryZero(NAND_FFS_BlockCache[i], NAND_FLASH_BLOCK_SIZE);
}
//memset((void *)NAND_FFS_CACHE_BASE_ADDRESS, 0xff, (16*16*1024+16*20));
#ifdef NAND_FFS_DEBUG
NAND_FFS_showCacheStatusAddress();
NAND_FFS_showCacheAddress();
#endif
// vertify the cache if warm boot
// if (queryHWStatus() == COLD_RESET)
#ifndef __WIN32__ // by zhang xue ping
if (queryHWStatus() == COLD_RESET)
#else
if(1)
#endif
{
// cold reset, clear the cache
NAND_FFS_clearAllCache();
}
else
{
// warm reset, vertify the cache
for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
{
// #ifdef NAND_FFS_DEBUG
// sprintf(NAND_FFS_DebugString, " verify cache %d", i);
// SprintStringLn(NAND_FFS_DebugString);
// #endif
if (NAND_FFS_vertifyCache(i) == -1)
{
// cache content incorrect, clear the cache
NAND_FFS_clearCache(i);
}
else
{
// cache content ok, flush the cache
if (NAND_FFS_flushCache(i) == -1)
{
// flush failed, clear the cache
NAND_FFS_clearCache(i);
}
// clear the last modification timestamp
NAND_FFS_CacheStatus[i]->lastModTime = 0;
NAND_FFS_CacheStatus[i]->handle = -1;
}
}
}
#endif
NAND_FlashAccessBuffer1 = (unsigned char *)sc_malloc(NAND_FLASH_BLOCK_SIZE);
if (NAND_FlashAccessBuffer1 == NULL)
{
NAND_FFS_Init_OK = FALSE;
#ifdef NAND_FFS_USE_CACHE
sc_free(NAND_FFS_BlockCache);
sc_free(NAND_FFS_CacheStatus);
#endif
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
NAND_FlashAccessBuffer2 = (unsigned char *)sc_malloc(NAND_FLASH_BLOCK_SIZE);
if (NAND_FlashAccessBuffer2 == NULL)
{
NAND_FFS_Init_OK = FALSE;
#ifdef NAND_FFS_USE_CACHE
sc_free(NAND_FFS_BlockCache);
sc_free(NAND_FFS_CacheStatus);
#endif
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
sc_free(NAND_FlashAccessBuffer1);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
/* marked by chilong 01/25/2002
NAND_LumpBuf1 = (unsigned char *)sc_malloc(NAND_LUMP_SIZE);
if (NAND_LumpBuf1 == NULL)
{
NAND_FFS_Init_OK = FALSE;
sc_free(NAND_FlashAccessBuffer1);
sc_free(NAND_FlashAccessBuffer2);
#ifdef NAND_FFS_USE_CACHE
sc_free(NAND_FFS_BlockCache);
sc_free(NAND_FFS_CacheStatus);
#endif
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
NAND_LumpBuf2 = (unsigned char *)sc_malloc(NAND_LUMP_SIZE);
if (NAND_LumpBuf2 == NULL)
{
NAND_FFS_Init_OK = FALSE;
sc_free(NAND_LumpBuf1);
sc_free(NAND_FlashAccessBuffer1);
sc_free(NAND_FlashAccessBuffer2);
#ifdef NAND_FFS_USE_CACHE
sc_free(NAND_FFS_BlockCache);
sc_free(NAND_FFS_CacheStatus);
#endif
sc_free(NAND_FFS_ProgramCount);
sc_free(NAND_FFS_EraseCount);
sc_free(NAND_FFS_ReadCount);
sc_deleteSemaphore(NAND_FFS_SemaphoreID);
NAND_FFS_Errno = ERROR_ALLOC_MEM;
return -1;
}
marekd by chilong 01/25/2002 */
/*
#ifdef NAND_FFS_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -