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

📄 fat.c

📁 看到最近大家都关心 usbhost 的实现, 论坛上能找到的代码仅是一些简单的 demo , 完整的源码级的协议层是找不到的 我就贡献一把, 将我前一段时间移植成功的 USBHost 代码奉上 注
💻 C
📖 第 1 页 / 共 5 页
字号:
  {
    tempChar = fileAlias[aliasPos++];
    if ((tempChar > ' ' && tempChar < ':' && tempChar!='.') || tempChar > '?')
      newDirEntry.ext[filePos++] = tempChar;
  }
  while (filePos < 3)
  {
    newDirEntry.ext[filePos++] = ' ';
  }

  // Scan Dir for free entry
  dirCluster = curWorkDirCluster;
  secOffset = 0;
  entryOffset = 0;
  //maxSectors = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? (filesysData - filesysRootDir) : filesysSecPerClus);
  firstSector = (dirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(dirCluster));
  disc_ReadSector (firstSector + secOffset, dirEntries);
  
  dirEntryRemain = dirEntryLength;
  tempDirCluster = dirCluster;
  tempSecOffset = secOffset;
  tempEntryOffset = entryOffset;
    
  // Search for a large enough space to fit in new directory entry
  while ((dirEntries[entryOffset].name[0] != FILE_LAST) && (dirEntryRemain > 0))
  {

    entryOffset++;

    if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
    {
      entryOffset = 0;
      secOffset++;
      if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
      {
        secOffset = 0;
        if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
        {
          dirCluster = FAT_LinkFreeCluster(dirCluster);
          dirEntries[0].name[0] = FILE_LAST;
        }
        else
        {
          dirCluster = FAT_NextCluster(dirCluster);
        }
        firstSector = FAT_ClustToSect(dirCluster);    
      }
      else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
      {
        return false;  // Got to end of root dir - can't fit in more files
      }
      disc_ReadSector (firstSector + secOffset, dirEntries);
    }

    if ((dirEntries[entryOffset].name[0] == FILE_FREE) || (dirEntries[entryOffset].name[0] == FILE_LAST) )
    {
      dirEntryRemain--;
    } else {
      dirEntryRemain = dirEntryLength;
      tempDirCluster = dirCluster;
      tempSecOffset = secOffset;
      tempEntryOffset = entryOffset;
    }
  }

  // Modifying the last directory is a special case - have to erase following entries
  if (dirEntries[entryOffset].name[0] == FILE_LAST) 
  {
    dirEndFlag = true;
  }

  // Recall last used entry
  dirCluster = tempDirCluster;
  secOffset = tempSecOffset;
  entryOffset = tempEntryOffset;
  dirEntryRemain = dirEntryLength;

  // Re-read in first sector that will be written to
  if (dirEndFlag && (entryOffset == 0))  {
    memset (dirEntries, FILE_LAST, BYTE_PER_READ);
  } else {
    disc_ReadSector (firstSector + secOffset, dirEntries);
  }

  // Add new directory entry
  while (dirEntryRemain > 0)  
  {
    // Move to next entry, first pass advances from last used entry
    entryOffset++;
    if (entryOffset == BYTE_PER_READ / sizeof (DIR_ENT))
    {
      // Write out the current sector if we need to
      entryOffset = 0;
      if (dirEntryRemain < dirEntryLength) // Don't write out sector on first pass
      {
        disc_WriteSector (firstSector + secOffset, dirEntries);
      }
      secOffset++;
      if ((secOffset == filesysSecPerClus) && (dirCluster != FAT16_ROOT_DIR_CLUSTER))
      {
        secOffset = 0;
        if (FAT_NextCluster(dirCluster) == CLUSTER_EOF)
        {
          dirCluster = FAT_LinkFreeCluster(dirCluster);
          dirEntries[0].name[0] = FILE_LAST;
        }
        else
        {
          dirCluster = FAT_NextCluster(dirCluster);
        }
        firstSector = FAT_ClustToSect(dirCluster);    
      }
      else if ((dirCluster == FAT16_ROOT_DIR_CLUSTER) && (secOffset == (filesysData - filesysRootDir)))
      {
        return false;  // Got to end of root dir - can't fit in more files
      }
      if (dirEndFlag)
      {
        memset (dirEntries, FILE_LAST, BYTE_PER_READ);
      } else {
        disc_ReadSector (firstSector + secOffset, dirEntries);
      }
    }

    // Generate LFN entries
    if (lfnPos >= 0)
    {
      lfnEntry.ordinal = (lfnPos + 1) | (dirEntryRemain == dirEntryLength ? LFN_END : 0);
      for (i = 0; i < 13; i++) {
        if (filename [lfnPos * 13 + i] == 0x01) {
          ((unsigned char*)&lfnEntry)[(int)lfn_offset_table[i]] = 0xff;
          ((unsigned char*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0xff;
        } else {
          ((unsigned char*)&lfnEntry)[(int)lfn_offset_table[i]] = filename [lfnPos * 13 + i];
          ((unsigned char*)&lfnEntry)[(int)(lfn_offset_table[i]) + 1] = 0x00;
        }
      }

      lfnEntry.checkSum = chkSum;
      lfnEntry.flag = ATTRIB_LFN;
      lfnEntry.reserved1 = 0;
      lfnEntry.reserved2 = 0;
      
      *((DIR_ENT_LFN*)&dirEntries[entryOffset]) = lfnEntry;
      lfnPos --;
      lfnEntry.ordinal = 0;
    }  // end writing long filename entries
    else
    {
      dirEntries[entryOffset] = newDirEntry;
      if (dirEndFlag && (entryOffset < (BYTE_PER_READ / sizeof (DIR_ENT))) )
        dirEntries[entryOffset+1].name[0] = FILE_LAST;
    }

    dirEntryRemain--;
  }
  
  // Write directory back to disk
  disc_WriteSector (firstSector + secOffset, dirEntries);

  // Change back to Working DIR
  curWorkDirCluster = oldWorkDirCluster;

  return true;
}
#endif

/*-----------------------------------------------------------------
FAT_FindNextFile
Gets the name of the next directory entry
  (can be a file or subdirectory)
char* filename: OUT filename, must be at least 13 chars long
FILE_TYPE return: OUT returns FT_NONE if failed, 
  FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindNextFile(char* filename)
{
  // Get the next directory entry
  DIR_ENT file;
  file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_CUR);

  if (file.name[0] == FILE_FREE)
  {
    return FT_NONE;  // Did not find a file
  }

  // Get the filename
  if (filename != NULL)
    FAT_GetFilename (file, filename);

  if ((file.attrib & ATTRIB_DIR) != 0)
  {
    return FT_DIR;  // Found a directory
  }
  else
  {
    return FT_FILE;  // Found a file
  }
}

/*-----------------------------------------------------------------
FAT_FindFirstFile
Gets the name of the first directory entry and resets the count
  (can be a file or subdirectory)
char* filename: OUT filename, must be at least 13 chars long
FILE_TYPE return: OUT returns FT_NONE if failed, 
  FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindFirstFile(char* filename)
{
  // Get the first directory entry
  DIR_ENT file;
  file = FAT_GetDirEntry (curWorkDirCluster, 1, SEEK_SET);
  
  if (file.name[0] == FILE_FREE)
  {
    return FT_NONE;  // Did not find a file
  }

  // Get the filename
  if (filename != NULL)
    FAT_GetFilename (file, filename);

  if ((file.attrib & ATTRIB_DIR) != 0)
  {
    return FT_DIR;  // Found a directory
  }
  else
  {
    return FT_FILE;  // Found a file
  }
}

/*-----------------------------------------------------------------
FAT_FindFirstFileLFN
Gets the long file name of the first directory entry and resets
  the count (can be a file or subdirectory)
char* lfn: OUT long file name, must be at least 256 chars long
FILE_TYPE return: OUT returns FT_NONE if failed, 
  FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindFirstFileLFN(char* lfn)
{
  FILE_TYPE type;
  type = FAT_FindFirstFile(NULL);
  FAT_GetLongFilename (lfn);
  return type;
}

/*-----------------------------------------------------------------
FAT_FindNextFileLFN
Gets the long file name of the next directory entry
  (can be a file or subdirectory)
char* lfn: OUT long file name, must be at least 256 chars long
FILE_TYPE return: OUT returns FT_NONE if failed, 
  FT_FILE if it found a file and FT_DIR if it found a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FindNextFileLFN(char* lfn)
{
  FILE_TYPE type;
  type = FAT_FindNextFile(NULL);
  FAT_GetLongFilename (lfn);
  return type;
}


/*-----------------------------------------------------------------
FAT_FileExists
Returns the type of file 
char* filename: IN filename of the file to look for
FILE_TYPE return: OUT returns FT_NONE if there is now file with 
  that name, FT_FILE if it is a file and FT_DIR if it is a directory
-----------------------------------------------------------------*/
FILE_TYPE FAT_FileExists(const char* filename)
{
    DIR_ENT dirEntry; 
    // Get the dirEntry for the path specified 
    dirEntry = FAT_DirEntFromPath (filename); 

    if (dirEntry.name[0] == FILE_FREE) 
    { 
        return FT_NONE; 
    } 
    else if (dirEntry.attrib & ATTRIB_DIR) 
    { 
        return FT_DIR; 
    } 
    else 
    { 
         return FT_FILE; 
    } 
}

/*-----------------------------------------------------------------
FAT_GetFileSystemType
FS_TYPE return: OUT returns the current file system type
-----------------------------------------------------------------*/
FS_TYPE FAT_GetFileSystemType (void)
{
  return filesysType;
}

/*-----------------------------------------------------------------
FAT_GetFileSystemTotalSize
unsigned int return: OUT returns the total disk space (used + free)
-----------------------------------------------------------------*/
unsigned int FAT_GetFileSystemTotalSize (void)
{
  return filesysTotalSize;
}



/*-----------------------------------------------------------------
FAT_chdir
Changes the current working directory
const char* path: IN null terminated string of directory separated by 
  forward slashes, / is root
char return: OUT returns true if successful
-----------------------------------------------------------------*/
char FAT_chdir (const char* path)
{
  DIR_ENT dir;
  if (path[0] == '/' && path[1] == '\0')
  {
    curWorkDirCluster = filesysRootDirClus;
    return true;
  }
  if (path[0] == '\0')  // Return true if changing relative to nothing
  {
    return true;
  }
  
  dir = FAT_DirEntFromPath (path);

  if (((dir.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (dir.name[0] != FILE_FREE))
  {
    // Change directory
    curWorkDirCluster = dir.startCluster | (dir.startClusterHigh << 16);

    // Move to correct cluster for root directory
    if (curWorkDirCluster == FAT16_ROOT_DIR_CLUSTER)
    {
      curWorkDirCluster = filesysRootDirClus;
    }

    // Reset file position in directory
    wrkDirCluster = curWorkDirCluster;
    wrkDirSector = 0;
    wrkDirOffset = -1;
    return true;
  }
  else
  { 
    // Couldn't change directory - wrong path specified
    return false;
  }
}

/*-----------------------------------------------------------------
FAT_fopen(filename, mode)
Opens a file
const char* path: IN null terminated string of filename and path 
  separated by forward slashes, / is root
const char* mode: IN mode to open file in
  Supported modes: "r", "r+", "w", "w+", "a", "a+", don't use
  "b" or "t" in any mode, as all files are openned in binary mode
FAT_FILE* return: OUT handle to open file, returns NULL if the file 
  couldn't be openned
-----------------------------------------------------------------*/
FAT_FILE* FAT_fopen(const char* path, const char* mode)
{
  int fileNum;
  FAT_FILE* file;
  DIR_ENT dirEntry;
#ifdef CAN_WRITE_TO_DISC
  unsigned int startCluster;
  int clusCount;
#endif

  char* pchTemp;
  // Check that a valid mode was specified
  pchTemp = strpbrk ( mode, "rRwWaA" );
  if (pchTemp == NULL)
  {
    return NULL;
  }
  if (strpbrk ( pchTemp+1, "rRwWaA" ) != NULL)
  {
    return NULL;
  }
    
  // Get the dirEntry for the path specified
  dirEntry = FAT_DirEntFromPath (path);
  
  // Check that it is not a directory
  if (dirEntry.attrib & ATTRIB_DIR)
  {
    return NULL;
  }

#ifdef CAN_WRITE_TO_DISC
  // Check that it is not a read only file being openned in a writing mode
  if ( (strpbrk(mode, "wWaA+") != NULL) && (dirEntry.attrib & ATTRIB_RO))
  {
    return NULL;
  }
#else
  if ( (strpbrk(mode, "wWaA+") != NULL))
  {
    return NULL;
  }
#endif

  // Find a free file buffer
  for (fileNum = 0; (fileNum < MAX_FILES_OPEN) && (openFiles[fileNum].inUse == true); fileNum++);
  
  if (fileNum == MAX_FILES_OPEN) // No free files
  {
    return NULL;
  }

  file = &openFiles[fileNum];
  // Remember where directory entry was
  file->dirEntSector = (wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector;
  file->dirEntOffset = wrkDirOffset;

  if ( strpbrk(mode, "rR") != NULL )  //(ucase(mode[0]) == 'R')
  {
    if (dirEntry.name[0] == FILE_FREE)  // File must exist
    {
      r

⌨️ 快捷键说明

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