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

📄 fsmdfs.c

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

		read_dirname[FIELD_SIZE(FsmFileDirEntryT, FileName)] = 0;

		if(strcmp(dirname, read_dirname) == 0)
		{
			*ParentDirFirstLsn = FirstLsn;
			FirstLsn = entry->FirstLsn;

			SectorLsn = FirstLsn;
			sector_offset = 0;

			offset += start + dir_name_len;

			if(offset >= name_len)
				break;

			if(entry->Type != ENTRY_TYPE_SUBDIR)
			{
				status = ERR_NOTEXIST;
				break;
			}

			GetFirstPath(&path[offset], &start, &dir_name_len);

			if(dir_name_len > max_name_len)
			{
				status = ERR_PARAM;
				break;
			}

			FsmMemoryMove((uint8 *)dirname, (uint8 *)&path[offset + start], dir_name_len);
			dirname[dir_name_len] = 0;
		}
		else
		{
			sector_offset += sizeof(FsmFileDirEntryT);
		}
	}

	if(status == ERR_EOF)
	{
		status = ERR_NOTEXIST;
	}

	return status;
}


/* read a file directory entry from flash. */
static uint32 DfsReadFileEntry(
	FsmDevObjHdrT * DevP, 
	uint32	*	SectorLsn, 
	uint32	*	sector_offset,
	FsmFileDirEntryT * entry
	)
{
	uint32				status;
	uint32				sector_size;
	uint32				paddr;
	FsmFlashMediaT *	MediaP;

	DEV_READ_FUNCPTR	DevRead = DevP->DevDrvP->FsmDevRead;


#ifdef FSM_DEBUG
	MonPrintf("Enter the DfsReadFileEntry\n");
#endif

	MediaP = (FsmFlashMediaT *)DevP->MediaObjP;

	sector_size = MediaP->SectorSize;

	if((*sector_offset % sizeof(FsmFileDirEntryT)) != 0)
	{
		return ERR_PARAM;
	}

	status = FsmGetMtxSem(MediaP->MapTblLock);

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

	paddr = DfsLsn2Psn(MediaP, *SectorLsn);
	paddr = DfsPsn2Addr(MediaP, paddr);

	if(paddr == (uint32)(-1))
	{
		FsmReleaseMtxSem(MediaP->MapTblLock);
		return ERR_EOF;
	}

	while(TRUE)
	{
		status = ERR_NONE;

		/* advance to the right sector. */
		while(*sector_offset >= sector_size)
		{
			status = DevRead( DevP, 
							  (uint8 *)SectorLsn,
							  paddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
							  FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
							  );

			if(status != ERR_NONE)
			{
				break;
			}

			/*
			// If the sector should be validated first,
			// read out the whole sector header in the
			// previous DevRead. 
			if(SectorHdr.Status != SECTOR_VALID)
			{
				status = ERR_EOF;
				break;
			}

			*SectorLsn = SectorHdr.NextLsn;
			*/

			if(*SectorLsn == (uint32)(-1))
			{
				status = ERR_EOF;
				break;
			}

			paddr = DfsLsn2Psn(MediaP, *SectorLsn);
			paddr = DfsPsn2Addr(MediaP, paddr);

			if(paddr == (uint32)(-1))
			{
				status = ERR_EOF;
				break;
			}

			*sector_offset -= sector_size;
		}

		if(status != ERR_NONE)
		{
			break;
		}

		status = DevRead( DevP,
						  (uint8 *)entry, 
						  paddr + sizeof(FsmFlashSectorHdrT) + (*sector_offset),
						  sizeof(FsmFileDirEntryT)
						  );

		if(status != ERR_NONE)
		{
			break;
		}

		if(entry->Status == ENTRY_VALID)
		{
			if((entry->Type == ENTRY_TYPE_FILE) 
				|| (entry->Type == ENTRY_TYPE_SUBDIR))
			{
				break;
			}
		}

		*sector_offset += sizeof(FsmFileDirEntryT);
	}

	FsmReleaseMtxSem(MediaP->MapTblLock);

	return status;
}

/* read data from flash. */
uint32 DfsReadData(
	FsmDevObjHdrT * DevP,
	uint8	*		buf,
	uint32			FirstLsn,
	uint32			offset, 
	uint32			size, 
	uint32	*		read_size
	)
{
	uint32				status = ERR_NONE;
	uint32				sector_size;
	uint32				paddr;
	uint32				req_read_bytes;

	FsmFlashMediaT *	MediaP;
	DEV_READ_FUNCPTR	DevRead;


#ifdef FSM_DEBUG
	MonPrintf("Enter the DfsReadData\n");
#endif


	*read_size = 0;

	MediaP  = (FsmFlashMediaT *)DevP->MediaObjP;
	DevRead = DevP->DevDrvP->FsmDevRead;

	sector_size = MediaP->SectorSize;



	/* lock the write task.
	if ((status = FsmGetMtxSem(MediaP->MapTblLock)) != ERR_NONE )
	{
	    return status;
	}
	*/

	paddr = DfsLsn2Psn(MediaP, FirstLsn);	/* lsn -> psn */
	paddr = DfsPsn2Addr(MediaP, paddr);		/* psn -> address */

	if(paddr == (uint32)(-1))
	{
		/* FsmReleaseMtxSem(MediaP->MapTblLock); */
		return ERR_EOF;
	}

	while(size > 0)
	{
		status = ERR_NONE;

		while (offset >= sector_size)
		{
			status = DevRead( DevP,
							  (uint8 *)&FirstLsn,
							  paddr + FIELD_OFFSET(FsmFlashSectorHdrT, NextLsn),
							  FIELD_SIZE(FsmFlashSectorHdrT, NextLsn)
							  );

			if (status != ERR_NONE)
			{
				break;
			}

			if(FirstLsn == (uint32)(-1))
			{
				status = ERR_EOF;
				break;
			}

			paddr = DfsLsn2Psn(MediaP, FirstLsn);	/* lsn -> psn */
			paddr = DfsPsn2Addr(MediaP, paddr);		/* psn -> address */

			if(paddr == (uint32)(-1))
			{
				status = ERR_EOF;
				break;
			}

			offset -= sector_size;
		}

		if(status != ERR_NONE)
		{
			break;
		}

		req_read_bytes = sector_size - offset;

		if(size < req_read_bytes)
		{
			req_read_bytes = size;
		}

		status = DevRead( DevP,
						  (uint8 *)buf, 
						  paddr + sizeof(FsmFlashSectorHdrT) + offset,
						  req_read_bytes
						  );

		if(status != ERR_NONE)
		{
			break;
		}

		buf += req_read_bytes;
		*read_size += req_read_bytes;
		size -= req_read_bytes;
		offset += req_read_bytes;
	}

	/* FsmReleaseMtxSem(MediaP->MapTblLock); */

	return status;
}

/*
 FLASE  : contains invalid characters.
 TRUE   : doesn't contain invalid character, filename valid.
 */
static uint32 DfsFilenameValid(const char * path)
{
	uint32	len;
	uint32	i;

	if(path == NULL)
		return FALSE;

	len = strlen(path);

	if (len == 0)
		return FALSE;

	i = 0;

	while(i < len)
	{
		if ((path[i] == '?') || (path[i] == '*'))
		{
			return FALSE;
		}

		i++;
	}

	return TRUE;
}

/* caller is responsible for obtaining the FD semaphore. */
static uint32 DfsAllocFd()
{
	uint32	fd;

	for (fd = 0; fd < MAX_DFS_FD; fd++)
	{
		if (FsmDfsFds[fd].Flag == DFD_FLAG_FREE)
		{
			FsmDfsFds[fd].Flag = DFD_FLAG_PENDING;

			return fd;
		}
	}

	return INVALID_FILE_HANDLE;
}

static uint32 DfsFreeFd(uint32 fd)
{
	uint32		status;

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

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

	FsmDfsFds[fd].PathName[0] = 0;

	FsmDfsFds[fd].FdHdr.DevObjP = NULL;

	FsmDfsFds[fd].Flag = DFD_FLAG_FREE;

	FsmReleaseMtxSem(FsmDfsMtxSem);

	return ERR_NONE;
}

