Nandflash 驱动移植 (四)
来源:互联网 发布:java web开发流程图 编辑:程序博客网 时间:2024/05/22 16:38
Nandflash驱动移植系列文章导航:
Nandflash 驱动移植 (一)
Nandflash 驱动移植 (二)
Nandflash 驱动移植 (三)
Nandflash 驱动移植 (四)
Nandflash 驱动移植 (五)
Nandflash 驱动移植 (六)
一共六篇
接着上一篇,这一篇介绍cpp部分
fmd.cpp,这里将逐个函数进行分析讲解:
// // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this sample source code is subject to the terms of the Microsoft // license agreement under which you licensed this sample source code. If // you did not accept the terms of the license agreement, you are not // authorized to use this sample source code. For the terms of the license, // please see the license agreement between you and Microsoft or, if applicable, // see the LICENSE.RTF on your install media or the root of your tools installation. // THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES. // #include <fmd.h> #include <nkintr.h> #include <oal.h> // BSP Configuration Files #include "bsp_cfg.h" #include "bsp_base_reg_cfg.h" // Base Definitions #include "s3c6410_base_regs.h" #include "s3c6410_nand.h" #include "s3c6410_syscon.h" //#include <ethdbg.h> #include "Cfnand.h" //#include <kitl.h> //#define SYNC_OP #define CHECK_SPAREECC (0) // 1 gjl #define NAND_DEBUG (0) #define NAND_BASE (0xB0200000) // PA:0x70200000 #define SYSCON_BASE (0xB2A0F000) // PA:0x7E00F000 #ifdef SYNC_OP CRITICAL_SECTION g_csNandFlash; #endif #ifdef __cplusplus // gjl extern "C" { int iSighForSlcMlc; // gjl } #endif static volatile S3C6410_NAND_REG *g_pNFConReg = NULL; static volatile S3C6410_SYSCON_REG *g_pSysConReg = NULL; #define DEBUG_WRITE_READ_EQUAL 0 #if DEBUG_WRITE_READ_EQUAL DWORD g_MECCBuf[8]; DWORD g_MECCBuf_R[8]; DWORD g_SECCBuf[2]; DWORD g_SECCBuf_R[2]; #endif extern "C" { void RdPage512(unsigned char *bufPt); void RdPage512Unalign(unsigned char *bufPt); void WrPage512(unsigned char *bufPt); void WrPage512Unalign(unsigned char *bufPt); void WrPageInfo(PBYTE pBuff); void RdPageInfo(PBYTE pBuff); } NANDDeviceInfo GetNandInfo(void) { return stDeviceInfo; }
引用头文件这部分不需要更改
1、读取Flash的ID:
/* @func DWORD | ReadFlashID | Reads the flash manufacturer and device codes. @rdesc Manufacturer and device codes. @comm @xref */ static DWORD ReadFlashID(void) { BYTE Mfg, Dev, Nouse, Infoma, Planesize; int i; NF_nFCE_L(); // Deselect the flash chip. NF_CMD(CMD_READID); // Send flash ID read command. NF_ADDR(0); for (i=0; i<10; i++) { Mfg = NF_RDDATA_BYTE(); if (Mfg == 0xEC || Mfg == 0x98) break; } Dev = NF_RDDATA_BYTE(); Nouse = NF_RDDATA_BYTE(); Infoma = NF_RDDATA_BYTE(); Planesize = NF_RDDATA_BYTE(); //RETAILMSG(1, (TEXT("[FMD:ERR] FMD_Init() : page info = 0x%08x,0x%08x,0x%08x\n"), Nouse,Infoma,Planesize)); //According to the read ID from flash, Nouse=0x14,Infoma=0xa5,planesize=0x64,the page size is 2K, block size is 256KB //there are 4096 blocks, plane num=2, plane size=4Gbit //So we should change the cfnand.h nandflash information. NF_nFCE_H(); return ((DWORD)(Mfg<<8)+Dev); }这个也不需要修改,具体请参照手册
2、flash初始化:
/* @func PVOID | FMD_Init | Initializes the Smart Media NAND flash controller. @rdesc Pointer to S3C2410 NAND controller registers. @comm @xref */ PVOID FMD_Init(LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut) { volatile DWORD nNandID; UINT8 nMID, nDID; UINT32 nCnt; BOOL bNandExt = FALSE; RETAILMSG(1, (TEXT("[FMD] ++FMD_Init() *######\r\n"))); if (pRegIn && pRegIn->MemBase.Num && pRegIn->MemBase.Reg[0]) { g_pNFConReg = (S3C6410_NAND_REG *)(pRegIn->MemBase.Reg[0]); } else { g_pNFConReg = (S3C6410_NAND_REG *)NAND_BASE; } g_pSysConReg = (S3C6410_SYSCON_REG *)SYSCON_BASE; #ifdef SYNC_OP InitializeCriticalSection(&g_csNandFlash); EnterCriticalSection(&g_csNandFlash); #endif // Configure BUS Width and Chip Select for NAND Flash g_pSysConReg->MEM_SYS_CFG &= ~(1<<12); // NAND Flash BUS Width -> 8 bit g_pSysConReg->MEM_SYS_CFG &= ~(0x1<<1); // Xm0CS2 -> NFCON CS0 // Set up initial flash controller configuration. g_pNFConReg->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4); NF_ECCTYPE_4BIT(); g_pNFConReg->NFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0); g_pNFConReg->NFSTAT = (1<<4); nNandID = ReadFlashID(); #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif nMID = (UINT8)(nNandID >> 8); nDID = (UINT8)(nNandID & 0xff); RETAILMSG(1, (TEXT("[FMD:INF] FMD_Init() : Read ID = 0x%08x\n"), nNandID)); for (nCnt = 0; astNandSpec[nCnt].nMID != 0; nCnt++) { if (nDID == astNandSpec[nCnt].nDID) { bNandExt = TRUE; break; } } if (!bNandExt) { RETAILMSG(1, (TEXT("[FMD:ERR] FMD_Init() : Unknown ID = 0x%08x\n"), nNandID)); return NULL; } NUM_OF_BLOCKS = astNandSpec[nCnt].nNumOfBlks; PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk; SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg; RETAILMSG(1, (TEXT("[FMD] FMD_Init() : NUM_OF_BLOCKS = %d\n"), NUM_OF_BLOCKS)); RETAILMSG(1, (TEXT("[FMD] FMD_Init() : PAGES_PER_BLOCK = %d\n"), PAGES_PER_BLOCK)); RETAILMSG(1, (TEXT("[FMD] FMD_Init() : SECTORS_PER_PAGE = %d\n"), SECTORS_PER_PAGE)); // gjl if(iSighForSlcMlc == 1) { NUM_OF_BLOCKS = 8192; PAGES_PER_BLOCK = 8; SECTORS_PER_PAGE = 4; } else { NUM_OF_BLOCKS = astNandSpec[nCnt].nNumOfBlks; PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk; SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg; } RETAILMSG(1, (TEXT("[FMD] --FMD_Init()\n"))); return((PVOID)g_pNFConReg); }
上面这个代码是原BSP中的,这个初始化函数里面,有些东西需要修改一下
// Set up initial flash controller configuration.
g_pNFConReg->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
这个我们对照手册看一下
NFCONF[0]必须写0,NFCONF[2]必须写1,所以最后修改为:
g_pNFConReg->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4) | (1<<2) | (0<<0);
这一句接下来,原代码中使用的是NF_ECCTYPE_4BIT(); 4bit的ECC,这里我们将使用8bit的ECC,修改为
NF_ECCTYPE_8BIT();// use 8bit ECC
原:
g_pNFConReg->NFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0);
参照手册修改为:
g_pNFConReg->NFCONT = (0<<13)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
接下来直接看到
// gjl if(iSighForSlcMlc == 1) { NUM_OF_BLOCKS = 8192; PAGES_PER_BLOCK = 8; SECTORS_PER_PAGE = 4; } else { NUM_OF_BLOCKS = astNandSpec[nCnt].nNumOfBlks; PAGES_PER_BLOCK = astNandSpec[nCnt].nPgsPerBlk; SECTORS_PER_PAGE = astNandSpec[nCnt].nSctsPerPg; }这里if中的NUM_OF_BLOCKS = 8192;这个定死了,不大好,咱改成(修改之后,可以同时兼容K9GAG08U0D 2G和K9LBG08U0D 4G的Nandflash)
NUM_OF_BLOCKS = astNandSpec[nCnt].nNumOfBlks;
到此,FMD_Init()函数就基本上搞掂了。
3、FMD_ReadSector()
/* @func BOOL | FMD_ReadSector | Reads the specified sector(s) from NAND flash. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors) { BOOL bRet; //RETAILMSG(1, (TEXT("[R:0x%08x] \n"), startSectorAddr)); #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] ++FMD_ReadSector(0x%08x) \n"), startSectorAddr)); #endif #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif if ( IS_LB ) { bRet = FMD_LB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors); } else { bRet = FMD_SB_ReadSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors); } #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] --FMD_ReadSector()\n"))); #endif return bRet; }这里我们不需要做修改,不过其中调用的FMD_LB_ReadSector()函数待会需要修改一下(FMD_LB_ReadSector()是针对Nandflash,4bit或8bit的ECC;而FMD_SB_ReadSector()是针对Norflash,1bit的ecc校验)
4、FMD_EraseBlock() 擦除块
/* @func BOOL | FMD_EraseBlock | Erases the specified flash block. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL FMD_EraseBlock(BLOCK_ID blockID) { BOOL bRet = TRUE; #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] ++FMD_EraseBlock(0x%08x) \n"), blockID)); #endif #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif if ( IS_LB ) { bRet = FMD_LB_EraseBlock(blockID); } else { bRet = FMD_SB_EraseBlock(blockID); } #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] --FMD_EraseBlock()\n"))); #endif return bRet; }
这个函数也没有什么需要修改的,其中调用到的FMD_LB_EraseBlock()待会会讲到。
5、FMD_WriteSector()
/* @func BOOL | FMD_WriteSector | Writes the specified data to the specified NAND flash sector/page. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors) { BOOL bRet = TRUE; #if DEBUG_WRITE_READ_EQUAL BYTE pSectorBuffRead[4096]; // gjl 2048 SectorInfo SectorInfoBuffRead; PSectorInfo pSectorInfoBuffRead = &SectorInfoBuffRead; BYTE *temp = (BYTE*)pSectorInfoBuff; BYTE *temp1 = (BYTE*)pSectorInfoBuffRead; UINT16 nSectorLoop,j=40; #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector(0x%08x) \n"), startSectorAddr)); #endif #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif if ( IS_LB ) { bRet = FMD_LB_WriteSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors); #if DEBUG_WRITE_READ_EQUAL FMD_LB_ReadSector(startSectorAddr, pSectorBuffRead, pSectorInfoBuffRead, dwNumSectors); for (nSectorLoop = 0; nSectorLoop < 2048; nSectorLoop++) { if(pSectorBuff[nSectorLoop] != pSectorBuffRead[nSectorLoop]) break; } RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector equal number = %x \n"), nSectorLoop)); for (nSectorLoop = 0; nSectorLoop < 8; nSectorLoop++) { if(temp1[nSectorLoop] != temp[nSectorLoop]) break; } RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector informationequal equal number = %x \n"), nSectorLoop)); RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector sector bytes:\n"))); for (nSectorLoop = 0; nSectorLoop < 2048; nSectorLoop++) { if(j--==0) { j=40; RETAILMSG(1, (TEXT("\n"))); } RETAILMSG(1, (TEXT("%x "), pSectorBuff[nSectorLoop])); } RETAILMSG(1, (TEXT("\n end\n"))); RETAILMSG(1, (TEXT("[FMD] ++FMD_ReadSector sector bytes:\n"))); for (nSectorLoop = 0; nSectorLoop < 2048; nSectorLoop++) { if(j--==0) { j=40; RETAILMSG(1, (TEXT("\n"))); } RETAILMSG(1, (TEXT("%x "), pSectorBuffRead[nSectorLoop])); } RETAILMSG(1, (TEXT("\n end\n"))); for (nSectorLoop = 0; nSectorLoop < 8; nSectorLoop++) { if(g_MECCBuf_R[nSectorLoop] != g_MECCBuf[nSectorLoop]) break; } RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector MECC data equal number = %x \n"), nSectorLoop)); for (nSectorLoop = 0; nSectorLoop < 8; nSectorLoop++) { if(g_SECCBuf_R[nSectorLoop] != g_SECCBuf[nSectorLoop]) break; } RETAILMSG(1, (TEXT("[FMD] ++FMD_WriteSector SECC data equal number = %x \n"), nSectorLoop)); #endif } else { bRet = FMD_SB_WriteSector(startSectorAddr, pSectorBuff, pSectorInfoBuff, dwNumSectors); } #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] --FMD_WriteSector()\n"))); #endif return bRet; }
该函数也没有什么地方需要修改的。
6、FMD_PowerUp()
VOID FMD_PowerUp(VOID) { #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] FMD_PowerUp() \n"))); #endif // Set up initial flash controller configuration. g_pNFConReg->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4); g_pNFConReg->NFCONT = (0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(0x3<<1)|(1<<0); g_pNFConReg->NFSTAT = (1<<4); }
这里我们参照之前在FMD_Init()的配置,修改其中的NFCONF和NFCONT的配置为:
g_pNFConReg->NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4) | (1<<2) | (0<<0);g_pNFConReg->NFCONT = (0<<13)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
7、FMD_PowerDown()
VOID FMD_PowerDown(VOID) { #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] FMD_PowerDown() \n"))); #endif }
该函数不需要修改什么。
接下来的这几个函数都不需要修改:
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned) { switch(dwIoControlCode) { case IOCTL_FMD_GET_INTERFACE: { RETAILMSG(1, (TEXT("[FMD] FMD_OEMIoControl() : IOCTL_FMD_GET_INTERFACE\n"))); if (!pOutBuf || nOutBufSize < sizeof(FMDInterface)) { DEBUGMSG(1, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\n"))); return(FALSE); } PFMDInterface pInterface = (PFMDInterface)pOutBuf; pInterface->cbSize = sizeof(FMDInterface); pInterface->pInit = FMD_Init; pInterface->pDeInit = FMD_Deinit; pInterface->pGetInfo = FMD_GetInfo; pInterface->pGetInfoEx = NULL; //FMD_GetInfoEx; pInterface->pGetBlockStatus = FMD_GetBlockStatus; pInterface->pSetBlockStatus = FMD_SetBlockStatus; pInterface->pReadSector = FMD_ReadSector; pInterface->pWriteSector = FMD_WriteSector; pInterface->pEraseBlock = FMD_EraseBlock; pInterface->pPowerUp = FMD_PowerUp; pInterface->pPowerDown = FMD_PowerDown; pInterface->pGetPhysSectorAddr = NULL; break; } case IOCTL_FMD_LOCK_BLOCKS: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_LOCK_BLOCKS Not Supported\n"))); return FALSE; case IOCTL_FMD_UNLOCK_BLOCKS: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_UNLOCK_BLOCKS Not Supported\n"))); return FALSE; case IOCTL_FMD_READ_RESERVED: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_READ_RESERVED\n"))); return FALSE; case IOCTL_FMD_WRITE_RESERVED: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_WRITE_RESERVED\n"))); return FALSE; case IOCTL_FMD_GET_RESERVED_TABLE: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_GET_RESERVED_TABLE\n"))); return FALSE; case IOCTL_FMD_SET_REGION_TABLE: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_SET_REGION_TABLE\n"))); return FALSE; case IOCTL_FMD_SET_SECTORSIZE: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_SET_SECTORSIZE\n"))); return FALSE; case IOCTL_FMD_RAW_WRITE_BLOCKS: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_RAW_WRITE_BLOCKS\n"))); return FALSE; case IOCTL_FMD_GET_RAW_BLOCK_SIZE: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_GET_RAW_BLOCK_SIZE\n"))); return FALSE; case IOCTL_FMD_GET_INFO: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_GET_INFO\n"))); return FALSE; case IOCTL_FMD_SET_XIPMODE : RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_SET_XIPMODE\n"))); return FALSE; case IOCTL_FMD_GET_XIPMODE: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_FMD_GET_XIPMODE\n"))); return FALSE; case IOCTL_DISK_FLUSH_CACHE: //RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : IOCTL_DISK_FLUSH_CACHE\n"))); return TRUE; default: RETAILMSG(1, (TEXT("[FMD:ERR] FMD_OEMIoControl() : Unknown IOCTL (0x%08x)\n"), dwIoControlCode)); return FALSE; } return TRUE; } BOOL FMD_Deinit(PVOID hFMD) { #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] FMD_Deinit() \n"))); #endif return(TRUE); } /* @func BOOL | FMD_GetInfo | Provides information on the NAND flash. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL FMD_GetInfo(PFlashInfo pFlashInfo) { // Add by AlexLee RunNo[5] UINT32 nCnt; UINT32 nNandID; UINT8 nMID, nDID; if (pFlashInfo == NULL) { RETAILMSG(1, (TEXT("[FMD:ERR] FMD_GetInfo() : Invalid Parameter\n"))); return(FALSE); } pFlashInfo->flashType = NAND; #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif nNandID = ReadFlashID(); #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif nMID = nNandID >> 8; nDID = nNandID & 0xff; for (nCnt = 0; astNandSpec[nCnt].nMID != 0; nCnt++) { if (nDID == astNandSpec[nCnt].nDID) { break; } } // OK, instead of reading it from the chip, we use the hardcoded // numbers here. pFlashInfo->dwNumBlocks = NUM_OF_BLOCKS; pFlashInfo->wSectorsPerBlock = PAGES_PER_BLOCK; pFlashInfo->wDataBytesPerSector = NAND_SECTOR_SIZE; pFlashInfo->dwBytesPerBlock = (PAGES_PER_BLOCK * NAND_SECTOR_SIZE); //RETAILMSG(1, (TEXT("[FMD] FMD_GetInfo() : NUMBLOCKS = %d(0x%x), SECTORSPERBLOCK = %d(0x%x), BYTESPERSECTOR = %d(0x%x) \n"), pFlashInfo->dwNumBlocks, pFlashInfo->dwNumBlocks, pFlashInfo->wSectorsPerBlock, pFlashInfo->wSectorsPerBlock, pFlashInfo->wDataBytesPerSector, pFlashInfo->wDataBytesPerSector)); // del by alexlee return TRUE; } /* @func DWORD | FMD_GetBlockStatus | Returns the status of the specified block. @rdesc Block status (see fmd.h). @comm @xref */ DWORD FMD_GetBlockStatus(BLOCK_ID blockID) { DWORD dwResult = 0; #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] ++FMD_GetBlockStatus(0x%08x) \n"), blockID)); #endif #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif if ( IS_LB ) { dwResult = FMD_LB_GetBlockStatus(blockID); } else { dwResult = FMD_SB_GetBlockStatus(blockID); } #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] --FMD_GetBlockStatus()\n"))); #endif return dwResult; } /* @func BOOL | FMD_SetBlockStatus | Marks the block with the specified block status. @rdesc TRUE = Success, FALSE = Failure. @comm @xref */ BOOL FMD_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus) { BOOL bRet = TRUE; #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] ++FMD_SetBlockStatus(0x%08x, 0x%08x) \n"), blockID, dwStatus)); #endif #ifdef SYNC_OP EnterCriticalSection(&g_csNandFlash); #endif if ( IS_LB ) { bRet = FMD_LB_SetBlockStatus(blockID, dwStatus); } else { bRet = FMD_SB_SetBlockStatus(blockID, dwStatus); } #ifdef SYNC_OP LeaveCriticalSection(&g_csNandFlash); #endif #if (NAND_DEBUG) RETAILMSG(1, (TEXT("[FMD] --FMD_SetBlockStatus()\n"))); #endif return bRet; }
文章有点长,先到这里了,关键点将在下一篇介绍
- Nandflash 驱动移植 (四)
- Nandflash 驱动移植 (一)
- Nandflash 驱动移植 (二)
- Nandflash 驱动移植 (三)
- Nandflash 驱动移植 (五)
- Nandflash 驱动移植 (六)
- nandflash驱动移植patch
- NandFlash驱动移植基础知识
- Nandflash 驱动移植
- mini2440 nandflash驱动移植
- Nandflash 驱动移植
- 《Mini2440_Linux移植开发实战指南》nandflash驱动移植(修改)
- 初试mini2440 nandflash驱动移植
- 移植3- uboot之nandflash驱动移植
- NandFlash驱动和Yaffs文件系统的移植
- NandFlash驱动和Yaffs文件系统的移植
- NandFlash驱动和Yaffs文件系统的移植
- 移植nandflash驱动并更改分区信息
- android上一个可追踪代码到函数具体某行的日志类
- ABOUT REST
- 启动ORACLE监听和数据库基本命令
- 汉字转拼音android实现(HanziToPinyin类)
- 收藏 android设备的唯一标示
- Nandflash 驱动移植 (四)
- 数字万用表的测试中的几点说明
- NGUI v2.0 Interaction_14:UIDraggableCamera UI可拖拽摄像机类
- XCode调试技巧之EXC_BAD_ACCESS中BUG解决
- Ubuntu 中使用apt-get命令下载的程序存放的目录
- svm 行人识别 训练 基于Opencv
- 主线程(UI线程)负责UI, 被阻塞过久会产生ANR
- UITextField
- 设置soapUI Pro 的超时时间