flashmng.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,302 行 · 第 1/5 页
C
1,302 行
/************************************************************************************/
/* */
/* Copyright (C) 2005 SHENZHEN MEIJIN CO.LTD */
/* */
/* FILE NAME: FlashMng.C */
/* MODULE NAME: Nand Flash Manager Modul */
/* */
/************************************************************************************/
/* DATE AUTHOR VERSION REMARKS */
/* =========== =========== ========= =============================================*/
/* 2005-05-07 Victor Ver 1.00 Just for 2K-page 128M nand flash */
/* memory dynamic allocation is not supported */
/************************************************************************************/
#include "Kernel.h"
#include "FlsMngIn.h"
#ifdef _WIN32 // Dennyhan added this for PC
// because PC use it, and L05 used L05\FlashMng
INT FlashMngBlockUpdate(void); // 2005.10.21谢永良增加 为清除警告信息
//#define FLASH_TEST 1
#ifdef FLASH_TEST
UINT8 g_FlashTestBuf[CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE];
// buffer for read and write data
UINT8* g_pFlashTestDataBuf; // always pointer to &g_FlashBuf[0]
UINT8* g_pFlashTestSpareBuf; // always pointer to &g_FlashBuf[CURRENT_PAGE_SIZE]
//#define FLASH_PHY_TEST 1
#define FLASH_LOG_TEST 1
//#define FLASH_TOTAL_TEST 1
#endif
// global variable
UINT g_multiTest; // test multi-task
NU_DRIVER* g_pFlashDriver; // Flash device handle
PNFLASH_PARAMETER g_pFlashPara; // pointer to the Nand flash parameter of the current machine
UINT8 g_FlashBuf[CURRENT_PAGE_SIZE + CURRENT_SPARE_SIZE];
// buffer for read and write data
UINT8* g_pFlashDataBuf; // always pointer to &g_FlashBuf[0]
UINT8* g_pFlashSpareBuf; // always pointer to &g_FlashBuf[CURRENT_PAGE_SIZE]
UINT8 g_pFlashOnlySpareBuf[CURRENT_SPARE_SIZE];
INT g_FlashPhyNum0; // current block's origin physical number
INT g_FlashPhyNum1; // current block's swap physical number
INT g_FlashPageOffset; // current page offset in current block
BOOL g_FlashModify; // if TRUE then need write to flash
BOOL g_FlashDirty; // if TRUE then need swap to swap block
UINT32 g_uSwapingBlockPhy;
UINT32 g_uSwapingBlockLog;
UINT32 g_uSwapBlockPhy;
UINT32 g_uSwapBlockLog;
UINT16 g_FlashTableLog2Phy[BLOCK_NUM]; // Flash Log2Phy Table
UINT16 g_FlashTablePrepare[PREPARE_BLOCK_NUM]; // prepare block table
UINT16 g_FlashTableBad[BAD_BLOCK_NUM]; // bad block tabel
UINT g_uFlashBlockUser; // user available block number
UINT g_uFlashBlockPrepare; // system available swap block number
UINT g_uFlashBlockBadUser; // bad block number
UINT g_uFlashBlockBadNature; // bad block number
/********************************************************************************/
/* FUNCTION: FlashMngReadDriver */
/* DESCRIPTION:read data from flash */
/* INPUTS: type FLASH_IO_DATASPARE:read data and spare */
/* FLASH_IO_ONLYDATA:just read data */
/* FLASH_IO_ONLYSPARE:just read spare */
/* linearAdd linear address of the flash */
/* dwLen read data length */
/* OUTPUTS: pBuf data read from flash */
/* RETURN: >=0 fact read data length */
/* NFLS_ERR_DRIVER nucleus driver manager error */
/* return from flash driver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngReadDriver(UINT type, UINT32 linearAdd, UINT8* pBuff, UINT32 dwLen)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_INPUT;
request.nu_supplemental = type;
request.nu_request_info.nu_input.nu_offset = linearAdd;
request.nu_request_info.nu_input.nu_request_size = dwLen;
request.nu_request_info.nu_input.nu_buffer_ptr = pBuff;
request.nu_request_info.nu_status.nu_logical_unit = 0;
if(NU_Request_Driver(g_pFlashDriver, &request) != NU_SUCCESS){
return NFLS_ERR_DRIVER;
}
if(request.nu_status != NFLS_ERR_NO)
return request.nu_status;
else
return dwLen;
}
/********************************************************************************/
/* FUNCTION: FlashMngWriteDriver */
/* DESCRIPTION:write data to flash */
/* INPUTS: type FLASH_IO_DATASPARE:write data and spare */
/* FLASH_IO_ONLYDATA:just write data */
/* FLASH_IO_ONLYSPARE:just write spare */
/* linearAdd linear address of the flash */
/* pBuf content of the data */
/* dwLen write data length */
/* OUTPUTS: */
/* RETURN: >=0 fact write data length */
/* NFLS_ERR_DRIVER nucleus driver manager error */
/* return from flash driver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngWriteDriver(UINT type, UINT32 linearAdd, UINT8* pBuff, UINT32 dwLen)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_OUTPUT;
request.nu_supplemental = type;
request.nu_request_info.nu_input.nu_offset = linearAdd;
request.nu_request_info.nu_input.nu_request_size = dwLen;
request.nu_request_info.nu_input.nu_buffer_ptr = pBuff;
request.nu_request_info.nu_status.nu_logical_unit = 0;
if(NU_Request_Driver(g_pFlashDriver, &request) != NU_SUCCESS){
return NFLS_ERR_DRIVER;
}
if(request.nu_status != NFLS_ERR_NO)
return request.nu_status;
else
return dwLen;
}
/********************************************************************************/
/* FUNCTION: FlashMngEraseDriver */
/* DESCRIPTION:erase one block of flash */
/* INPUTS: linearAdd linear address of the flash */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_DRIVER nucleus driver manager error */
/* return from flash driver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngEraseDriver(UINT32 linearAdd)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_STATUS;
request.nu_supplemental = FLASH_IO_ERASEBLK;
request.nu_request_info.nu_status.nu_extra_status = (VOID *)linearAdd;
request.nu_request_info.nu_status.nu_logical_unit = 0;
if(NU_Request_Driver(g_pFlashDriver, &request) != NU_SUCCESS){
return NFLS_ERR_DRIVER;
}
return request.nu_status;
}
/********************************************************************************/
/* FUNCTION: FlashMngGetDriver */
/* DESCRIPTION:get flash parameter */
/* INPUTS: linearAdd linear address of the flash */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_DRIVER nucleus driver manager error */
/* return from flash driver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngGetDriver(PNFLASH_PARAMETER* ppFlashParam)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_STATUS;
request.nu_timeout = NU_NO_SUSPEND;
request.nu_supplemental = FLASH_IO_GETPARAM;
request.nu_request_info.nu_status.nu_logical_unit = 0;
if(NU_Request_Driver(g_pFlashDriver, &request) != NU_SUCCESS){
return NFLS_ERR_DRIVER;
}
*ppFlashParam = (PNFLASH_PARAMETER)(request.nu_request_info.nu_status.nu_extra_status);
return request.nu_status;
}
/********************************************************************************/
/* FUNCTION: FlashMngTableRead */
/* DESCRIPTION:Read logical block number from physical block, establish the */
/* table of contrast between logical block and physical block. then*/
/* check validity of the table. */
/* INPUTS: */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_NO ok */
/* NFLS_ERR_FORMAT format error, need format */
/* NFLS_ERR_NOSPACE bad blocks are too many to use */
/* return from FlashMngReadDriver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngTableRead(void)
{
UINT i;
INT retVal;
UINT8 attribute;
UINT16 status;
// initial global variable
memset((VOID *)(g_FlashTableLog2Phy), 0xFF, g_pFlashPara->uUserBlockNum * sizeof(UINT16));
g_uFlashBlockUser = 0;
g_uFlashBlockPrepare = 0;
g_uFlashBlockBadUser = 0;
g_uFlashBlockBadNature = 0;
g_uSwapingBlockPhy = 0xffff;
g_uSwapingBlockLog = 0xffff;
g_uSwapBlockPhy = 0xffff;
g_uSwapBlockLog = 0xffff;
// read logical number of physical block, establish contrast table
for(i = FLASH_RESERVE_BLOCK; i < g_pFlashPara->uBlockSum; i ++){
// read block spare
if((retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE, i*g_pFlashPara->uDataPerBlock,
g_pFlashSpareBuf, CURRENT_SPARE_SIZE)) != CURRENT_SPARE_SIZE){
return retVal;
}
// process according to the attribute of this block
attribute = BLOCK_ATTRIBUTE(g_pFlashSpareBuf);
if(attribute == FLASH_ATTRIBUTE_GOOD){ // this block is a good block
// process according to the status of this block
status = BLOCK_STATUS(g_pFlashSpareBuf);
switch(status){
case FLASH_STATUS_ORG: // the block is a org block. establish contrast table.
if(BLOCK_LOGIC(g_pFlashSpareBuf) >= g_pFlashPara->uUserBlockNum){
return NFLS_ERR_FORMAT; // illegal logical number
}
if(g_FlashTableLog2Phy[BLOCK_LOGIC(g_pFlashSpareBuf)] != 0xffff){
return NFLS_ERR_FORMAT; // It's impossible
}
g_FlashTableLog2Phy[BLOCK_LOGIC(g_pFlashSpareBuf)] = i;
g_uFlashBlockUser ++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?