/* caller is responsible for obtaining the FD semaphore. */
static uint32 DfsIsFileOpened(char * path)
{
	uint32		fd;

	for (fd = 0; fd < MAX_DFS_FD; fd++)
	{
		/* skip if the fd is not in use. */
		if (FsmDfsFds[fd].Flag == DFD_FLAG_FREE)
		{
			continue;
		}

		/* This fd may be IN USE, 
		 * or PENDING (when it is closing, opening or creating).
		 */
		if (strcmp(FsmDfsFds[fd].PathName, path) == 0)
		{
			return fd;
		}
	}

	return INVALID_FILE_HANDLE;
}

/* caller is responsible for obtaining the FD semaphore. */
/* check whether the parent directory is opened. */
static uint32 DfsIsParentDirOpened(char * path)
{
#ifdef DFS_DIR_LOCK_ENABLED

	uint32		len;
	char		dir[DFS_MAX_PATH_LEN + 1];
	uint32		i;


	if(ExtractDir(path, &len) != 0)
	{
		if(len > 0)
		{
			FsmMemoryMove((uint8 *)dir, (uint8 *)path, len);
			dir[len] = 0; /* It is a zero-end string now. */

			/* If it is not root dir, then discard the last slash. */
			if(len != 1)
				dir[len - 1] = 0; 
		}
		else
		{
			return 1;
		}
	}
	else
	{
		return 1;
	}

	for (i = 0; i < MAX_DFS_FD; i++)
	{
		if (FsmDfsFds[i].Flag != DFD_FLAG_FREE)
		{
			if(strcmp(dir, FsmDfsFds[i].PathName) == 0)
			{
				return 1
			}
		}
	}
#endif

	return 0;
}

/* avaliable space calculate. */
uint32 DfsAvailSpaceCalc(FsmFlashMediaT * MediaP)
{
	uint32		i;
	uint32		Blocks;
	uint32		AvailSpace = 0;
	uint32		reseverdSpace;

	if (FsmGetMtxSem(MediaP->InfoLock) != ERR_NONE)
	{
		return 0;
	}

	Blocks = ((FsmFlashDevT *)( MediaP->MediaObjHdr.DevObjP))->Blocks;

	for (i = 0; i < Blocks; i++)
	{
		if (i == MediaP->SpareBlk)
		{
			continue;
		}

		AvailSpace += MediaP->BlockInfoP[i].FreeSectors;
		AvailSpace += MediaP->BlockInfoP[i].DirtySectors;
	}

	reseverdSpace = 0;

	GetAccumSize(&reseverdSpace);

	AvailSpace -= reseverdSpace;

    FsmReleaseMtxSem(MediaP->InfoLock);

	return AvailSpace;
}

/* translate logical sector number to physical sector number */
uint32 DfsLsn2Psn(FsmFlashMediaT * MediaObjP, uint32 Lsn)
{
	uint32		Psn;

	/*
	if (FsmGetMtxSem((MediaObjP->MapTblLock)) != ERR_NONE )
	{
		return INVALID_PSN;
	}
	*/

	if ( Lsn >= MediaObjP->MaxPsn )
	{
		Psn = INVALID_PSN;
	}
	else
	{
		Psn = MediaObjP->Lsn2PsnP[Lsn];
	}

	/* FsmReleaseMtxSem((MediaObjP->MapTblLock)); */

	return Psn;
}

/* translate pyhsical sector number to address */
uint32 DfsPsn2Addr(FsmFlashMediaT * MediaObjP, uint32 psn)
{
	uint16		pbn;
	uint16		psn_rest;
	uint32		psn_addr;

	uint32		sectors_per_blk;
	uint32		blk_size;
	uint32		sector_size;

	sectors_per_blk = MediaObjP->SectorsPerBlock;
	blk_size        = ((FsmFlashDevT *)(MediaObjP->MediaObjHdr.DevObjP))->BlockSize;
	sector_size     = MediaObjP->SectorSize + sizeof(FsmFlashSectorHdrT);

	if (psn == INVALID_PSN)
	{
	#ifdef FSM_DEBUG
        MonPrintf("\nError PSN input! Check your LSN");
	#endif

		return (uint32)(-1);
	}

	pbn = (uint16)(psn / sectors_per_blk);
	psn_rest = (uint16)(psn % sectors_per_blk);

	psn_addr = pbn * blk_size + psn_rest * sector_size;

	return psn_addr;
}

/*****************************************************************************
* $Log: FsmDfs.c $
* Revision 1.4  2004/03/17 12:57:22  zgy
* Revision 2.31  2004/03/16 15:54:22  jjs
* Revision 2.30  2004/03/11 15:09:06  jjs
* moved some functions from fileutil.c
* Revision 2.29  2004/02/20 17:32:33  jjs
* Reserved some flash space for modification operation.
* Revision 2.28  2003/12/10 19:42:17  jjs
* added directory name len validity check in DfsLocateFile().
* Revision 2.27  2003/11/25 17:07:36  wsm
* Revision 2.26  2003/11/25 16:53:31  wsm
* Revision 2.25  2003/11/25 16:01:50  wsm
* 1.format (use extern dfsformat to use it)
* 2.get blockinfo
* 3.attrib define change
* Revision 2.24  2003/11/11 11:29:01  jjs
* Check file validaty before open/create/delete.
* Revision 2.23  2003/11/05 11:37:12  jjs
* Revision 2.22  2003/11/05 11:18:18  jjs
* replaced //
* Revision 2.20  2003/10/26 11:25:41  jjs
* Revision 2.19  2003/10/26 10:56:40  jjs
* Revision 2.18  2003/10/24 17:23:06  jjs
* added support for device format.
* Revision 2.17  2003/10/24 16:23:09  jjs
* Revision 2.16  2003/10/24 14:06:38  jjs
* Revision 2.15  2003/10/23 15:50:39  jjs
* updated some comments.
* Revision 2.14  2003/10/22 14:32:30  jjs
* Revision 2.13  2003/10/22 10:48:51  jjs
* Revision 2.12  2003/10/21 11:06:48  jjs
* Revision 2.11  2003/10/21 10:21:43  jjs
* Revision 2.10  2003/10/16 10:32:04  jjs
* Revision 2.9  2003/10/15 16:49:53  jjs
* Revision 2.8  2003/10/10 14:00:46  jjs
* Revision 2.7  2003/10/09 17:46:30  jjs
* Revision 2.6  2003/10/08 21:09:33  jjs
* Revision 2.5  2003/10/08 18:07:28  jjs
* Revision 2.4  2003/10/08 17:39:29  jjs
* Revision 2.3  2003/10/08 12:40:45  jjs
* Revision 2.2  2003/09/20 15:27:01  wsm
* Revision 2.1  2003/09/20 14:36:35  wsm
* Revision 1.22  2003/09/20 12:36:25  wsm
* Revision 1.21  2003/09/19 14:07:34  wsm
* Revision 1.19  2003/09/19 10:59:40  wsm
* date/time set in lfd & space check
* Revision 1.18  2003/09/18 17:31:53  wsm
* Revision 1.17  2003/09/18 12:06:14  wsm
* Revision 1.16  2003/09/17 16:57:40  wsm
* Revision 1.15  2003/09/17 14:29:25  wsm
* Revision 1.14  2003/09/17 13:21:01  wsm
* Revision 1.13  2003/09/16 17:09:42  wsm
* Revision 1.12  2003/09/16 13:58:08  wsm
* Revision 1.11  2003/09/16 11:29:56  wsm
* Revision 1.10  2003/09/15 09:49:33  wsm
* Revision 1.9  2003/09/14 16:57:11  jjs
* Revision 1.8  2003/09/13 20:50:50  jjs
* Added FsmDfsStartup and FsmDfsExit functions.
* Revision 1.7  2003/09/12 15:19:16  wsm
* Revision 1.6  2003/09/12 14:46:46  wsm
* Revision 1.5  2003/09/12 10:18:11  wsm
* code style
* Revision 1.4  2003/09/11 15:02:04  wsm
* update Lfd check and output message
* Revision 1.3  2003/09/11 09:49:41  wsm
* update the Macro name
* Revision 1.2  2003/09/10 19:10:27  wsm
* update
* Revision 1.1  2003/09/09 15:07:32  wsm
* Initial revision
*****************************************************************************/

⌨️ 快捷键说明

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