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

📄 fs_fat32util.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
void fat_putuint16(ubyte *ptr, uint16 value16){  ubyte *val = (ubyte*)&value16;#ifdef CONFIG_ENDIAN_BIG  /* The bytes always have to be swapped if the target is big-endian */  ptr[0] = val[1];  ptr[1] = val[0];#else  /* Byte-by-byte transfer is still necessary if the address is un-aligned */  ptr[0] = val[0];  ptr[1] = val[1];#endif}/**************************************************************************** * Name: fat_putuint32 ****************************************************************************/void fat_putuint32(ubyte *ptr, uint32 value32){  uint16 *val = (uint16*)&value32;#ifdef CONFIG_ENDIAN_BIG  /* The bytes always have to be swapped if the target is big-endian */  fat_putuint16(&ptr[0], val[2]);  fat_putuint16(&ptr[2], val[0]);#else  /* Byte-by-byte transfer is still necessary if the address is un-aligned */  fat_putuint16(&ptr[0], val[0]);  fat_putuint16(&ptr[2], val[2]);#endif}/**************************************************************************** * Name: fat_semtake ****************************************************************************/void fat_semtake(struct fat_mountpt_s *fs){  /* Take the semaphore (perhaps waiting) */  while (sem_wait(&fs->fs_sem) != 0)    {      /* The only case that an error should occur here is if       * the wait was awakened by a signal.       */      ASSERT(*get_errno_ptr() == EINTR);    }}/**************************************************************************** * Name: fat_semgive ****************************************************************************/void fat_semgive(struct fat_mountpt_s *fs){   sem_post(&fs->fs_sem);}/**************************************************************************** * Name: fat_systime2fattime * * Desciption: Get the system time convertto a time and and date suitble * for writing into the FAT FS. * *    TIME in LS 16-bits: *      Bits 0:4   = 2 second count (0-29 representing 0-58 seconds) *      Bits 5-10  = minutes (0-59) *      Bits 11-15 = hours (0-23) *    DATE in MS 16-bits *      Bits 0:4   = Day of month (0-31) *      Bits 5:8   = Month of year (1-12) *      Bits 9:15  = Year from 1980 (0-127 representing 1980-2107) * ****************************************************************************/uint32 fat_systime2fattime(void){#warning "Time not implemented"    return 0;}/**************************************************************************** * Name: fat_fattime2systime * * Desciption: Convert FAT data and time to a system time_t * *    16-bit FAT time: *      Bits 0:4   = 2 second count (0-29 representing 0-58 seconds) *      Bits 5-10  = minutes (0-59) *      Bits 11-15 = hours (0-23) *    16-bit FAT date: *      Bits 0:4   = Day of month (0-31) *      Bits 5:8   = Month of year (1-12) *      Bits 9:15  = Year from 1980 (0-127 representing 1980-2107) * ****************************************************************************/time_t fat_fattime2systime(uint16 fattime, uint16 fatdate){#warning "Time not implemented"    return 0;}/**************************************************************************** * Name: fat_mount * * Desciption: This function is called only when the mountpoint is first *   established.  It initializes the mountpoint structure and verifies *   that a valid FAT32 filesystem is provided by the block driver. * *   The caller should hold the mountpoint semaphore * ****************************************************************************/int fat_mount(struct fat_mountpt_s *fs, boolean writeable){  FAR struct inode *inode;  struct geometry geo;  int ret;  /* Assume that the mount is successful */  fs->fs_mounted = TRUE;  /* Check if there is media available */  inode = fs->fs_blkdriver;  if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry ||      inode->u.i_bops->geometry(inode, &geo) != OK || !geo.geo_available)    {      ret = -ENODEV;      goto errout;    }  /* Make sure that that the media is write-able (if write access is needed) */  if (writeable && !geo.geo_writeenabled)    {      ret = -EACCES;      goto errout;    }  /* Save the hardware geometry */  fs->fs_hwsectorsize = geo.geo_sectorsize;  fs->fs_hwnsectors   = geo.geo_nsectors;  /* Allocate a buffer to hold one hardware sector */  fs->fs_buffer = (ubyte*)malloc(fs->fs_hwsectorsize);  if (!fs->fs_buffer)    {      ret = -ENOMEM;      goto errout;    }  /* Search FAT boot record on the drive.  First check at sector zero.  This   * could be either the boot record or a partition that refers to the boot   * record.   *   * First read sector zero.  This will be the first access to the drive and a   * likely failure point.   */  fs->fs_fatbase = 0;  ret = fat_hwread(fs, fs->fs_buffer, 0, 1);  if (ret < 0)    {      goto errout_with_buffer;    }  if (fat_checkbootrecord(fs) != OK)    {      /* The contents of sector 0 is not a boot record.  It could be a       * partition, however.  Assume it is a partition and get the offset       * into the partition table.  This table is at offset MBR_TABLE and is       * indexed by 16x the partition number.  Here we support only       * parition 0.       */      ubyte *partition = &fs->fs_buffer[MBR_TABLE + 0];      /* Check if the partition exists and, if so, get the bootsector for that       * partition and see if we can find the boot record there.       */       if (partition[4])        {          /* There appears to be a partition, get the sector number of the           * partition (LBA)           */          fs->fs_fatbase = MBR_GETPARTSECTOR(&partition[8]);          /* Read the new candidate boot sector */          ret = fat_hwread(fs, fs->fs_buffer, fs->fs_fatbase, 1);          if (ret < 0)          {              goto errout_with_buffer;          }          /* Check if this is a boot record */          if (fat_checkbootrecord(fs) != OK)            {              goto errout_with_buffer;            }        }    }  /* We have what appears to be a valid FAT filesystem! Now read the   * FSINFO sector (FAT32 only)   */  if (fs->fs_type == FSTYPE_FAT32)  {      ret = fat_checkfsinfo(fs);      if (ret != OK)      {          goto errout_with_buffer;      }  }  /* We did it! */  fdbg("FAT%d:\n", fs->fs_type == 0 ? 12 : fs->fs_type == 1  ? 16 : 32);  fdbg("\tHW  sector size:     %d\n", fs->fs_hwsectorsize);  fdbg("\t    sectors:         %d\n", fs->fs_hwnsectors);  fdbg("\tFAT reserved:        %d\n", fs->fs_fatresvdseccount);  fdbg("\t    sectors:         %d\n", fs->fs_fattotsec);  fdbg("\t    start sector:    %d\n", fs->fs_fatbase);  fdbg("\t    root sector:     %d\n", fs->fs_rootbase);  fdbg("\t    root entries:    %d\n", fs->fs_rootentcnt);  fdbg("\t    data sector:     %d\n", fs->fs_database);  fdbg("\t    FSINFO sector:   %d\n", fs->fs_fsinfo);  fdbg("\t    Num FATs:        %d\n", fs->fs_fatnumfats);  fdbg("\t    FAT sectors:     %d\n", fs->fs_nfatsects);  fdbg("\t    sectors/cluster: %d\n", fs->fs_fatsecperclus);  fdbg("\t    max clusters:    %d\n", fs->fs_nclusters);  fdbg("\tFSI free count       %d\n", fs->fs_fsifreecount);  fdbg("\t    next free        %d\n", fs->fs_fsinextfree);  return OK; errout_with_buffer:  free(fs->fs_buffer);  fs->fs_buffer = 0; errout:  fs->fs_mounted = FALSE;  return ret;}/**************************************************************************** * Name: fat_checkmount * * Desciption: Check if the mountpoint is still valid. * *   The caller should hold the mountpoint semaphore * ****************************************************************************/int fat_checkmount(struct fat_mountpt_s *fs){  /* If the fs_mounted flag is FALSE, then we have already handled the loss   * of the mount.   */  if (fs && fs->fs_mounted)    {      struct fat_file_s *file;      /* We still think the mount is healthy.  Check an see if this is       * still the case       */      if (fs->fs_blkdriver)        {          struct inode *inode = fs->fs_blkdriver;          if (inode && inode->u.i_bops && inode->u.i_bops->geometry)            {              struct geometry geo;              int errcode = inode->u.i_bops->geometry(inode, &geo);              if (errcode == OK && geo.geo_available && !geo.geo_mediachanged)                {                  return OK;                }            }        }      /* If we get here, the mount is NOT healthy */      fs->fs_mounted = FALSE;      /* Make sure that this is flagged in every opened file */      for (file = fs->fs_head; file; file = file->ff_next)        {          file->ff_open = FALSE;        }    }  return -ENODEV;}/**************************************************************************** * Name: fat_hwread * * Desciption: Read the specified sector into the sector buffer * ****************************************************************************/int fat_hwread(struct fat_mountpt_s *fs, ubyte *buffer,  size_t sector,               unsigned int nsectors){  int ret = -ENODEV;  if (fs && fs->fs_blkdriver )    {      struct inode *inode = fs->fs_blkdriver;      if (inode && inode->u.i_bops && inode->u.i_bops->read)        {          ssize_t nSectorsRead = inode->u.i_bops->read(inode, buffer,                                                       sector, nsectors);          if (nSectorsRead == nsectors)            {              ret = OK;            }          else if (nSectorsRead < 0)            {              ret = nSectorsRead;            }        }    }  return ret;}/**************************************************************************** * Name: fat_hwwrite * * Desciption: Write the sector buffer to the specified sector * ****************************************************************************/int fat_hwwrite(struct fat_mountpt_s *fs, ubyte *buffer, size_t sector,                unsigned int nsectors){  int ret = -ENODEV;  if (fs && fs->fs_blkdriver )    {      struct inode *inode = fs->fs_blkdriver;      if (inode && inode->u.i_bops && inode->u.i_bops->write)        {          ssize_t nSectorsWritten =              inode->u.i_bops->write(inode, buffer, sector, nsectors);          if (nSectorsWritten == nsectors)            {              ret = OK;            }          else if (nSectorsWritten < 0)            {              ret = nSectorsWritten;            }        }    }  return ret;}/**************************************************************************** * Name: fat_cluster2sector * * Desciption: Convert a cluster number to a start sector number * ****************************************************************************/ssize_t fat_cluster2sector(struct fat_mountpt_s *fs,  uint32 cluster ){  cluster -= 2;  if (cluster >= fs->fs_nclusters - 2)    {       return -EINVAL;    }  return cluster * fs->fs_fatsecperclus + fs->fs_database;}/**************************************************************************** * Name: fat_getcluster * * Desciption: Get the cluster start sector into the FAT. * * Return:  <0: error, 0:cluster unassigned, >=0: start sector of cluster * ****************************************************************************/ssize_t fat_getcluster(struct fat_mountpt_s *fs, uint32 clusterno){  /* Verify that the cluster number is within range */  if (clusterno >= 2 && clusterno < fs->fs_nclusters)    {      /* Okay.. Read the next cluster from the FAT.  The way we will do       * this depends on the type of FAT filesystm we are dealing with.       */      switch (fs->fs_type)        {          case FSTYPE_FAT12 :            {              size_t       fatsector;              unsigned int fatoffset;              unsigned int startsector;              unsigned int fatindex;              /* FAT12 is more complex because it has 12-bits (1.5 bytes)               * per FAT entry. Get the offset to the first byte:               */              fatoffset = (clusterno * 3) / 2;              fatsector = fs->fs_fatbase + SEC_NSECTORS(fs, fatoffset);              /* Read the sector at this offset */              if (fat_fscacheread(fs, fatsector) < 0)                {                  /* Read error */                  break;                }              /* Get the first, LS byte of the cluster from the FAT */              fatindex    = fatoffset & SEC_NDXMASK(fs);              startsector = fs->fs_buffer[fatindex];              /* With FAT12, the second byte of the cluster number may lie in               * a different sector than the first byte.               */              fatindex++;              if (fatindex >= fs->fs_hwsectorsize)                {                  fatsector++;                  fatindex = 0;                  if (fat_fscacheread(fs, fatsector) < 0)                    {                      /* Read error */                      break;                    }                }              /* Get the second, MS byte of the cluster for 16-bits.  The               * does not depend on the endian-ness of the target, but only               * on the fact that the byte stream is little-endian.               */              startsector |= (unsigned int)fs->fs_buffer[fatindex] << 8;              /* Now, pick out the correct 12 bit cluster start sector value */              if ((clusterno & 1) != 0)                {                  /* Odd.. take the MS 12-bits */

⌨️ 快捷键说明

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