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

📄 bfsa_internal.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 3 页
字号:
* int addNewEntry(UCHAR newEntry[32],USHORT dirCluster, UCHAR isRoot)
*
* Object :
*   This function find a free entry in cluster directory and
*   create a new entry.
*
* Argument:
*       newEntry                [IN] : buffer that contains the Entry to add.
*       dirCluster              [IN] : cluster of the directory into which add the entry
*       isRoot                  [IN] : if TRUE add in root directory
*
* Return value :
*       0 on success,
*       on error                DISK_FULL
*****************************************************************/
ULONG addNewEntry(UCHAR newEntry[32],USHORT dirCluster, UCHAR isRoot)
{
  UCHAR *_flashDirEnt = NULL;             // Point to a directory entry on Flash
  USHORT _currentDirClus = dirCluster,_newDirClus;
  UCHAR  pDirEnt[DIRECTORY_ENTRIE_SIZE];
  USHORT _currentEntry;
  USHORT _numberDirEntryPerCluster;

  // Compute the number max of Entries to look (by cluster)
  if (isRoot)
  {
    USHORT _RootSize = BFSA_media.numRootSectors * BFSA_media.bytesPerSector;
    //(BFSA_media.ClusterStart - BFSA_media.RootStart)*BFSA_media.SectPerCluster*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 (isRoot)
    {
      // when root directory, the cluster number is from the start of the disk
      _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==FREE_ENTRY_DIR)
        || (*pDirEnt==FREE_ENTRY_DIR_2)
        || (*pDirEnt==FREE_ENTRY_DIR_AND_NO_ALLOCATED) )
      {
        // Free entry found, copy the entry
        if( FALSE == AT91F_Flash_Write_Address((unsigned int)_flashDirEnt,DIRECTORY_ENTRIE_SIZE,newEntry, FALSE) )
        {
          return FLASH_ACCESS_ERROR;
        }
        return BFSA_SUCCESS;
      }

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

    if (isRoot)
    {
      // No multi cluster for root dir
      break;
    }

    // Get the next cluster from FAT
    _newDirClus = getNextCluster(_currentDirClus);

    // Create Cluster if all clusters of directory are full
    if (!_newDirClus)
    {
      _newDirClus = findFreeCluster();
      if( BFSA_SUCCESS != writeFatEntry(_currentDirClus,_newDirClus) )
      {
        return FLASH_ACCESS_ERROR;
      }
    }
    _currentDirClus = _newDirClus;

  }while (_currentDirClus != 0);

  return DISK_FULL;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : deleteEntry
