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

📄 tffsdrv.c

📁 VxWOrks中bspMCF5200下的Nand Flash TFFS的驱动程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
         (pTffsDev->tffsDriveNo >= DRIVES) )        {        return (ERROR);        }    ioreq.irHandle = pTffsDev->tffsDriveNo;    status = flCheckVolume(&ioreq);    if (status == flNotMounted)        {        status = flMountVolume(&ioreq);        if (status == flOK)            {            ioreq.irData = &bpb;            status = flGetBPB(&ioreq);            }        if (status != flOK)            {            pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;            return (ERROR);            }        /* Modify BLK_DEV structure */        tffsSetFromBPB( &(pTffsDev->tffsBlkdev), &bpb);        pTffsDev->tffsBlkdev.bd_mode = O_RDWR; /* initial mode for device */        }    ioreq.irSectorNo    = startBlk;    ioreq.irSectorCount = numBlks;    ioreq.irData        = pBuffer;    status = flAbsRead(&ioreq);    /* if success cancel dosFs re-mount volume request */    if (status != flOK)        pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;    return ((status == flOK) ? OK : ERROR);    }/********************************************************************************* tffsBlkWrt - write sequence of blocks to TFFS device** This routine writes a sequence of blocks to TrueFFS device.** RETURNS: OK, or ERROR if it failed.** NOMANUAL*/LOCAL STATUS tffsBlkWrt     (    FAST TFFS_DEV * pTffsDev,		/* pointer to device descriptor */    int startBlk,			/* starting block number to write */    int numBlks,			/* number of blocks to write */    char * pBuffer			/* pointer to buffer containing data */    )    {    FLStatus   status = flOK;    IOreq      ioreq;    BPB        bpb;    if ( (NULL == pTffsDev) || (NULL == pBuffer) ||         (pTffsDev->tffsDriveNo >= DRIVES) )        {        return (ERROR);        }    ioreq.irHandle = pTffsDev->tffsDriveNo;    status = flCheckVolume(&ioreq);    if (status == flNotMounted)        {        status = flMountVolume(&ioreq);        if (status == flOK)            {            ioreq.irData = &bpb;            status = flGetBPB(&ioreq);            }        if (status != flOK)            {            pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;            return (ERROR);            }        /* Modify BLK_DEV structure */        tffsSetFromBPB( &(pTffsDev->tffsBlkdev), &bpb);        pTffsDev->tffsBlkdev.bd_mode = O_RDWR;	/* initial mode for device */        }    ioreq.irSectorNo    = startBlk;    ioreq.irSectorCount = numBlks;    ioreq.irData        = pBuffer;    status = flAbsWrite(&ioreq);    if (status == flWriteProtect)        {        flDismountVolume(&ioreq);		/* force a remount */        pTffsDev->tffsBlkdev.bd_mode = O_RDONLY;        }    /* re-mount volume request */    if (status != flOK)        pTffsDev->tffsBlkdev.bd_readyChanged = TRUE;    return ((status == flOK) ? OK : ERROR);    }/********************************************************************************* tffsSetFromBPB - copy some data from BIOS parameter block** This routine copies BIOS parameter block data describing the flash device* returned by TrueFFS into a device descriptor.** RETURNS: N/A** NOMANUAL*/LOCAL void tffsSetFromBPB     (    BLK_DEV * pBlkDev,		/* pointer to device descriptor */    BPB * pBPB			/* pointer to BIOS parameters block */    )    {    if ((NULL == pBlkDev) || (NULL == pBPB))        return;    pBlkDev->bd_nBlocks      = 0;    pBlkDev->bd_bytesPerBlk  = 0;    pBlkDev->bd_blksPerTrack = 0;    pBlkDev->bd_nHeads       = 0;     /* clear first */    if( UNAL2(pBPB->totalSectorsInVolumeDOS3) )        pBlkDev->bd_nBlocks  = UNAL2(pBPB->totalSectorsInVolumeDOS3);    else        pBlkDev->bd_nBlocks  = LE4(pBPB->totalSectorsInVolume);    pBlkDev->bd_bytesPerBlk  = UNAL2(pBPB->bytesPerSector);    pBlkDev->bd_blksPerTrack = LE2(pBPB->sectorsPerTrack);    pBlkDev->bd_nHeads       = LE2(pBPB->noOfHeads);    }/********************************************************************************* tffsDiskChangeAnnounce - announce disk change to the file system attached** This routine is called by TFFS to update the the readyChanged field in the* device descriptor so that the file system can be notified of a disk change.** RETURNS: N/A** NOMANUAL*/void tffsDiskChangeAnnounce    (    unsigned volNo		/* FLite drive number (0 - DRIVES-1) */    )    {    if ((volNo < DRIVES) && (tffsBlkDevs[volNo] != NULL))        tffsBlkDevs[volNo]->tffsBlkdev.bd_readyChanged = TRUE;    }/********************************************************************************* tffsDevFormat - format a flash device for use with TrueFFS** This routine formats a flash device for use with TrueFFS.  It takes two * parameters, a drive number and a pointer to a device format structure. * This structure describes how the volume should be formatted.  The structure * is defined in dosformt.h.  The drive number is assigned in the order that * the socket component for the device was registered.** The format process marks each erase unit with an Erase Unit Header (EUH) and* creates the physical and virtual Block Allocation Maps (BAM) for the device. * The erase units reserved for the "boot-image" are skipped and the first* EUH is placed at number (boot-image length - 1). To write to the boot-image* region, call tffsBootImagePut(). * * WARNING: If any of the erase units in the boot-image * region contains an erase unit header from a previous format call (this can* happen if you reformat a flash device specifying a larger boot region) * TrueFFS fails to mount the device.  To fix this problem, use tffsRawio() to* erase the problem erase units (thus removing the outdated EUH).  ** The macro TFFS_STD_FORMAT_PARAMS defines the default values used for * formatting a flask disk device. If the second argument to this routine * is zero, tffsDevFormat() uses these default values.** RETURNS: OK, or ERROR if it failed.*/STATUS tffsDevFormat     (    int tffsDriveNo,		/* TrueFFS drive number (0 - DRIVES-1) */    int arg			/* pointer to tffsDevFormatParams structure */    )    {    tffsDevFormatParams defaultParams = TFFS_STD_FORMAT_PARAMS;    tffsDevFormatParams *devFormatParams;    IOreq                ioreq;    FLStatus             status;    if (tffsDriveNo >= DRIVES)        return (ERROR);    /* tell dosFs to re-mount volume */      if (tffsBlkDevs[tffsDriveNo] != NULL)        tffsBlkDevs[tffsDriveNo]->tffsBlkdev.bd_readyChanged = TRUE;    if (arg == 0)        devFormatParams = &defaultParams;    else        devFormatParams = (tffsDevFormatParams *) arg;    ioreq.irHandle = tffsDriveNo;    ioreq.irFlags  = devFormatParams->formatFlags;    ioreq.irData   = &(devFormatParams->formatParams);    status = flFormatVolume(&ioreq);    return ((status == flOK) ? OK : ERROR);    }/********************************************************************************* tffsRawio - low level I/O access to flash components** Use the utilities provided by thisroutine with the utmost care. If you use * these routines carelessly, you risk data loss as well as  permanent * physical damage to the flash device.** This routine is a gateway to a series of utilities (listed below). Functions * such as mkbootTffs() and tffsBootImagePut() use these tffsRawio() utilities * to write boot sector information. The functions for physical read, write, and * erase are made available with the intention that they be used on erase units * allocated to the boot-image region by tffsDevFormat(). Using these functions * elsewhere could be dangerous.** The <arg0>, <arg1>, and <arg2> parameters to tffsRawio() are interpreted * differently depending on the function number you specify for <functionNo>. * The drive number is determined by the order in which the socket * components were registered. ** .TS* tab(|);* lf3 lf3 lf3 lf3* l l l l .* Function Name | arg0 | arg1 | arg2* _* TFFS_GET_PHYSICAL_INFO | user buffer address | N/A | N/A* TFFS_PHYSICAL_READ | address to read | byte count | user buffer address* TFFS_PHYSICAL_WRITE | address to write | byte count | user buffer address* TFFS_PHYSICAL_ERASE | first unit | number of units | N/A* TFFS_ABS_READ	| sector number | number of sectors | user buffer address* TFFS_ABS_WRITE | sector number | number of sectors | user buffer address* TFFS_ABS_DELETE | sector number | number of sectors | N/A* TFFS_DEFRAGMENT_VOLUME | number of sectors | user buffer address | N/A* .TE** TFFS_GET_PHYSICAL_INFO writes the flash type, erasable block size, and media* size to the user buffer specified in <arg0>.** TFFS_PHYSICAL_READ reads <arg1> bytes from <arg0> and writes them to * the buffer specified by <arg2>.** TFFS_PHYSICAL_WRITE copies <arg1> bytes from the <arg2> buffer and writes * them to the flash memory location specified by <arg0>.  * This aborts if the volume is already mounted to prevent the versions of * translation data in memory and in flash from going out of synchronization.** TFFS_PHYSICAL_ERASE erases <arg1> erase units, starting at the erase unit* specified in <arg0>.* This aborts if the volume is already mounted to prevent the versions of * translation data in memory and in flash from going out of synchronization.** TFFS_ABS_READ reads <arg1> sectors, starting at sector <arg0>, and writes* them to the user buffer specified in <arg2>.** TFFS_ABS_WRITE takes data from the <arg2> user buffer and writes <arg1> * sectors of it to the flash location starting at sector <arg0>.* * TFFS_ABS_DELETE deletes <arg1> sectors of data starting at sector <arg0>. ** TFFS_DEFRAGMENT_VOLUME calls the defragmentation routine with the minimum* number of sectors to be reclaimed, <arg0>, and writes the actual number * reclaimed in the user buffer by <arg1>. Calling this function through some * low priority task will make writes more deterministic.* No validation is done of the user specified address fields, so the functions * assume they are writable. If the address is invalid, you could see bus errors* or segmentation faults.* * RETURNS: OK, or ERROR if it failed.*/STATUS tffsRawio     (    int tffsDriveNo,		/* TrueFFS drive number (0 - DRIVES-1) */    int functionNo,		/* TrueFFS function code */    int arg0,			/* argument 0 */    int arg1,			/* argument 1 */    int arg2			/* argument 2 */    )    {    IOreq	ioreq;    FLStatus	status;    int		function;    if (tffsDriveNo >= DRIVES)        return (ERROR);    ioreq.irHandle = tffsDriveNo;	/* drive number */    switch (functionNo)	{	case TFFS_GET_PHYSICAL_INFO:	    function = FL_GET_PHYSICAL_INFO;	    ioreq.irData = (char *)arg0; /* address of user buffer to store */	    break;	case TFFS_PHYSICAL_READ:	    function = FL_PHYSICAL_READ;	    ioreq.irAddress = arg0;	/* chip/card address to read/write */	    ioreq.irByteCount = arg1;	/* number of bytes to read/write */	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */	    break;	case TFFS_PHYSICAL_WRITE:	    function = FL_PHYSICAL_WRITE;	    ioreq.irAddress = arg0;	/* chip/card address to read/write */	    ioreq.irByteCount = arg1;	/* number of bytes to read/write */	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */	    break;	case TFFS_PHYSICAL_ERASE:	    function = FL_PHYSICAL_ERASE;	    ioreq.irUnitNo = arg0;	/* first unit to erase */	    ioreq.irUnitCount = arg1;	/* number of units to erase */	    break;		case TFFS_ABS_READ:	    function = FL_ABS_READ;	    ioreq.irSectorNo = arg0;	/* sector number to read/write */	    ioreq.irSectorCount = arg1;	/* number of sectors to read/write */	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */	    break;		case TFFS_ABS_WRITE:	    function = FL_ABS_WRITE;	    ioreq.irSectorNo = arg0;	/* sector number to read/write */	    ioreq.irSectorCount = arg1;	/* number of sectors to read/write */	    ioreq.irData = (char *)arg2; /* address of user buffer to r/w */	    break;		case TFFS_ABS_DELETE:	    function = FL_ABS_DELETE;	    ioreq.irSectorNo = arg0;	/* sector number to delete */	    ioreq.irSectorCount = arg1;	/* number of sectors to delete */	    break;		case TFFS_DEFRAGMENT_VOLUME:	    function = FL_DEFRAGMENT_VOLUME;	    ioreq.irLength = arg0;	/* minimum number of sectors to get */	    break;		default:	    return (ERROR);	}    status = flCall (function, &ioreq);    switch (functionNo)	{	case TFFS_DEFRAGMENT_VOLUME:	    *(int *)arg1 = ioreq.irLength; /* min number of sectors gotten */	    break;	}    return ((status == flOK) ? OK : ERROR);    }#if     (POLLING_INTERVAL > 0)/********************************************************************************* flPollSemCreate - create semaphore for polling task** This routine creates the semaphore used to delay socket polling until* TrueFFS initialization is complete.** RETURNS: flOK, or flNotEnoughMemory if it fails.*/LOCAL FLStatus flPollSemCreate (void)    {    if ((flPollSemId = semBCreate (SEM_Q_PRIORITY, SEM_EMPTY)) == NULL)        return (flNotEnoughMemory);    else        return (flOK);    }#endif /* (POLLING_INTERVAL > 0) */

⌨️ 快捷键说明

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