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

📄 fat.c

📁 看到最近大家都关心 usbhost 的实现, 论坛上能找到的代码仅是一些简单的 demo , 完整的源码级的协议层是找不到的 我就贡献一把, 将我前一段时间移植成功的 USBHost 代码奉上 注
💻 C
📖 第 1 页 / 共 5 页
字号:
/*-----------------------------------------------------------------
FAT_GetFileCreationTime
Get the creation time of the last file found or openned.
time_t return OUT: the file's creation time
-----------------------------------------------------------------*/
time_t FAT_GetFileCreationTime (void)
{
  // Read in the last accessed directory entry
  disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
  
  return   FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].cTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].cDate);
}

/*-----------------------------------------------------------------
FAT_GetFileLastWriteTime
Get the creation time of the last file found or openned.
time_t return OUT: the file's creation time
-----------------------------------------------------------------*/
time_t FAT_GetFileLastWriteTime (void)
{
  // Read in the last accessed directory entry
  disc_ReadSector ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER ? filesysRootDir : FAT_ClustToSect(wrkDirCluster)) + wrkDirSector, globalBuffer);
  
  return   FAT_FileTimeToCTime(((DIR_ENT*)globalBuffer)[wrkDirOffset].mTime, ((DIR_ENT*)globalBuffer)[wrkDirOffset].mDate);
}
#endif

/*-----------------------------------------------------------------
FAT_DirEntFromPath
Finds the directory entry for a file or directory from a path
Path separator is a forward slash /
const char* path: IN null terminated string of path.
DIR_ENT return OUT: dirEntry of found file. First char will be FILE_FREE
  if the file was not found
-----------------------------------------------------------------*/
DIR_ENT FAT_DirEntFromPath (const char* path)
{
  int pathPos;
  char name[MAX_FILENAME_LENGTH];
  char alias[13];
  int namePos;
  char found, notFound;
  DIR_ENT dirEntry;
  unsigned int dirCluster;
  char flagLFN, dotSeen;
  
  // Start at beginning of path
  pathPos = 0;
  
  if (path[pathPos] == '/') 
  {
    dirCluster = filesysRootDirClus;  // Start at root directory
  }
  else
  {
    dirCluster = curWorkDirCluster;  // Start at current working dir
  }
  
  // Eat any slash /
  while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
  {
    pathPos++;
  }
  
  // Search until can't continue
  found = false;
  notFound = false;
  while (!notFound && !found)
  {
    flagLFN = false;
    // Copy name from path
    namePos = 0;
    if ((path[pathPos] == '.') && ((path[pathPos + 1] == '\0') || (path[pathPos + 1] == '/'))) {
      // Dot entry
      name[namePos++] = '.';
      pathPos++;
    } else if ((path[pathPos] == '.') && (path[pathPos + 1] == '.') && ((path[pathPos + 2] == '\0') || (path[pathPos + 2] == '/'))){
      // Double dot entry
      name[namePos++] = '.';
      pathPos++;
      name[namePos++] = '.';
      pathPos++;
    } else {
      // Copy name from path
      if (path[pathPos] == '.') {
        flagLFN = true;
      }
      dotSeen = false;
      while ((namePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0') && (path[pathPos] != '/'))
      {
        name[namePos] = ucase(path[pathPos]);
        if ((name[namePos] <= ' ') || ((name[namePos] >= ':') && (name[namePos] <= '?'))) // Invalid character
        {
          flagLFN = true;
        }
        if (name[namePos] == '.') {
          if (!dotSeen) {
            dotSeen = true;
          } else {
            flagLFN = true;
          }
        }
        namePos++;
        pathPos++;
      }
      // Check if a long filename was specified
      if (namePos > 12)
      {
        flagLFN = true;
      }
    }
    
    // Add end of string char
    name[namePos] = '\0';

    // Move through path to correct place
    while ((path[pathPos] != '/') && (path[pathPos] != '\0'))
      pathPos++;
    // Eat any slash /
    while ((path[pathPos] == '/') && (path[pathPos] != '\0'))
    {
      pathPos++;
    }

    // Search current Dir for correct entry
    dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_SET);
    while ( !found && !notFound)
    {
      // Match filename
      found = true;
      for (namePos = 0; (namePos < MAX_FILENAME_LENGTH) && found && (name[namePos] != '\0') && (lfnName[namePos] != '\0'); namePos++)
      {
        if (name[namePos] != ucase(lfnName[namePos]))
        {
          found = false;
        }
      }
      if ((name[namePos] == '\0') != (lfnName[namePos] == '\0'))
      {
        found = false;
      }

      // Check against alias as well.
      if (!found)
      {
        FAT_GetFilename(dirEntry, alias);
        found = true;
        for (namePos = 0; (namePos < 13) && found && (name[namePos] != '\0') && (alias[namePos] != '\0'); namePos++)
        {
          if (name[namePos] != ucase(alias[namePos]))
          {
            found = false;
          }
        }
        if ((name[namePos] == '\0') != (alias[namePos] == '\0'))
        {
          found = false;
        }
      }

      if (dirEntry.name[0] == FILE_FREE)
        // Couldn't find specified file
      {
        found = false;
        notFound = true;
      }
      if (!found && !notFound)
      {
        dirEntry = FAT_GetDirEntry (dirCluster, 1, SEEK_CUR);
      }
    }
    
    if (found && ((dirEntry.attrib & ATTRIB_DIR) == ATTRIB_DIR) && (path[pathPos] != '\0'))
      // It has found a directory from within the path that needs to be followed
    {
      found = false;
      dirCluster = dirEntry.startCluster | (dirEntry.startClusterHigh << 16);
    }
  }
  
  if (notFound)
  {
    dirEntry.name[0] = FILE_FREE;
    dirEntry.attrib = 0x00;
  }

  return (dirEntry);
}


#ifdef CAN_WRITE_TO_DISC
/*-----------------------------------------------------------------
FAT_AddDirEntry
Creates a new dir entry for a file
Path separator is a forward slash /
const char* path: IN null terminated string of path to file.
DIR_ENT newDirEntry IN: The directory entry to use.
int file IN: The file being added (optional, use -1 if not used)
char return OUT: true if successful
-----------------------------------------------------------------*/
char FAT_AddDirEntry (const char* path, DIR_ENT newDirEntry)
{
  char filename[MAX_FILENAME_LENGTH];
  int filePos, pathPos, aliasPos;
  char tempChar;
  char flagLFN, dotSeen;
  char fileAlias[13] = {0};
  int tailNum;
  
  unsigned char chkSum = 0;
  
  unsigned int oldWorkDirCluster;
  
  DIR_ENT* dirEntries = (DIR_ENT*)globalBuffer;
  unsigned int dirCluster;
  int secOffset;
  int entryOffset;
  //int maxSectors;
  unsigned int firstSector;

  DIR_ENT_LFN lfnEntry;
  int lfnPos = 0;

  int dirEntryLength = 0;
  int dirEntryRemain = 0;
  unsigned int tempDirCluster;
  int tempSecOffset;
  int tempEntryOffset;
  char dirEndFlag = false;

  int i;

  // Store current working directory
  oldWorkDirCluster = curWorkDirCluster;

  // Find filename within path and change to correct directory
  if (path[0] == '/')
  {
    curWorkDirCluster = filesysRootDirClus;
  }
  
  pathPos = 0;
  filePos = 0;
  flagLFN = false;

  while (path[pathPos + filePos] != '\0')
  {
    if (path[pathPos + filePos] == '/')
    {
      filename[filePos] = '\0';
      if (FAT_chdir(filename) == false) 
      {
        curWorkDirCluster = oldWorkDirCluster;
        return false; // Couldn't change directory
      }
      pathPos += filePos + 1;
      filePos = 0;
    }
    filename[filePos] = path[pathPos + filePos];
    filePos++;
  }
  
  // Skip over last slashes
  while (path[pathPos] == '/')
    pathPos++;
  
  // Check if the filename has a leading "."
  // If so, it is an LFN
  if (path[pathPos] == '.') {
    flagLFN = true;
  }
  
  // Copy name from path
  filePos = 0;
  dotSeen = false;

  while ((filePos < MAX_FILENAME_LENGTH - 1) && (path[pathPos] != '\0'))
  {
    filename[filePos] = path[pathPos];
    if ((filename[filePos] <= ' ') || ((filename[filePos] >= ':') && (filename[filePos] <= '?'))) // Invalid character
    {
      flagLFN = true;
    }
    if (filename[filePos] == '.') {
      if (!dotSeen) {
        dotSeen = true;
      } else {
        flagLFN = true;
      }
    }
    filePos++;
    pathPos++;
    if ((filePos > 8) && !dotSeen) {
      flagLFN = true;
    }
  }
  
  if (filePos == 0)  // No filename
  {
    return false;
  }
  
  // Check if a long filename was specified
  if (filePos > 12)
  {
    flagLFN = true;
  }

  // Check if extension is > 3 characters long
  if (!flagLFN && (strrchr (filename, '.') != NULL) && (strlen(strrchr(filename, '.')) > 4)) {
    flagLFN = true;
  }
  
  lfnPos = (filePos - 1) / 13;

  // Add end of string char
  filename[filePos++] = '\0';
  // Clear remaining chars
  while (filePos < MAX_FILENAME_LENGTH)
    filename[filePos++] = 0x01;  // Set for LFN compatibility
  
  
  if (flagLFN)
  {
    // Generate short filename - always a 2 digit number for tail
    // Get first 5 chars of alias from LFN
    aliasPos = 0;
    filePos = 0;
    if (filename[filePos] == '.') {
      filePos++;
    }
    for ( ; (aliasPos < 5) && (filename[filePos] != '\0') && (filename[filePos] != '.') ; filePos++)
    {
      tempChar = ucase(filename[filePos]);
      if (((tempChar > ' ' && tempChar < ':') || tempChar > '?') && tempChar != '.')
        fileAlias[aliasPos++] = tempChar;
    }
    // Pad Alias with underscores
    while (aliasPos < 5)
      fileAlias[aliasPos++] = '_';
    
    fileAlias[5] = '~';
    fileAlias[8] = '.';
    fileAlias[9] = ' ';
    fileAlias[10] = ' ';
    fileAlias[11] = ' ';
    if (strchr (filename, '.') != NULL) {
      while(filename[filePos] != '\0')
      {
        filePos++;
        if (filename[filePos] == '.')
        {
          pathPos = filePos;
        }
      }
      filePos = pathPos + 1;  //pathPos is used as a temporary variable
      // Copy first 3 characters of extension
      for (aliasPos = 9; (aliasPos < 12) && (filename[filePos] != '\0'); filePos++)
      {
        tempChar = ucase(filename[filePos]);
        if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
          fileAlias[aliasPos++] = tempChar;
      }
    } else {
      aliasPos = 9;
    }
    
    // Pad Alias extension with spaces
    while (aliasPos < 12)
      fileAlias[aliasPos++] = ' ';
    
    fileAlias[12] = '\0';
    
    
    // Get a valid tail number
    tailNum = 0;
    do {
      tailNum++;
      fileAlias[6] = 0x30 + ((tailNum / 10) % 10);  // 10's digit
      fileAlias[7] = 0x30 + (tailNum % 10);  // 1's digit
    } while ((FAT_DirEntFromPath(fileAlias).name[0] != FILE_FREE) && (tailNum < 100));
    
    if (tailNum < 100)  // Found an alias not being used
    {
      // Calculate file checksum
      chkSum = 0;
      for (aliasPos=0; aliasPos < 12; aliasPos++)
      {
        // Skip '.'
        if (fileAlias[aliasPos] == '.')
          aliasPos++;
        // NOTE: The operation is an unsigned char rotate right
        chkSum = ((chkSum & 1) ? 0x80 : 0) + (chkSum >> 1) + fileAlias[aliasPos];
      }
    }
    else  // Couldn't find a valid alias
    {
      return false;
    }
    
    dirEntryLength = lfnPos + 2;
  }
  else  // Its not a long file name
  {
    // Just copy alias straight from filename
    for (aliasPos = 0; aliasPos < 13; aliasPos++)
    {
      tempChar = ucase(filename[aliasPos]);
      if ((tempChar > ' ' && tempChar < ':') || tempChar > '?')
        fileAlias[aliasPos] = tempChar;
    }
    fileAlias[12] = '\0';

    lfnPos = -1;

    dirEntryLength = 1;
  }
  
  // Change dirEntry name to match alias
  for (aliasPos = 0; ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0') && (aliasPos < 8)); aliasPos++)
  {
    newDirEntry.name[aliasPos] = fileAlias[aliasPos];
  }
  while (aliasPos < 8)
  {
    newDirEntry.name[aliasPos++] = ' ';
  }
  aliasPos = 0;
  while ((fileAlias[aliasPos] != '.') && (fileAlias[aliasPos] != '\0'))
    aliasPos++;
  filePos = 0;
  while (( filePos < 3 ) && (fileAlias[aliasPos] != '\0'))

⌨️ 快捷键说明

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