OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [filesys.c] - Blame information for rev 405

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 398 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: Plasma File System
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 4/26/07
5
 * FILENAME: filesys.c
6
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    Plasma File System.  Supports RAM, flash, and disk file systems.
11
 *    Possible call tree:
12
 *      OS_fclose()
13
 *        FileFindRecursive()      //find the existing file
14
 *          FileOpen()             //open root file system
15
 *          FileFind()             //find the next level of directory
16
 *            OS_fread()           //read the directory file
17
 *              BlockRead()        //read blocks of directory
18
 *                MediaBlockRead() //low level read
19
 *          FileOpen()             //open next directory
20
 *        OS_fwrite()              //write file entry into directory
21
 *        BlockRead()              //flush changes to directory
22
 *--------------------------------------------------------------------*/
23
#include "rtos.h"
24
 
25
#define FLASH_SIZE        1024*1024*16
26
#define FLASH_SECTOR_SIZE 1024*128
27
#define FLASH_BLOCK_SIZE  512
28
#define FLASH_LN2_SIZE    9                  //2^FLASH_LN2_SIZE == FLASH_BLOCK_SIZE
29
#define FLASH_OFFSET      FLASH_SECTOR_SIZE  //offset to start of flash file system
30
 
31
#define BLOCK_SIZE        512
32
#define FILE_NAME_SIZE    40
33
#define FULL_NAME_SIZE    128
34
#define BLOCK_MALLOC      0x0
35
#define BLOCK_EOF         0xffffffff
36
 
37
typedef enum {
38
   FILE_MEDIA_RAM,
39
   FILE_MEDIA_FLASH,
40
   FILE_MEDIA_DISK
41
} OS_MediaType_e;
42
 
43
typedef struct OS_FileEntry_s {
44
   char name[FILE_NAME_SIZE];
45
   uint32 blockIndex;       //first block of file
46
   uint32 modifiedTime;
47
   uint32 length;
48
   uint8 isDirectory;
49
   uint8 attributes;
50
   uint8 valid;
51
   uint8 mediaType;
52
   uint16 blockSize;        //Normally BLOCK_SIZE
53
   uint8 pad1, pad2;
54
} OS_FileEntry_t;
55
 
56
typedef struct OS_Block_s {
57
   uint32 next;
58
   uint8 data[BLOCK_SIZE - sizeof(uint32)];
59
} OS_Block_t;
60
 
61
struct OS_FILE_s {
62
   OS_FileEntry_t fileEntry;  //written to directory upon OS_fclose()
63
   uint8 fileModified;
64
   uint8 blockModified;
65
   uint8 pad1, pad2;
66
   uint32 blockIndex;         //index of block
67
   uint32 blockOffset;        //byte offset into block
68
   uint32 fileOffset;         //byte offset into file
69
   char fullname[FULL_NAME_SIZE]; //includes full path
70
   OS_Block_t *block;
71
   OS_Block_t blockLocal;     //local copy for flash or disk file system
72
};
73
 
74
static OS_FileEntry_t rootFileEntry;
75
static OS_Mutex_t *mutexFilesys;
76
 
77
// Public prototypes
78
#ifndef _FILESYS_
79
typedef struct OS_FILE_s OS_FILE;
80
#endif
81
OS_FILE *OS_fopen(char *name, char *mode);
82
void OS_fclose(OS_FILE *file);
83
int OS_fread(void *buffer, int size, int count, OS_FILE *file);
84
int OS_fwrite(void *buffer, int size, int count, OS_FILE *file);
85
int OS_fseek(OS_FILE *file, int offset, int mode);
86
int OS_fmkdir(char *name);
87
int OS_fdir(OS_FILE *dir, char name[64]);
88
void OS_fdelete(char *name);
89
 
90
 
91
/***************** Media Functions Start ***********************/
92
#ifdef INCLUDE_FLASH
93
#define FLASH_BLOCKS FLASH_SIZE/FLASH_BLOCK_SIZE
94
#define FLASH_START  (FLASH_OFFSET+FLASH_BLOCKS/8*2)/FLASH_BLOCK_SIZE
95
static unsigned char FlashBlockEmpty[FLASH_BLOCKS/8];
96
static unsigned char FlashBlockUsed[FLASH_BLOCKS/8];
97
static int FlashBlock;
98
 
