//-----------------------------------------------------------------------------
// fl_fclose: Close an open file
//-----------------------------------------------------------------------------
void fl_fclose(void *f)
{
	FL_FILE *file = (FL_FILE *)f;

	// If first call to library, initialise
	CHECK_FL_INIT();

	if (file)
	{
		FL_LOCK(&_fs);

		// Flush un-written data to file
		fl_fflush(f);

		// File size changed?
		if (file->filelength_changed)
		{
#ifdef FATFS_INC_WRITE_SUPPORT
			// Update filesize in directory
			fatfs_update_file_length(&_fs, file->parentcluster, (char*)file->shortfilename, file->filelength);
#endif
			file->filelength_changed = 0;
		}

		file->bytenum = 0;
		file->filelength = 0;
		file->startcluster = 0;
		file->file_data.address = 0xFFFFFFFF;
		file->file_data.dirty = 0;
		file->filelength_changed = 0;

		// Free file handle
		_free_file(file);

		fatfs_fat_purge(&_fs);

		FL_UNLOCK(&_fs);
	}
}
Exemple #2
0
int32_t file_flush(file_handle_t handle)
{
    return fl_fflush(handle);
}
int fl_fwrite(const void * data, int size, int count, void *f )
{
	FL_FILE *file = (FL_FILE *)f;
	unsigned long sector;
	unsigned long offset;	
	unsigned long length = (size*count);
	unsigned char *buffer = (unsigned char *)data;
//	int dirtySector = 0;
	unsigned long bytesWritten = 0;
	unsigned long copyCount;

	// If first call to library, initialise
	CHECK_FL_INIT();

	if (!file)
		return -1;

	FL_LOCK(&_fs);

	// No write permissions
	if (!(file->flags & FILE_WRITE))
	{
		FL_UNLOCK(&_fs);
		return -1;
	}

	// Append writes to end of file
	if (file->flags & FILE_APPEND)
		file->bytenum = file->filelength;
	// Else write to current position

	// Calculate start sector
	sector = file->bytenum / FAT_SECTOR_SIZE;

	// Offset to start copying data from first sector
	offset = file->bytenum % FAT_SECTOR_SIZE;

	while (bytesWritten < length)
	{
		// We have upto one sector to copy
		copyCount = FAT_SECTOR_SIZE - offset;

		// Only require some of this sector?
		if (copyCount > (length - bytesWritten))
			copyCount = (length - bytesWritten);

		// Do we need to read a new sector?
		if (file->file_data.address != sector)
		{
			// Flush un-written data to file
			if (file->file_data.dirty)
				fl_fflush(file);

			// If we plan to overwrite the whole sector, we don't need to read it first!
			if (copyCount != FAT_SECTOR_SIZE)
			{
				// NOTE: This does not have succeed; if last sector of file
				// reached, no valid data will be read in, but write will 
				// allocate some more space for new data.

				// Get LBA of sector offset within file
				if (!_read_sector(file, sector))
					memset(file->file_data.sector, 0x00, FAT_SECTOR_SIZE);	
			}

			file->file_data.address = sector;
			file->file_data.dirty = 0;
		}

		// Copy from application buffer into sector buffer
		memcpy((unsigned char*)(file->file_data.sector + offset), (unsigned char*)(buffer + bytesWritten), copyCount);

		// Mark buffer as dirty
		file->file_data.dirty = 1;
	
		// Increase total read count 
		bytesWritten += copyCount;

		// Increment file pointer
		file->bytenum += copyCount;

		// Move onto next sector and reset copy offset
		sector++;
		offset = 0;
	}

	// Write increased extent of the file?
	if (file->bytenum > file->filelength)
	{
		// Increase file size to new point
		file->filelength = file->bytenum;

		// We are changing the file length and this 
		// will need to be writen back at some point
		file->filelength_changed = 1;
	}

	FL_UNLOCK(&_fs);

	return (size*count);
}
//-----------------------------------------------------------------------------
// fl_fread: Read a block of data from the file
//-----------------------------------------------------------------------------
int fl_fread(void * buffer, int size, int length, void *f )
{
	unsigned long sector;
	unsigned long offset;
	int copyCount;
	int count = size * length;
	int bytesRead = 0;	

	FL_FILE *file = (FL_FILE *)f;

	// If first call to library, initialise
	CHECK_FL_INIT();

	if (buffer==NULL || file==NULL)
		return -1;

	// No read permissions
	if (!(file->flags & FILE_READ))
		return -1;

	// Nothing to be done
	if (!count)
		return 0;

	// Check if read starts past end of file
	if (file->bytenum >= file->filelength)
		return -1;

	// Limit to file size
	if ( (file->bytenum + count) > file->filelength )
		count = file->filelength - file->bytenum;

	// Calculate start sector
	sector = file->bytenum / FAT_SECTOR_SIZE;

	// Offset to start copying data from first sector
	offset = file->bytenum % FAT_SECTOR_SIZE;

	while (bytesRead < count)
	{		
		// Do we need to re-read the sector?
		if (file->file_data.address != sector)
		{
			// Flush un-written data to file
			if (file->file_data.dirty)
				fl_fflush(file);

			// Get LBA of sector offset within file
			if (!_read_sector(file, sector))
				// Read failed - out of range (probably)
				break;

			file->file_data.address = sector;
			file->file_data.dirty = 0;
		}

		// We have upto one sector to copy
		copyCount = FAT_SECTOR_SIZE - offset;

		// Only require some of this sector?
		if (copyCount > (count - bytesRead))
			copyCount = (count - bytesRead);

		// Copy to application buffer
		memcpy( (unsigned char*)((unsigned char*)buffer + bytesRead), (unsigned char*)(file->file_data.sector + offset), copyCount);
	
		// Increase total read count 
		bytesRead += copyCount;

		// Increment file pointer
		file->bytenum += copyCount;

		// Move onto next sector and reset copy offset
		sector++;
		offset = 0;
	}	

	return bytesRead;
}