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

📄 flash.c

📁 可移到ucos上的文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:

	if (bank >= FLASHBANKS) {
		printf("lastlargesector(%d) failed\n",bank);
		return(-1);
	}

	fbnk = &FlashBank[bank];
	sinfo = fbnk->sectors;
	largest_ssize = 0;
	largest_snum = 0;
	largest_sbase = (uchar *)0;

	for(i=0;i<fbnk->sectorcnt;i++,sinfo++) {
		if (sinfo->size >= largest_ssize) {
			largest_ssize = sinfo->size;
			largest_snum = sinfo->snum;
			largest_sbase = sinfo->begin;
		}
	}
	if (sector)
		*sector = largest_snum;
	if (size)
		*size = largest_ssize;
	if (base)
		*base = largest_sbase;
	return(0);
}

void
LowerFlashProtectWindow()
{
	if (FlashProtectWindow)
		FlashProtectWindow--;
}

/* AppFlashWrite():
 *	Takes in a source, destination and byte count and converts that to
 *	the appropriate flashwrite() call.  This function supports the possibility
 *	of having one write request span across multiple devices in contiguous
 *	memory space.
 */
int
AppFlashWrite(dest,src,bytecnt)
ulong	*src, *dest;
long bytecnt;
{
	struct flashinfo *fbnk;
	ulong	oints;
	int		ret;
	long	tmpcnt;

	ret = 0;
	while(bytecnt > 0) {
		fbnk = addrtobank((uchar *)dest);
		if (!fbnk)
			return(-1);
	
		if (((int)dest + bytecnt) <= (int)(fbnk->end))
			tmpcnt = bytecnt;
		else
			tmpcnt = ((int)(fbnk->end) - (int)dest) + 1;
	
		oints = FLASH_INTSOFF();
		ret = flashwrite(fbnk,(uchar *)dest,(uchar *)src,tmpcnt);
		FLASH_INTSRESTORE(oints);
		if (ret < 0) {
			printf("AppFlashWrite(0x%lx,0x%lx,%ld) failed\n",
				(ulong)dest,(ulong)src,bytecnt);
			break;
		}
		(int)dest += tmpcnt;
		(int)src += tmpcnt;
		bytecnt -= tmpcnt;
	}
	return(ret);
}

int
AppFlashEraseAll()
{
	int		ret, i;
	ulong	oints;
	struct	flashinfo *fbnk;

	oints = FLASH_INTSOFF();
	fbnk = FlashBank;
	for(i=0;i<FLASHBANKS;i++,fbnk++) {
		ret = flasherase(fbnk,ALL_SECTORS);
		if (ret == -1)
			break;
	}
	FLASH_INTSRESTORE(oints);
	return(ret);
}

/* Erase the flash sector specified. */
int
AppFlashErase(snum)	/* erase specified sector */
int snum;
{
	ulong	oints;
	uchar	*base;
	int		ret, size;
	struct	flashinfo *fbnk;

	sectortoaddr(snum,&size,&base);
	fbnk = addrtobank(base);
	if (!fbnk)
		return(-1);
	oints = FLASH_INTSOFF();
	ret = flasherase(fbnk,snum);
	FLASH_INTSRESTORE(oints);
	return(ret);
}


/* srange():
 *	Take the incoming string to be a number, number range or the string
 *	'all'. Return...
 *		SRANGE_ERROR	for error;
 *		SRANGE_SINGLE	for single sector (loaded in *lo);
 *		SRANGE_RANGE	for sector range (loaded in *lo & *hi);
 *		SRANGE_ALL		for all sectors.
 */
int
srange(char *rangestring, int *lo, int *hi)
{
	int	num1, num2;
	char *dash;

	if (!strcmp(rangestring,"all")) {
		*lo = ALL_SECTORS; 
		return(SRANGE_ALL);
	}

	dash = strchr(rangestring,'-');
	if (!dash) {
		if (isdigit(*rangestring)) {
			*lo = atoi(rangestring);
			return(SRANGE_SINGLE);
		}
		else
			return(SRANGE_ERROR);
	}
	*dash = 0;
	num1 = atoi(rangestring);
	num2 = atoi(dash+1);
	if (((num1 < 0) || (num2 < 0)) || (num1 >= num2))
		return(SRANGE_ERROR);
	*lo = num1;
	*hi = num2;
	return(SRANGE_RANGE);
}

