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

📄 bfsa_api.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 4 页
字号:
          return FILE_NOT_EXIST;
        }
      }
      else
      {
        // . case
        if (path[1]=='\0')
        {
          continue;
        }
        else
        {
          // invalide name
          po_unlock();
          return FILE_NOT_EXIST;
        }
      }
    }
    else
    {
      // Check filename validity
      if (!isValidFileName(path))
      {
        po_unlock();
        return NOT_A_VALID_DIRECTORY;
      }

      // Is the directory exist
      _pucEntry = (UCHAR*)findEntry(path);
      if (!_pucEntry)
      {
        po_unlock();
        return FILE_NOT_EXIST;
      }
      // Is it a directory?
      AT91F_ReadMedia((unsigned int)_pucEntry, DIRECTORY_ENTRIE_SIZE, pPucEntry);
      if (!pPucEntry[11]&BFSA_ATTR_DIRECTORY)
      {
        po_unlock();
        return NOT_A_VALID_DIRECTORY;
      }

      // Get the first directory Cluster
      _firstDirCluster = pPucEntry[26]+pPucEntry[27]*0x100;

      // Update absolute path
      _pabsolutePathCurrent++;
      while (*path!='\0')
      {
        *_pabsolutePathCurrent = *path;
        path++;
        _pabsolutePathCurrent++;
      }
      *_pabsolutePathCurrent = '\\';
      _pabsolutePathCurrent[1] = '\0';

      // Update current directory
      BFSA_current_dir.DirStart = _firstDirCluster;
      if (_firstDirCluster)
      {
          BFSA_current_dir.IsRoot = FALSE;
      }
      else
      {
          BFSA_current_dir.IsRoot = TRUE;
      }

      // Next directory name
      _pt++;
    }
  }
  po_unlock();
  END:
  return _status;
}

/*****************************************************************
*
*
* S U B - R O U T I N E  : BFSA_path
*
*-----------------------------------------------------------------
*
* int BFSA_path(char *path)
*
* Object:
*   This function return the current path.
*
* Argument:
*       pucPath         [OUT]: pointer to a string allocated by
*                              caller at BFSA_MAX_PATH_LEN to store
*                              the path.
*
* Return value:
*       BFSA_SUCCESS on success
*       BAD_ARGUMENT on error
*
*****************************************************************/
ULONG BFSA_path(char *path)
{
  ULONG status = BAD_ARGUMENT;

  if (path)
  {
    po_memcpy( path, BFSA_current_dir.absolutePath, sizeof( BFSA_current_dir.absolutePath ) );
    status = BFSA_SUCCESS;
  }
  return status;
}


/*****************************************************************
*
*
* S U B - R O U T I N E  : BFSA_write
*
*-----------------------------------------------------------------
*
* int BFSA_write(char* filename,char* dataBuffer,ULONG dataSize,UCHAR append)
*
* Object:
*   This function writes data to file in the current directory.
*
* Argument:
*       filename        [IN] : pointer to file name to write to.
*       dataBuffer      [IN] : buffer allocated by caller, contains data to write.
*       dataSize        [IN] : size to write.
*       append          [IN] : TRUE to appends data to existing file,
*                              otherwise the file is overwritten.
*
* Return value:
*       size read on success,
*       on error:       FILE_NOT_EXIST
*                       ERROR_READING_FAT_ENTRY
*                       MEMORY_ERROR
*                       FLASH_ACCESS_ERROR
*                       BAD_ARGUMENT
*                       DISK_FULL
*
*****************************************************************/
ULONG BFSA_write(char* filename,char* dataBuffer,ULONG dataSize, UCHAR append)
{
  ULONG  _dataWritten = 0;
  ULONG  _freeSpace = 0;
  ULONG  _fileSize = 0;
  ULONG  _iFatEntry;
  ULONG  _status;
  USHORT _dataToWrite = 0;
  USHORT _fileCluster=0;
  USHORT _offsetLastCluster=0;
  UCHAR  _newEntry[32];
  UCHAR* _pucFileEntry;
  UCHAR  _needToWriteEntry = FALSE;

  // Check parameters
  // Need a file name, need a buffer if datasize>0, need a datasize if append
  if (!filename || (dataSize && !dataBuffer) || (append && !dataSize))
    return BAD_ARGUMENT;

  // Check filename validity
  if (!isValidFileName(filename))
      return BAD_ARGUMENT;

  // Lock and Load FAT
  po_lock();
  readFAT();

  // Look if there is enough room on disk
  for ( _iFatEntry = 0;
        _iFatEntry<(BFSA_media.MaxCluster - BFSA_media.ClusterStart);
        _iFatEntry++)
  {
    if (readFatEntry(_iFatEntry + 2) == FREE)
    {
      _freeSpace += BFSA_media.bytesPerSector*BFSA_media.SectPerCluster;
      if (_freeSpace > dataSize)
        break;
    }
  }

  if (_freeSpace < dataSize)
  {
    po_unlock();
    return DISK_FULL;
  }

  _pucFileEntry = (UCHAR*)findEntry(filename);
  if (_pucFileEntry)
  {
    // Get the Entry
    AT91F_ReadMedia((unsigned int)_pucFileEntry, DIRECTORY_ENTRIE_SIZE, _newEntry);

    // Get the first file cluster and size
    _fileCluster = _newEntry[26]+_newEntry[27]*0x100;
    _fileSize = _newEntry[28]+_newEntry[29]*0x100+_newEntry[30]*0x1000 +_newEntry[31]*0x10000;
    _offsetLastCluster = (_fileSize) % (BFSA_media.bytesPerSector*BFSA_media.SectPerCluster);
    if (append)
    {
      // Find last cluster
      if (_fileCluster)
      {
        USHORT _nextCluster = _fileCluster;

        // Find the last cluster of the file
        do
        {
          _fileCluster = _nextCluster;
          _nextCluster = getNextCluster(_fileCluster);
        }while (_nextCluster);

        // At this point _fileCluster is the last file cluster
        if (_offsetLastCluster == 0)
        {
          // Need to allocate a new cluster.
          _nextCluster = findFreeCluster();
          if (!_nextCluster)
          {
            po_unlock();
            return DISK_FULL;
          }

          // Update FAT (clusters chain)
          if( BFSA_SUCCESS != writeFatEntry(_fileCluster,_nextCluster) )
          {
            po_unlock();
            return FLASH_ACCESS_ERROR;
          }

          _fileCluster = _nextCluster;
          _offsetLastCluster = 0;
        }
      }
      else// append to empty file
      {
        // Allocate a new cluster
        _fileCluster = findFreeCluster();
        if (!_fileCluster)
        {
          po_unlock();
          return DISK_FULL;
        }

        // Update the entry
        _newEntry[26] = LOW_BYTE(_fileCluster);
        _newEntry[27] = HIGH_BYTE(_fileCluster);
        _needToWriteEntry = TRUE;

        _offsetLastCluster = 0;
      }
    }
    else // Overwrite
    {
      // File to overwrite exists, delete it
      _status = deleteFile(filename);
      if (BFSA_FAILURE(_status))
      {
        po_unlock();
        TRACE_ERROR( "write delete pb\n\r");
        return _status;
      }

      // Create a new file
      goto CREATE;
    }

  }
  else // No entry found for this file
  {
    USHORT* pAddress;
    USHORT* pAddressDate;
    FILE_DATE FileDate;
    FILE_TIME FileTime;

    if (append)
    {
      po_unlock();
      return FILE_NOT_EXIST;
    }
    else    // overwrite - CREATE a new file
    {

CREATE:
      _fileSize = 0;
      _offsetLastCluster = 0;
      if (dataSize)
      {
        // Get a free cluster
        _fileCluster = findFreeCluster();
        if (!_fileCluster)
        {
          po_unlock();
          return DISK_FULL;
        }
      }

      // Populate the new File
      padFileName(filename,(char*)_newEntry);
      _newEntry[11] = BFSA_ATTR_ARCHIVE;  // Attribut for File
      _newEntry[12] = 0;                  // Reserved
      _newEntry[13] = 0;                  // Reserved

      FileTime.Seconds = 15;
      FileTime.Minutes = 23;
      FileTime.Hours   = 17;
      pAddress = (USHORT*)&FileTime;
      _newEntry[14] = (UCHAR)*pAddress;      // Create Time
      _newEntry[15] = (UCHAR)(*pAddress>>8); // Create Time

      FileDate.Day = 13;
      FileDate.Month = 02;
      FileDate.Years80 = 2005-1980;
      pAddressDate = (USHORT*)&FileDate;
      _newEntry[16] = (UCHAR)*pAddressDate;      // Create Date
      _newEntry[17] = (UCHAR)(*pAddressDate>>8); // Create Date

      _newEntry[18] = _newEntry[19] = 0;       // Last acces
      _newEntry[20] = _newEntry[21] = 0;       // Hi Cluster (reserved)

      _newEntry[22] = (UCHAR)*pAddress;        // Time Last Modification
      _newEntry[23] = (UCHAR)(*pAddress>>8);   // Time Last Modification

      _newEntry[24] = (UCHAR)*pAddressDate;      // Date Last Modification
      _newEntry[25] = (UCHAR)(*pAddressDate>>8); // Date Last Modification

      _newEntry[26] = LOW_BYTE(_fileCluster);  // Cluster LO
      _newEntry[27] = HIGH_BYTE(_fileCluster); // Cluster HI
      _newEntry[28] = _newEntry[29] = 0;  // Size always 0 for directory
      _newEntry[30] = _newEntry[31] = 0;  // Size always 0 for directory

      _status = addNewEntry( _newEntry, BFSA_current_dir.DirStart, BFSA_current_dir.IsRoot );
      if (BFSA_FAILURE(_status))
      {
        // Can't add a new entry
        writeFatEntry(_fileCluster,FREE);
        po_unlock();
        return _status;
      }

      // Get a pointer to entry to update file size later
      _pucFileEntry = (UCHAR*)findEntry(filename);
    }
  }

  // At this point :
  //    _fileCluster is the last cluster
  //    _offsetLastCluster is the offset in this cluster where start to write
  //    _fileSize is the current size of file before the write
  //    _pucFileEntry points to the fille entry in current directory

  while (dataSize)
  {
    UCHAR *pucAdd;
    USHORT _newCluster;

    _dataToWrite = min(dataSize, (BFSA_media.bytesPerSector*BFSA_media.SectPerCluster) - (_offsetLastCluster));

    pucAdd =(UCHAR*)( FIRST_SECTOR_DATACLUSTER(_fileCluster)*BFSA_media.bytesPerSector
                     + (_offsetLastCluster) + (unsigned int)FlashBaseAdd);

//assert((unsigned int)pucAdd!=0x100000UL);

    // copy
    if( FALSE == AT91F_Flash_Write_Address( (unsigned int)pucAdd, _dataToWrite, (UCHAR*)dataBuffer, FALSE ) )
    {
      po_unlock();
      return FLASH_ACCESS_ERROR;
    }

    // Update file size
    _fileSize += _dataToWrite;
    _newEntry[28] = (UCHAR)(_fileSize &0x000000FFUL);
    _newEntry[29] = (UCHAR)((_fileSize &0x0000FF00UL)>>8);
    _newEntry[30] = (UCHAR)((_fileSize &0x00FF0000UL)>>16);
    _newEntry[31] = (UCHAR)((_fileSize &0xFF000000UL)>>24);
    _needToWriteEntry = TRUE;

    dataSize -= _dataToWrite;
    dataBuffer += dataSize;
    _dataWritten += _dataToWrite;
    if (dataSize)
    {
      // Need to allocate a new cluster.
      _newCluster = findFreeCluster();
      if (!_newCluster)
      {
        // In this error case, nothing is store on disk, the FAT on disk is still
        // the old one, same for the file entry.
        po_unlock();
        return DISK_FULL;
      }

      // Update FAT (clusters chain)
      if( BFSA_SUCCESS != writeFatEntry(_fileCluster,_newCluster) )
      {
        po_unlock();
        return FLASH_ACCESS_ERROR;
      }
      _fileCluster = _newCluster;
      _offsetLastCluster = 0;
    }
  }

  // Update the entry on disk
  if (_needToWriteEntry)
  {
    if( FALSE == AT91F_Flash_Write_Address((unsigned int)_pucFileEntry,DIRECTORY_ENTRIE_SIZE ,_newEntry, FALSE) )
    {
      po_unlock();
      return FLASH_ACCESS_ERROR;
    }
  }

  // Save and unlock FAT
  if( BFSA_SUCCESS != writeFAT() )
  {
    _dataWritten = FLASH_ACCESS_ERROR;
  }
  po_unlock();

⌨️ 快捷键说明

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