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

📄 falmain.cpp

📁 基于WINCE的文件系统FAL驱动
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.


	2007 Modified by Chris Gray at Raza Microelectronics Inc for WinCE 5.0 optimizations
			(cgray@razamicro.com)


Module Name:    FALMAIN.CPP

Abstract:       FLASH Abstraction Layer (FAL) for Windows CE

Notes:          The following stream interface driver is used to support FLASH
                memory devices.  Specifically, this purpose of this driver is to
                interface file systems (i.e. FAT) with specific FLASH chips in a
                device-independent manner.  Here is a diagram illustrating the
                overall architecture:

                                ---------------
                                | File System |
                                ---------------
                                       |             uses logical sector addresses
                                ---------------
                                |     FAL     |
                                ---------------
                                       |             uses physical sector addresses
                                ---------------
                                |     FMD     |
                                ---------------
                                       |             uses program/erase algorithms
                               ------------------
                               | FLASH Hardware |
                               ------------------

                Each of the components is defined as follows:

                FAL (FLASH Abstraction Layer) - abstracts underlying FLASH hardware to file system(s)
                FMD (FLASH Media Driver)      - interfaces directly with underlying FLASH media

                Using this design, OEMs are free to implement custom FMDs for their respective FLASH chips.
                Practically, the simple FMD interface means that it is *very easy* for OEMs to port an example
                FMD to their respective hardware.

                The primary responsibilities of the FAL are as follows:

                    * Abstract the physical FLASH media from the file system.

                    * Translate logical sector addresses to physical sector addresses.

                    * "Wear-level" the physcial media.  FLASH memory has a limited write/erase lifetime and
                      it is important to spread the write/erase cycles across the entire media in order to
                      extend the lifetime of the memory device.

                Note that the FAL is NOT a file system; rather, it is a translation layer that file systems
                use in order to interface with FLASH media in a device-independent manner.


Environment:    This module (FAL.LIB) needs to be linked with a FLASH Media Driver (FMD.LIB) in
                order to create the full FLASH driver (FLASHDRV.DLL).

-----------------------------------------------------------------------------*/
#include <windows.h>
#include <windev.h>
#include "storemgr.h"

#include "fal.h"

//#undef DEBUGMSG
//#define DEBUGMSG(cond,msg) RETAILMSG(1,msg)

DBGPARAM dpCurSettings = {
    TEXT("MSFLASH"), {
        TEXT("Init"),
        TEXT("Error"),
        TEXT("Compactor"),
        TEXT("Write"),
        TEXT("Read"),
        TEXT("Function"),
        TEXT("6"),
        TEXT("7"),
        TEXT("8"),
        TEXT("9"),
        TEXT("10"),
        TEXT("11"),
        TEXT("12"),
        TEXT("CeLog Errors"),
        TEXT("CeLog Compaction"),
        TEXT("CeLog Verbose")},
    0x2          // Errors are only on by default
};

//------------------------------ GLOBALS -------------------------------------------
CRITICAL_SECTION   g_csMain;                 // Only allow one request at a time.
CRITICAL_SECTION   g_csFlashDevice;          // Used to make driver re-entrant
static LONG        g_lReferenceCount = 0;

static PDEVICE     g_pDevice = NULL;         // Handle to the device
static DWORD       *g_Context = NULL;		 // Used as a lock to the FAL driver, allowing only one instance

PFlashInfoEx       g_pFlashMediaInfo = NULL; // FLASH chip-specific device information

HKEY               g_hDeviceKey = NULL;
HINSTANCE          g_hCoreDll = NULL;

TCHAR              g_szProfile[PROFILENAMESIZE];


DWORD              g_dwCompactionPrio256 = THREAD_PRIORITY_IDLE + 248;
DWORD              g_dwCompactionCritPrio256 = THREAD_PRIORITY_TIME_CRITICAL + 248;

DWORD              g_dwAvailableSectors        = 0;            // Total # of available sectors on media

CEDEVICE_POWER_STATE g_CurrentPowerState = D0;
FMDInterface FMD;
Fal** g_FalObjects;
//----------------------------------------------------------------------------------


BOOL GetDeviceInfo(PSTORAGEDEVICEINFO psdi)
{
    BOOL fXipMode = FALSE;

    wcscpy( psdi->szProfile, g_szProfile);
    psdi->dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
    psdi->dwDeviceType = STORAGE_DEVICE_TYPE_FLASH;
    psdi->dwDeviceFlags = STORAGE_DEVICE_FLAG_READWRITE | STORAGE_DEVICE_FLAG_TRANSACTED;

    if (g_pFlashMediaInfo->flashType == NOR)
        psdi->dwDeviceFlags |= STORAGE_DEVICE_FLAG_XIP;

    return TRUE;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                          DLL ENTRY
-------------------------------------------------------------------*/
STDAPI_(BOOL) WINAPI
DllEntry(HINSTANCE DllInstance, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
        RETAILREGISTERZONES (DllInstance);
        DEBUGMSG(ZONE_INIT,(TEXT("FLASHDRV.DLL:DLL_PROCESS_ATTACH \r\n")));
        break;

    case DLL_PROCESS_DETACH:
        DEBUGMSG(ZONE_INIT,(TEXT("FLASHDRV.DLL:DLL_PROCESS_DETACH \r\n")));
        break;
    }
    return TRUE;
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       DSK_Init()

Description:    Initializes the FAL, queries the FMD for the FLASH
                memory device properties, etc.

Returns:        Context data for the FLASH device.
-------------------------------------------------------------------*/
DWORD DSK_Init(DWORD dwContext)
{
    PDEVICE pDevice = g_pDevice;
    DWORD dwNumReserved = 0;
    DWORD dwUpdateReadOnly = 0;

    DEBUGMSG(ZONE_FUNCTION,(TEXT("FLASHDRV.DLL:Init() %d\r\n"),g_lReferenceCount));
	RETAILMSG(1,(TEXT("DSK_Init start:%d\r\n"),GetTickCount() ));

    //----- 1. Check for re-entrant call.  If we have already initialized, then return -----
    //         the open handle to the FLASH device.
    if(InterlockedIncrement(&g_lReferenceCount) > 1)
    {
      return (DWORD)g_pDevice;
    }

    //----- 2. First time initializing.  Create the handle for the FLASH device -----
    if((pDevice = (PDEVICE)LocalAlloc(LPTR, sizeof(DEVICE))))
    {
        memset(pDevice, 0, sizeof(pDevice) );
        pDevice->dwID = 'GOOD';         // "Anything" validates pdev, 'GOOD' is a fine choice
    }else
    {
        ReportError((TEXT("FLASHDRV.DLL:LocalAlloc() failed - unable to allocate PDEVICE handle for FLASH device.\r\n")));
        goto INIT_ERROR;
    }

    GetFMDInterface(pDevice);

RETAILMSG(1,(TEXT("Initialize the FLASH Media Driver (FMD) start:%d\r\n"),GetTickCount() ));
    //----- 3. Initialize the FLASH Media Driver (FMD) -----
    if((pDevice->hFMD=FMD.pInit((LPTSTR)dwContext,NULL,NULL))==NULL)
    {
        ReportError((TEXT("FLASHDRV.DLL:Unable to initialize FLASH Media Driver (FMD dwContext:%X).\r\n"),dwContext));
        goto INIT_ERROR;
    }

    if (FMD.pGetInfoEx)
    {
        if(!FMD.pGetInfoEx(NULL, &dwNumReserved) || (dwNumReserved == 0))
        {
            ReportError((TEXT("FLASHDRV.DLL:Unable to query FMD for FLASH device properties.\r\n")));
            goto INIT_ERROR;
        }

        g_pFlashMediaInfo = (PFlashInfoEx)LocalAlloc (LPTR, sizeof(FlashInfoEx) + (dwNumReserved - 1) * sizeof(FlashRegion));
        if (!g_pFlashMediaInfo)
        {
            goto INIT_ERROR;
        }

        if(!FMD.pGetInfoEx(g_pFlashMediaInfo, &dwNumReserved))
        {
            ReportError((TEXT("FLASHDRV.DLL:Unable to query FMD for FLASH device properties.\r\n")));
            goto INIT_ERROR;
        }
    }
    else
    {
        FlashInfo oldFlashInfo;

        // Use the old version of GetInfo
        if(!FMD.pGetInfo(&oldFlashInfo))
        {
            ReportError((TEXT("FLASHDRV.DLL:Unable to query FMD for FLASH device properties.\r\n")));
            goto INIT_ERROR;
        }

        g_pFlashMediaInfo = (PFlashInfoEx)LocalAlloc (LPTR, sizeof(FlashInfoEx));
        if (!g_pFlashMediaInfo)
        {
            goto INIT_ERROR;
        }

        // Fill in the FlashInfoEx version with the info from FlashInfo.
        g_pFlashMediaInfo->flashType = oldFlashInfo.flashType;
        g_pFlashMediaInfo->dwNumBlocks = oldFlashInfo.dwNumBlocks;
        g_pFlashMediaInfo->dwDataBytesPerSector = oldFlashInfo.dwDataBytesPerSector;
        g_pFlashMediaInfo->dwNumRegions = 1;

        g_pFlashMediaInfo->region[0].regionType = FILESYS;
        g_pFlashMediaInfo->region[0].dwStartPhysBlock = 0;
        g_pFlashMediaInfo->region[0].dwNumPhysBlocks = oldFlashInfo.dwNumBlocks;
        g_pFlashMediaInfo->region[0].dwNumLogicalBlocks = FIELD_NOT_IN_USE;
        g_pFlashMediaInfo->region[0].dwSectorsPerBlock = oldFlashInfo.wSectorsPerBlock;
        g_pFlashMediaInfo->region[0].dwBytesPerBlock = oldFlashInfo.dwBytesPerBlock;
        g_pFlashMediaInfo->region[0].dwCompactBlocks = MINIMUM_FLASH_BLOCKS_TO_RESERVE;

    }


    //----- 6. Initialize the FLASH device's critical section -----
RETAILMSG(1,(TEXT("Initialize the FLASH device's critical section start:%d\r\n"),GetTickCount() ));
    InitializeCriticalSection(&g_csMain);
    InitializeCriticalSection(&g_csFlashDevice);

    g_hCoreDll = LoadLibrary (TEXT("coredll.dll"));
    if (g_hCoreDll)
    {
        pOpenDeviceKey fnOpenDeviceKey = (pOpenDeviceKey)GetProcAddress(g_hCoreDll, TEXT("OpenDeviceKey"));
        if (fnOpenDeviceKey)
            g_hDeviceKey = fnOpenDeviceKey ((PCTSTR)dwContext);
    }


    // Get profile name
    wcscpy(g_szProfile, L"FlashDisk");
    if (g_hDeviceKey)
    {
        DWORD dwLen = 0;
        pRegQueryValueEx fnRegQueryValueEx = (pRegQueryValueEx)GetProcAddress(g_hCoreDll, TEXT("RegQueryValueExW"));

        if (fnRegQueryValueEx)
        {
            if ((fnRegQueryValueEx (g_hDeviceKey, TEXT("Profile"), NULL, NULL, NULL, &dwLen) == ERROR_SUCCESS) &&
                 (dwLen <= (sizeof(TCHAR) * PROFILENAMESIZE)))
            {
                fnRegQueryValueEx (g_hDeviceKey, TEXT("Profile"), NULL, NULL, (LPBYTE)g_szProfile, &dwLen);
            }

            dwLen = sizeof(DWORD);

            if (fnRegQueryValueEx(g_hDeviceKey, L"CompactionPrio256", 0, NULL, (LPBYTE)&g_dwCompactionPrio256, &dwLen) != ERROR_SUCCESS)
                g_dwCompactionPrio256 = THREAD_PRIORITY_IDLE + 248;

            if (fnRegQueryValueEx(g_hDeviceKey, L"CompactionCritPrio256", 0, NULL, (LPBYTE)&g_dwCompactionCritPrio256, &dwLen) != ERROR_SUCCESS)
                g_dwCompactionCritPrio256 = THREAD_PRIORITY_TIME_CRITICAL + 248;

            if (fnRegQueryValueEx(g_hDeviceKey, L"UpdateReadOnly", 0, NULL, (LPBYTE)&dwUpdateReadOnly, &dwLen) != ERROR_SUCCESS)
                dwUpdateReadOnly = 0;

        }
    }

RETAILMSG(1,(TEXT("Initialize the FAL start:%d\r\n"),GetTickCount() ));
    //----- 7. Initialize the FAL -----
    g_FalObjects = new Fal*[g_pFlashMediaInfo->dwNumRegions];
    if (!g_FalObjects) {
        ReportError((TEXT("FLASHDRV.DLL: Out of memory!\r\n")));
        goto INIT_ERROR;
    }
    memset (g_FalObjects, 0, sizeof(Fal*) * g_pFlashMediaInfo->dwNumRegions);

    DWORD dwStartLogSector = 0;
    DWORD dwStartPhysSector = 0;

    if (g_pFlashMediaInfo->region[0].dwNumPhysBlocks) {
        dwStartPhysSector = g_pFlashMediaInfo->region[0].dwStartPhysBlock * g_pFlashMediaInfo->region[0].dwSectorsPerBlock;
    }

    for (DWORD iRegion = 0; iRegion < g_pFlashMediaInfo->dwNumRegions; iRegion++)
    {
        PFlashRegion pRegion = &g_pFlashMediaInfo->region[iRegion];

        // calculate the number of logical and physical blocks
        if (pRegion->dwNumLogicalBlocks == FIELD_NOT_IN_USE)
        {
            // Determine logical range from the given physical range
            if (!CalculateLogicalRange(pRegion))
            {
                goto INIT_ERROR;
            }
        }
        else
        {
            if (iRegion == 0)
            {
                pRegion->dwStartPhysBlock = 0;
            }
            else
            {
                pRegion->dwStartPhysBlock = g_pFlashMediaInfo->region[iRegion-1].dwStartPhysBlock +
                    g_pFlashMediaInfo->region[iRegion-1].dwNumPhysBlocks;
            }

            if (pRegion->dwNumLogicalBlocks == END_OF_FLASH)
            {
                // This region goes to the end of flash.  Determine how many logical
                // sectors are available
                pRegion->dwNumPhysBlocks = g_pFlashMediaInfo->dwNumBlocks - pRegion->dwStartPhysBlock;
                if (!CalculateLogicalRange(pRegion))
                {
                    goto INIT_ERROR;
                }
            }
            else
            {
                // Determine phsyical range from the given logical number of blocks
                if (!CalculatePhysRange(pRegion))
                {
                    goto INIT_ERROR;
                }
            }

⌨️ 快捷键说明

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