flashmngl05.c
来自「好记星的控件,包括button,list,对文件操作」· C语言 代码 · 共 1,671 行 · 第 1/5 页
C
1,671 行
/************************************************************************************/
/* */
/* 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 */
/************************************************************************************/
//#define __OS_SOURCE_FILE__//
/* 包含所需头文件 */
#include "Kernel.h"
#include "FlsMngInL05.h"
//#include "SysWatch.h"
#define FLASH__MNG_MEMALLOC_OPT 1 // optimize memalloc when init
#define FLASH__MNG_NOUSE_REMOVE 1 // remove no used function
#define FLASH__MNG_OPTIMIZE 1 // Disable callback for display when create table
#ifdef FLASH__MNG_OPTIMIZE
//#define FLASH_TEST 1
#define FLASH_CREATE_CALLBACK 1 // DennyHan added this @2006-5-25
#endif
// global variable
NU_DRIVER* g_pFlashDriver; // Flash device handle
PNFLASH_PARAMETER g_pFlashParam; // pointer to the Nand flash parameter of the current machine
UINT8* g_pFlashBuf; // buffer for read and write data[page size + spare size]
UINT8* g_pFlashDataBuf; // always pointer to g_FlashBuf
UINT8* g_pFlashSpareBuf; // always pointer to g_FlashBuf + page size
UINT8* g_pFlashOnlyBuf;
UINT8* g_pFlashOnlyDataBuf;
UINT8* g_pFlashOnlySpareBuf;
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; // Flash Log2Phy Table
UINT16* g_FlashTablePrepare; // prepare block table
UINT16* g_FlashTableBad; // 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
// functions define
INT FlashMngBlockUpdate(void);
int dead(void)
{
while(1){
#ifndef _WIN32
asm("nop");
#endif
}
return 0;
}
/********************************************************************************/
/* FUNCTION: FlashMngResetDriver */
/* DESCRIPTION:Reset flash device and ECC module */
/* INPUTS: */
/* OUTPUTS: */
/* RETURN: NFLS_ERR_DRIVER nucleus driver manager error */
/* return from flash driver */
/********************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==================================================*/
/* Victor 2005-05-09 create */
/********************************************************************************/
INT FlashMngResetDriver(void)
{
NU_DRIVER_REQUEST request;
request.nu_function = NU_STATUS;
request.nu_supplemental = FLASH_IO_RESET;
request.nu_request_info.nu_status.nu_extra_status = (VOID *)0;
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: 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;
INT errorFlag;
errorFlag = 0;
Read_Retry:
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_ECC ||request.nu_status == NFLS_ERR_TIMEOUT){
if(errorFlag == 0){
FlashMngResetDriver();
errorFlag = 1;
goto Read_Retry;
}
}
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;
INT errorFlag;
errorFlag = 0;
Write_Retry:
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_TIMEOUT){
if(errorFlag == 0){
FlashMngResetDriver();
errorFlag = 1;
goto Write_Retry;
}
}
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;
INT errorFlag;
errorFlag = 0;
Erase_Retry:
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;
}
if(request.nu_status == NFLS_ERR_TIMEOUT){
if(errorFlag == 0){
FlashMngResetDriver();
errorFlag = 1;
goto Erase_Retry;
}
}else{
return request.nu_status;
}
// dennyhan added for return entries
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_pFlashParam->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_pFlashParam->uBlockSum; i ++)
{
// read block spare
retVal = FlashMngReadDriver(FLASH_IO_ONLYSPARE,
i * g_pFlashParam->uDataPerBlock,
g_pFlashSpareBuf, g_pFlashParam->uSparePerPage);
if (retVal != (INT)g_pFlashParam->uSparePerPage)
{
return retVal;
}
// process according to the attribute of this block
attribute = BLOCK_ATTRIBUTE(g_pFlashSpareBuf);
// this block is a good block
if (attribute == FLASH_ATTRIBUTE_GOOD)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?