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

📄 fatlib.c

📁 The high portable FAT filesystem library for embedded system.
💻 C
📖 第 1 页 / 共 3 页
字号:
	else
	{
		while((i < BUFFER_SIZE) && (index < 0))
		{
			if(openedRead[i].fileHandle == -1)
			{
				index = i;
			}
			i++;
		}
	}
	cluster = fileSys;	
	if(*pathname == 0x5C)
	{
		pathname++;
	}
	tempPathname = pathname;

	while(*tempPathname)
	{
		if(*tempPathname == 0x5C)
			return -128;
		tempPathname++;
	}	

	tempPathname = pathname;
	if(cluster != 0)
	{
		tempCluster = cluster;
		cluster = getFirstCluster(tempPathname, cluster, buf, FILE, &fileSize);
	}
	else
	{
		return -1;
	}
	if(cluster > 0)
	{
		i = openedCheck(cluster);
		if( i < 0 )
		{
			if(i ==  -1)
			{
				return -4;
			}
			else
			{
				return -3;
			}
		}
		openedRead[index].dirLocation = tempCluster;
		openedRead[index].firstCluster = cluster;	
		openedRead[index].currentCluster = cluster;
		openedRead[index].fileSize = fileSize;
		openedRead[index].byteCount = 0;
		openedRead[index].sectorCount = 0;
		openedRead[index].fileHandle = getFileHandle();
        openedRead[index].updateDir = FALSE;
		filesOpenedRead++;
		return openedRead[index].fileHandle;
	}
	else
	{
		return -2;
	}
	return -128;
}

/**
 *	opens the file indicated by the input path name.  If the pathname
 *	points to a valid path, the file is created and added to the list of
 *	currently opened files for writing and the unique file handle is returned.
 *
 *	@param	pathname	a pointer to the location of the file to be opened
 *
 *	@return	-1			invalid pathname
 *	@return	-2			file already exist
 *	@return	-3			file already opened for writing
 *	@return	-4			no directory entries left
 *	@return -10			no handles available
 *	@return	-20			memory card error
 *	@return	-128		other error
 *	@return	(non-negative)	file handle of sucessfully opened file
 **/
signed char fat_openWrite(const char *pathname)
{
    unsigned char buf[SECTOR_SIZE];
	const char *tempPathname;
	unsigned long cluster;
	unsigned long tempCluster;
	unsigned long fileSize = 0;
	signed char i = 0;
	signed char index = -1;

	if(detectCard() == FALSE)
	{
		return -20;
	}

	if(filesOpenedWrite >= BUFFER_SIZE)
	{
		return -10;
	}
	else
	{
		while((i < BUFFER_SIZE) && (index < 0))
		{
			if(openedWrite[i].fileHandle == -1)
			{
				index = i;
			}
			i++;
		}
	}
	cluster = fileSys;
	
	if(*pathname == 0x5C)
	{
		pathname++;
	}
	tempPathname = pathname;
	while(*tempPathname)
	{
		if(*tempPathname == 0x5C)
			return -128;
		tempPathname++;
	}	

	tempPathname = pathname;

	if(cluster != 0)
	{
		tempCluster = cluster;
		cluster = getFirstCluster(tempPathname, cluster, buf, FILE, &fileSize);
		if(cluster != 0)
		{
			return -2;
		}
		else
		{	
			cluster = createNewEntry(tempPathname, tempCluster, buf, FILE);
			if(cluster != 0)
			{
				openedWrite[index].currentCluster = cluster;
				openedWrite[index].dirLocation = tempCluster;
				openedWrite[index].fileHandle = getFileHandle();
				openedWrite[index].fileSize = 0;
				openedWrite[index].sectorCount = 0;
				openedWrite[index].firstCluster = cluster;
				openedWrite[index].byteCount = 0;
                openedWrite[index].updateDir = FALSE;
				filesOpenedWrite++;
				return openedWrite[index].fileHandle;
			}
			else
			{
				return -4;
			}
		}
	}
	else
	{
		return -1;
	}
	return -128;
}

/**
 *	reads the content of the file identified by the input handle.  It reads from
 *	where the last read operation on the same file ended.  If it's the first time
 *	the file is being read, it starts from the begining of the file.
 *
 *	@pre	nByte < SECTOR_SIZE
 *
 *	@param	buf			the buffer to be used to access the MMC/SD card
 *	@param	handle		handle of file to be closed
 *	@param	nByte		number of bytes to read
 *
 *	@return	-10			memory card error
 *	@return -1			invalid handle
 *	@return -32768		other error
 *	@return	...			number of bytes read
 **/