/* sectorProtect():
 *	Set or clear (based on value of protect) the protected flag for the
 *	specified range of sectors...
 */
int
sectorProtect(char *range, int protect)
{
	struct	flashinfo *fbnk;
	int	i, lo, hi, all, dev, snum;

	all = 0;
	switch(srange(range,&lo,&hi)) {
	case SRANGE_ERROR:
		return(-1);
	case SRANGE_ALL:
		all = 1;
		break;
	case SRANGE_SINGLE:
		hi = lo;
		break;
	case SRANGE_RANGE:
		break;
	}
	snum = 0;
	for(dev=0;dev<FLASHBANKS;dev++) {
		fbnk = &FlashBank[dev];
		for(i=0;i<fbnk->sectorcnt;i++,snum++) {
			if (all || ((snum >= lo) && (snum <= hi)))
				fbnk->sectors[i].protected = protect;
		}
		if (snum > hi)
			break;
	}
	return(0);
}

#ifdef FLASHRAM_BASE
/* FlashRamInit():
 * This monitor supports TFS space allocated across multiple flash devices
 * that may not be in contiguous memory space.  To allow BBRAM to be seen
 * as a "flash-like" device to TFS, we set it up in sectors similar to
 * those in a real flash device.
 * Input...
 *	snum:	All the "flash" space is broken up into	individual sectors.
 *			This is the starting sector number that is to be used for
 *			the block of sectors within this BBRAM space.
 *	fbnk:	Pointer to the structure that must be populated with the
 *			flash bank information.  Usually this contains pointers to the
 *			functions that operate on the flash; but for RAM they aren't
 *			necessary.
 *	sinfo:	Table populated with the characteristics (size, start, etc...)
 *			of each sector.
 *	ssizes:	A table containing the size of each of the sectors.  This is
 *			copied to the sinfo space.
 */
int
FlashRamInit(int snum, int scnt, struct flashinfo *fbnk,
			struct sectorinfo *sinfo, int *ssizes)
{
	int	i;
    uchar	*begin;

	/* FLASHRAM_SECTORCOUNT (in config.h) must match the number of sectors
	 * allocated to the flash ram device in flashdev.c...
	 */
	if (scnt != FLASHRAM_SECTORCOUNT)
		printf("Warning: flashram sector count inconsistency\n");

    fbnk->id = FLASHRAM;						/* Device id. */
    fbnk->base = (uchar *)FLASHRAM_BASE;		/* Base address of bank. */
    fbnk->end = (uchar *)FLASHRAM_END;			/* End address of bank. */
    fbnk->sectorcnt = scnt;						/* Number of sectors. */
    fbnk->width = 1;							/* Width (in bytes). */
    fbnk->fltype = NotUsed;						/* Flashtype() function. */
    fbnk->flerase = NotUsed;					/* Flasherase() function. */
    fbnk->flwrite = NotUsed;					/* Flashwrite() function. */
    fbnk->flewrite = NotUsed;					/* Flashewrite() function. */
    fbnk->sectors = sinfo;					/* Ptr to sector size table. */
    begin = fbnk->base;
    for(i=0;i<fbnk->sectorcnt;i++,snum++) {
		sinfo[i].snum = snum;
		sinfo[i].size = ssizes[i];
		sinfo[i].begin = begin;
		sinfo[i].end = sinfo[i].begin + sinfo[i].size - 1;
		sinfo[i].protected = 0;
		begin += sinfo[i].size;
	}
	return(snum);
}
#endif

char *FlashHelp[] = {
	"Flash memory operations",
	"{op} [args]",
	"Ops...",
	"  opw",
	"  info",
	"  init",
	"  bank [#]",
	"  prot {SRNG}",
	"  unprot {SRNG}",
#if FLASH_LOCK_SUPPORTED
	"  lock {SRNG}",
	"  unlock {SRNG}",
	"  lockdwn {SRNG}",
#endif
	"  erase {SRNG}",
	"  write {dest} {src} {byte_cnt}",
	"  ewrite {dest} {src} {byte_cnt}",
	"",
	" SRNG..."
	"  Sector range specification: X, | X-Y | all",
	"  Where 'X' and 'Y' are sector numbers.",
	0,
};

/* FlashCmd():
 *	Code that handles the user interface.  See FlashHelp[] below for usage.
 */
