/* * ck_merge(c1,c2). * Merge neighboring free chunks together. * c1 and c2 are removed from the free list, merged into a single chunk * accessible by c1 and added back into the free list. */ void ck_merge(chunk *c1, chunk *c2) // pre: c1 and c2 are adjacent free chunks with c1 < c2 // post: c2 is merged into c1 and the entire chunk is classified as free { fl_remove(c1); fl_remove(c2); chunk *sum = c1; //merge c1 with c2; take sum of sizes info totalSize = ck_size(c1) + ck_size(c2); ck_setInfo(sum, totalSize|H_FREE); fl_insert(sum, FreeList); }
void LOS_init(void) { if (media_init() == 0) { mSD_status = SD_ERR_INIT; printf("ERROR: Media init failed\n"); return; } // Attach media access functions to library if (fl_attach_media(media_read, media_write) != FAT_INIT_OK) { mSD_status = SD_ERR_ATTACH; printf("ERROR: Media attach failed\n"); return; } #ifndef __LOCAL_STORE_ACCEL_MODE__ BQ_init(&LOS_queue, LOS_write_buffer, sizeof(LOS_write_buffer)); #endif LOS_tid = registerTask(LOS_proc, 0, 0, 0xFF); #ifdef FRAM_ENABLED FRAM_WR_init(); #endif // Delete File int i = 0; while ((i = fl_remove("/file.txt")) == -1); if (!i) { //printf("ERROR: Delete file failed\n"); } }
/* * hmalloc(size). * Allocate and return memory to hold size bytes. */ void *hmalloc(int size) { /* Look through free list to see if there's a chunk big enough to suit your needs (size). If no, grows by at least size. Returns the pointer to the beginning of the whole payload area, not the header; to preserve header info */ init(); if (size < H_MINPAYLOAD) { size = H_MINPAYLOAD; } chunk *found = fl_findBestFit(FreeList, size); if (found->header == 0) { //if dummy found = grow(size, FreeList); //we know if we got to this point nothing in freelist fit //chunk we allocate in grow is the one we want to grab } else { ck_split(found, size); } ck_setInfo(found, ck_size(found)); fl_remove(found); return (chunk*)PTR_ADD(found, H_IS); //return pointer to the payload }
void* kma_coalesce(void* ptr) { unsigned int size = GETSIZE(ptr); /* for debugging use void* base_addr = BASEADDR(ptr); unsigned int offset = (ptr - base_addr)/size; printf("%d", offset); */ int bud = WHERE_BUD(ptr, size); //0 if bud on the right, 1 if bud on the left /* corner condition: size == PAGESIZE */ if (size == PAGESIZE) return ptr; /* find bud location */ void* bud_addr; if (bud) bud_addr = ptr - size; //bud on the left else bud_addr = ptr + size; //bud on the right bool can_coalesce; can_coalesce = (!IF_ALLOC(bud_addr)) && (GETSIZE(ptr) == GETSIZE(bud_addr)); if (!can_coalesce) { //bud allocated - do nothing,simply return, this is great! fl_add(ptr); return ptr; } //we need to coalesce! if (bud) { fl_remove(bud_addr); PUT(bud_addr, PACK(size<<1,0)); //bud on the left, update bud header return kma_coalesce(bud_addr); } fl_remove(bud_addr); PUT(ptr, PACK(size<<1,0)); //bud on the right, update our header return kma_coalesce(ptr); }
/* * Destroy all data in the list. * * No error checks, region of list is zeroed with memset. */ void fl_drop(IList * list) { void *data; while (list->size > 0) { if (fl_remove(list, &data) == 0 && list->drop_node != NULL) list->drop_node(data); } memset(list, 0, sizeof(IList)); return; }
void* kma_malloc(kma_size_t size) { /* size + header size larger than page size, do nothing and return null */ if ((size + BLKHDR) > PAGESIZE) return NULL; /* if master page is not set up, call kma_init */ if (master == NULL) { kma_init(); } /* find the page to insert */ void* block = kma_find_block(size); //remove the block from freelist fl_remove(block); /* split the blocks */ void* alloc = kma_split(block, size); return alloc + BLKHDR; }
//----------------------------------------------------------------- // Main: Test bench file to create 5 files with psuedo random // sequences in of varying lengths - read them back and complete // then remove them. //----------------------------------------------------------------- void main() { int i,j,x; FL_FILE * files[5]; FL_FILE *readFile; char filenames[5][260]; BYTE fileData[5][10000]; BYTE readBuffer[10000]; int fileLengths[5]; BYTE *massiveData; time_t timeStart, timeEnd; #define TESTFILES 6 char *testfile[] = { "X:\\1", "X:\\1.bin", "X:\\12345678.321", "X:\\mylongfilename", "X:\\mylongfilename.bin", "X:\\the Quick Brown Fox jumped over the lazy dog.elf.binfile.jar" }; srand(time(NULL)); // Initialise FAT32_InitDrive(); fl_init(); if (fl_attach_media(FAT_ReadSector, FAT_WriteSector) != FAT_INIT_OK) return; // List directory fl_listdirectory("C:\\"); // return ; test_start: // Generate 5 random files memset(filenames, 0x00, 260*5); for (j=0;j<5;j++) { // Length fileLengths[j] = GetRandom(9999); // Data for (x=0;x<fileLengths[j];x++) fileData[j][x] = (BYTE)GetRandom(255); // Names sprintf(filenames[j], "X:\\Auto Generated Filename Number %d", j+1); } // Create some files for (j=0;j<5;j++) { printf("Creating File: %s [%d bytes]\n", filenames[j], fileLengths[j]); // Create File files[j] = fl_fopen(filenames[j], "w"); if (files[j]!=NULL) { if (fl_fwrite(fileData[j], 1, fileLengths[j], files[j])!=fileLengths[j]) { printf("ERROR: File Write Block Failed File %s Length %d\n", filenames[j], fileLengths[j]); fl_assert(0); } } else { printf("ERROR: Error Creating File %s\n", filenames[j]); fl_assert(0); } fl_fclose(files[j]); // Clear buffer for (i=0;i<sizeof(readBuffer);i++) readBuffer[i] = 0; // Verify File readFile = fl_fopen(filenames[j], "r"); if (readFile!=NULL) { int failed = FALSE; printf("File %s Read Check (fread whole file) [%d bytes]\n", filenames[j], fileLengths[j]); if (fl_fread(readBuffer, 1, fileLengths[j], readFile)!=fileLengths[j]) { printf("ERROR: File %s Read Length Error %d\n", filenames[j], fileLengths[j]); fl_assert(0); } for (i=0;i<fileLengths[j];i++) if ( fileData[j][i] != (BYTE)readBuffer[i] ) failed = TRUE; if (failed) { printf("ERROR: File %s Data Verify Failed\n", filenames[j]); fl_assert(0); } } fl_fclose(readFile); // Clear buffer for (i=0;i<sizeof(readBuffer);i++) readBuffer[i] = 0; // Verify File using fgetc readFile = fl_fopen(filenames[j], "r"); if (readFile!=NULL) { int failed = FALSE; printf("File %s Read Check (fgetc) [%d bytes]\n", filenames[j], fileLengths[j]); i = 0; while (i < fileLengths[j]) { int res = fl_fgetc(readFile); if (res == -1) break; readBuffer[i++] = (BYTE)res; } if (i != fileLengths[j]) { printf("ERROR: File %s Read Length Error %d\n", filenames[j], fileLengths[j]); fl_assert(0); } for (i=0;i<fileLengths[j];i++) if ( fileData[j][i] != (BYTE)readBuffer[i] ) failed = TRUE; if (failed) { printf("ERROR: File %s Data Verify Failed\n", filenames[j]); fl_assert(0); } } fl_fclose(readFile); // Clear buffer for (i=0;i<sizeof(readBuffer);i++) readBuffer[i] = 0; // Verify File chunks readFile = fl_fopen(filenames[j], "r"); if (readFile!=NULL) { int failed = FALSE; printf("File %s Read Check (fread chunks) [%d bytes]\n", filenames[j], fileLengths[j]); i = 0; while (i < fileLengths[j]) { int read_length = GetRandom(1025); if (read_length > (fileLengths[j] - i)) read_length = fileLengths[j] - i; if (fl_fread(readBuffer + i, 1, read_length, readFile) != read_length) { printf("ERROR: File %s fread error\n", filenames[j]); fl_assert(0); break; } i += read_length; } if (i != fileLengths[j]) { printf("ERROR: File %s Read Length Error %d\n", filenames[j], fileLengths[j]); fl_assert(0); } for (i=0;i<fileLengths[j];i++) if ( fileData[j][i] != (BYTE)readBuffer[i] ) { failed = TRUE; break; } if (failed) { printf("ERROR: File %s Data Verify Failed at %d\n", filenames[j], i); fl_assert(0); } } fl_fclose(readFile); // Delete File if (fl_remove(filenames[j])<0) printf("ERROR: Delete File %s Failed\n", filenames[j]); // Verify file is no longer present! readFile = fl_fopen(filenames[j], "r"); if (readFile != NULL) { printf("ERROR: File %s still present after delete!\n", filenames[j]); fl_assert(0); fl_fclose(readFile); } } // Create folder fl_createdirectory("C:\\folder1"); #if 0 // Create massive file #define MASSIVE_FILE_LEN (1024 * 1024) printf("Creating Massive File [%d bytes]\n", MASSIVE_FILE_LEN); massiveData = malloc(MASSIVE_FILE_LEN); if (!massiveData) { printf("ERROR: Could not allocate memory for massive array!\n"); fl_assert(0); fl_shutdown(); return ; } // Create random data for file for (x=0;x<MASSIVE_FILE_LEN;x++) massiveData[x] = (BYTE)GetRandom(255); // Remove if it already exists! fl_remove("X:\\folder1\\massive file.bin"); timeStart = time(NULL); // Create Large File readFile = fl_fopen("X:\\folder1\\massive file.bin", "w"); if (readFile != NULL) { if (fl_fwrite(massiveData, 1, MASSIVE_FILE_LEN, readFile) != MASSIVE_FILE_LEN) { printf("ERROR: File Write Block Failed for massive file (Length %d)\n", MASSIVE_FILE_LEN); fl_assert(0); } } else { printf("ERROR: Error Creating massive file\n"); fl_assert(0); } fl_fclose(readFile); // Verify Massive File readFile = fl_fopen("X:\\folder1\\massive file.bin", "r"); if (readFile!=NULL) { int failed = FALSE; printf("File Massive File Read Check (fread whole file) [%d bytes]\n", MASSIVE_FILE_LEN); i = 0; while (i < MASSIVE_FILE_LEN) { int read_length = GetRandom(2048) + 128; if (read_length > (MASSIVE_FILE_LEN - i)) read_length = MASSIVE_FILE_LEN - i; if (fl_fread(readBuffer, 1, read_length, readFile) != read_length) { printf("ERROR: File massive file fread error\n"); fl_assert(0); break; } for (j=0;j<read_length;j++) if ( massiveData[i+j] != (BYTE)readBuffer[j] ) { printf("ERROR: File Massive File Data Verify Failed at %d\n", i+j); fl_assert(0); break; } i += read_length; } if (i != MASSIVE_FILE_LEN) { printf("ERROR: File massive file Read Length Error %d\n", MASSIVE_FILE_LEN); fl_assert(0); } } fl_fclose(readFile); timeEnd = time(NULL); printf("Time taken %d seconds\n", (int)(timeEnd-timeStart)); free(massiveData); #endif // Filename test for (i=0;i<TESTFILES;i++) { // Create File readFile = fl_fopen(testfile[i], "w"); if (readFile != NULL) ; else { printf("ERROR: Error Creating File %s\n", testfile[i]); fl_assert(0); } fl_fputc(0, readFile); fl_fclose(readFile); readFile = fl_fopen(testfile[i], "r"); assert(readFile); fl_fclose(readFile); } // List directory fl_listdirectory("C:\\"); for (i=0;i<TESTFILES;i++) { // Delete File if (fl_remove(testfile[i])<0) { printf("ERROR: Delete File %s Failed\n", testfile[i]); fl_assert(0); } } fl_shutdown(); printf("\r\nCompleted\r\n"); // List directory fl_listdirectory("C:\\"); }
int32_t file_remove(mountpoint_t* mountpoint, const char* filename) { return fl_remove(filename); }
//----------------------------------------------------------------------------- // fopen: Open or Create a file for reading or writing //----------------------------------------------------------------------------- void* fl_fopen(const char *path, const char *mode) { int i; FL_FILE* file; unsigned char flags = 0; // If first call to library, initialise CHECK_FL_INIT(); if (!_filelib_valid) return NULL; if (!path || !mode) return NULL; // Supported Modes: // "r" Open a file for reading. The file must exist. // "w" Create an empty file for writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a" Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist. // "r+" Open a file for update both reading and writing. The file must exist. // "w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a+" Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist. for (i=0;i<(int)strlen(mode);i++) { switch (tolower(mode[i])) { case 'r': flags |= FILE_READ; break; case 'w': flags |= FILE_WRITE; flags |= FILE_ERASE; flags |= FILE_CREATE; break; case 'a': flags |= FILE_WRITE; flags |= FILE_APPEND; flags |= FILE_CREATE; break; case '+': if (flags & FILE_READ) flags |= FILE_WRITE; else if (flags & FILE_WRITE) { flags |= FILE_READ; flags |= FILE_ERASE; flags |= FILE_CREATE; } else if (flags & FILE_APPEND) { flags |= FILE_READ; flags |= FILE_WRITE; flags |= FILE_APPEND; flags |= FILE_CREATE; } break; case 'b': flags |= FILE_BINARY; break; } } file = NULL; #ifndef FATFS_INC_WRITE_SUPPORT // No write support! flags &= ~(FILE_CREATE | FILE_WRITE | FILE_APPEND); #endif // No write access - remove write/modify flags if (!_fs.disk_io.write_sector) flags &= ~(FILE_CREATE | FILE_WRITE | FILE_APPEND); FL_LOCK(&_fs); // Read file = _open_file(path); //if (!(flags & FILE_READ)) // _free_file(file); // Create New #ifdef FATFS_INC_WRITE_SUPPORT // Remove old file if(flags & FILE_ERASE) { fl_remove(path); if(file) _free_file(file); } if (!file && (flags & FILE_CREATE)) file = _create_file(path); #endif // Write Existing (and not open due to read or create) //if (!(flags & FILE_READ)) // if (!(flags & FILE_CREATE)) // if (flags & (FILE_WRITE | FILE_APPEND)) // file = _open_file(path); if (file) file->flags = flags; FL_UNLOCK(&_fs); return file; }