99
//Free unused flash blocks
100
static int MediaBlockCleanup(void)
101
{
102
   int i, sector, block, count=0;
103
   unsigned char *buf;
104
 
105
   printf("FlashCleanup\n");
106
   buf = (unsigned char*)malloc(FLASH_SECTOR_SIZE);
107
   if(buf == NULL)
108
      return 0;
109
   for(sector = FLASH_OFFSET / FLASH_SECTOR_SIZE; sector < FLASH_SIZE / FLASH_SECTOR_SIZE; ++sector)
110
   {
111
      FlashRead((uint16*)buf, FLASH_SECTOR_SIZE*sector, FLASH_SECTOR_SIZE);
112
      if(sector == FLASH_OFFSET / FLASH_SECTOR_SIZE)
113
      {
114
         for(i = 0; i < FLASH_BLOCKS/8; ++i)
115
            FlashBlockEmpty[i] |= ~FlashBlockUsed[i];
116
         memcpy(buf, FlashBlockEmpty, sizeof(FlashBlockEmpty));
117
         memset(FlashBlockUsed, 0xff, sizeof(FlashBlockUsed));
118
         memset(buf+sizeof(FlashBlockEmpty), 0xff, sizeof(FlashBlockUsed));
119
      }
120
      //Erase empty blocks
121
      for(block = 0; block < FLASH_SECTOR_SIZE / FLASH_BLOCK_SIZE; ++block)
122
      {
123
         i = sector * FLASH_SECTOR_SIZE / FLASH_BLOCK_SIZE + block;
124
         if(i < FLASH_BLOCKS/8 && (FlashBlockEmpty[i >> 3] & (1 << (i & 7))))
125
         {
126
            memset(buf + FLASH_BLOCK_SIZE*block, 0xff, FLASH_BLOCK_SIZE);
127
            ++count;
128
         }
129
      }
130
      FlashErase(FLASH_SECTOR_SIZE * sector);
131
      FlashWrite((uint16*)buf, FLASH_SECTOR_SIZE * sector, FLASH_SECTOR_SIZE);
132
   }
133
   free(buf);
134
   return count;
135
}
136
 
137
 
138
int MediaBlockInit(void)
139
{
140
   FlashRead((uint16*)FlashBlockEmpty, FLASH_OFFSET, sizeof(FlashBlockEmpty));
141
   FlashRead((uint16*)FlashBlockUsed, FLASH_OFFSET+sizeof(FlashBlockEmpty),
142
             sizeof(FlashBlockUsed));
143
   FlashBlock = FLASH_START;
144
   return FlashBlockEmpty[FlashBlock >> 3] & (1 << (FlashBlock & 7));
145
}
146
#endif
147
 
148
 
149
static uint32 MediaBlockMalloc(OS_FILE *file)
150
{
151
   int i, j;
152
   (void)i; (void)j;
153
 
154
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
155
      return (uint32)malloc(file->fileEntry.blockSize);
156
#ifdef INCLUDE_FLASH
157
   //Find empty flash block
158
   for(i = FlashBlock; i < FLASH_BLOCKS; ++i)
159
   {
160
      if(FlashBlockEmpty[i >> 3] & (1 << (i & 7)))
161
      {
162
         FlashBlock = i + 1;
163
         FlashBlockEmpty[i >> 3] &= ~(1 << (i & 7));
164
         j = i >> 3;
165
         j &= ~1;
166
         FlashWrite((uint16*)(FlashBlockEmpty + j), FLASH_OFFSET + j, 2);
167
         return i;
168
      }
169
   }
170
 
171
   i = MediaBlockCleanup();
172
   if(i == 0)
173
      return 0;
174
   FlashBlock = FLASH_START;
175
   return MediaBlockMalloc(file);
176
#else
177
   return 0;
178
#endif
179
}
180
 
181
 
182
static void MediaBlockFree(OS_FILE *file, uint32 blockIndex)
183
{
184
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
185
      free((void*)blockIndex);
186
#ifdef INCLUDE_FLASH
187
   else
188
   {
189
      int i=blockIndex, j;
190
      FlashBlockUsed[i >> 3] &= ~(1 << (i & 7));
191
      j = i >> 3;
192
      j &= ~1;
193
      FlashWrite((uint16*)(FlashBlockUsed + j), FLASH_OFFSET + sizeof(FlashBlockEmpty) + j, 2);
194
   }
195
#endif
196
}
197
 
198
 
199
static void MediaBlockRead(OS_FILE *file, uint32 blockIndex)
200
{
201
   if(file->fileEntry.mediaType == FILE_MEDIA_RAM)
202
      file->block = (OS_Block_t*)blockIndex;
203
#ifdef INCLUDE_FLASH
204
   else
205
   {
206
      file->block = &file->blockLocal;
207
      FlashRead((uint16*)file->block, blockIndex << FLASH_LN2_SIZE, FLASH_BLOCK_SIZE);
208
   }
209
#endif
210
}
211
 
212
 
213
static void MediaBlockWrite(OS_FILE *file, uint32 blockIndex)
214
{
215
   (void)file;
216
   (void)blockIndex;
217
#ifdef INCLUDE_FLASH
218
   if(file->fileEntry.mediaType != FILE_MEDIA_RAM)
219
      FlashWrite((uint16*)file->block, blockIndex << FLASH_LN2_SIZE, FLASH_BLOCK_SIZE);
220
#endif
221
}
222
 
223
/***************** Media Functions End *************************/
224
 
225
// Get the next block and write the old block if it was modified
226
static void BlockRead(OS_FILE *file, uint32 blockIndex)
227
{
228
   uint32 blockIndexSave = blockIndex;
229
 
230
   OS_MutexPend(mutexFilesys);
231
   if(blockIndex == BLOCK_MALLOC)
232
   {
233
      // Get a new block
234
      blockIndex = MediaBlockMalloc(file);
235
      if(blockIndex == 0)
236
         blockIndex = BLOCK_EOF;
237
      if(file->block)
238
      {
239
         // Set next pointer in previous block
240
         file->block->next = blockIndex;
241
         file->blockModified = 1;
242
      }
243
   }
244
   if(file->block && file->blockModified)
245
   {
246
      // Write block back to flash or disk
247
      MediaBlockWrite(file, file->blockIndex);
248
      file->blockModified = 0;
249
   }
250
   if(blockIndex == BLOCK_EOF)
251
   {
252
      OS_MutexPost(mutexFilesys);
253
      return;
254
   }
255
   file->blockIndex = blockIndex;
256
   file->blockOffset = 0;
257
   MediaBlockRead(file, blockIndex);
258
   if(blockIndexSave == BLOCK_MALLOC)
259
   {
260
      memset(file->block, 0xff, file->fileEntry.blockSize);
261
      file->blockModified = 1;
262
   }
263
   OS_MutexPost(mutexFilesys);
264
}
265
 
266
 
267
int OS_fread(void *buffer, int size, int count, OS_FILE *file)
268
{
269
   int items, bytes;
270
   uint8 *buf = (uint8*)buffer;
271
 
272
   for(items = 0; items < count; ++items)
273
   {
274
      for(bytes = 0; bytes < size; ++bytes)
275
      {
276
         if(file->fileOffset >= file->fileEntry.length &&
277
            file->fileEntry.isDirectory == 0)
278
            return items;
279
         if(file->blockOffset >= file->fileEntry.blockSize - sizeof(uint32))
280
         {
281
            if(file->block->next == BLOCK_EOF)
282
               return items;
283
            BlockRead(file, file->block->next);
284
         }
285
         *buf++ = file->block->data[file->blockOffset++];
286
         ++file->fileOffset;
287
      }
288
   }
289
   return items;
290
}
291
 
292
 
