⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmd.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            if(dwStatus & BLOCK_STATUS_READONLY)
            {
                DEBUGMSG(ZONE_INFO, (TEXT("set block %d OEM readonly.\r\n"), blockID));
                SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
            }

            if(dwStatus & BLOCK_STATUS_RESERVED)
            {
                DEBUGMSG(ZONE_FUNCTION, (TEXT("set block %d OEM reserved.\r\n"), blockID));
                SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
            }

            if(!FMD_WriteSector(Sector, NULL, &SI, 1))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("write block %d OEM status failed.\r\n"), blockID));
                return FALSE;
            }
        }
    }    
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_SetBlockStatus-\r\n")));
    return TRUE;
}

//-----------------------------------------------------------------------------
//
// Function: FMD_EraseBlock
//
// Function Erases the specified flash block. 
//
// Parameters:
//      blockID 
//          [in] block number to erase.
//
// Returns:  
//      TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_EraseBlock(BLOCK_ID blockID)
{
    ULONG BlockAddress;
    ULONG Len;
    BOOL bLastMode;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_EraseBlock+: blockID=0x%X\r\n"), blockID));

    bLastMode = SetKMode(TRUE);
    BlockAddress = (ULONG)g_pNORFlashBase + g_FMDInfo.FMDBaseOffset + (blockID * g_FMDInfo.EraseBlockSize);
    Len = NORErase(BlockAddress, g_FMDInfo.EraseBlockSize);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_EraseBlock- len 0x%08X\r\n"), Len));
    
    SetKMode(bLastMode);
    if(Len != 0)
        return TRUE;
    else	
    	return FALSE;
}

//-----------------------------------------------------------------------------
//
// Function: FMD_PowerUp
//
// Function Restores power to the flash memory device. 
//
// Parameters:
//      None
//
// Returns:  
//      None
//
//-----------------------------------------------------------------------------
VOID FMD_PowerUp(VOID)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_PowerUp+\r\n")));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_PowerUp-\r\n")));
}

//-----------------------------------------------------------------------------
//
// Function: FMD_PowerDown
//
// Function Suspends power to the flash memory device. 
//
// Parameters:
//      None
//
// Returns:  
//      None
//
//-----------------------------------------------------------------------------
VOID FMD_PowerDown(VOID)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_PowerDown+\r\n")));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_PowerDown-\r\n")));
}

//-----------------------------------------------------------------------------
//
// Function: FMD_GetPhysSectorAddr
//
// Function returns the physical address for the physical sector passed in.
//
// Parameters:
//          dwSector
//          [in] sector number
//
//          pStartSectorAddr
//          [out] physical address.
//
// Returns:  
//      None
//
//-----------------------------------------------------------------------------
VOID FMD_GetPhysSectorAddr(DWORD dwSector, PSECTOR_ADDR pStartSectorAddr)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetPhysSectorAddr+: dwSector 0x%08X\r\n"), dwSector));
    GetPhysicalSectorAddress(dwSector, pStartSectorAddr, NULL);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FMD_GetPhysSectorAddr-\r\n")));
}

//-----------------------------------------------------------------------------
//
// Function: FMD_OEMIoControl
//
// Function Implements user-defined commands for the flash memory device. 
//
// Parameters:
//      dwIoControlCode 
//          [in] control code specifying the command to execute.
//
//		pInBuf
//			[in] buffer that contains the data required to perform the operation
//						
//		nInBufSize
//			[in] Size, in bytes, of the buffer pointed to by pInBuf
//
//		pOutBuf
//			[out] buffer that receives the output data for the operation.
//
//		nOutBufSize
//			[in] Size, in bytes, of the buffer pointed to by pOutBuf
//
//		pBytesReturned
//			[out] receives the size, in bytes of the data stored into the buffer
//				  pointed to by pOutBuf		
//
// Returns:  
//      TRUE/FALSE for success
//
//-----------------------------------------------------------------------------
BOOL FMD_OEMIoControl(DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize,
                       PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
    switch(dwIoControlCode)
    {
        case IOCTL_FMD_GET_INTERFACE:
        {
            if (!pOutBuf || nOutBufSize < sizeof(FMDInterface))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_INTERFACE bad parameter(s).\r\n")));
                return FALSE;
            }    
            PFMDInterface pInterface = (PFMDInterface)pOutBuf;
            pInterface->cbSize = sizeof(FMDInterface);
            pInterface->pInit = FMD_Init;
            pInterface->pDeInit = FMD_Deinit;
            pInterface->pGetInfo = FMD_GetInfo;        
            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 = FMD_GetPhysSectorAddr;            
            break;
        }
        case IOCTL_FMD_SET_XIPMODE:
            // Select between XIP mode or non-XIP mode.  The difference from 
            // the FMD's standpoint is whether or not sector information is 
            // stored along with each sector. This should be called before 
            // FMD_Init.
            if(!pInBuf || nInBufSize < sizeof(BOOL))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_SET_XIPMODE bad parameter(s).\r\n")));
                return FALSE;
            }
            g_bXIPMode = *(BOOL *)pInBuf;      
            break;

        case IOCTL_FMD_GET_XIPMODE:
            if(!pOutBuf || nOutBufSize < sizeof(BOOLEAN))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_GET_XIPMODE bad parameter(s).\r\n")));
                return FALSE;
            }
            *(BOOL *)pOutBuf = g_bXIPMode;      
            break;        
        
        case IOCTL_FMD_LOCK_BLOCKS:
            // Lock one of more blocks in a specified range.
            if(!pInBuf || nInBufSize < sizeof(BlockLockInfo))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS bad parameter(s).\r\n")));
                return FALSE;
            }
            if(!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, TRUE))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_LOCK_BLOCKS failed to lock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
                return FALSE;
            }
            break;
        
        case IOCTL_FMD_UNLOCK_BLOCKS:
            // Unlock one of more blocks in a specified range.
            if(!pInBuf || nInBufSize < sizeof(BlockLockInfo))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS bad parameter(s).\r\n")));
                return FALSE;
            }
            if(!SetBlockLock(((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks, FALSE))
            {
                ERRORMSG(ZONE_ERROR, (TEXT("FMD_OEMIoControl: IOCTL_FMD_UNLOCK_BLOCKS failed to unlock blocks (start=0x%x, number=0x%x).\r\n"), ((PBlockLockInfo)pInBuf)->StartBlock, ((PBlockLockInfo)pInBuf)->NumBlocks));
                return FALSE;
            }
            break;

        default:
            DEBUGMSG(ZONE_INFO, (TEXT("FMD_OEMIoControl: unrecognized IOCTL (0x%x).\r\n"), dwIoControlCode));
            return FALSE;
    }
    return TRUE;
}

//-----------------------------------------------------------------------------
// PRIVATE FUNCTIONS
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// Function: DefineLayout
//
// 
// Notes:          
//     The FAL expects the Flash media to be broken up into Flash blocks
//     which are then subdivided into physical sectors.  Some types of 
//     Flash memory (i.e. NAND Flash) already have this layout.  NOR Flash,
//     on the other hand, DOES NOT breakup each Flash block into physical
//     sectors.  Instead, each byte is individually addressable (like RAM).
//     Despite this characteristic, NOR Flash can still logically be broken
//     up into discrete sectors as follows:
// 
//                     NOR Flash
// 
//                 Sector Data     SectorInfo
//         ---------------------------------
//         |Sector(0)              |       |
//         |Sector(1)              |       |
//         |Sector(2)              |       |       Block 0
//         |...                    |       |
//         |Sector(k)              |       |
//         |                       |-------|
//         |Sector info            |       |
//         |for all blocks         |       |
//         |                       |-------|
//         |                       XXXXXXXXX
//          -------------------------------
//         |Sector(k+1)            |       |
//         |Sector(k+2)            |       |   
//         |Sector(k+3)            |       |       Block 1
//         |...                    |       |
//         |Sector(2k)             |       |
//         |                       |-------|
//         |Sector info            |       |
//         |for all blocks         |       |
//         |                       |-------|
//         |                       XXXXXXXXX
//          -------------------------------
//         |                       |       |
//         |                       |       |
//         |                       |       |       Block 2
//         |                       |       |
//         |                       |       |
//         |                       |-------|
//         |Sector info            |       |
//         |for all blocks         |       |
//         |                       |-------|
//         |                       XXXXXXXXX
//          -------------------------------        ...
//         |                       |       |
//         |                       |       |
//         |                       |       |       Block N
//         |                       |       |
//         |                       |       |
//         |                       |-------|
//         |Sector info            |       |
//         |for all blocks         |       |
//         |                       |-------|
//         |                       XXXXXXXXX
//         ---------------------------------
// 
//     That is, each NOR Flash block is logically subdivided into a "page", 
//     where each page contains space for sector data and SectorInfo metadata.
//     Most often, Flash blocks are a power of 2 in size but the size of a page 
//     is not a power of 2 (i.e. 512 + 8 = 520 bytes).
//     Thus, each Flash block DOES NOT evenly divide into an integral number of 
//     pages and some bytes in a block are left unused. These unused bytes are 
//     denoted above by XXXXX's.
// 
//     To help clarify how this process works, consider the following example:
//     suppose you have a NOR Flash memory device that contains 256 Flash blocks
//     each 256K in size. From these size characteristics, we find:
// 
//         (256K / (512+8)) ==> 504 sectors + 64 unused bytes
// 
//     Therefore, each Flash block can map 504 sectors (including SectorInfo 
//     metadata)and leave 64 unused bytes per block. Notice that 8 bytes is 
//     used for the SectorInfo metadata although the SectorInfo structure is 
//     currently only 6 bytes. The reason for this is to make sure that all 
//     sector addresses are DWORD aligned. (i.e. 520 divides by 4 evenly while 
//     518 doesn't divide by 4 evenly).  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -