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

📄 bfsa_internal.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 3 页
字号:
        // write fail, mark the cluster as bad cluster in fat
        writeFatEntry(_freeCluster,BFSA_media.FATtype == BFSA_FAT12?BAD12:BAD16);
        TRACE_DEBUG_L( "Bad cluster:%d\n\r",_currentCluster);
        _freeCluster = 0;
      }
      else
      {
        // Cluster found and initialized
        break;
      }
    }
  }

  return _freeCluster;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : getNextCluster
*
*-----------------------------------------------------------------
*
* int getNextCluster(USHORT uCurrent)
*
* Object :
*   This function returns the next cluster from the FAT for the
*   current cluster.
*
* Argument:
*       uCurrent        :[IN] current cluster.
*
* Return value :
*       the next cluster if any,
*       0 if there is no more cluster in chain
*       on error :
*                       BAD_ARGUMENT
*
*****************************************************************/
ULONG getNextCluster(USHORT uCurrent)
{
  ULONG status = BFSA_SUCCESS;

  if (uCurrent > BFSA_media.MaxCluster)
  {
    status = BAD_ARGUMENT;
  }
  else
  {
    status = readFatEntry(uCurrent);

    if( ((BFSA_media.FATtype == BFSA_FAT16)&&(status == EOC16 || status == 0xFFF8 || status == BAD16))
      || ((BFSA_media.FATtype == BFSA_FAT12)&&(status == EOC12 || status == 0x0FF8 || status == BAD12)) )
    {
      // No more Cluster in chain
      status = BFSA_SUCCESS;
    }
  }
  return( status );
}


/*****************************************************************
*
*
* S U B - R O U T I N E  : isValidFileNameChar
*
*-----------------------------------------------------------------
*
* UCHAR isValidFileNameChar(char car)
*
* Object :
*   This function returns TRUE if car is a valid character in a
*   file name.
*
* Argument:
*       car             :[IN] character to test.
*
*****************************************************************/
#ifdef ADS_COMPIL
  __inline
#else
  inline
#endif
UCHAR isValidFileNameChar( char car )
{
  UCHAR status = TRUE;

  // Invalid char
  if( (car < 0x20) && (car != 0x05) )
  {
    status = FALSE;
  }
  else
  {
    // Lower case not allowed
    if( (car >= 'a') && (car <= 'z') )
    {
      status = FALSE;
    }
    else
    {
      // Invalid char
      /* 0x22 : '"', 0x2A : '*', 0x2B : '+', 0x2C : ',', 0x2E : '.', 0x2F : '/' */
      /* 0x3A : '',  0x3B : ';', 0x3C : '<', 0x3D : '=', 0x3E : '>', 0x3F : '?' */
      /* 0x5B : '[', 0x5C : '\', 0x5D : ']', 0x7C : '|' */
      if ( (car==0x22) || (car==0x2A) || (car==0x2B) || (car==0x2C) || (car==0x2E) || (car==0x2F)
        || (car==0x3A) || (car==0x3B) || (car==0x3C) || (car==0x3D) || (car==0x3E) || (car==0x3F)
        || (car==0x5B) || (car==0x5C) || (car==0x5D) || (car==0x7C) )
      {
        status = FALSE;
      }
    }
  }
  return( status );
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : isValidFileName
*
*-----------------------------------------------------------------
*
* UCHAR isValidFileName(char *fileName)
*
* Object :
*   This function returns TRUE if the file name is valid.
*
* Argument:
*       fileName        :[IN] file name string.
*
*****************************************************************/
UCHAR isValidFileName(char *fileName)
{
  UCHAR _c;

  if (!fileName)
  {
    return FALSE;
  }
  if (*fileName == '.')   // File name can't be only an extension
  {
    return FALSE;
  }
  // Filename
  for (_c=0;
       _c<8 && fileName[_c]!='\0' && fileName[_c]!='.';
       _c++)
  {
    if (!isValidFileNameChar(fileName[_c]))
    {
      return FALSE;
    }
  }
  if (fileName[_c]!='\0' && fileName[_c]!='.') // Wrong size
  {
    return FALSE;
  }

  // File extension
  if (fileName[_c]=='.')
  {
    fileName = &fileName[_c+1];
    for (_c=0;
     _c<3 && fileName[_c]!='\0';
     _c++)
    {
      if (!isValidFileNameChar(fileName[_c]))
      {
        return FALSE;
      }
    }
    if (fileName[_c]!='\0') // Wrong extension size
    {
      return FALSE;
    }
  }

  return TRUE;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : padFileName
*
*-----------------------------------------------------------------
*
* void padFileName(const char *filename, char* strFileName)
*
* Object :
*   This function add spaces to filename to have always a filename of 8+3 chars.
*   Eg. filename = "test.exe", strFileName = "test    exe"
*
* Argument:
*       FileName             :[IN] Valid Filename.
*       strFileName          :[OUT] filename padded, allocated by user to [8+3]
*
* Return value :
*       returns First cluster of the file,
*       or 0 if no matching file was found
*****************************************************************/
void padFileName(const char *filename, char* strFileName)
{
  UCHAR i;
  char *puc = strFileName;

  if (!filename || !strFileName)
  {
    return;
  }

  for( i=0; i<8+3; i++ )
  {
    strFileName[i] = 0x20;
  }
  strFileName[8+3] = '\0';

  for (i=0; i<BFSA_MAX_FILENAME_LEN && filename[i]!='\0'; i++)
  {
    if (filename[i]=='.')
    {
      puc = strFileName + 8;  // The '.' is not retrived
    }
    else
    {
      *puc = filename[i];
      puc++;
    }
  }
}


/*****************************************************************
*
*
* S U B - R O U T I N E  : findEntry
*
*-----------------------------------------------------------------
*
* USHORT findEntry(char* fileName)
*
* Object :
*   This function looks for a file in current directory.
*
* Argument:
*       FileName             :[IN] Valid Filename to find.
*
* Return value :
*       returns entry address,
*       or 0 if no matching file was found
*****************************************************************/
int findEntry(char *fileName)
{
  UCHAR *_flashDirEnt = NULL;             // Point to a directory entry DIR_Name
  UCHAR  pDirEnt[DIRECTORY_ENTRIE_SIZE];
  USHORT _currentDirClus = BFSA_current_dir.DirStart;
  USHORT _currentEntry;
  USHORT _numberDirEntryPerCluster;
  char strFileName[8+3+1] ="";   // File name space padded.
  char strFileName2[8+3+1]="";   // From entry

  // Spaces pad the file
  padFileName(fileName,strFileName);

  // Compute the number max of Entries to look (by cluster)
  if (BFSA_current_dir.IsRoot)
  {
    USHORT _RootSize = BFSA_media.numRootSectors * BFSA_media.bytesPerSector;

    _numberDirEntryPerCluster = _RootSize/DIRECTORY_ENTRIE_SIZE;
  }
  else
  {
    _numberDirEntryPerCluster = BFSA_media.bytesPerSector*BFSA_media.SectPerCluster
                                         / DIRECTORY_ENTRIE_SIZE;
  }

  // Walk through the cluster chain of the directory
  do
  {
    // Point to the start of current cluster of the directory
    if (BFSA_current_dir.IsRoot)
    {
      _flashDirEnt = (UCHAR*)FlashBaseAdd + _currentDirClus*BFSA_media.bytesPerSector;
    }
    else
    {
      _flashDirEnt = (UCHAR*)FlashBaseAdd +
                      FIRST_SECTOR_DATACLUSTER(_currentDirClus)*BFSA_media.bytesPerSector;
    }

    // Walk through the directory entries of the current cluster to find the file
    for (_currentEntry = 0;
         _currentEntry < _numberDirEntryPerCluster;
         _currentEntry++)
    {
      AT91F_ReadMedia((unsigned int)_flashDirEnt, DIRECTORY_ENTRIE_SIZE, pDirEnt);

      if (*pDirEnt == 0x00)     // no more directory entry
      {
          break;
      }

      if ( (pDirEnt[11]&BFSA_ATTR_LONG_NAME != BFSA_ATTR_LONG_NAME) // Don't look at Long names
           && !(pDirEnt[11]&BFSA_ATTR_VOLUME_ID)                    // neither VOLUME ID
           && *pDirEnt!=FREE_ENTRY_DIR                              // Free Entry
           && *pDirEnt!=FREE_ENTRY_DIR_2                            // Free Entry
           && *pDirEnt!=FREE_ENTRY_DIR_AND_NO_ALLOCATED)            // No more entry
      {
        // Get file name from entry
        po_memcpy( strFileName2, pDirEnt, 11 );
        strFileName2[11] = '\0';

        if ( po_strcmp( strFileName2, strFileName ) == 0 )
        {
          // File found return the entry
          return (int)_flashDirEnt;
        }
      }

      // Next entry in the current cluster
      _flashDirEnt += DIRECTORY_ENTRIE_SIZE;

    }

    if ( BFSA_current_dir.IsRoot )
    {
      // there only one cluster for root directory.
      break;
    }

    AT91F_ReadMedia((unsigned int)_flashDirEnt, 1, pDirEnt);
    if (*pDirEnt == 0)
    {
      // File found or no more allocated directory entries
      break;
    }

    // Get the next cluster from FAT
    _currentDirClus = getNextCluster(_currentDirClus);
  }while (_currentDirClus != 0);

  return 0;
}


/*****************************************************************
*
*
* S U B - R O U T I N E  : findFile
*
*-----------------------------------------------------------------
*
* USHORT findFile(char* fileName)
*
* Object :
*   This function looks for a file in current directory.
*
* Argument:
*       FileName             :[IN] Valid Filename to find.
*
* Return value :
*       returns First cluster of the file,
*       or 0 if no matching file was found
*****************************************************************/
USHORT findFile(const char* fileName)
{
  USHORT _firstFileCluster = 0;
  UCHAR *_pucEntry;

  _pucEntry = (UCHAR*)findEntry ((char*)fileName);
  if (_pucEntry)
  {
    // File found return the First Cluster
    _firstFileCluster = *(_pucEntry+26)+*(_pucEntry+27)*0x100;
  }

  return _firstFileCluster;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : addNewEntry
*
*-----------------------------------------------------------------
*

⌨️ 快捷键说明

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