293
int OS_fwrite(void *buffer, int size, int count, OS_FILE *file)
294
{
295
   int items, bytes;
296
   uint8 *buf = (uint8*)buffer;
297
 
298
   OS_MutexPend(mutexFilesys);
299
   file->blockModified = 1;
300
   for(items = 0; items < count; ++items)
301
   {
302
      for(bytes = 0; bytes < size; ++bytes)
303
      {
304
         if(file->blockOffset >= file->fileEntry.blockSize - sizeof(uint32))
305
         {
306
            if(file->block->next == BLOCK_EOF)
307
               file->block->next = BLOCK_MALLOC;
308
            BlockRead(file, file->block->next);
309
            if(file->blockIndex == BLOCK_EOF)
310
            {
311
               count = 0;
312
               --items;
313
               break;
314
            }
315
            file->blockModified = 1;
316
         }
317
         file->block->data[file->blockOffset++] = *buf++;
318
         ++file->fileOffset;
319
      }
320
   }
321
   file->blockModified = 1;
322
   file->fileModified = 1;
323
   if(file->fileOffset > file->fileEntry.length)
324
      file->fileEntry.length = file->fileOffset;
325
   OS_MutexPost(mutexFilesys);
326
   return items;
327
}
328
 
329
 
330
int OS_fseek(OS_FILE *file, int offset, int mode)
331
{
332
   if(mode == 1)      //SEEK_CUR
333
      offset += file->fileOffset;
334
   else if(mode == 2) //SEEK_END
335
      offset += file->fileEntry.length;
336
   file->fileOffset = offset;
337
   BlockRead(file, file->fileEntry.blockIndex);
338
   while(offset > (int)file->fileEntry.blockSize - (int)sizeof(uint32))
339
   {
340
      BlockRead(file, file->block->next);
341
      offset -= file->fileEntry.blockSize - (int)sizeof(uint32);
342
   }
343
   file->blockOffset = offset;
344
   return 0;
345
}
346
 
347
 
348
static int FileOpen(OS_FILE *file, char *name, OS_FileEntry_t *fileEntry)
349
{
350
   memset(file, 0, sizeof(OS_FILE));
351
   if(fileEntry == NULL)
352
   {
353
      // Open root file
354
      memcpy(&file->fileEntry, &rootFileEntry, sizeof(OS_FileEntry_t));
355
   }
356
   else if(fileEntry->valid == 1)
357
   {
358
      // Open existing file
359
      memcpy(&file->fileEntry, fileEntry, sizeof(OS_FileEntry_t));
360
   }
361
   else
362
   {
363
      // Initialize new file
364
      file->fileModified = 1;
365
      file->blockModified = 1;
366
      memset(&file->fileEntry, 0, sizeof(OS_FileEntry_t));
367
      file->fileEntry.isDirectory = 0;
368
      file->fileEntry.length = 0;
369
      strncpy(file->fileEntry.name, name, FILE_NAME_SIZE-1);
370
      file->fileEntry.blockIndex = 0;
371
      file->fileEntry.valid = 1;
372
      file->fileEntry.blockSize = fileEntry->blockSize;
373
      file->fileEntry.mediaType = fileEntry->mediaType;
374
   }
375
   BlockRead(file, file->fileEntry.blockIndex);    //Get first block
376
   file->fileEntry.blockIndex = file->blockIndex;
377
   file->fileOffset = 0;
378
   if(file->blockIndex == BLOCK_EOF)
379
      return -1;
380
   return 0;
381
}
382
 
383
 
384
static int FileFind(OS_FILE *directory, char *name, OS_FileEntry_t *fileEntry)
385
{
386
   int count, rc = -1;
387
   uint32 blockIndex, blockOffset;
388
   uint32 blockIndexEmpty=BLOCK_EOF, blockOffsetEmpty=0;
389
 
390
   // Loop through files in directory
391
   for(;;)
392
   {
393
      blockIndex = directory->blockIndex;
394
      blockOffset = directory->blockOffset;
395
      count = OS_fread(fileEntry, sizeof(OS_FileEntry_t), 1, directory);
396
      if(count == 0 || fileEntry->blockIndex == BLOCK_EOF)
397
         break;
398
      if(fileEntry->valid == 1 && strcmp(fileEntry->name, name) == 0)
399
      {
400
         rc = 0;  //Found the file in the directory
401
         break;
402
      }
403
      if(fileEntry->valid != 1 && blockIndexEmpty == BLOCK_EOF)
404
      {
405
         blockIndexEmpty = blockIndex;
406
         blockOffsetEmpty = blockOffset;
407
      }
408
   }
409
   if(rc == 0 || directory->fileEntry.mediaType == FILE_MEDIA_FLASH ||
410
      blockIndexEmpty == BLOCK_EOF)
411
   {
412
      // Backup to start of fileEntry or last entry in directory
413
      if(directory->blockIndex != blockIndex)
414
         BlockRead(directory, blockIndex);
415
      directory->blockOffset = blockOffset;
416
   }
417
   else
418
   {
419
      // Backup to empty slot
420
      if(directory->blockIndex != blockIndexEmpty)
421
         BlockRead(directory, blockIndexEmpty);
422
      directory->blockOffset = blockOffsetEmpty;
423
   }
424
   return rc;
425
}
426
 
