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