*
*-----------------------------------------------------------------
*
* void deleteEntry(char* filename)
*
* Object :
*   This function look for an entry in directory and mark it free
*
* Argument:
*       filename            [IN] : filename to find.
*
*****************************************************************/
void deleteEntry(char* fileName)
{
  UCHAR *_pucEntry;

  _pucEntry = (UCHAR*)findEntry (fileName);
  if (_pucEntry)
  {
    // Mark the entry as free
    *_pucEntry = FREE_ENTRY_DIR;
    AT91F_Flash_Write_Address((unsigned int)_pucEntry,sizeof(unsigned int),_pucEntry, FALSE);
  }
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : listFile
*
*-----------------------------------------------------------------
*
* int listFile(FILE_OBJECT* pfobj,ULONG nbFileObj,ULONG *nbFileObjFound,USHORT dirCluster)
*
* Object:
*   This function List the files and directory present in current directory.
*
* Argument:
*       pfobj           [OUT]: pointer to FILE_OBJECTs array, allocated
*                              by caller.
*       nbFileObj       [IN] :  number of elements allocated in pfobj.
*       nbFileObjFound  [OUT]: number of elements actually written in
*                              pfobj up to nbFileObj.
*                        If nbFileObjFound>nbFileObj, there are more FILE_OBJECTs
*                        to be writen, we need pfobj with nbFileObjFound elements.
*       dirCluster      [IN] : Cluster of the directory (0 for ROOT)
*
* Return value:
*       0 if success,
*       on error:       ERROR_READING_FAT_ENTRY
*                       MEMORY_ERROR
*                       FLASH_ACCESS_ERROR
*                       BAD_ARGUMENT
*
*****************************************************************/
ULONG listFile(FILE_OBJECT* pfobj,ULONG nbFileObj,ULONG *nbFileObjFound,USHORT dirCluster)
{
  UCHAR *_flashDirEnt = NULL;             // Point to a directory entry
  int    count;
  UCHAR  pDirEnt[DIRECTORY_ENTRIE_SIZE];
  USHORT _currentDirClus = dirCluster;
  USHORT _currentEntry;
  USHORT _numberDirEntryPerCluster;

  if (!nbFileObjFound || (nbFileObj!=0 && !pfobj))
  {
    return BAD_ARGUMENT;
  }

  *nbFileObjFound = 0;

  // Compute the number max of Entries to look (by cluster)
  if (_currentDirClus == 0)
  {
    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 (_currentDirClus == 0)
    {
        _flashDirEnt = (UCHAR*)FlashBaseAdd +
                        BFSA_current_dir.DirStart*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
      {
        // While there is room in pfobj
        if (*nbFileObjFound < nbFileObj)
        {
          UCHAR _precedentIsSpace = TRUE;

          // Populate the FILE OBJECT
          //pfobj[*nbFileObjFound].time.Seconds = (0x1F&pDirEnt[14]);                             // Create Time
          //pfobj[*nbFileObjFound].time.Minutes = (0x07&(pDirEnt[14]>>5))+((0x07&pDirEnt[15])<<3);// Create Time
          //pfobj[*nbFileObjFound].time.Hours   = (0x1F&(pDirEnt[15]>>3));                        // Create Time

          pfobj[*nbFileObjFound].time.Seconds = (0x1F&pDirEnt[22]);                             // Time Last Modification
          pfobj[*nbFileObjFound].time.Minutes = (0x07&(pDirEnt[22]>>5))+((0x07&pDirEnt[23])<<3);// Time Last Modification
          pfobj[*nbFileObjFound].time.Hours   = (0x1F&(pDirEnt[23]>>3));                        // Time Last Modification

          pfobj[*nbFileObjFound].attributes    = pDirEnt[11];

          //pfobj[*nbFileObjFound].date.Day     = (0x1F&pDirEnt[16]);                               // Create Date
          //pfobj[*nbFileObjFound].date.Month   = (0x07&(pDirEnt[16]>>5))+((0x01&(pDirEnt[17]))<<3);// Create Date
          //pfobj[*nbFileObjFound].date.Years80 = (0x7F&(pDirEnt[17]>>1));                          // Create Date

          pfobj[*nbFileObjFound].date.Day     = (0x1F&pDirEnt[24]);                               // Date Last Modification
          pfobj[*nbFileObjFound].date.Month   = (0x07&(pDirEnt[24]>>5))+((0x01&(pDirEnt[25]))<<3);// Date Last Modification
          pfobj[*nbFileObjFound].date.Years80 = (0x7F&(pDirEnt[25]>>1));                          // Date Last Modification

          pfobj[*nbFileObjFound].startCluster  = pDirEnt[26] + pDirEnt[27]*0x100;
          pfobj[*nbFileObjFound].length        = pDirEnt[28] + pDirEnt[29]*0x100
                                               + pDirEnt[30]*0x10000 + pDirEnt[31]*0x1000000;
          pfobj[*nbFileObjFound].extension[0]  = pDirEnt[8]==' '?'\0':pDirEnt[8];
          pfobj[*nbFileObjFound].extension[1]  = pDirEnt[9]==' '?'\0':pDirEnt[9];
          pfobj[*nbFileObjFound].extension[2]  = pDirEnt[10]==' '?'\0':pDirEnt[10];
          pfobj[*nbFileObjFound].extension[3]  = '\0';

          // UnPad the fileName
          for(count=1; count<=8; count++)
          {
            if (_precedentIsSpace && pDirEnt[8-count] == ' ')
            {
              // Ignore space ending the file name
              pfobj[*nbFileObjFound].fileName[8-count] = '\0';
            }
            else
            {
              _precedentIsSpace = FALSE;
              pfobj[*nbFileObjFound].fileName[8-count] = pDirEnt[8-count];
            }
          }
          pfobj[*nbFileObjFound].fileName[8] = '\0';
        }

        // Total number of entries in the directory
        *nbFileObjFound = *nbFileObjFound+1;
      }

      // 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 BFSA_SUCCESS;
}


/*****************************************************************
*
*
* S U B - R O U T I N E  : deleteFile
*
*-----------------------------------------------------------------
*
* int deleteFile(char* filename)
*
* Object:
*   This function frees directory entry and cluster of a file of the
*   current directory.
*   The FAT must be locked and updated in BFSA_fatBuff
*
* Argument:
*       filename        :[IN] pointer to the file name to delete.
*                             This file name must be valid.
*
* Return value:
*       0 if success,
*       on error:       FILE_NOT_EXIST
*                       ERROR_READING_FAT_ENTRY
*                       FLASH_ACCESS_ERROR
*                       BAD_ARGUMENT
*                       DIRECTORY_NOT_EMPTY
*
*****************************************************************/
ULONG deleteFile(char* filename)
{
  ULONG _status = BFSA_SUCCESS;
  unsigned int _temp;
  UCHAR  pPucEntry[DIRECTORY_ENTRIE_SIZE];
  USHORT _currentFileCluster = 0;
  USHORT _nextFileCluster;
  UCHAR *_pucEntry;

  // Look for the file to delete
  _pucEntry = (UCHAR*)findEntry (filename);
  if (_pucEntry)
  {
    AT91F_ReadMedia((unsigned int)_pucEntry, DIRECTORY_ENTRIE_SIZE, pPucEntry);

    // File found return the First Cluster
    _currentFileCluster = *(pPucEntry+26)+*(pPucEntry+27)*0x100;
  }
  else
  {
    po_unlock(); //jcb
    return FILE_NOT_EXIST;
  }

  // Check empty directory
  if (pPucEntry[11]&BFSA_ATTR_DIRECTORY)
  {
    ULONG _NbFile = 0;
    listFile(NULL,0,&_NbFile,_currentFileCluster);
    if (_NbFile>2)     // . and .. directory
    {
      po_unlock(); //jcb
      return DIRECTORY_NOT_EMPTY;
    }
  }

  // Marks files cluster free
  do
  {
    // Get next cluster of the chain
    _nextFileCluster = getNextCluster(_currentFileCluster);

    // Mark current cluster free
    if( BFSA_SUCCESS != writeFatEntry(_currentFileCluster,FREE) )
    {
      po_unlock(); //jcb
      return FLASH_ACCESS_ERROR;
    }
    _currentFileCluster = _nextFileCluster;
  }while (_currentFileCluster);

  // Mark the entry as free
  _temp = FREE_ENTRY_DIR + (pPucEntry[1]<<8) + (pPucEntry[2]<<16) + (pPucEntry[3]<<24);
  if( FALSE == AT91F_Flash_Write_Address((unsigned int)_pucEntry,sizeof(unsigned int),(unsigned char*)&_temp, FALSE) )
  {
    _status = FLASH_ACCESS_ERROR;
  }

  return _status;
}


⌨️ 快捷键说明

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