int
FlashCmd(argc,argv)
int argc;
char **argv;
{
	int		snum, ret, lo, hi;
	ulong	dest, src, oints;
	long	bytecnt, rslt;
	struct	flashinfo *fbnk;

	oints = FLASH_INTSOFF();

	fbnk = &FlashBank[FlashCurrentBank];
	ret = 0;

	if (strcmp(argv[1],"init") == 0)
		FlashInit();
	else if (strcmp(argv[1],"info") == 0)
		showflashinfo(fbnk);
	else if (strcmp(argv[1],"bank") == 0)  {
		int	tmpbank;
		if (argc == 3) {
			tmpbank = atoi(argv[2]);
			if (tmpbank < FLASHBANKS)
				FlashCurrentBank = tmpbank;
			printf("Subsequent flash ops apply to bank %d\n",FlashCurrentBank);
		}
		else 
			printf("Current flash bank: %d\n",FlashCurrentBank);
	}
	else if (strcmp(argv[1],"ewrite") == 0) {
		if (argc == 5) {
			dest = strtoul(argv[2],(char **)0,0);
			src = strtoul(argv[3],(char **)0,0);
			bytecnt = (long)strtoul(argv[4],(char **)0,0);
			if (flashewrite(fbnk,(uchar *)dest,(uchar *)src,bytecnt) == -1)
				printf("ewrite failed\n");
		}
		else
			ret = -1;
	}
	else if (!strcmp(argv[1],"write")) {
		if (argc == 5) {
			dest = strtoul(argv[2],(char **)0,0);
			src = strtoul(argv[3],(char **)0,0);
			bytecnt = (long)strtoul(argv[4],(char **)0,0);
			rslt = flashwrite(fbnk,(uchar *)dest,(uchar *)src,bytecnt);
			if (rslt == -1)
				printf("Write failed\n");
		}
		else
			ret = -1;
	}
	else if (!strcmp(argv[1],"opw")) {
		FlashProtectWindow = 2;
	}
	else if (!strcmp(argv[1],"unprot")) {
		if (argc != 3)
			ret = -1;
		else
			sectorProtect(argv[2],0);
	}
	else if (!strcmp(argv[1],"prot")) {
		if (argc != 3) 
			ret = -1;
		else
			sectorProtect(argv[2],1);
	}
	else if (!strcmp(argv[1],"erase")) {
		if (argc != 3) {
			ret = -1;
		}
		else {
			switch(srange(argv[2],&lo,&hi)) {
			case SRANGE_ERROR:
				hi = 0;
				lo = 1;
				ret = -1;
				break;
			case SRANGE_ALL:
			case SRANGE_SINGLE:
				hi = lo;
				break;
			case SRANGE_RANGE:
				break;
			}
			for(snum=lo;snum<=hi;snum++) {
				rslt = flasherase(fbnk,snum);
				if (rslt == -1) {
					printf("Erase failed\n");
					break;
				}
			}
		}
	}
#if FLASH_LOCK_SUPPORTED
	else if ((!strcmp(argv[1],"lock")) || (!strcmp(argv[1],"unlock")) ||
		(!strcmp(argv[1],"lockdwn"))) {
		extern int flashlock(struct flashinfo *fbnk,int snum,int operation);
		int	operation, snum;

		if (!strcmp(argv[1],"lock")) 
			operation = FLASH_LOCK;
		else if (!strcmp(argv[1],"unlock")) 
			operation = FLASH_UNLOCK;
		else
			operation = FLASH_LOCKDWN;
		if (argc != 3)
			ret = -1;
		else {
			switch(srange(argv[2],&lo,&hi)) {
			case SRANGE_ERROR:
				hi = 0;
				lo = 1;
				ret = -1;
				break;
			case SRANGE_ALL:
			case SRANGE_SINGLE:
				hi = lo;
				break;
			case SRANGE_RANGE:
				break;
			}
			for(snum=lo;snum<=hi;snum++) {
				rslt = flashlock(fbnk,snum,operation);
				if (rslt == -1) {
					printf("Erase failed\n");
					break;
				}
			}
		}
	}
#endif
	else {
		ret = -1;
	}

	FLASH_INTSRESTORE(oints);
	return(ret);
}

int
NotUsed()
{
	printf("ERROR: flash operation not supported\n");
	return(0);
}

#endif

⌨️ 快捷键说明

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