//----------------------------------------------------------------------------- // 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); } }
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; }