📄 nandfblk.c
字号:
/*************************************************************
File Name: NANDfblk.c
Last Modified Date: 2001/03/20
Programmer: MSC
Compiler:
Platform:
Usage:
NAND Flash block functions.
Other Information:
**************************************************************/
#include <sys/syscall.h>
//#include "../../rDebug/rdebug.h"
//#include "../../nflash/include/nflash.h"
//#include "nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif
//#include "../../rDebug/include/rdebug.h"
#include "../include/FFS_NAND.h"
#include "../include/NANDfdrv.h"
#include "../include/NANDlump.h"
#include "../include/NANDfblk.h"
#ifdef NAND_FLASH_DISK_ID
#ifdef NAND_FFS_DEBUG
#include <ansi_c/stdio.h>
#endif
// FFS_NAND.c
extern char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];
extern unsigned long *NAND_FFS_ReadCount;
extern unsigned long *NAND_FFS_EraseCount;
extern unsigned long *NAND_FFS_ProgramCount;
// marked by chilong 01/14/2002
//extern unsigned char *NAND_FlashAccessBuffer;
extern unsigned char *NAND_FlashAccessBuffer1;
extern unsigned char *NAND_FlashAccessBuffer2;
#ifdef NAND_FFS_USE_CACHE
extern struct NAND_FFS_cacheInfo **NAND_FFS_CacheStatus;
extern unsigned char **NAND_FFS_BlockCache;
#endif
// NANDfile.c
extern int NAND_FFS_CurrentHandle;
// NANDlump.c
extern unsigned long NAND_LumpNum;
extern unsigned long NAND_TotalLumpNum;
/**** added by chilong 01/24/2002 ****/
#ifdef NAND_FFS_CACHE_DEBUG
unsigned long numReadHit; /* ATA read hit count */
unsigned long numReadMiss; /* ATA read miss count */
unsigned long numWriteHit; /* ATA write hit count */
unsigned long numWriteMiss; /* ATA write miss count */
unsigned long numSwap; /* ATA cache swap count */
unsigned long numFlush; /* ATA cache flush count */
#endif
/**** added by chilong 01/24/2002 ****/
/*************************************************************
Function: NAND_FFS_readFlashBlock
Description:
program the flash block
Input:
block - the flash block number
pData - the buffer
Output:
0 succeeded
-1 failed
**************************************************************/
int NAND_FFS_readFlashBlock(int block, unsigned char *pData)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_readFlashBlock] block = %d", block);
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_ReadCount[block]++;
if (NAND_FFS_fshBlockRead(block + NAND_FFS_START_BLOCK, pData) == 0)
{
return 0;
}
else
{
NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
return -1;
}
}
/*************************************************************
Function: NAND_FFS_eraseFlashBlock
Description:
erase the flash block
Input:
block - the flash block number
Output:
0 succeeded
-1 failed
**************************************************************/
int NAND_FFS_eraseFlashBlock(int block)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "Erase block %d", block);
SprintStringLn(NAND_FFS_DebugString);
#endif
/*
if ((NAND_FFS_EraseCount[block] & (~NAND_BLOCK_FULL_BIT_MASK)) == 0x7FFFFFFF)
{
// the count reaches 0x7FFFFFFF, set the count to zero but keep the full bit
// actually, it is quite impossible to reach here since the block will be broken if
// it has been program/erase 100000 times.
NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] & NAND_BLOCK_FULL_BIT_MASK;
}
else
{
if ((NAND_FFS_EraseCount[block] & NAND_BLOCK_FULL_BIT_MASK) == NAND_BLOCK_FULL_BIT_MASK)
{
// full bit set
// remove the full bit, increase the erase count, and then set the full bit
NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] & (~NAND_BLOCK_FULL_BIT_MASK);
NAND_FFS_EraseCount[block]++;
NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | ~NAND_BLOCK_FULL_BIT_MASK;
}
else
{
// full bit is not set, just increase the erase count
NAND_FFS_EraseCount[block]++;
}
}
*/
NAND_FFS_EraseCount[block]++;
if (NAND_FFS_fshBlockErase(block + NAND_FFS_START_BLOCK) == 0)
{
return 0;
}
else
{
NAND_FFS_Errno = ERROR_FLASH_BLOCK_ERASE;
return -1;
}
}
/*************************************************************
Function: NAND_FFS_programFlashBlock
Description:
program the flash block
Input:
block - the flash block number
pData - the buffer
Output:
0 succeeded
-1 failed
**************************************************************/
int NAND_FFS_programFlashBlock(int block, unsigned char *pData)
{
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "Program block %d", block);
SprintStringLn(NAND_FFS_DebugString);
#endif
NAND_FFS_ProgramCount[block]++;
if (NAND_FFS_fshBlockProgram(block + NAND_FFS_START_BLOCK, pData) == 0)
{
return 0;
}
else
{
NAND_FFS_Errno = ERROR_FLASH_BLOCK_PROGRAM;
return -1;
}
}
/*************************************************************
Function: NAND_FFS_readBlock
Description:
read a flash block to buffer
Input:
block - the flash block number
pData - the pointer to address of the buffer
// chilong: 01/14/2002
bUseBuf2 - the flag to tell if FlashAccessBuffer1 or
FlashAccessBuffer2 will be used
Output:
0 succeeded
-1 failed
Note:
The pointer to the address of the buffer is used to
reduce data copying.
Users can regard this function to own an internal buffer.
The content of the target block are copied to the buffer
and the pointer of the buffer is returned to the caller
via a parameter.
**************************************************************/
/**** modified by chilong 01/14/2002 ****/
int NAND_FFS_readBlock(int block, unsigned char **pData, int bUseBuf2)
{
#ifdef NAND_FFS_USE_CACHE
int cacheNum;
#endif
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_readBlock] block = %d", block);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (NAND_FFS_checkBlock(block) == -1)
{
NAND_FFS_Errno = ERROR_INVALID_BLOCK;
return -1; // invalid block
}
#ifdef NAND_FFS_USE_CACHE
// cache present
// swap the block into the cache
// the swap function will automatically check if the block is already in cache,
// and swap the new block into block if necessary
/* marked by chilong 01/24/2002
cacheNum = NAND_FFS_putBlockInCache(block, 1);
if (cacheNum > -1)
{
*pData = NAND_FFS_BlockCache[cacheNum];
return 0;
}
else
{
// errno set by NAND_FFS_putBlockInCache()
return -1;
}
marked by chilong 01/24/2002 */
/**** modified by chilong 01/24/2002 ****/
cacheNum = NAND_FFS_searchBlockInCache(block);
if (cacheNum > -1)
{
#ifdef NAND_FFS_CACHE_DEBUG
numReadHit++;
#endif
*pData = NAND_FFS_BlockCache[cacheNum];
return 0;
}
else
{
if (bUseBuf2)
{
if (NAND_FFS_readFlashBlock(block, NAND_FlashAccessBuffer2) != -1)
{
*pData = NAND_FlashAccessBuffer2;
return 0;
}
else
{
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
}
else
{
if (NAND_FFS_readFlashBlock(block, NAND_FlashAccessBuffer1) != -1)
{
*pData = NAND_FlashAccessBuffer1;
return 0;
}
else
{
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
}
}
/**** modified by chilong 01/24/2002 ****/
#else
/* marked by chilong 01/14/2002
// no cache present, read from flash
if (NAND_FFS_readFlashBlock(block, NAND_FlashAccessBuffer) != -1)
{
*pData = NAND_FlashAccessBuffer;
return 0;
}
else
{
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
marked by chilong 01/14/2002 */
/**** modified by chilong 01/14/2002 ****/
if (bUseBuf2)
{
if (NAND_FFS_readFlashBlock(block, NAND_FlashAccessBuffer2) != -1)
{
*pData = NAND_FlashAccessBuffer2;
return 0;
}
else
{
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
}
else
{
if (NAND_FFS_readFlashBlock(block, NAND_FlashAccessBuffer1) != -1)
{
*pData = NAND_FlashAccessBuffer1;
return 0;
}
else
{
// errno set by NAND_FFS_readFlashBlock()
return -1;
}
}
/**** modified by chilong 01/14/2002 ****/
#endif
}
/**** modified by chilong 01/14/2002 ****/
/*************************************************************
Function: NAND_FFS_writeBlock
Description:
read a flash block to buffer
Input:
block - the flash block number
pData - the buffer
Output:
0 succeeded
-1 failed
**************************************************************/
int NAND_FFS_writeBlock(int block, unsigned char *pData)
{
#ifdef NAND_FFS_USE_CACHE
int *src;
int *des;
int i;
int cacheNum;
#endif
#ifdef NAND_FFS_DEBUG
sprintf(NAND_FFS_DebugString, "[NAND_FFS_writeBlock] block = %d", block);
SprintStringLn(NAND_FFS_DebugString);
#endif
if (NAND_FFS_checkBlock(block) == -1)
{
// errno set by NAND_FFS_checkBlock()
return -1; // invalid block
}
#ifdef NAND_FFS_USE_CACHE
// cache present
// put the block into the cache
// the function will automatically check if the block is already in cache,
// and swap the new block into block if necessary
// no need to copy data from flash to cache
#ifdef NAND_FFS_CACHE_DEBUG
cacheNum = NAND_FFS_putBlockInCache(block, 1, 0);
#else
cacheNum = NAND_FFS_putBlockInCache(block, 1);
#endif
if (cacheNum > -1)
{
// block in cache, write to cache
src = (int *)pData;
des = (int *)NAND_FFS_BlockCache[cacheNum];
if (src != des)
{
for (i = 0; i < NAND_FLASH_BLOCK_SIZE; i += sizeof(int))
*des++ = *src++;
}
NAND_FFS_modifyCache(cacheNum);
return 0;
}
else
{
// errno set by NAND_FFS_putBlockInCache()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -