47 static int _filelib_init = 0;
48 static int _filelib_valid = 0;
49 static struct fatfs _fs;
50 static struct fat_list _open_file_list;
51 static struct fat_list _free_file_list;
58 #define CHECK_FL_INIT() { if (_filelib_init==0) fl_init(); }
60 #define FL_LOCK(a) do { if ((a)->fl_lock) (a)->fl_lock(); } while (0)
61 #define FL_UNLOCK(a) do { if ((a)->fl_unlock) (a)->fl_unlock(); } while (0)
66 static void _fl_init();
71 static FL_FILE* _allocate_file(
void) {
73 struct fat_node *node = fat_list_pop_head(&_free_file_list);
76 fat_list_insert_last(&_open_file_list, node);
92 if (openFile !=
file) {
106 fat_list_remove(&_open_file_list, &
file->list_node);
109 fat_list_insert_last(&_free_file_list, &
file->list_node);
120 static int _open_directory(
char *path,
uint32 *pathCluster) {
134 for (sublevel = 0; sublevel < (levels + 1); sublevel++) {
150 *pathCluster = startcluster;
156 #if FATFS_INC_WRITE_SUPPORT
157 static int _create_directory(
char *path) {
165 file = _allocate_file();
180 if (_check_file_open(
file)) {
186 if (
file->path[0] == 0)
190 if (!_open_directory(
file->path, &
file->parentcluster)) {
202 file->startcluster = 0;
219 #if FATFS_INC_LFN_SUPPORT
239 }
while (tailNum < 9999);
242 if (tailNum == 9999) {
284 file->filelength = 0;
286 file->file_data_address = 0xFFFFFFFF;
287 file->file_data_dirty = 0;
288 file->filelength_changed = 0;
291 file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF;
292 file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF;
303 static FL_FILE* _open_file(
const char *path) {
308 file = _allocate_file();
323 if (_check_file_open(
file)) {
328 if (
file->path[0] == 0)
332 if (!_open_directory(
file->path, &
file->parentcluster)) {
346 file->file_data_address = 0xFFFFFFFF;
347 file->file_data_dirty = 0;
348 file->filelength_changed = 0;
351 file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF;
352 file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF;
367 #if FATFS_INC_WRITE_SUPPORT
368 static FL_FILE* _create_file(
const char *filename) {
379 file = _allocate_file();
394 if (_check_file_open(
file)) {
400 if (
file->path[0] == 0)
404 if (!_open_directory(
file->path, &
file->parentcluster)) {
416 file->startcluster = 0;
424 #if FATFS_INC_LFN_SUPPORT
443 }
while (tailNum < 9999);
446 if (tailNum == 9999) {
488 file->filelength = 0;
490 file->file_data_address = 0xFFFFFFFF;
491 file->file_data_dirty = 0;
492 file->filelength_changed = 0;
495 file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF;
496 file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF;
524 if (ClusterIdx ==
file->last_fat_lookup.ClusterIdx)
525 Cluster =
file->last_fat_lookup.CurrentCluster;
529 if (ClusterIdx && ClusterIdx ==
file->last_fat_lookup.ClusterIdx + 1) {
530 i =
file->last_fat_lookup.ClusterIdx;
531 Cluster =
file->last_fat_lookup.CurrentCluster;
537 Cluster =
file->startcluster;
541 for (; i < ClusterIdx; i++) {
553 Cluster = nextCluster;
558 file->last_fat_lookup.CurrentCluster = Cluster;
559 file->last_fat_lookup.ClusterIdx = ClusterIdx;
587 fat_list_init(&_free_file_list);
588 fat_list_init(&_open_file_list);
592 fat_list_insert_last(&_free_file_list, &_files[i].list_node);
617 FAT_PRINTF((
"FAT_FS: Error could not load FAT details (%d)!\r\n", res));
638 void*
fl_fopen(
const char *path,
const char *mode) {
670 for (i = 0; i < (int)
strlen(mode); i++) {
712 #if FATFS_INC_WRITE_SUPPORT == 0
725 file = _open_file(path);
729 #if FATFS_INC_WRITE_SUPPORT
731 file = _create_file(path);
738 file = _open_file(path);
749 #if FATFS_INC_WRITE_SUPPORT
757 uint32 TotalWriteCount = count;
768 if (ClusterIdx ==
file->last_fat_lookup.ClusterIdx)
769 Cluster =
file->last_fat_lookup.CurrentCluster;
773 if (ClusterIdx && ClusterIdx ==
file->last_fat_lookup.ClusterIdx + 1) {
774 i =
file->last_fat_lookup.ClusterIdx;
775 Cluster =
file->last_fat_lookup.CurrentCluster;
781 Cluster =
file->startcluster;
785 for (; i < ClusterIdx; i++) {
797 LastCluster = Cluster;
798 Cluster = nextCluster;
811 Cluster = LastCluster;
815 file->last_fat_lookup.CurrentCluster = Cluster;
816 file->last_fat_lookup.ClusterIdx = ClusterIdx;
832 #if FATFS_INC_WRITE_SUPPORT
842 if (
file->file_data_dirty) {
844 if (_write_sectors(
file,
file->file_data_address,
file->file_data_sector, 1))
845 file->file_data_dirty = 0;
869 if (
file->filelength_changed) {
870 #if FATFS_INC_WRITE_SUPPORT
874 file->filelength_changed = 0;
878 file->filelength = 0;
879 file->startcluster = 0;
880 file->file_data_address = 0xFFFFFFFF;
881 file->file_data_dirty = 0;
882 file->filelength_changed = 0;
914 while (idx < (n - 1)) {
922 s[idx++] = (char) ch;
933 return (idx > 0) ? s : 0;
942 int count = size * length;
962 if (
file->bytenum >=
file->filelength)
966 if ((
file->bytenum + count) >
file->filelength)
967 count =
file->filelength -
file->bytenum;
975 while (bytesRead < count) {
985 sector += sectorsRead;
993 if (
file->file_data_address != sector) {
995 if (
file->file_data_dirty)
999 if (!_read_sectors(
file, sector,
file->file_data_sector, 1))
1003 file->file_data_address = sector;
1004 file->file_data_dirty = 0;
1011 if (copyCount > (count - bytesRead))
1012 copyCount = (count - bytesRead);
1023 bytesRead += copyCount;
1026 file->bytenum += copyCount;
1044 if (origin ==
SEEK_END && offset != 0)
1050 file->file_data_address = 0xFFFFFFFF;
1051 file->file_data_dirty = 0;
1056 if (
file->bytenum >
file->filelength)
1064 file->bytenum += offset;
1066 if (
file->bytenum >
file->filelength)
1078 file->bytenum -= offset;
1106 *position =
file->bytenum;
1134 if (
file->bytenum ==
file->filelength)
1146 #if FATFS_INC_WRITE_SUPPORT
1161 #if FATFS_INC_WRITE_SUPPORT
1162 int fl_fwrite(
const void *data,
int size,
int count,
void *f) {
1166 uint32 length = (size * count);
1196 while (bytesWritten < length) {
1202 if (
file->file_data_address != 0xFFFFFFFF) {
1204 if (
file->file_data_dirty)
1207 file->file_data_address = 0xFFFFFFFF;
1208 file->file_data_dirty = 0;
1216 bytesWritten += copyCount;
1219 file->bytenum += copyCount;
1222 sector += sectorsWrote;
1233 if (copyCount > (length - bytesWritten))
1234 copyCount = (length - bytesWritten);
1237 if (
file->file_data_address != sector) {
1239 if (
file->file_data_dirty)
1249 if (!_read_sectors(
file, sector,
file->file_data_sector, 1))
1253 file->file_data_address = sector;
1254 file->file_data_dirty = 0;
1261 file->file_data_dirty = 1;
1264 bytesWritten += copyCount;
1267 file->bytenum += copyCount;
1276 if (
file->bytenum >
file->filelength) {
1282 file->filelength_changed = 1;
1285 #if FATFS_INC_TIME_DATE_SUPPORT
1288 file->filelength_changed = 1;
1293 return (size * count);
1299 #if FATFS_INC_WRITE_SUPPORT
1301 int len = (int)
strlen(str);
1313 #if FATFS_INC_WRITE_SUPPORT
1344 #if FATFS_INC_WRITE_SUPPORT
1352 res = _create_directory((
char*) path);
1361 #if FATFS_DIR_LIST_SUPPORT
1376 #if FATFS_INC_TIME_DATE_SUPPORT
1380 FAT_PRINTF((
"%02d/%02d/%04d %02d:%02d ", d,mn,y,h,m));
1400 #if FATFS_DIR_LIST_SUPPORT
1418 res = _open_directory((
char*) path, &
cluster);
1431 #if FATFS_DIR_LIST_SUPPORT
1444 return res ? 0 : -1;
1450 #if FATFS_DIR_LIST_SUPPORT
1459 #if FATFS_DIR_LIST_SUPPORT
1475 #if FATFS_INC_FORMAT_SUPPORT
1483 #ifdef FATFS_INC_TEST_HOOKS
1484 struct fatfs* fl_get_fs(
void)