⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fatlite.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	cluster		: Cluster no.                                   *//*                                                                      *//* Returns:                                                             *//*	first sector no. of cluster					*//*----------------------------------------------------------------------*/static SectorNo firstSectorOfCluster(Volume vol, unsigned cluster){  return (SectorNo) (cluster - 2) * vol.sectorsPerCluster +	 vol.firstDataSectorNo;}/*----------------------------------------------------------------------*//*		       g e t D i r E n t r y    			*//*									*//* Get a read-only copy of a directory entry.				*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	file		: File belonging to directory entry		*//*                                                                      *//* Returns:                                                             *//*	dirEntry	: Pointer to directory entry			*//*----------------------------------------------------------------------*/static const DirectoryEntry FAR0 *getDirEntry(File *file){  return (DirectoryEntry FAR0 *) findSector(file->fileVol,file->directorySector) +	 file->directoryIndex;}/*----------------------------------------------------------------------*//*		  g e t D i r E n t r y F o r U p d a t e		*//*									*//* Read a directory sector into the sector buffer and point to an	*//* entry, with the intention of modifying it.				*//* The buffer will be flushed on operation exit.			*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	file		: File belonging to directory entry		*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*	dirEntry	: Pointer to directory entry in buffer		*//*----------------------------------------------------------------------*/static FLStatus getDirEntryForUpdate(File *file, DirectoryEntry * *dirEntry){  Volume vol = file->fileVol;  checkStatus(updateSector(file->fileVol,file->directorySector,TRUE));  *dirEntry = directory + file->directoryIndex;  buffer.checkPoint = TRUE;  return flOK;}/*----------------------------------------------------------------------*//*		  s e t C u r r e n t D a t e T i m e                   *//*									*//* Set current time/date in directory entry                             *//*                                                                      *//* Parameters:                                                          *//*	dirEntry	: Pointer to directory entry                    *//*                                                                      *//*----------------------------------------------------------------------*/static void setCurrentDateTime(DirectoryEntry *dirEntry){  toLE2(dirEntry->updateTime,flCurrentTime());  toLE2(dirEntry->updateDate,flCurrentDate());}/*----------------------------------------------------------------------*//*		        g e t F A T e n t r y				*//*									*//* Get an entry from the FAT. The 1st FAT copy is used.			*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	cluster		: Cluster no. of enrty.				*//*                                                                      *//* Returns:                                                             *//*	Value of FAT entry.						*//*----------------------------------------------------------------------*/static unsigned getFATentry(Volume vol, unsigned cluster){  LEushort FAR0 *fat16Sector;  unsigned fatSectorNo = vol.firstFATSectorNo;#ifdef FAT_12BIT  if (vol.flags & VOLUME_12BIT_FAT)    fatSectorNo += (cluster * 3) >> (SECTOR_SIZE_BITS + 1);  else#endif    fatSectorNo += cluster >> (SECTOR_SIZE_BITS - 1);#ifndef SINGLE_BUFFER  if (!buffer.dirty) {    /* If the buffer is free, use it to store this FAT sector */    updateSector(&vol,fatSectorNo,TRUE);    buffer.dirty = FALSE;  }#endif  fat16Sector = (LEushort FAR0 *) findSector(&vol,fatSectorNo);#ifdef FAT_12BIT  if (vol.flags & VOLUME_12BIT_FAT) {    unsigned char FAR0 *fat12Sector = (unsigned char FAR0 *) fat16Sector;    unsigned halfByteOffset = (cluster * 3) & (SECTOR_SIZE * 2 - 1);    unsigned char firstByte = fat12Sector[halfByteOffset / 2];    halfByteOffset += 2;    if (halfByteOffset >= SECTOR_SIZE * 2) {      /* Entry continues on the next sector. What a mess */      halfByteOffset -= SECTOR_SIZE * 2;      fat12Sector = (unsigned char FAR0 *) findSector(&vol,fatSectorNo + 1);    }    if (halfByteOffset & 1)      return ((firstByte & 0xf0) >> 4) + (fat12Sector[halfByteOffset / 2] << 4);    else      return firstByte + ((fat12Sector[halfByteOffset / 2] & 0xf) << 8);  }  else#endif    return LE2(fat16Sector[cluster & (SECTOR_SIZE / 2 - 1)]);}/*----------------------------------------------------------------------*//*		         s e t F A T e n t r y				*//*									*//* Writes a new value to a given FAT cluster entry.                     *//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	cluster		: Cluster no. of enrty.				*//*	entry		: New value of FAT entry.			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus setFATentry(Volume vol, unsigned cluster, unsigned entry){  LEushort *fat16Sector;  unsigned fatSectorNo = vol.firstFATSectorNo;#ifdef FAT_12BIT  if (vol.flags & VOLUME_12BIT_FAT)    fatSectorNo += (cluster * 3) >> (SECTOR_SIZE_BITS + 1);  else#endif    fatSectorNo += cluster >> (SECTOR_SIZE_BITS - 1);  checkStatus(updateSector(&vol,fatSectorNo,TRUE));  fat16Sector = (LEushort *) buffer.data;#ifdef FAT_12BIT  if (vol.flags & VOLUME_12BIT_FAT) {    unsigned char *fat12Sector = (unsigned char *) buffer.data;    unsigned halfByteOffset = (cluster * 3) & (SECTOR_SIZE * 2 - 1);    if (halfByteOffset & 1) {      fat12Sector[halfByteOffset / 2] &= 0xf;      fat12Sector[halfByteOffset / 2] |= (entry & 0xf) << 4;    }    else      fat12Sector[halfByteOffset / 2] = entry;    halfByteOffset += 2;    if (halfByteOffset >= SECTOR_SIZE * 2) {      /* Entry continues on the next sector. What a mess */      halfByteOffset -= SECTOR_SIZE * 2;      fatSectorNo++;      checkStatus(updateSector(&vol,fatSectorNo,TRUE));    }    if (halfByteOffset & 1)      fat12Sector[halfByteOffset / 2] = entry >> 4;    else {      fat12Sector[halfByteOffset / 2] &= 0xf0;      fat12Sector[halfByteOffset / 2] |= (entry & 0x0f00) >> 8;    }  }  else#endif    toLE2(fat16Sector[cluster & (SECTOR_SIZE / 2 - 1)],entry);  return flOK;}/*----------------------------------------------------------------------*//*		        a l l o c a t e C l u s t e r			*//*									*//* Allocates a new cluster for a file and adds it to a FAT chain or     *//* marks it in a directory entry.					*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	file		: File to extend. It should be positioned at    *//*			  end-of-file.					*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus allocateCluster(File *file){  Volume vol = file->fileVol;  unsigned originalRover;  if (file->flags & FILE_READ_ONLY)    return flNoWriteAccess;  /* Look for a free cluster. Start at the allocation rover */  originalRover = vol.allocationRover;  do {    vol.allocationRover++;    if (vol.allocationRover > vol.maxCluster)      vol.allocationRover = 2;	/* wraparound to start of volume */    if (vol.allocationRover == originalRover)      return flNoSpaceInVolume;  } while (getFATentry(&vol,vol.allocationRover) != FAT_FREE);  /* Found a free cluster. Mark it as an end of chain */  checkStatus(setFATentry(&vol,vol.allocationRover,FAT_LAST_CLUSTER));  /* Mark previous cluster or directory to point to it */  if (file->currentCluster == 0) {    DirectoryEntry *dirEntry;    checkStatus(getDirEntryForUpdate(file,&dirEntry));    toLE2(dirEntry->startingCluster,vol.allocationRover);    setCurrentDateTime(dirEntry);  }  else    checkStatus(setFATentry(&vol,file->currentCluster,vol.allocationRover));  /* Set our new current cluster */  file->currentCluster = vol.allocationRover;  return flOK;}/*----------------------------------------------------------------------*//*		     g e t S e c t o r A n d O f f s e t		*//*									*//* Based on the current position of a file, gets a sector number and    *//* offset in the sector that marks the file's current position.		*//* If the position is at the end-of-file, and the file is opened for    *//* write, this routine will extend the file by allocating a new cluster.*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus getSectorAndOffset(File *file,				 SectorNo *sectorNo,				 unsigned *offsetInSector){  Volume vol = file->fileVol;  unsigned offsetInCluster =	      (unsigned) file->currentPosition & (vol.bytesPerCluster - 1);  if (offsetInCluster == 0) {	/* This cluster is finished. Get next */    if (file->flags & FILE_IS_ROOT_DIR) {      if (file->currentPosition >= file->fileSize)	return flRootDirectoryFull;    }    else {      if (file->currentPosition >= file->fileSize) {	checkStatus(allocateCluster(file));      }      else {	unsigned nextCluster;	if (file->currentCluster == 0)	  nextCluster = LE2(getDirEntry(file)->startingCluster);	else	  nextCluster = getFATentry(&vol,file->currentCluster);	if (nextCluster < 2 || nextCluster > vol.maxCluster)	  /* We have a bad file size, or the FAT is bad */	  return flInvalidFATchain;	file->currentCluster = nextCluster;      }    }  }  *offsetInSector = offsetInCluster & (SECTOR_SIZE - 1);  if (file->flags & FILE_IS_ROOT_DIR)    *sectorNo = vol.rootDirectorySectorNo +		      (SectorNo) (file->currentPosition >> SECTOR_SIZE_BITS);  else    *sectorNo = firstSectorOfCluster(&vol,file->currentCluster) +		      (SectorNo) (offsetInCluster >> SECTOR_SIZE_BITS);  return flOK;}/*----------------------------------------------------------------------*//*		        c l o s e F i l e				*//*									*//* Closes an open file, records file size and dates in directory and    *//* releases file handle.						*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	file		: File to close.		                *//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus closeFile(File *file){  if ((file->flags & FILE_MODIFIED) && !(file->flags & FILE_IS_ROOT_DIR)) {    DirectoryEntry *dirEntry;    checkStatus(getDirEntryForUpdate(file,&dirEntry));    dirEntry->attributes |= ATTR_ARCHIVE;    if (!(file->flags & FILE_IS_DIRECTORY))      toLE4(dirEntry->fileSize,file->fileSize);    setCurrentDateTime(dirEntry);  }  file->flags = 0;		/* no longer open */  return flOK;}#ifdef SUB_DIRECTORY/*----------------------------------------------------------------------*//*		        e x t e n d D i r e c t o r y			*//*									*//* Extends a directory, writing empty entries and the mandatory '.' and *//* '..' entries.							*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	file		: Directory file to extend. On entry,	        *//*			  currentPosition == fileSize. On exit, fileSize*//*			  is updated.					*//*	ownerDir	: Cluster no. of owner directory		*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus extendDirectory(File *file, unsigned ownerDir){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -