📄 fatlite.c
字号:
/* fatlite.c - True Flash File System *//* * Copyright (c) 2004, 2005 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. *//* FAT-FTL Lite Software Development Kit * Copyright (C) M-Systems Ltd. 1995-1997 *//*modification history--------------------01d,29jun05,j_b replace INCLUDE_RELFS_MAIN with global flFileSysSectorStart01c,17may05,jb3 Fix to work for DosFS after Reliance fix.01b,13apr05,jb3 Protect the BPB for TFFS, allow Reliance compatability01a,29jul04,alr modified file header, restarted history*/#include <fltl.h>#include <flsocket.h>#include <dosformt.h>#include <backgrnd.h>#include <flbuffer.h>#include <stdcomp.h>#include <fatlite.h>volatile unsigned long flMsecCounter = 0;/* * Starting sector of File System: protects overwriting TFFS at sector 0 * dosFS shares TFFS sector 0, other file systems may not */int flFileSysSectorStart = 0; /* 0 for dosFS, 1 for Reliance *//* Volume flag definitions */#define VOLUME_LOW_LVL_MOUNTED 1 /* volume is mounted for low level operations */#define VOLUME_MOUNTED 2 /* Volume is mounted */#define VOLUME_12BIT_FAT 4 /* Volume uses 12-bit FAT */#define VOLUME_ABS_MOUNTED 8 /* Volume is mounted for abs calls */typedef struct{ char flags; /* See description above */ unsigned sectorsPerCluster; /* Cluster size in sectors */ unsigned maxCluster; /* highest cluster no. */ unsigned bytesPerCluster; /* Bytes per cluster */ unsigned bootSectorNo; /* Sector no. of DOS boot sector */ unsigned firstFATSectorNo; /* Sector no. of 1st FAT */ unsigned secondFATSectorNo; /* Sector no. of 2nd FAT */ unsigned numberOfFATS; /* number of FAT copies */ unsigned sectorsPerFAT; /* Sectors per FAT copy */ unsigned rootDirectorySectorNo; /* Sector no. of root directory */ unsigned sectorsInRootDirectory; /* No. of sectors in root directory */ unsigned firstDataSectorNo; /* 1st cluster sector no. */ unsigned allocationRover; /* rover pointer for allocation */#ifndef SINGLE_BUFFER #if FILES > 0 FLBuffer volBuffer; /* Define a sector buffer */ #endif FLMutex volExecInProgress;#endif/* #ifdef LOW_LEVEL */ FLFlash flash; /* flash structure for low level operations *//* #endif */ TL tl; /* Translation layer methods */ FLSocket *socket; /* Pointer to socket */} Volume;static FLBoolean initDone = FALSE; /* Initialization already done */static Volume vols[DRIVES];typedef struct{ long currentPosition; /* current byte offset in file */#define ownerDirCluster currentPosition /* 1st cluster of owner directory */ long fileSize; /* file size in bytes */ SectorNo directorySector; /* sector of directory containing file */ unsigned currentCluster; /* cluster of current position */ unsigned char directoryIndex; /* entry no. in directory sector */ unsigned char flags; /* See description below */ Volume * fileVol; /* Drive of file */} File;/* File flag definitions */#define FILE_MODIFIED 4 /* File was modified */#define FILE_IS_OPEN 8 /* File entry is used */#define FILE_IS_DIRECTORY 0x10 /* File is a directory */#define FILE_IS_ROOT_DIR 0x20 /* File is root directory */#define FILE_READ_ONLY 0x40 /* Writes not allowed */#define FILE_MUST_OPEN 0x80 /* Create file if not found */#if FILES > 0static File fileTable[FILES]; /* the file table */#endif /* FILES > 0 */#ifdef SINGLE_BUFFERFLBuffer buffer;FLMutex execInProgress;#else#define buffer (vol.volBuffer)#define execInProgress (vol.volExecInProgress)#endif#define directory ((DirectoryEntry *) buffer.data)/*----------------------------------------------------------------------*//* s e t B u s y *//* *//* Notifies the start and end of a file-system operation. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* state : TFFS_ON (1) = operation entry *//* TFFS_OFF(0) = operation exit *//* *//*----------------------------------------------------------------------*/static FLStatus setBusy(Volume vol, FLBoolean state){ if (state == TFFS_ON) { if(!flTakeMutex(&execInProgress,1)) return flDriveNotAvailable; flSocketSetBusy(vol.socket,TFFS_ON); flNeedVcc(vol.socket); if(vol.flags & VOLUME_ABS_MOUNTED) vol.tl.tlSetBusy(vol.tl.rec,TFFS_ON); } else { if(vol.flags & VOLUME_ABS_MOUNTED) vol.tl.tlSetBusy(vol.tl.rec,TFFS_OFF); flDontNeedVcc(vol.socket); flSocketSetBusy(vol.socket,TFFS_OFF); flFreeMutex(&execInProgress); } return flOK;}/*----------------------------------------------------------------------*//* f i n d S e c t o r *//* *//* Locates a sector in the buffer or maps it *//* *//* Parameters: *//* vol : Pointer identifying drive *//* sectorNo : Sector no. to locate *//* *//*----------------------------------------------------------------------*/static const void FAR0 *findSector(Volume vol, SectorNo sectorNo){ CardAddress *physAddress =0; return#if FILES > 0 (sectorNo == buffer.sectorNo && &vol == buffer.owner) ? buffer.data :#endif vol.tl.mapSector(vol.tl.rec,sectorNo, physAddress);}#if FILES > 0static FLStatus closeFile(File *file); /* forward */static FLStatus flushBuffer(Volume vol); /* forward */#endif/*----------------------------------------------------------------------*//* d i s m o u n t V o l u m e *//* *//* Dismounts the volume, closing all files. *//* This call is not normally necessary, unless it is known the volume *//* will soon be removed. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus dismountVolume(Volume vol){#if FILES > 0 int i;#endif if(vol.flags & VOLUME_ABS_MOUNTED) { FLStatus status = flOK;#ifndef FIXED_MEDIA status = flMediaCheck(vol.socket);#endif if(status != flOK) vol.flags = 0;#if FILES > 0 else { checkStatus(flushBuffer(&vol)); } /* Close or discard all files and make them available */ for(i = 0; i < FILES; i++) if(fileTable[i].fileVol == &vol) if(vol.flags & VOLUME_MOUNTED) closeFile(&fileTable[i]); else fileTable[i].flags = 0; vol.tl.dismount(vol.tl.rec); buffer.sectorNo = UNASSIGNED_SECTOR; /* Current sector no. (none) */ buffer.dirty = buffer.checkPoint = FALSE;#endif /* FILES > 0 */ } vol.flags = 0; /* mark volume unmounted */ return flOK;}/*----------------------------------------------------------------------*//* m o u n t V o l u m e *//* *//* Mounts the Flash volume. *//* *//* In case the inserted volume has changed, or on the first access to *//* the file system, it should be mounted before file operations can be *//* done on it. *//* Mounting a volume has the effect of discarding all open files (the *//* files cannot be properly closed since the original volume is gone), *//* and turning off the media-change indication to allow file processing *//* calls. *//* *//* The volume automatically becomes unmounted if it is removed or *//* changed. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed *//*----------------------------------------------------------------------*/static FLStatus mountVolume(Volume vol){ SectorNo noOfSectors; PartitionTable FAR0 *partitionTable; DOSBootSector FAR0 *bootSector; checkStatus(dismountVolume(&vol)); checkStatus(flMount(&vol - vols,&vol.tl,&vol.flash)); /* Try to mount translation layer */ /* Read in paritition table */ partitionTable = (PartitionTable FAR0 *) findSector(&vol,0); if(partitionTable == NULL) { return flSectorNotFound; } /* *BUG* *BUG* Doesn't work if SECTOR_SIZE < 512 */ if(LE2(partitionTable->signature) == PARTITION_SIGNATURE && partitionTable->type != 0) vol.bootSectorNo = (unsigned) UNAL4(partitionTable->startingSectorOfPartition); else vol.bootSectorNo = 0; /* If partition table is undetected, assume sector 0 is DOS boot block */ vol.firstFATSectorNo = vol.secondFATSectorNo = 0; /* Disable FAT monitoring */ vol.flags |= VOLUME_ABS_MOUNTED; /* Enough to do abs operations */ bootSector = (DOSBootSector FAR0 *) findSector(&vol,vol.bootSectorNo); if(bootSector == NULL) { return flSectorNotFound; } /* Do the customary sanity checks */ if(!(bootSector->bpb.jumpInstruction[0] == 0xe9 || (bootSector->bpb.jumpInstruction[0] == 0xeb && bootSector->bpb.jumpInstruction[2] == 0x90))) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: did not recognize format.\n"); #endif return flNonFATformat; } /* See if we handle this sector size */ if(UNAL2(bootSector->bpb.bytesPerSector) != SECTOR_SIZE) { return flFormatNotSupported; } vol.sectorsPerCluster = bootSector->bpb.sectorsPerCluster; vol.numberOfFATS = bootSector->bpb.noOfFATS; vol.sectorsPerFAT = LE2(bootSector->bpb.sectorsPerFAT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -