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

📄 tfsapi.c

📁 uCOS-II for AT91M55800A完整实例
💻 C
字号:
/* tfsapi.c: *	This file contains the portion of TFS that provides the function-level *	API to the application.  If this is not being used by the application *	then it can be omitted from the monitor build. *	Note that not all of the api-specific code is here; some of it is in *	tfs.c.  This is because the the MicroMonitor uses some of the api itself, *	so it cannot be omitted from the TFS package without screwing up some  *	other monitor functionality that needs it. * *	General notice: *	This code is part of a boot-monitor package developed as a generic base *	platform for embedded system designs.  As such, it is likely to be *	distributed to various projects beyond the control of the original *	author.  Please notify the author of any enhancements made or bugs found *	so that all may benefit from the changes.  In addition, notification back *	to the author will allow the new user to pick up changes that may have *	been made by other users after this version of the code was distributed. * *	Author:	Ed Sutter *	email:	esutter@lucent.com		(home: lesutter@worldnet.att.net) *	phone:	908-582-2351			(home: 908-889-5161) */#include "config.h"#include "cpu.h"#include "stddefs.h"#include "genlib.h"#include "tfs.h"#if INCLUDE_TFSAPI/* tfstruncate(): *	To support the ability to truncate a file (make it smaller); this *	function allows the user to adjust the high-water point of the currently *	opened (and assumed to be opened for modification) file and replaces *	that with the incoming argument.  This replacement is only done if the *	current high-water point is higher than the incoming length. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfstruncate(int fd, long len){	struct tfsdat *tdat;	/* Verify valid range of incoming file descriptor. */	if ((fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADFD);	tdat = &tfsSlots[fd];	/* Make sure the file pointed to by the incoming descriptor is active	 * and that the incoming length is greater than the current high-water	 * point...	 */	if (tdat->offset == -1)		return(TFSERR_BADFD);	if (len > tdat->hwp)		return(TFSERR_BADARG);	/* Make the adjustment... */	tdat->hwp = len;	return(TFS_OKAY);}/* tfseof(): *	Return 1 if at the end of the file, else 0 if not at end; else negative *	if error. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfseof(int fd){	struct tfsdat *tdat;	/* Verify valid range of incoming file descriptor. */	if ((fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	/* Make sure the file pointed to by the incoming descriptor is active. */	if (tdat->offset == -1)		return(TFSERR_BADFD);	if (tdat->offset >= tdat->hdr.filsize)		return(1);	else		return(0);}/* tfsread(): *	Similar to a standard read call to a file. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsread(int fd, char *buf, int cnt){	struct tfsdat *tdat;	uchar *from;	if (tfsTrace > 1)		printf("tfsread(%d,0x%lx,%d)\n",fd,(ulong)buf,cnt);	/* Verify valid range of incoming file descriptor. */	if ((cnt < 1) || (fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	/* Make sure the file pointed to by the incoming descriptor is active. */	if (tdat->offset == -1)		return(TFSERR_BADFD);	if (tdat->offset >= tdat->hdr.filsize)		return(TFSERR_EOF);	from = (uchar *) tdat->base + tdat->offset;	/* If request size is within the range of the file and current	 * then copy the data to the requestors buffer, increment offset 	 * and return the count.	 */	if ((tdat->offset + cnt) <= tdat->hdr.filsize) {		if (tfsmemcpy(buf, from, cnt,0,0) != 0)			return(TFSERR_MEMFAIL);	}	/* If request size goes beyond the size of the file, then copy	 * to the end of the file and return that smaller count.	 */	else {		cnt = tdat->hdr.filsize - tdat->offset;		if (tfsmemcpy(buf, from, cnt, 0, 0) != 0)			return(TFSERR_MEMFAIL);	}	tdat->offset += cnt;	tdat->wptr += cnt;	return(cnt);}/* tfswrite(): *	Similar to a standard write call to a file. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfswrite(int fd, char *buf, int cnt){	struct tfsdat *tdat;	if (tfsTrace > 1)		printf("tfswrite(%d,0x%lx,%d)\n", fd,(ulong)buf,cnt);	/* Verify valid range of incoming file descriptor. */	if ((cnt < 1) || (fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	/* Make sure the file pointed to by the incoming descriptor is active. */	if (tfsSlots[fd].offset == -1)		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	/* Make sure file is not opened as read-only */	if (tdat->flagmode & TFS_RDONLY)		return(TFSERR_RDONLY);	if (tfsmemcpy(tdat->wptr,buf,cnt,0,0) != 0)		return(TFSERR_MEMFAIL);	tdat->wptr += cnt;	tdat->offset += cnt;	/* If new offset is greater than current high-water point, then	 * adjust the high water point so that it is always reflecting the	 * highest offset into which the file has had some data written.	 */	if (tdat->offset > tdat->hwp)		tdat->hwp = tdat->offset;	return(TFS_OKAY);}/* tfsseek(): *	Adjust the current pointer into the specified file. *	If file is read-only, then the offset cannot exceed the file size; *	otherwise, the only check made to the offset is that it is positive. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsseek(int fd, int offset, int whence){	int	o_offset;	uchar *o_wptr;	struct tfsdat *tdat;	if ((fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	o_offset = tdat->offset;	o_wptr = tdat->wptr;	switch (whence) {		case TFS_BEGIN:			tdat->offset = offset;			tdat->wptr = tdat->base+offset;			break;		case TFS_CURRENT:			tdat->offset += offset;			tdat->wptr += offset;			break;		default:			return(TFSERR_BADARG);	}	/* If new offset is less than zero or if the file is read-only and the	 * new offset is greater than the file size, return EOF...	 */	if ((tdat->offset < 0) ||		((tdat->flagmode & TFS_RDONLY) && (tdat->offset > tdat->hdr.filsize))){		tdat->offset = o_offset;		tdat->wptr = o_wptr;		return(TFSERR_EOF);	}	return(TFS_OKAY);}/* tfsgetline(): *	Read into the buffer a block of characters upto the next CR or LF in *	the file.  After the CR/LF, or after max-1 chars are loaded, terminate *	with a NULL.  Return the number of characters loaded. *	At end of file return 0. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsgetline(int fd,char *buf,int max){	int		cnt;	uchar	*from, *fromtmp;	struct	tfsdat *tdat;	max--;	if (tfsTrace > 1)		printf("tfsgetline(%d,0x%lx,%d)\n",fd,(ulong)buf,max);	/* Verify valid range of incoming file descriptor. */	if ((max < 1) || (fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	/* Make sure the file pointed to by the incoming descriptor is active. */	if (tfsSlots[fd].offset == -1)		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	if (tdat->offset == -1)		return(TFSERR_BADFD);	if (tdat->offset >= tdat->hdr.filsize)		return(0);	from = (uchar *) tdat->base + tdat->offset;	/* Determine the count based on the presence (or lack thereof) of a	 * carriage return or line feed...	 */	for(fromtmp=from,cnt=0;cnt<max && *fromtmp;cnt++,fromtmp++) {		if ((*fromtmp == '\r') || (*fromtmp == '\n')) {			cnt++;			break;		}	}	/* If request size is within the range of the file and current	 * then copy the data to the requestors buffer, increment offset	 * and return the count.	 */	if ((tdat->offset + cnt) <= tdat->hdr.filsize) {		if (tfsmemcpy(buf, from, cnt,0,0) != 0)			return(TFSERR_MEMFAIL);	}	/* If request size goes beyond the size of the file, then copy	 * to the end of the file and return that smaller count.	 */	else {		cnt = tdat->hdr.filsize - tdat->offset;		if (tfsmemcpy(buf, from, cnt, 0, 0) != 0)			return(TFSERR_MEMFAIL);	}	buf[cnt] = 0;	tdat->offset += cnt;	return(cnt);}/* tfsipmod(): *	Modify "in-place" a portion of a file in TFS. *	This is a cheap and dirty way to modify a file... *	The idea is that a file is created with a lot of writeable flash space *	(data = 0xff).  This function can then be called to immediately modify *	blocks of space in that flash.  It will not do any tfsunlink/tfsadd, and *	it doesn't even require a tfsopen() tfsclose() wrapper.  Its a fast and *	efficient way to modify flash in the file system. *	Arguments: *	name	=	name of the file to be in-place-modified; *	buf		=	new data to be written to flash; *	offset	=	offset into file into which new data is to be written; *	size	=	size of new data (in bytes). *	 *	With offset of -1, set offset to location containing first 0xff value. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsipmod(char *name,char *buf,int offset,int size){	TFILE	*fp;	uchar	*cp;	fp = tfsstat(name);	if (!fp)		return (TFSERR_NOFILE);	if (!(fp->flags & TFS_IPMOD))		return(TFSERR_NOTIPMOD);		if (offset == -1) {		cp = (uchar *)(TFS_BASE(fp));		for (offset=0;offset<fp->filsize;offset++,cp++) {			if (*cp == 0xff)				break;		}	}	else if (offset < -1)		return(TFSERR_BADARG);		if ((offset + size) > fp->filsize)		return(TFSERR_WRITEMAX);		if (tfsflashwrite((ulong *)(TFS_BASE(fp))+offset,(ulong *)buf,size) == -1)		return (TFSERR_FLASHFAILURE);	tfslog(TFSLOG_IPM,name);	return(TFS_OKAY);}/* tfsopen(): *	Open a file for reading or creation.  If file is opened for writing, *	then the caller must provide a RAM buffer  pointer to be used for *	the file storage until it is transferred to flash by tfsclose(). *	Note that the "buf" pointer is only needed for opening a file for *	creation or append (writing). *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsopen(char *file,long flagmode,char *buf){	register int i;	int		errno, retval;	long	fmode;	TFILE	*fp;	struct	tfsdat *slot;	/* See if file exists... */	fp = tfsstat(file);	/* If file exists, do a crc32 on the data... */	if (fp) {		if (crc32(TFS_BASE(fp),fp->filsize) != fp->filcrc) {			retval = TFSERR_BADCRC;			goto done;		}	}	errno = TFS_OKAY;	fmode = flagmode & (TFS_RDONLY | TFS_APPEND | TFS_CREATE);	/* This switch verifies...	 * - that the file exists if TFS_RDONLY or TFS_APPEND	 * - that the file does not exist if TFS_CREATE	 */	switch(fmode) {	case TFS_RDONLY:	/* Read existing file only, no change to file at all. */		if (!fp)			errno = TFSERR_NOFILE;		else {			if ((fp->flags & TFS_UNREAD) && (TFS_USRLVL(fp) > getUsrLvl()))				errno = TFSERR_USERDENIED;		}		break;	case TFS_APPEND:	/* Append to the end of the current file. */		if (!fp)			errno = TFSERR_NOFILE;		else {			if (TFS_USRLVL(fp) > getUsrLvl())				errno = TFSERR_USERDENIED;		}		break;	case TFS_CREATE:	/* Create a new file */		if (fp)			errno = TFSERR_FILEEXISTS;		break;	case (TFS_APPEND|TFS_CREATE):	/* If both mode bits are set, clear one */		if (fp) {					/* based on the presence of the file. */			if (TFS_USRLVL(fp) > getUsrLvl())				errno = TFSERR_USERDENIED;			fmode = TFS_APPEND;		}		else {			fmode = TFS_CREATE;		}		break;	default:		errno = TFSERR_BADARG;		break;	}	if (errno != TFS_OKAY) {		retval = errno;		goto done;	}	slot = tfsSlots;	for (i=0;i<TFS_MAXOPEN;i++,slot++) {		if (slot->offset == -1) {			slot->hwp = 0;			slot->offset = 0;			slot->flagmode = fmode;			if (fmode & TFS_CREATE) {				strncpy(slot->hdr.name,file,TFSNAMESIZE);				slot->flagmode |= (flagmode & TFS_FLAGMASK);				slot->base = (uchar *)buf;				slot->wptr = (uchar *)buf;			}			else if (fmode & TFS_APPEND) {				slot->hdr = *fp;				if (tfsmemcpy(buf,(uchar *)(TFS_BASE(fp)),					fp->filsize,0,0) != 0) {					retval = TFSERR_MEMFAIL;					goto done;				}				slot->flagmode = fp->flags;				slot->flagmode |= TFS_APPEND;				slot->base = (uchar *)buf;				slot->wptr = (uchar *)buf+fp->filsize;				slot->hwp = fp->filsize;				slot->offset = fp->filsize;			}			else {				slot->base = (uchar *) (TFS_BASE(fp));				slot->wptr = 0;				slot->hdr = *fp;			}			break;		}	}	if (i == TFS_MAXOPEN)		retval = TFSERR_NOSLOT;	else		retval = i;done:			if (tfsTrace > 0)		printf("tfsopen(%s,0x%lx,0x%lx)=%d\n",file,flagmode,(ulong)buf,retval);	return(retval);}/* tfsclose(): *	If the file was opened for reading only, then just close out the  *	entry in the tfsSlots table.  If the file was opened for creation, *	then add it to the tfs list.  Note the additional argument is *	only needed for tfsclose() of a newly created file. *	info  = additional text describing the file. *	MONLIB NOTICE: this function is accessible through monlib.c. */inttfsclose(int fd,char *info){	int		err;	struct tfsdat *tdat;	if (tfsTrace > 0)		printf("tfsclose(%d,%s)\n",fd,info);	if ((fd < 0) || (fd >= TFS_MAXOPEN))		return(TFSERR_BADARG);	tdat = &tfsSlots[fd];	if (tdat->offset == -1)		return(TFSERR_BADFD);	/* Mark the file as closed by setting the offset to -1.	 * Note that this is done prior to potentially calling tfsadd() so	 * that tfsadd() will not think the file is opened and reject the add...	 */	tdat->offset = -1;	/* If the file was opened for creation or append, then add it now. */	if (tdat->flagmode & (TFS_CREATE | TFS_APPEND)) {		char	buf[16];		err = tfsadd(tdat->hdr.name, info, tfsflagsbtoa(tdat->flagmode,buf),			tdat->base, tdat->hwp);		if (err != TFS_OKAY) {			printf("%s: %s\n",tdat->hdr.name,tfserrmsg(err));			return(err);		}	}	return(TFS_OKAY);}#else /* INCLUDE_TFSAPI */inttfstruncate(int fd, long len){	return(TFSERR_NOTAVAILABLE);}inttfseof(int fd){	return(TFSERR_NOTAVAILABLE);}inttfsread(int fd, char *buf, int cnt){	return(TFSERR_NOTAVAILABLE);}inttfswrite(int fd, char *buf, int cnt){	return(TFSERR_NOTAVAILABLE);}inttfsseek(int fd, int offset, int whence){	return(TFSERR_NOTAVAILABLE);}inttfsopen(char *file,long flagmode,char *buf){	return(TFSERR_NOTAVAILABLE);}inttfsclose(int fd,char *info){	return(TFSERR_NOTAVAILABLE);}inttfsgetline(int fd,char *buf,int max){	return(TFSERR_NOTAVAILABLE);}inttfsipmod(char *name,char *buf,int offset,int size){	return(TFSERR_NOTAVAILABLE);}#endif	/* INCLUDE_TFSAPI else */

⌨️ 快捷键说明

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