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

📄 fsmvfs.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		return ERR_PARAM;
	}

	if(VolumeName == NULL)
		return ERR_PARAM;

	path = (char *)VolumeName;

    if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
	{
		return status;
	}

	VolIndex = FsmGetMatchedVolume(&path);

	if (VolIndex == MAX_VOLUME_NUM)
	{
		FsmReleaseMtxSem(FsmVolumeMtxSem);

		return ERR_PARAM;
	}

	FsmVolumes[VolIndex].RefCnt++; /* prevent volume from being unmounted. */

	FsP = FsmVolumes[VolIndex].FsDrvP;

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	GetFreeSpace.total_space = total_space;
	GetFreeSpace.avail_space = avail_space;
	GetFreeSpace.free_space  = free_space;
	GetFreeSpace.DevObjP     = FsmVolumes[VolIndex].DevObjP;

	status = FsP->FsmIoCtrl(INVALID_FILE_HANDLE, FSM_IOCTL_GET_FREE_SPACE, (void *)&GetFreeSpace);

	FsmGetMtxSem(FsmVolumeMtxSem);

	FsmVolumes[VolIndex].RefCnt--;

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	return status;
}

/*
* Function Name: FsmMount
* Description  : Delete a empty directory
* Arguments    : pFs             : fiel systme object
*              : pDev            : device object
*              : name            : mount path
*              : sectorsize      : sector size in bytes
* First Edit 2003.8.13 wsm
*/

uint32 FsmMount(FsmFsDrvT * pFs, FsmDevObjHdrT * pDev, const char * name, uint32 sectorsize)
{
	uint32		status;
	uint32		i;
	uint32		j;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmMount in %s,%d :Mount %s\n", __FILE__, __LINE__, name);
#endif

	if ((pDev == NULL) || (pFs == NULL) || (name  == NULL))
	{
		return ERR_PARAM;
	}

	if(GetFirstPath(name, &i, &j) == 0)
	{
		return ERR_PARAM; /* invalid volume name */
	}

	if(strlen(name) != j)
	{
		return ERR_PARAM;
	}

	FsmGetMtxSem(FsmVolumeMtxSem);
/*	if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
	{
		return status;
	}*/

	for(i = 0; i < MAX_VOLUME_NUM; i++ )
	{
		if (strcmp(FsmVolumes[i].VolName, name) == 0 )
		{
			FsmReleaseMtxSem(FsmVolumeMtxSem);
			return ERR_EXIST;	/* volume in use */
		}

		if (FsmVolumes[i].DevObjP == pDev )
		{
			FsmReleaseMtxSem(FsmVolumeMtxSem);
			return ERR_MOUNTED;	/* device in use */
		}
	}

	for(i = 0; i < MAX_VOLUME_NUM; i++ )
	{
		if (FsmVolumes[i].VolName[0] == 0 )
		{
			j = i;		/* get a empty volume */
			break;
		}
	}

	if (i >= MAX_VOLUME_NUM)
	{
		FsmReleaseMtxSem(FsmVolumeMtxSem);
		return ERR_MAX_VOLUME;
	}

	status = pFs->FsmInit(pDev, sectorsize);

	if(status == ERR_NONE)
	{
		FsmVolumes[j].DevObjP = pDev;
		FsmVolumes[j].FsDrvP  = pFs;
		strcpy(FsmVolumes[j].VolName, name);
	}
	else
	{
		FsmVolumes[j].VolName[0] = 0;
		FsmVolumes[j].FsDrvP  = NULL;
		FsmVolumes[j].DevObjP = NULL;
	}

	FsmVolumes[j].RefCnt = 0;

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	return status;
}

/*
* Function Name: FsmUnMount
* Description  : Delete a empty directory
* Arguments    : name             : volumn name (path)
* First Edit 2003.8.13 wsm
*/

uint32 FsmUnMount(const char * path)
{
	uint32			status = ERR_NONE;
	uint32          VolIndex;
	FsmFsDrvT     *	FsP;
	FsmDevObjHdrT *	DevP;
	char          * name;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmUnMount in %s,%d :Unmount %s\n", __FILE__, __LINE__, path);
#endif

	name = (char *)path;

	FsmGetMtxSem(FsmVolumeMtxSem);

	/* If it is called when system starts, FsmGetMtxSem always fails.
	status = FsmGetMtxSem(FsmVolumeMtxSem);

	if(status != ERR_NONE)
	{
		return status;
	}
	*/

	VolIndex = FsmGetMatchedVolume(&name);

	if (VolIndex == MAX_VOLUME_NUM)
	{
		status = ERR_PARAM;

		goto FsmUnMount_Exit;
    }

	/* ensure that all files opened externally have been closed. */
	if(FsmVolumes[VolIndex].RefCnt > 0)
	{
		status = ERR_ACCESS_DENY;

		goto FsmUnMount_Exit;
	}

	FsP  = FsmVolumes[VolIndex].FsDrvP;
	DevP = FsmVolumes[VolIndex].DevObjP;

	/* we should be sure that all files opened from  */
	/* this device internally also have been closed. */
	status = FsP->FsmTerminate(DevP);

	if(status == ERR_NONE)
	{
		FsmVolumes[VolIndex].VolName[0] = 0;

		FsmVolumes[VolIndex].DevObjP = NULL;
		FsmVolumes[VolIndex].FsDrvP = NULL;
	}

FsmUnMount_Exit:

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	return status;
}

/*
* Function Name: FsmFileIoCtrl
* Description  : send command to the file
* Arguments    : fd         : file descriptor
*              : cmd        : command
*              : arg        : argument pointer
* First Edit 2003.8.13 wsm
*/

uint32 FsmFileIoCtrl(uint32 fd, uint32 cmd, void * arg)
{
	uint32			status;
	FsmFsDrvT *		FsP;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmFileIoCtrl in %s,%d \n", __FILE__, __LINE__);
#endif

	if (fd >= MAX_VFS_FD)
	{
		return ERR_PARAM;
	}

	if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
	{
		FsmVfsFds[fd].ErrorCode = status;
		return status;
	}

	if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
		|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
		|| (FsmVfsFds[fd].VolumeP == NULL))
	{
		FsmVfsFds[fd].ErrorCode = ERR_PARAM;
		FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
		return ERR_PARAM;
	}

	FsP = FsmVfsFds[fd].VolumeP->FsDrvP;

	status = FsP->FsmIoCtrl(FsmVfsFds[fd].LowerFd, cmd, arg);

	FsmVfsFds[fd].ErrorCode = status;

	FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);

	return status;
}

/*
* Function Name: FsmOpenDir
* Description  : open a directory for read operation
* Arguments    : path       : directory path
* First Edit 2003.8.13 wsm
*/