427
 
428
static int FileFindRecursive(OS_FILE *directory, char *name,
429
                             OS_FileEntry_t *fileEntry, char *filename)
430
{
431
   int rc, length;
432
 
433
   rc = FileOpen(directory, NULL, NULL);            //Open root directory
434
   for(;;)
435
   {
436
      if(name[0] == '/')
437
         ++name;
438
      for(length = 0; length < FILE_NAME_SIZE; ++length)
439
      {
440
         if(name[length] == 0 || name[length] == '/')
441
            break;
442
         filename[length] = name[length];
443
      }
444
      filename[length] = 0;
445
      rc = FileFind(directory, filename, fileEntry);  //Find file
446
      if(rc)
447
      {
448
         // File not found
449
         fileEntry->mediaType = directory->fileEntry.mediaType;
450
         fileEntry->blockSize = directory->fileEntry.blockSize;
451
         fileEntry->valid = 0;
452
         if(strstr(name, "/") == NULL)
453
            return rc;
454
         else
455
            return -2;  //can't find parent directory
456
      }
457
      name += length;
458
      if(name[0])
459
         rc = FileOpen(directory, filename, fileEntry);  //Open subdir
460
      else
461
         break;
462
   }
463
   return rc;
464
}
465
 
466
 
467
OS_FILE *OS_fopen(char *name, char *mode)
468
{
469
   OS_FILE *file;
470
   OS_FileEntry_t fileEntry;
471
   OS_FILE dir;
472
   char filename[FILE_NAME_SIZE];  //Name without directories
473
   int rc;
474
 
475
   //printf("OS_fopen(%s)\n", name);
476
   if(rootFileEntry.blockIndex == 0)
477
   {
478
      // Mount file system
479
      mutexFilesys = OS_MutexCreate("filesys");
480
      memset(&dir, 0, sizeof(OS_FILE));
481
      dir.fileEntry.blockSize = BLOCK_SIZE;
482
      //dir.fileEntry.mediaType = FILE_MEDIA_FLASH;  //Test flash
483
      BlockRead(&dir, BLOCK_MALLOC);
484
      strcpy(rootFileEntry.name, "/");
485
      rootFileEntry.mediaType = dir.fileEntry.mediaType;
486
      rootFileEntry.blockIndex = dir.blockIndex;
487
      rootFileEntry.blockSize = dir.fileEntry.blockSize;
488
      rootFileEntry.isDirectory = 1;
489
      BlockRead(&dir, BLOCK_EOF);    //Flush data
490
#ifdef INCLUDE_FLASH
491
      file = OS_fopen("flash", "w+");
492
      if(file == NULL)
493
         return NULL;
494
      file->fileEntry.isDirectory = 1;
495
      file->fileEntry.mediaType = FILE_MEDIA_FLASH;
496
      file->fileEntry.blockSize = FLASH_BLOCK_SIZE;
497
      file->block = NULL;
498
      rc = MediaBlockInit();
499
      if(rc == 1)
500
         BlockRead(file, BLOCK_MALLOC);
501
      else
502
         BlockRead(file, FLASH_START);
503
      file->fileEntry.blockIndex = file->blockIndex;
504
      OS_fclose(file);
505
#endif
506
   }
507
 
508
   file = (OS_FILE*)malloc(sizeof(OS_FILE));
509
   if(file == NULL)
510
      return NULL;
511
   OS_MutexPend(mutexFilesys);
512
   if(name[0] == 0 || strcmp(name, "/") == 0)
513
   {
514
      FileOpen(file, NULL, NULL);
515
      OS_MutexPost(mutexFilesys);
516
      return file;
517
   }
518
   if(mode[0] == 'w')
519
   {
520
      //Don't over write a directory
521
      fileEntry.isDirectory = 0;
522
      rc = FileFindRecursive(&dir, name, &fileEntry, filename);
523
      if(rc == 0)
524
      {
525
         if(fileEntry.isDirectory)
526
         {
527
            free(file);
528
            return NULL;
529
         }
530
         OS_fdelete(name);
531
      }
532
   }
533
   rc = FileFindRecursive(&dir, name, &fileEntry, filename);
534
   if(rc == -2 || (rc && mode[0] == 'r'))
535
   {
536
      free(file);
537
      OS_MutexPost(mutexFilesys);
538
      return NULL;
539
   }
540
   if(rc)
541
      fileEntry.valid = 0;
542
   rc = FileOpen(file, filename, &fileEntry);  //Open file
543
   file->fullname[0] = 0;
544 360 rhoads
   strncat(file->fullname, name, FULL_NAME_SIZE);
545 398 rhoads
   OS_MutexPost(mutexFilesys);
546 360 rhoads
   if(mode[0] == 'a')
547
      OS_fseek(file, 0, 2);  //goto end of file
548 398 rhoads
   return file;
549
}
550
 
551
 
552
void OS_fclose(OS_FILE *file)
553
{
554
   OS_FileEntry_t fileEntry;
555
   OS_FILE dir;
556
   char filename[FILE_NAME_SIZE];
557
   int rc;
558
 
559
   if(file->fileModified)
560
   {
561
      // Write file->fileEntry into parent directory
562
      OS_MutexPend(mutexFilesys);
563
      BlockRead(file, BLOCK_EOF);
564
      rc = FileFindRecursive(&dir, file->fullname, &fileEntry, filename);
565
      if(file->fileEntry.mediaType == FILE_MEDIA_FLASH && rc == 0)
566
      {
567
         // Invalidate old entry and add new entry at the end
568
         fileEntry.valid = 0;
569
         OS_fwrite(&fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
570
         FileFind(&dir, "endoffile", &fileEntry);
571
      }
572
      OS_fwrite(&file->fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
573
      BlockRead(&dir, BLOCK_EOF);  //flush data
574
      OS_MutexPost(mutexFilesys);
575
   }
576
   free(file);
577
}
578
 
579
 
580
int OS_fmkdir(char *name)
581
{
582
   OS_FILE *file;
583
   file = OS_fopen(name, "w+");
584
   if(file == NULL)
585
      return -1;
586
   file->fileEntry.isDirectory = 1;
587
   OS_fclose(file);
588
   return 0;
589
}
590
 
591
 
592
void OS_fdelete(char *name)
593
{
594
   OS_FILE dir, file;
595
   OS_FileEntry_t fileEntry;
596
   int rc;
597
   uint32 blockIndex;
598
   char filename[FILE_NAME_SIZE];  //Name without directories
599
 
600
   OS_MutexPend(mutexFilesys);
601
   rc = FileFindRecursive(&dir, name, &fileEntry, filename);
602
   if(rc == 0)
603
   {
604
      FileOpen(&file, NULL, &fileEntry);
605
      for(blockIndex = file.blockIndex; file.block->next != BLOCK_EOF; blockIndex = file.blockIndex)
606
      {
607
         BlockRead(&file, file.block->next);
608
         MediaBlockFree(&file, blockIndex);
609
      }
610
      MediaBlockFree(&file, blockIndex);
611
      fileEntry.valid = 0;
612
      OS_fwrite((char*)&fileEntry, sizeof(OS_FileEntry_t), 1, &dir);
613
      BlockRead(&dir, BLOCK_EOF);
614
   }
615
   OS_MutexPost(mutexFilesys);
616
}
617
 
618
 
619
int OS_flength(char *entry)
620
{
621
   OS_FileEntry_t *entry2=(OS_FileEntry_t*)entry;
622
   return entry2->length;
623
}
624
 
625
 
626
int OS_fdir(OS_FILE *dir, char name[64])
627
{
628
   OS_FileEntry_t *fileEntry = (OS_FileEntry_t*)name;
629
   int count;
630
   for(;;)
631
   {
632
      count = OS_fread(fileEntry, sizeof(OS_FileEntry_t), 1, dir);
633
      if(count == 0 || fileEntry->blockIndex == BLOCK_EOF)
634
         return -1;
635
      if(fileEntry->valid == 1)
636
         break;
637
   }
638
   return 0;
639
}
640
 
641
/*************************************************/
642
#define TEST_FILES
643
#ifdef TEST_FILES
644
int DirRecursive(char *name)
645
{
646
   OS_FileEntry_t fileEntry;
647
   OS_FILE *dir;
648
   char fullname[FULL_NAME_SIZE];
649
   int rc;
650
 
651
   dir = OS_fopen(name, "r");
652
   for(;;)
653
   {
654
      rc = OS_fdir(dir, (char*)&fileEntry);
655
      if(rc)
656
         break;
657
      printf("%s %d\n", fileEntry.name, fileEntry.length);
658
      if(fileEntry.isDirectory)
659
      {
660
         if(strcmp(name, "/") == 0)
661
            sprintf(fullname, "/%s", fileEntry.name);
662
         else
663
            sprintf(fullname, "%s/%s", name, fileEntry.name);
664
         DirRecursive(fullname);
665
      }
666
   }
667
   OS_fclose(dir);
668
   return 0;
669
}
670
 
671
int OS_ftest(void)
672
{
673
   OS_FILE *file;
674
   char *buf;
675
   int count;
676
   int i, j;
677
 
678
   buf = (char*)malloc(5000);
679
   memset(buf, 0, 5000);
680
   for(count = 0; count < 4000; ++count)
681
      buf[count] = (char)('A' + (count % 26));
682
   OS_fmkdir("dir");
683
   OS_fmkdir("/dir/subdir");
684
   file = OS_fopen("/dir/subdir/test.txt", "w");
685
   count = OS_fwrite(buf, 1, 4000, file);
686
   OS_fclose(file);
687
   memset(buf, 0, 5000);
688
   file = OS_fopen("/dir/subdir/test.txt", "r");
689
   count = OS_fread(buf, 1, 5000, file);
690
   OS_fclose(file);
691
   printf("(%s)\n", buf);
692
 
693
   DirRecursive("/");
694
 
695
   for(i = 0; i < 5; ++i)
696
   {
697
      sprintf(buf, "/dir%d", i);
698
      OS_fmkdir(buf);
699
      for(j = 0; j < 5; ++j)
700
      {
701
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
702
         file = OS_fopen(buf, "w");
703
         sprintf(buf, "i=%d j=%d", i, j);
704
         OS_fwrite(buf, 1, 8, file);
705
         OS_fclose(file);
706
      }
707
   }
708
 
709
   OS_fdelete("/dir1/file12");
710
   DirRecursive("/");
711
   file = OS_fopen("/baddir/myfile.txt", "w");
712
   if(file)
713
      printf("ERROR!\n");
714
 
715
   for(i = 0; i < 5; ++i)
716
   {
717
      for(j = 0; j < 5; ++j)
718
      {
719
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
720
         file = OS_fopen(buf, "r");
721
         if(file)
722
         {
723
            count = OS_fread(buf, 1, 500, file);
724
            printf("i=%d j=%d count=%d (%s)\n", i, j, count, buf);
725
            OS_fclose(file);
726
         }
727
      }
728
   }
729
 
730
   OS_fdelete("/dir/subdir/test.txt");
731
   OS_fdelete("/dir/subdir");
732
   OS_fdelete("/dir");
733
   for(i = 0; i < 5; ++i)
734
   {
735
      for(j = 0; j < 5; ++j)
736
      {
737
         sprintf(buf, "/dir%d/file%d%d", i, i, j);
738
         OS_fdelete(buf);
739
      }
740
      sprintf(buf, "/dir%d", i);
741
      OS_fdelete(buf);
742
   }
743
 
744
   DirRecursive("/");
745
 
746
   free(buf);
747
   return 0;
748
}
749
#endif  //TEST_FILES

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.