signed int fat_read(signed char handle, unsigned char *buf, unsigned int nByte)
{
	unsigned long sectorToRead;
	unsigned long sectorToRead2;
	signed char index;
	char tempBuf[SECTOR_SIZE];

	if(detectCard() == FALSE)
	{
		return -10;
	}
	index = findFileIndex(handle);
	if(index == -1)
	{
		return -1;	// invalid handle
	}

	if(fileSys == FAT16)
	{
		if((openedRead[index].currentCluster > 0xFFF6)||(openedRead[index].currentCluster < 2))
		{
			return -32768;		// already reached the end of file
		}
	}

	else
	{
		return -32768;		// invalid file system
	}
	sectorToRead = (openedRead[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
	sectorToRead += openedRead[index].sectorCount;
	if(openedRead[index].fileSize < nByte)
	{
		nByte = openedRead[index].fileSize;
	}
	if((openedRead[index].byteCount + nByte) > SECTOR_SIZE)
	{
		if((openedRead[index].sectorCount + 1) == sectorsPerCluster)
		{
			// cross cluster read
			openedRead[index].currentCluster = getNextFAT(openedRead[index].currentCluster, tempBuf);
			sectorToRead2 = (openedRead[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
			openedRead[index].sectorCount = 0;			
		}
		else
		{
			// cross sector read
			sectorToRead2 = sectorToRead + 1;
			openedRead[index].sectorCount++;
		}
		readPartialMultiSector(sectorToRead,sectorToRead2, openedRead[index].byteCount, nByte, buf);
		openedRead[index].byteCount += nByte;
		openedRead[index].byteCount -= SECTOR_SIZE;
		if(nByte > openedRead[index].fileSize)
			openedRead[index].fileSize = 0;
		else
            openedRead[index].fileSize -= nByte;
		return nByte;
	}
	else
	{
		// single sector read
		readPartialSector(sectorToRead, openedRead[index].byteCount, nByte, buf);
		openedRead[index].byteCount += nByte;
		if(nByte > openedRead[index].fileSize)
			openedRead[index].fileSize = 0;
		else
            openedRead[index].fileSize -= nByte;
		return nByte;
	}
	return -32768;
}


/**
 *	writes the content in the buffer to the file identified by the input handle.  It writes
 *	to where the last write operation on the same file ended.  If it's the first time
 *	the file is being written to, it starts from the beginning of the file.
 *
 *	@pre	nByte < SECTOR_SIZE
 *
 *	@param	buf			the buffer to be used to access the MMC/SD card
 *	@param	handle		handle of file to be written to
 *	@param	nByte		number of bytes to write
 *
 *	@return	-10			memory card error
 *	@return -1			invalid handle
 *	@return	-2			memory card is full
 *	@return -32768		other error
 *	@return	...			number of bytes written
 **/
signed int fat_write(signed char handle, unsigned char *buf, unsigned int nByte)
{
	unsigned long sectorToWrite;
	unsigned long sectorToWrite2;
	signed char index;
	char tempBuf[SECTOR_SIZE];

	if(detectCard() == FALSE)
	{
		return -10;
	}

	index = findFileIndex(handle);
	if(index == -1)
	{
		return -1;	// invalid handle
	}
	sectorToWrite = (openedWrite[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
	sectorToWrite += openedWrite[index].sectorCount;

	if((openedWrite[index].byteCount + nByte) > SECTOR_SIZE)
	{
		if((openedWrite[index].sectorCount + 1) == sectorsPerCluster)
		{
			// cross cluster write
			sectorToWrite2 = openedWrite[index].currentCluster;
			openedWrite[index].currentCluster = findEmptyCluster(tempBuf);
			if(openedWrite[index].currentCluster > 0)
			{		
				updateFAT(sectorToWrite2, openedWrite[index].currentCluster, tempBuf);
				sectorToWrite2 = (openedWrite[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
				openedWrite[index].sectorCount = 0;						
			}
			else
			{
				return -2;	// memory card full
			}
		}
		else
		{
			// cross sector write
			sectorToWrite2 = sectorToWrite + 1;
			openedWrite[index].sectorCount++;
		}
		writePartialMultiSector(sectorToWrite, sectorToWrite2, openedWrite[index].byteCount, nByte, buf);
		openedWrite[index].byteCount += nByte;
		openedWrite[index].byteCount -= SECTOR_SIZE;
		openedWrite[index].fileSize += nByte;
        // Uncomment next line if you want FAT constantly updated, instead of using fat_flush():
		//updateDirectory(openedWrite[index].dirLocation, openedWrite[index].firstCluster, openedWrite[index].fileSize, tempBuf);
        openedWrite[index].updateDir = TRUE;
		return nByte;
	}
	else
	{
		// single sector write
		writePartialSector(sectorToWrite, openedWrite[index].byteCount, nByte, buf);
		openedWrite[index].byteCount += nByte;
		openedWrite[index].fileSize += nByte;
        // Uncomment next line if you want FAT constantly updated, instead of using fat_flush():
		//updateDirectory(openedWrite[index].dirLocation, openedWrite[index].firstCluster, openedWrite[index].fileSize, tempBuf);
        openedWrite[index].updateDir = TRUE;
		return nByte;
	}
	return -32768;
}


/**
 *	updates the file size in the directory table for all files with the update flag set
 **/
void fat_flush(void)
{
	int i;
	char tempBuf[SECTOR_SIZE];
	for(i = 0; i < filesOpenedWrite; i++)
	{
		if(openedWrite[i].updateDir == TRUE)
		{
			updateDirectory(openedWrite[i].dirLocation, openedWrite[i].firstCluster, openedWrite[i].fileSize, tempBuf);
			openedWrite[i].updateDir = FALSE;
		}
	}
}


/**
 *	updates the file size and date/time in the directory table of the file identified by the input first cluster.
 *
 *	@param	buf				the buffer to be used to access the MMC/SD card
 *	@param	dirCluster		location of the cluster where the directory table is store
 *	@param	firstCluster	the location of the first cluster of the file being updated
 **/
static void updateDirectory(unsigned long dirCluster, unsigned long firstCluster, unsigned long filesize, unsigned char *buf)
{
	unsigned long sector;
	unsigned char sectorCount = 0;
	unsigned char i;
	unsigned int offset;
	unsigned long cluster;
	boolean done = FALSE;

 	if((dirCluster == 1)&&(fileSys == FAT16))
	{
		sector = rootDirectory;
	}
	else
	{
		sector = (dirCluster - 2) * sectorsPerCluster + dataStarts;		
	}

	while((!done) && (sectorCount < sectorsPerCluster))
	{
		readSector(sector, buf);
		for(i = 0; i < 16; i++)
		{
			offset = i * 32;
			cluster = buf[26+offset];
			cluster |= (unsigned long int)buf[27+offset] << 8;
			
			if(cluster == firstCluster)
			{	
				done = TRUE;

				buf[28+offset] = (filesize) & 0x000000FF;
				buf[29+offset] = (filesize >> 8) & 0x000000FF;
				buf[30+offset] = (filesize >> 16) & 0x000000FF;
				buf[31+offset] = (filesize >> 24) & 0x000000FF;
	
				/** Set access date to March 04, 2005 23:15:18 . **/
                // If a real time clock is available, we could use it.
				buf[offset+22] = (18 >> 1) & 0x1F;  // Seconds.
				buf[offset+22] |= 15 << 5;  // Part of minutes.
				buf[offset+23] = (15 >> 3) & 0x07;  // More of inutes.
				buf[offset+23] |= 23 << 3;  // Hours.
				buf[offset+18] = 04 & 0x1F; // Day.
				buf[offset+18] |= (03 << 5) & 0xE0; // Part of month.
				buf[offset+24] = buf[offset+18];
				buf[offset+19] = (03 >> 3) & 0x01;    // More of month.
				buf[offset+19] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE; // Year.
				buf[offset+25] = buf[offset+19];

				writeSector(sector, buf);
			}
		}
		sector++;
		sectorCount++;
	}
}


// *** updateAccessDate() is not called right now.  It should probably be
// *** called when a file is opened for reading, and closed in read mode.
/**
 *	updates the access date of the file specified by the input parameters
 *
 *	@param	buf				the buffer to be used to access the MMC/SD card
 *	@param	dirCluster		location of the cluster where the directory table is store
 *	@param	firstCluster	the location of the first cluster of the file being updated
 **/
static void updateAccessDate(unsigned long dirCluster, unsigned long firstCluster, unsigned char *buf)
{
	unsigned long sector;
	unsigned char sectorCount = 0;
	unsigned char i;
	unsigned int offset;
	unsigned long cluster;
	boolean done = FALSE;

 	if((dirCluster == 1)&&(fileSys == FAT16))
	{
		sector = rootDirectory;
	}
	else
	{
		sector = (dirCluster - 2) * sectorsPerCluster + dataStarts;		
	}

	while((!done) && (sectorCount < sectorsPerCluster))
	{
		readSector(sector, buf);
		for(i = 0; i < 16; i++)
		{
			offset = i * 32;
			cluster = buf[26+offset];
			cluster |= (unsigned long int)buf[27+offset] << 8;
			
			if(cluster == firstCluster)
			{	
				done = TRUE;

				/** set access date to February 03, 2005. **/
                // If a real time clock is available, we could use it.
				buf[offset+18] = 03 & 0x1F; // Day.
				buf[offset+18] |= (02 << 5) & 0xE0; // Part of month.
				buf[offset+19] = (02 >> 3) & 0x01;   // More of month.
				buf[offset+19] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE;
				writeSector(sector, buf);
			}
		}
		sector++;
		sectorCount++;
	}
}

⌨️ 快捷键说明

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