uint32 FsmOpenDir(const char * dirname)
{
	uint32			status;
	uint32			VolIndex;
	FsmFsDrvT *		FsP;
	uint32			vfd;
	uint32			lfd;
	char   *		path;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmOpenDir in %s,%d :OpenDir %s \n", __FILE__, __LINE__, dirname);
#endif

	if(strlen(dirname) > MAX_PATH_LENGTH)
	{
		return INVALID_FILE_HANDLE;
	}

	path = (char *)dirname;

    if ((status = FsmGetMtxSem(FsmVolumeMtxSem)) != ERR_NONE )
	{
		return INVALID_FILE_HANDLE;
	}

	VolIndex = FsmGetMatchedVolume(&path);

	if (VolIndex == MAX_VOLUME_NUM)
	{
		FsmReleaseMtxSem(FsmVolumeMtxSem);

		return INVALID_FILE_HANDLE;
	}

	FsmVolumes[VolIndex].RefCnt++;	/* prevent volume from being unmounted. */

	FsP = FsmVolumes[VolIndex].FsDrvP;

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	vfd = FsmAllocVfd();

	if (vfd == INVALID_FILE_HANDLE)
	{
		goto OpenDir_Exit;
	}

	status = FsmGetMtxSem(FsmVfsFds[vfd].MutexSem);

	if(status != ERR_NONE)
	{
		FsmFreeVfd(vfd);

		goto OpenDir_Exit;
	}

	FsmVfsFds[vfd].LowerFd = (uint32)(-1);
	FsmVfsFds[vfd].VolumeP    = &FsmVolumes[VolIndex];
	FsmVfsFds[vfd].ErrorCode  = ERR_NONE;

	lfd = FsP->FsmOpen( FsmVolumes[VolIndex].DevObjP,
						path, 
						FSM_OPEN_DIR | FSM_OPEN_READ | FSM_OPEN_EXISTING,
						&status
						);

	if(lfd != INVALID_FILE_HANDLE)
	{
		FsmVfsFds[vfd].LowerFd = lfd;
		FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
		return vfd;
	}

	FsmReleaseMtxSem(FsmVfsFds[vfd].MutexSem);
	FsmFreeVfd(vfd);

OpenDir_Exit:

	FsmGetMtxSem(FsmVolumeMtxSem);

	FsmVolumes[VolIndex].RefCnt--;

	FsmReleaseMtxSem(FsmVolumeMtxSem);

	return INVALID_FILE_HANDLE;
}

/*
* Function Name: FsmReadDir
* Description  : open a directory for read operation
* Arguments    : DirId       : directory descriptor
*              : direntry    : directory info buffer
* First Edit 2003.8.13 wsm
*/

uint32 FsmReadDir(uint32 fd, FsmFileInfoT * FileInfo)
{
	uint32			status;
	FsmFsDrvT *		FsP;
	uint32			size;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmReadDir in %s,%d \n", __FILE__, __LINE__);
#endif

	if (fd >= MAX_VFS_FD)
	{
		return ERR_PARAM;
	}

	if (FileInfo == NULL)
	{
		FsmVfsFds[fd].ErrorCode = ERR_PARAM;
		return ERR_PARAM;
	}

	if ((status = FsmGetMtxSem(FsmVfsFds[fd].MutexSem)) != ERR_NONE)
	{
		FsmVfsFds[fd].ErrorCode = status;
		return status;
	}

	if((FsmVfsFds[fd].Flag == VFD_FLAG_FREE)
		|| (FsmVfsFds[fd].LowerFd == (uint32)(-1))
		|| (FsmVfsFds[fd].VolumeP == NULL))
	{
		FsmVfsFds[fd].ErrorCode = ERR_PARAM;
		FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);
		return ERR_PARAM;
	}

	FsP = FsmVfsFds[fd].VolumeP->FsDrvP;

	size = FsP->FsmRead( FsmVfsFds[fd].LowerFd, 
						 (uint8 *)FileInfo, 
						 sizeof(FsmFileInfoT),
						 &status
						 );

	FsmVfsFds[fd].ErrorCode = status;

	FsmReleaseMtxSem(FsmVfsFds[fd].MutexSem);

	return status;
}

/*
* Function Name: FsmCloseDir
* Description  : close an opened directory
* Arguments    : DirId       : directory descriptor
* First Edit 2003.8.13 wsm
*/

uint32 FsmCloseDir(uint32 fd)
{
	return FsmClose(fd);
}

/*********************************************
 *
 * Function Name: FsmFormat
 *
 * Description  : format the flash
 * Arguments    : VolumeName
 *
 * First Edit 2003.8.13 wsm
 *
 * anyhow, you should reboot the 
 * system after this function is called
**********************************************/

uint32 FsmFormat(FsmFormatArgumentT * FormatArg)
{
   	uint32			status = ERR_NONE;
	uint32          VolIndex;
	FsmFsDrvT     *	FsP;
	FsmDevObjHdrT *	DevP;
	char          * name;

#ifdef FSM_DEBUG
	MonPrintf("Interface FsmFormat :Format\n");
#endif

    if (FormatArg == NULL)
    {
        return ERR_PARAM;
    }

    if (FormatArg->mode == FSM_FORMAT_NAME)
    {
        name = FormatArg->Param.VolumeName;

        status = FsmGetMtxSem(FsmVolumeMtxSem);

        if(status != ERR_NONE)
        {
            return status;
        }

        VolIndex = FsmGetMatchedVolume(&name);  

        if (VolIndex == MAX_VOLUME_NUM)
        {
            status = ERR_PARAM;

			FsmReleaseMtxSem(FsmVolumeMtxSem);

            return status;
        }

        FsP  = FsmVolumes[VolIndex].FsDrvP;
        DevP = FsmVolumes[VolIndex].DevObjP;

		FsmReleaseMtxSem(FsmVolumeMtxSem);

		status = FsmUnMount(FormatArg->Param.VolumeName);

        if(status != ERR_NONE)
        {
			return status;
        }

    }
    else if (FormatArg->mode == FSM_FORMAT_DEV)
    {
        uint32		i;

        /* maybe the volume has been mounted successful */

        DevP = FormatArg->Param.DevArg.DevP; 
        FsP  = FormatArg->Param.DevArg.FsP; 
        
        status = FsmGetMtxSem(FsmVolumeMtxSem);
/*
        if(status != ERR_NONE)
        {
            return status;
        }
*/
        for(i = 0; i < MAX_VOLUME_NUM; i++)
        {
            if(FsmVolumes[i].DevObjP == DevP)
            {
				break;
            }
        }

		FsmReleaseMtxSem(FsmVolumeMtxSem);

		if(i < MAX_VOLUME_NUM)
		{
            status = FsmUnMount(FsmVolumes[i].VolName);

            if(status != ERR_NONE)
            {
                return status;
            }
		}
    }
    else
    {
        return ERR_PARAM;
    }

    /* The data item always coexist on the same device with data file system. */
	if (DevP == FsmDataItemDevObjP)
	{
		status = FsmDataItemExit();

		if(status != ERR_NONE)
		{
			return status;
		}
	}

	status = FsP->FsmIoCtrl(INVALID_FILE_HANDLE, FSM_IOCTL_FORMAT, (void *)DevP);

	return status;
}



/*------------------------- local function --------------------------*/

static uint32 FsmAllocVfd()
{
	uint32		i;

	if (FsmGetMtxSem(FsmVfsMtxSem) != ERR_NONE)
	{
#ifdef FSM_DEBUG
		MonPrintf("VFDLock semaphore fail!\n");
#endif
		return INVALID_FILE_HANDLE;
	}

	for (i = 0; i < MAX_VFS_FD; i++ )
	{
		if (FsmVfsFds[i].Flag == VFD_FLAG_FREE)
		{
		    FsmVfsFds[i].Flag = VFD_FLAG_IN_USE;
			FsmReleaseMtxSem(FsmVfsMtxSem);
			return i;
		}
	}

	FsmReleaseMtxSem(FsmVfsMtxSem);

	return INVALID_FILE_HANDLE;
}

static uint32 FsmFreeVfd(uint32 vfd)
{
	uint32		status;

	if (vfd >= MAX_VFS_FD)
	{
		return ERR_PARAM;
	}

	if ((status = FsmGetMtxSem(FsmVfsMtxSem)) != ERR_NONE )
	{
#ifdef FSM_DEBUG
		MonPrintf("VFDLock semaphore fail!\n");
#endif
		return status;
	}

	FsmVfsFds[vfd].LowerFd = (uint32)(-1);
	FsmVfsFds[vfd].VolumeP = NULL;
	FsmVfsFds[vfd].ErrorCode = 0;
	FsmVfsFds[vfd].Flag = VFD_FLAG_FREE;

	FsmReleaseMtxSem(FsmVfsMtxSem);

	return ERR_NONE;
}

/* The caller of this function should be 
 * responsible for obtaining the FsmVolumeMtxSem 
 * semaphore before call this function. */
static uint32 FsmGetMatchedVolume (char ** path)
{
	uint32		i, j;
	uint32		volume_len;
	uint32		offset;

	if(GetFirstPath(*path, &offset, &volume_len) == 0)
	{
		return MAX_VOLUME_NUM;
	}

	/*
	if (FsmGetMtxSem(FsmVolumeMtxSem) != ERR_NONE )
	{
		return MAX_VOLUME_NUM;
	}
	*/

	for (i = 0; i < MAX_VOLUME_NUM; i++ )
	{
		if (strlen(FsmVolumes[i].VolName) == volume_len )
		{
			for (j = 0; j < volume_len; j++ )
			{
				if (FsmVolumes[i].VolName[j] != (*path)[offset + j] )
				{
					break;
				}
			}

			if( j >= volume_len)
			{
				(*path) += (offset + volume_len);
				break;
				/*
				FsmReleaseMtxSem(FsmVolumeMtxSem);
				return i;
				*/
			}
		}
	}

	/*
	FsmReleaseMtxSem(FsmVolumeMtxSem);
	*/

	return i;
	/* return MAX_VOLUME_NUM; */
}


/*****************************************************************************
* $Log: FsmVfs.c $
* Revision 1.3.1.2  2004/04/05 12:31:24  zgy
* Modify FsmFormat.
* Revision 1.3.1.1  2004/03/17 12:58:53  zgy
* Duplicate revision
* Revision 1.3  2004/03/17 12:58:53  zgy
* Revision 1.29  2004/03/16 16:00:50  jjs
* Revision 1.28  2004/03/11 14:51:49  jjs
* Added vfs initialize function
* Revision 1.27  2003/11/25 16:02:48  wsm
* 1.remove fsmformat (use extern dfsformat to use it)
* Revision 1.26  2003/11/05 11:37:38  jjs
* Revision 1.25  2003/11/05 11:25:30  jjs
* replaced //
* Revision 1.23  2003/10/26 17:00:37  jjs
* Fixed the return code bug in FsmEof function. Updated the funtion prototype.
* Revision 1.22  2003/10/26 11:25:57  jjs
* Revision 1.21  2003/10/26 11:14:14  jjs
* Revision 1.20  2003/10/24 17:08:30  jjs
* added Support  for Volume format.
* Revision 1.19  2003/10/22 10:40:31  jjs
* Added support for 16-byte file name searching.
* Revision 1.18  2003/10/15 18:22:29  jjs
* Revision 1.17  2003/10/08 18:07:34  jjs
* Revision 1.16  2003/10/08 17:29:12  jjs
* Revision 1.15  2003/10/08 12:46:16  jjs
* Revision 1.14  2003/09/20 16:58:14  wsm
* Revision 1.13  2003/09/20 12:36:19  wsm
* Revision 1.12  2003/09/19 11:26:19  wsm
* Revision 1.11  2003/09/16 17:12:39  wsm
* Revision 1.10  2003/09/16 11:36:03  wsm
* Revision 1.9  2003/09/15 14:40:38  wsm
* Revision 1.8  2003/09/15 10:00:23  wsm
* Revision 1.7  2003/09/14 16:55:45  jjs
* Revision 1.6  2003/09/12 15:27:56  wsm
* Revision 1.5  2003/09/12 15:05:27  wsm
* Revision 1.4  2003/09/11 15:05:58  wsm
* update out put message
* Revision 1.3  2003/09/11 09:58:17  wsm
* update the Macro name
* Revision 1.2  2003/09/10 19:11:13  wsm
* update
* Revision 1.1  2003/09/09 15:07:32  wsm
* Initial revision
*****************************************************************************/

⌨️ 快捷键说明

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