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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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