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

📄 flashdrvlib.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
字号:
/* flashDrvLib.c - Flash memory device driver */

/* Copyright 1984-2000 Wind River Systems, Inc. */
#include "copyright_wrs.h"
/*
modification history
--------------------
V1.09:---------------------------------------------------------------------
05/13/2004 pcd
1. modify to support ks8695 board with AMD AM29LV033 flash memory .
*/


#include "types.h"
#include "vxWorks.h"
#include "taskLib.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "config.h"
#include "drv/mem/flashDev.h"
#include "drv/mem/flash29.h"
#include "flash28.h"
#include "flashFsLib.h"
#include "flashMem.h"


/* Driver debug control */
#define  FLASH_DEBUGDRV

/* Driver debug control */
#ifdef FLASH_DEBUGDRV
#define FLASHDRV_DEBUG_OFF		0x0000
#define FLASHDRV_DEBUG_ERROR    0x0001
#define FLASHDRV_DEBUG_BLKWRITE	0x0002
#define FLASHDRV_DEBUG_BLKREAD 	0x0004
#define FLASHDRV_DEBUG_ERASE	0x0008
#define FLASHDRV_DEBUG_TYPEGET	0x0010
#define FLASHDRV_DEBUG_INIT 	0x0020
#define FLASHDRV_DEBUG_DIAG 	0x0040
#define FLASHDRV_DEBUG_CHECK 	0x0080
#define FLASHDRV_DEBUG_ALL    	0xffff

LOCAL int flashDrvDebug = ( FLASHDRV_DEBUG_ERROR  | FLASHDRV_DEBUG_DIAG ) ;

#define FD_DRV_PRINT(FLG, X)						\
    do {								\
    if (flashDrvDebug & FLG)						\
	printf X;							\
    } while (0)

#else /* FLASH_DEBUGDRV */

#define FD_DRV_PRINT(FLG, X)

#endif /* FLASH_DEBUGDRV */

/*
 * The FLASH_BASE_ADDRS is 0x02800000 for flash boot.
 */



/* LOCAL */

static	int	  flashSectorCount = 0;
static	int	  flashLoadedSector = -1;
static	int	  flashLoadedSectorDirty = 0;
static	char *flashLoadedSectorBuffer;


 /* forward declarations */

IMPORT UINT8 sysFlashTypeGet (void);
IMPORT int   AmdflashEraseDevice(FLASH_DEF *, int);
IMPORT int   AmdflashWrite(int, char *, unsigned int, unsigned int);

int flashDrvLibInit();
int flashEraseSector(int);
int flashEraseBank();
int flashBlkRead(int, char *, unsigned int, unsigned int);
int flashBlkWrite(int, char *, unsigned int, unsigned int);
int flashDiagnostic();
int flashSyncFilesystem();

LOCAL int flashGetSectorCount();
LOCAL int flashRead(int, char *, unsigned int, unsigned int);
LOCAL int flashCheckCanProgram(int, unsigned int, unsigned int);
LOCAL int flashFlushLoadedSector();






int flashDrvLibInit()
{
    UINT8 flashtype ;


    /* GET the manufacturer id and device id */
    flashtype = sysFlashTypeGet ();

    switch( flashtype ) 
    {
		case FLASH_29LV033:
			flashSectorCount = EB_FLASH_SECTORS;
			FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
	  	               ( "flashInit(): AM29LV033 Found\n" ));
			break;
		default:
			FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
		              ( "flashInit(): Unrecognized Device (0x%02X)\n", flashtype ));
			return( ERROR );
    }


    flashLoadedSectorBuffer = malloc( FLASH_BANK_SECTOR_SIZE );
    if( !flashLoadedSectorBuffer ) 
    {
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashInit(): malloc() failed\n" ));
	
	    return( ERROR );
    }

    return( 0 );
}


LOCAL int flashGetSectorCount()
{
    UINT8 flashtype ;
    int   flashSectorCount = 0;


    /* GET the manufacturer id and device id */
    flashtype = sysFlashTypeGet ();

    switch( flashtype ) 
    {
    	case FLASH_29LV033:
			flashSectorCount = EB_FLASH_SECTORS;
	        FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
                       ( "flashGetSectorCount(): AMD AM29LV033 Found\n" ));
			break;
        default:
	        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
                       ( "flashGetSectorCount(): Unrecognized Device (0x%02X)\n", flashtype ));
            return( ERROR );

    }

    return( flashSectorCount );
}


