📄 fatlib.c
字号:
filesOpenedRead--;
openedRead[i].fileHandle = -1;
return 0;
}
}
for(i = 0; i < filesOpenedWrite; i++)
{
if(openedWrite[i].fileHandle == fileHandle)
{
filesOpenedWrite--;
openedWrite[i].fileHandle = -1;
return 0;
}
}
return -1;
}
/**
* determines the location of the cluster of the file or directory
* pointed to by the input pathname. Only the first token in
* the string pointed to by pathname is used (anything before '\').
*
* @param buf the buffer to be used to access the MMC/SD card
* @param pathname pointer to the string of the pathname
* @param cluster location of the current directory where the
* file or directory being seek is located
* @param control determines whether a file or a directory is being seek
* @param fileSize stores the size of the file being seeked
*
* @return 0 if the directory or file does not exist
* @return ... the first cluster of the directory or file being seeked
**/
static unsigned long getFirstCluster(const char *pathname, unsigned long cluster, unsigned char *buf, boolean control, unsigned long * fileSize)
{
int offset = 0;
unsigned int sectorCount;
unsigned long sector;
unsigned char i, j;
unsigned char tokenLength = 0; // path name contails tokes less than 255 characters long
const char *tempPathname;
boolean matchingNames;
boolean targetFound;
if((cluster == 1)&&(fileSys == FAT16))
{
sector = rootDirectory;
}
else
{
return 0;
}
tempPathname = pathname;
while((*tempPathname != 0x5C)&&(*tempPathname))
{
tokenLength++;
tempPathname++;
}
targetFound = FALSE;
sectorCount = 0;
i = 0;
readSector(sector, buf);
if(((tokenLength < 13)&&(control == FILE)))
{
while((targetFound == FALSE)&&(sector > 0))
{
offset = i * 32;
tempPathname = pathname;
matchingNames = TRUE;
if (control == FILE)
{
if (buf[offset] == '\0')
{
// End of entries.
break;
}
// Check attributes except for ARCHIVE or READONLY, and for deleted entries:
if(((buf[11+offset] & 0xDE) == 0x00)&&((buf[offset] & 0xFF) != 0xE5))
{
for(j = 0; j < 8; j++)
{
if (*tempPathname != '.' && *tempPathname != '\0')
{
// Before end of filename, characters must match:
if (!charEquals(buf[offset+j], *tempPathname))
{
matchingNames = FALSE;
}
tempPathname++;
}
else if ((buf[offset+j]) != ' ')
{
// After end of filename, must have blanks.
matchingNames = FALSE;
}
}
if (*tempPathname != '\0')
{
tempPathname++;
}
for(j = 8; j < 11; j++)
{
if (*tempPathname != '\0')
{
// Before end of extension, characters must match:
if (!charEquals(buf[offset+j], *tempPathname))
{
matchingNames = FALSE;
}
tempPathname++;
}
else if ((buf[j+offset]) != ' ')
{
// After end of extension, must have blanks.
matchingNames = FALSE;
}
}
if (matchingNames)
{
targetFound = TRUE;
}
}
}
i++;
if(i == 16) // 16 = directory entries per sector (fixed number)
{
i = 0;
sectorCount++;
if((cluster == 1)&&(fileSys == FAT16))
{
if( sectorCount < rootSectors )
{
sector++;
}
else
{
sector = 0;
}
}
else
{
if(sectorCount != sectorsPerCluster)
{
sector++;
}
else
{
sectorCount = 0;
cluster = getNextFAT(cluster, buf);
if((cluster <= 0xFFF6)&&(cluster >= 2))
{
sector = (cluster - 2) * sectorsPerCluster + dataStarts;
}
else
{
sector = 0;
}
}
}
readSector(sector, buf);
}
}
}
if(targetFound)
{
cluster = buf[26+offset];
cluster |= (unsigned long int)buf[27+offset] << 8;
*fileSize = buf[28+offset];
*fileSize += (unsigned long int)buf[29+offset] << 8;
*fileSize += (unsigned long int)buf[30+offset] << 16;
*fileSize += (unsigned long int)buf[31+offset] << 24;
}
else
{
cluster = 0;
}
return cluster;
}
/**
* creates a new entry (file or directory) at the location indicated by the
* input cluster. The input control determines whether a file or a
* directory is created
* *****ONLY FILES AND DIRECTORY WITH SHORT FILE NAMES ARE SUPPORTED
*
* @param buf the buffer to be used to access the MMC/SD card
* @param entryName pointer to the name of the new entry
* @param cluster location of the current directory where the new entry will be added
* @param control FILE or DIRECTORY
*
* @return 0 if an error occurs while adding a new entry
* @return ... the location of the first cluster of the new entry
**/
static unsigned long createNewEntry(const char *entryName, unsigned long cluster, unsigned char *buf, boolean control)
{
unsigned int offset;
unsigned int sectorCount = 0;
unsigned int tokenLength = 0;
unsigned long sector;
unsigned long newCluster;
unsigned char i;
const char *tempEntryName;
boolean done = FALSE;
// Note: findEmptyCluster() will mark the returned cluster in the FAT
// as used. If we fail for some other reason below, we should really
// free the newCluster, but we don't right now. Also, unless we are
// creating a directory, we really shouldn't allocate a first cluster
// until some data is written to the file. Additionally, if we re-use a
// deleted entry, we should re-use the cluster chain, adding clusters as
// required, but we don't do that right now either.
newCluster = findEmptyCluster(buf);
if(newCluster == 0)
{
return 0; // no more empty cluster
}
if((cluster == 1) && (fileSys == FAT16))
{
sector = rootDirectory;
}
else
{
sector = (cluster - 2) * sectorsPerCluster + dataStarts;
}
tempEntryName = entryName;
while((*tempEntryName != '.')&&(*tempEntryName)&&(*tempEntryName != 0x5C))
{
tokenLength++;
tempEntryName++;
}
while(!done)
{
readSector(sector, buf);
i = 0;
while(i < 16)
{
offset = i * 32;
if(((buf[offset] & 0xFF) == 0x00) || ( (buf[offset] & 0xFF) == 0xE5) )
{
done = TRUE;
i = 15;
}
i++;
}
if(!done)
{
sectorCount++;
if((cluster == 1)&&(fileSys == FAT16))
{
if(sectorCount < rootSectors)
{
sector++;
}
else
{
return 0; // no more root directory
}
}
else
{
return 0;
}
}
}
if(control == FILE)
{
buf[offset+11] = 0x20;
if(tokenLength < 9)
{
for(i = 0; i < 8; i++)
{
if(*entryName != '.')
{
if((*entryName >= 'a')&&(*entryName <= 'z'))
{
buf[offset+i] = (*entryName - 32);
}
else
{
buf[offset+i] = *entryName ;
}
entryName++;
}
else
{
buf[offset+i] = 0x20;
}
}
entryName++;
for(i = 8; i < 11; i++)
{
if(*entryName)
{
if((*entryName >= 'a')&&(*entryName <= 'z'))
{
buf[offset+i] = (*entryName - 32);
}
else
{
buf[offset+i] = *entryName ;
}
entryName++;
}
else
{
buf[offset+i] = 0x20;
}
}
}
else
{
// file with long file name
return 0;
}
}
buf[offset+12] = 0x00;
buf[offset+13] = 0x00;
// Set the date and time to January 02, 2005 21:00:00 .
// If a real time clock is available, we could use it.
buf[offset+14] = (04 >> 1) & 0x1F; // Seconds.
buf[offset+14] |= 03 << 5; // Part of minutes.
buf[offset+22] = buf[offset+14];
buf[offset+15] = (03 >> 3) & 0x07; // More of minutes.
buf[offset+15] |= 21 << 3; // Hours.
buf[offset+23] = buf[offset+15];
buf[offset+16] = 02 & 0x1F; // Day.
buf[offset+16] |= (01 << 5) & 0xE0; // Part of month.
buf[offset+18] = buf[offset+16];
buf[offset+24] = buf[offset+16];
buf[offset+17] = (01 >> 3) & 0x01; // More of month.
buf[offset+17] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE; // Year.
buf[offset+19] = buf[offset+17];
buf[offset+25] = buf[offset+17];
buf[offset+26] = (newCluster & 0xFF);
buf[offset+27] = (newCluster >> 8) & 0xFF;
for(i = 28; i < 32; i++)
{
buf[offset+i] = 0x00;
}
writeSector(sector, buf);
return newCluster;
}
/**
* finds the index of the for the array of pointers which
* corresponds to the input file handle.
*
* @param handle the handle of the file being seeked
*
* @return -1 invalid file handle
* @return ... the index to the correct file pointer
**/
static signed char findFileIndex(signed char handle)
{
signed char i, tempIndex;
for(i = 0; i < BUFFER_SIZE; i++)
{
tempIndex = openedWrite[i].fileHandle;
if(openedRead[i].fileHandle != -1)
{
if(openedRead[i].fileHandle == handle)
{
return i;
}
}
if(tempIndex != -1)
{
if(tempIndex == handle)
{
return i;
}
}
}
return -1;
}
/**
* checks to see if the file indicated by the input cluster
* is already opened for either reading or writing
*
* @pre the input must be the location of the first cluster
* of a file
* @param cluster first cluster of the file being checked
*
* @return -1 file is already opened for reading
* @return -2 file is already opened for writing
* @return 0 file is currently not opened
**/
static signed char openedCheck(unsigned long cluster)
{
unsigned char i;
for(i = 0; i < BUFFER_SIZE; i++)
{
if(openedRead[i].fileHandle != -1)
{
if(openedRead[i].firstCluster == cluster)
{
return -1;
}
}
}
for(i = 0; i < BUFFER_SIZE; i++)
{
if(openedWrite[i].fileHandle != -1)
{
if(openedWrite[i].firstCluster == cluster)
{
return -2;
}
}
}
return 0;
}
/**
* opens the file indicated by the input path name. If the pathname
* points to a valid file, the file is added to the list of currently
* opened files for reading and the unique file handle is returned.
*
* @param pathname a pointer to the location of the file to be opened
* @param buf the buffer to be used to access the MMC/SD card
*
* @return -1 invalid pathname
* @return -2 file does not exist
* @return -3 file already opened for writing
* @return -4 file already opened for reading
* @return -10 no handles available
* @return -20 memory card error
* @return -128 other error
* @return ... file handle of sucessfully opened file
**/
signed char fat_openRead(const char *pathname)
{
char buf[SECTOR_SIZE];
const char *tempPathname;
unsigned long cluster;
unsigned long tempCluster;
unsigned long fileSize = 0;
signed char i = 0;
signed char index = -1;
if(detectCard() == FALSE)
{
return -20;
}
if(filesOpenedRead >= BUFFER_SIZE)
{
return -10;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -