📄 bfsa_api.c
字号:
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 + -