int flashEraseSector( int sectorNum )
{

    int	          totalSectors   = flashGetSectorCount();
	FLASH_DEF	* sectorBasePtr = (FLASH_DEF *)(FLASH_BASE_ADDRESS + \
									 (int)(sectorNum * (int)FLASH_BANK_SECTOR_SIZE));
	int	device;


    /*  Don't erase the very last sector bank; those are reserved
     *  for BSP usage (registers, exception reports, etc...).
     */
    totalSectors--;
    if( (sectorNum >= 0) && (sectorNum < totalSectors) ) 
	{
	      
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERASE,
			      ( "flashEraseSector(): Sector %d erased, SectorAddr=0x%08X\n", (int)sectorNum, (int)sectorBasePtr ));	

		for( device = 0; device < FLASH_BANK_WIDTH; device++ ) 
		{
			if( AmdflashEraseDevice( (FLASH_DEF	*)sectorBasePtr, device ) == ERROR ) 
			{
				FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
			          ( "flashEraseSector(): device %d failed\n", device));
				return( ERROR );
			}
		}

		return( OK );

    } /*     if( (sectorNum >= 0) && (sectorNum < totalSectors) )  */
	else 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashEraseSector(): Sector %d invalid\n", sectorNum ));
		return( ERROR );
    }

}

int  flashEraseBank()
{
	int	totalSectors = flashGetSectorCount();
	int	sectorNum;
	int	errCnt = 0;


	FD_DRV_PRINT (FLASHDRV_DEBUG_ERASE,
			      ( "flashEraseBank(): erased flash\n"));

    /*  Don't erase the very last sector bank; those are reserved
     *  for BSP usage (registers, exception reports, etc...).
     */
    totalSectors--;
    for( sectorNum = 0; sectorNum < totalSectors ; sectorNum++ ) 
	{
		/* print out '.' every sector */
	
		/*printf("."); */

		if( flashEraseSector( sectorNum ) == ERROR )
			errCnt++;
    }

    if( errCnt ) {
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
			      ( "flashEraseBank(): failed, ERROR count = %d\n", errCnt));

		return( ERROR );
    }
    else
		return( 0 );
}


LOCAL int flashRead( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{

    bcopy( (char *)(FLASH_BASE_ADDRESS + (sectorNum * FLASH_BANK_SECTOR_SIZE) + offset), buff, count );

    return( 0 );
}


int flashBlkRead( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{

    if( (sectorNum < 0) || (sectorNum >= flashSectorCount) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashBlkRead(): Sector %d invalid\n", sectorNum ));
		return( ERROR );
    }

    if( (offset < 0) || (offset >= FLASH_BANK_SECTOR_SIZE) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashBlkRead(): Offset 0x%08X invalid\n", offset ));
		return( ERROR );
    }

    if( (count < 0) || (count > (FLASH_BANK_SECTOR_SIZE - offset)) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashBlkRead(): Count 0x%08X invalid\n", count ));
		return( ERROR );
    }


    if( flashLoadedSector == sectorNum ) 
	{
	   bcopy( &flashLoadedSectorBuffer[ offset ], buff, count );
	   FD_DRV_PRINT (FLASHDRV_DEBUG_BLKREAD,
	              ( "flashBlkRead(): bcopy() Sector %d, offset %d, count %d\n", sectorNum, offset, count ));
	   return( 0 );
    } 
	else 
	{
	   flashRead( sectorNum, buff, offset, count );
	   FD_DRV_PRINT (FLASHDRV_DEBUG_BLKREAD,
	              ( "flashBlkRead(): flashRead() Sector %d, offset %d, count %d\n", sectorNum, offset, count ));
  		return( 0 );
    }

}


LOCAL int flashCheckCanProgram( int sectorNum, unsigned int offset, unsigned int count )
{
	FLASH_DEF	*flashBuffPtr;
	int	         i, dataCount;

    dataCount = (count / sizeof(FLASH_DEF) );
    flashBuffPtr = (FLASH_DEF *)(FLASH_BASE_ADDRESS + (sectorNum * FLASH_BANK_SECTOR_SIZE) + offset);

    for( i = 0; i < dataCount; i++ ) 
	{
		if ( (FLASH_DEF)flashBuffPtr[ i ] != (FLASH_DEF)0xFFFFFFFF )
		{
	        FD_DRV_PRINT (FLASHDRV_DEBUG_CHECK,
	              ( "flashCheckCanProgram(): flashAddr 0x%08X is 0x%02x (not 0xFF)\n", 
                    (int)flashBuffPtr, *flashBuffPtr ));
			return( ERROR );
		}
    }

    FD_DRV_PRINT (FLASHDRV_DEBUG_CHECK,
	              ( "flashCheckCanProgram(): flashAddr 0x%08X is 0x%02x (0xFF)\n", 
                    (int)flashBuffPtr, *flashBuffPtr ));
    return( OK );
}


LOCAL int flashFlushLoadedSector()
{
    int status;
 

	FD_DRV_PRINT (FLASHDRV_DEBUG_BLKWRITE,
	          ( "flashFllushLoadedSector(): Flushing %d\n",	flashLoadedSector ));

    if( (flashLoadedSector < 0) || (flashLoadedSector >= flashSectorCount) ) {
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashFlushLoadedSector(): Sector %d invalid\n", flashLoadedSector ));

		return( ERROR );
    }
    
    if (flashEraseSector( flashLoadedSector ) == ERROR)
		return (ERROR);

	status = AmdflashWrite( flashLoadedSector, flashLoadedSectorBuffer, 0, FLASH_BANK_SECTOR_SIZE );
    return( status) ;


}


int flashBlkWrite( int sectorNum, char *buff, unsigned int offset, unsigned int count )
{

    if( (sectorNum < 0) || (sectorNum >= flashSectorCount) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
				  ( "flashBlkWrite(): Sector %d invalid\n", sectorNum ));
		return( ERROR );
    }

    if( (offset < 0) || (offset >= FLASH_BANK_SECTOR_SIZE) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
				  ( "flashBlkWrite(): Offset 0x%08X invalid\n", offset ));
		return( ERROR );
    }

    /*  Count must be within range, but more so, must be a long word
     *  multiple, as we always program long words.
     */
    if( (count < 0) || (count > (FLASH_BANK_SECTOR_SIZE - offset)) || (count % sizeof(FLASH_DEF)) ) 
	{
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
				  ( "flashBlkWrite(): Count 0x%08X invalid\n", count ));
		return( ERROR );
    }

    if( sectorNum == flashLoadedSector ) 
	{

		bcopy( buff, &flashLoadedSectorBuffer[ offset ], count );

		flashLoadedSectorDirty = 1;

		return( 0 );

    } 
	else if( flashCheckCanProgram( sectorNum, offset, count ) != ERROR ) 
	{

		return( AmdflashWrite( sectorNum, buff, offset, count ) );
    
    } 
	else 
	{

		if( flashLoadedSectorDirty ) 
		{
			if( flashFlushLoadedSector() == ERROR ) 
			{
		        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
				          ( "flashBlkWrite(): flashFlushLoadedSector() err\n" ));
				return( ERROR );
			}	 
			else 
			{
				flashLoadedSectorDirty = 0;
				flashLoadedSector = -1;
			}
		}

		flashRead( sectorNum, flashLoadedSectorBuffer, 0, FLASH_BANK_SECTOR_SIZE );

		flashLoadedSector = sectorNum;

		bcopy( buff, &flashLoadedSectorBuffer[ offset ], count );

		flashLoadedSectorDirty = 1;

		return( 0 );
    }


    return( 0 );
}


int flashSyncFilesystem()
{

    if( (flashLoadedSector != -1) && flashLoadedSectorDirty ) 
	{
	    FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
			      ( "flashSyncFilesystem(): flushing dirty sector %d\n", flashLoadedSector ));

		if( flashFlushLoadedSector() == ERROR ) 
		{
			FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
			          ("flashSyncFilesystem(): flashFlushLoadedSector() failed\n" ));
			return( ERROR );
		}
		flashLoadedSectorDirty = 0;
    } 
	else 
	{
	    FD_DRV_PRINT (FLASHDRV_DEBUG_INIT,
			      ( "flashSyncFilesystem(): no dirty sector to flush\n" ));
    }
    return( 0 );
}


/*-- Debug Functions   -----------------------------------------------------*/


int flashDiagnostic
( 
	int	        sector
)
{
	FLASH_DEF * flashSectorBuff;
	int	        sectorNum, i, min, max;
    int         length = FLASH_BANK_SECTOR_SIZE;


	FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
	             ( "flashDiagnostic(): Executing ...\n" ));

    /* can't erase Boot sectors */
    if ( (sector >= BOOT_BEGIN_SECTOR) && (sector < (BOOT_BEGIN_SECTOR + FLASH_RAW_NUM_SEC)) )
    {
	    FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
	                 ( "flashDiagnostic(): can't erase Boot sectors !\n" ));
        return (ERROR);
    }

    min = sector;
	max = sector+1;
    length = 0x100;


    /*  Erase each sector.
     */
    for( sectorNum = min; sectorNum < max ; sectorNum++ ) 
	{

		if( flashEraseSector( sectorNum ) == ERROR )
		{
			FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashDiagnostic(): flashEraseBank() fail on sector %d\n", sectorNum ));
			return( ERROR );
		}
		FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
	              ( "flashDiagnostic(): flashEraseBank() OK on sector %d\n", sectorNum ));
    }

    flashSectorBuff = (FLASH_DEF *)malloc( length );
    if( !flashSectorBuff ) {
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashDiagnostic(): malloc() failed\n" ));
		return( ERROR );
    }

    /*  Write unique counting pattern to each sector.
     */
    for( sectorNum = min; sectorNum < max; sectorNum++ ) 
    {

		for( i = 0; i < length / sizeof(FLASH_DEF); i++ )
			flashSectorBuff[ i ] = (i + sectorNum-min);

		if( AmdflashWrite( sectorNum, (FLASH_DEF *)flashSectorBuff, 0, length ) == ERROR ) 
		{
		        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
					      ( "flashDiagnostic(): flashWrite() failed on %d\n", sectorNum ));
				return( ERROR );
		}
        FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
			      ( "flashDiagnostic(): flashWrite() ok on sector %d\n", sectorNum ));
    }

    /*  Verify each sector.
     */
    for( sectorNum = min; sectorNum < max; sectorNum++ ) 
    {

		if( flashRead( sectorNum, (FLASH_DEF *)flashSectorBuff, 0, length  ) == ERROR ) {
		    FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
				      ( "flashDiagnostic(): flashRead() failed on sector %d\n", sectorNum ));
			return( ERROR );
		}
        FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
			      ( "flashDiagnostic(): flashRead() ok on sector %d\n", sectorNum ));


		for( i = 0; i < length / sizeof(FLASH_DEF); i++ ) {
			if( flashSectorBuff[ i ] != (i + sectorNum-min) ) 
			{
		        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
					      ( "flashDiagnostic(): verification failed\n" )); 
		        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
					      ( "flashDiagnostic(): sector %d, offset 0x%08X\n", sectorNum, (int)(i * sizeof( long )) ));
		        FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
					      ( "flashDiagnostic(): expected 0x%08X, got 0x%08X\n",	(i + sectorNum), (int)flashSectorBuff[ i ] ));
				return( ERROR );
			}
		}
    }

    /*  Erase each sector after finished diagnostic it .
     */
    for( sectorNum = min; sectorNum < max ; sectorNum++ ) 
	{
		if( flashEraseSector( sectorNum ) == ERROR )
		{
			FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
	              ( "flashDiagnostic(): flashEraseBank() #2 failed\n" ));
			return( ERROR );
		}
    }

    free( flashSectorBuff );

	FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
		      ( "flashDiagnostic(): Completed without error\n" ));

    return( 0 );

}

int flashDiagEraseAppSectors
( 
)
{
	int	sectorNum;
	int	errCnt = 0;

    for (sectorNum = APPLICATION_BEGIN_SECTOR; 
         sectorNum < (APPLICATION_BEGIN_SECTOR+FLASH_FS2_NUM_SEC); 
         sectorNum++)
	{
		if( flashEraseSector( sectorNum ) == ERROR )
			errCnt++;
    }

    if( errCnt ) {
		FD_DRV_PRINT (FLASHDRV_DEBUG_ERROR,
			      ( "flashDiagEraseAppSectors(): failed, ERROR count = %d\n", errCnt));

		return( ERROR );
    }
    else
    {
	    FD_DRV_PRINT (FLASHDRV_DEBUG_DIAG,
		          ( "flashDiagEraseAppSectors(): Completed without error\n" ));
        return ( 0 );
    }
}

⌨️ 快捷键说明

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