📄 fatlib.c
字号:
else
{
while((i < BUFFER_SIZE) && (index < 0))
{
if(openedRead[i].fileHandle == -1)
{
index = i;
}
i++;
}
}
cluster = fileSys;
if(*pathname == 0x5C)
{
pathname++;
}
tempPathname = pathname;
while(*tempPathname)
{
if(*tempPathname == 0x5C)
return -128;
tempPathname++;
}
tempPathname = pathname;
if(cluster != 0)
{
tempCluster = cluster;
cluster = getFirstCluster(tempPathname, cluster, buf, FILE, &fileSize);
}
else
{
return -1;
}
if(cluster > 0)
{
i = openedCheck(cluster);
if( i < 0 )
{
if(i == -1)
{
return -4;
}
else
{
return -3;
}
}
openedRead[index].dirLocation = tempCluster;
openedRead[index].firstCluster = cluster;
openedRead[index].currentCluster = cluster;
openedRead[index].fileSize = fileSize;
openedRead[index].byteCount = 0;
openedRead[index].sectorCount = 0;
openedRead[index].fileHandle = getFileHandle();
openedRead[index].updateDir = FALSE;
filesOpenedRead++;
return openedRead[index].fileHandle;
}
else
{
return -2;
}
return -128;
}
/**
* opens the file indicated by the input path name. If the pathname
* points to a valid path, the file is created and added to the list of
* currently opened files for writing and the unique file handle is returned.
*
* @param pathname a pointer to the location of the file to be opened
*
* @return -1 invalid pathname
* @return -2 file already exist
* @return -3 file already opened for writing
* @return -4 no directory entries left
* @return -10 no handles available
* @return -20 memory card error
* @return -128 other error
* @return (non-negative) file handle of sucessfully opened file
**/
signed char fat_openWrite(const char *pathname)
{
unsigned 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(filesOpenedWrite >= BUFFER_SIZE)
{
return -10;
}
else
{
while((i < BUFFER_SIZE) && (index < 0))
{
if(openedWrite[i].fileHandle == -1)
{
index = i;
}
i++;
}
}
cluster = fileSys;
if(*pathname == 0x5C)
{
pathname++;
}
tempPathname = pathname;
while(*tempPathname)
{
if(*tempPathname == 0x5C)
return -128;
tempPathname++;
}
tempPathname = pathname;
if(cluster != 0)
{
tempCluster = cluster;
cluster = getFirstCluster(tempPathname, cluster, buf, FILE, &fileSize);
if(cluster != 0)
{
return -2;
}
else
{
cluster = createNewEntry(tempPathname, tempCluster, buf, FILE);
if(cluster != 0)
{
openedWrite[index].currentCluster = cluster;
openedWrite[index].dirLocation = tempCluster;
openedWrite[index].fileHandle = getFileHandle();
openedWrite[index].fileSize = 0;
openedWrite[index].sectorCount = 0;
openedWrite[index].firstCluster = cluster;
openedWrite[index].byteCount = 0;
openedWrite[index].updateDir = FALSE;
filesOpenedWrite++;
return openedWrite[index].fileHandle;
}
else
{
return -4;
}
}
}
else
{
return -1;
}
return -128;
}
/**
* reads the content of the file identified by the input handle. It reads from
* where the last read operation on the same file ended. If it's the first time
* the file is being read, it starts from the begining of the file.
*
* @pre nByte < SECTOR_SIZE
*
* @param buf the buffer to be used to access the MMC/SD card
* @param handle handle of file to be closed
* @param nByte number of bytes to read
*
* @return -10 memory card error
* @return -1 invalid handle
* @return -32768 other error
* @return ... number of bytes read
**/
signed int fat_read(signed char handle, unsigned char *buf, unsigned int nByte)
{
unsigned long sectorToRead;
unsigned long sectorToRead2;
signed char index;
char tempBuf[SECTOR_SIZE];
if(detectCard() == FALSE)
{
return -10;
}
index = findFileIndex(handle);
if(index == -1)
{
return -1; // invalid handle
}
if(fileSys == FAT16)
{
if((openedRead[index].currentCluster > 0xFFF6)||(openedRead[index].currentCluster < 2))
{
return -32768; // already reached the end of file
}
}
else
{
return -32768; // invalid file system
}
sectorToRead = (openedRead[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
sectorToRead += openedRead[index].sectorCount;
if(openedRead[index].fileSize < nByte)
{
nByte = openedRead[index].fileSize;
}
if((openedRead[index].byteCount + nByte) > SECTOR_SIZE)
{
if((openedRead[index].sectorCount + 1) == sectorsPerCluster)
{
// cross cluster read
openedRead[index].currentCluster = getNextFAT(openedRead[index].currentCluster, tempBuf);
sectorToRead2 = (openedRead[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
openedRead[index].sectorCount = 0;
}
else
{
// cross sector read
sectorToRead2 = sectorToRead + 1;
openedRead[index].sectorCount++;
}
readPartialMultiSector(sectorToRead,sectorToRead2, openedRead[index].byteCount, nByte, buf);
openedRead[index].byteCount += nByte;
openedRead[index].byteCount -= SECTOR_SIZE;
if(nByte > openedRead[index].fileSize)
openedRead[index].fileSize = 0;
else
openedRead[index].fileSize -= nByte;
return nByte;
}
else
{
// single sector read
readPartialSector(sectorToRead, openedRead[index].byteCount, nByte, buf);
openedRead[index].byteCount += nByte;
if(nByte > openedRead[index].fileSize)
openedRead[index].fileSize = 0;
else
openedRead[index].fileSize -= nByte;
return nByte;
}
return -32768;
}
/**
* writes the content in the buffer to the file identified by the input handle. It writes
* to where the last write operation on the same file ended. If it's the first time
* the file is being written to, it starts from the beginning of the file.
*
* @pre nByte < SECTOR_SIZE
*
* @param buf the buffer to be used to access the MMC/SD card
* @param handle handle of file to be written to
* @param nByte number of bytes to write
*
* @return -10 memory card error
* @return -1 invalid handle
* @return -2 memory card is full
* @return -32768 other error
* @return ... number of bytes written
**/
signed int fat_write(signed char handle, unsigned char *buf, unsigned int nByte)
{
unsigned long sectorToWrite;
unsigned long sectorToWrite2;
signed char index;
char tempBuf[SECTOR_SIZE];
if(detectCard() == FALSE)
{
return -10;
}
index = findFileIndex(handle);
if(index == -1)
{
return -1; // invalid handle
}
sectorToWrite = (openedWrite[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
sectorToWrite += openedWrite[index].sectorCount;
if((openedWrite[index].byteCount + nByte) > SECTOR_SIZE)
{
if((openedWrite[index].sectorCount + 1) == sectorsPerCluster)
{
// cross cluster write
sectorToWrite2 = openedWrite[index].currentCluster;
openedWrite[index].currentCluster = findEmptyCluster(tempBuf);
if(openedWrite[index].currentCluster > 0)
{
updateFAT(sectorToWrite2, openedWrite[index].currentCluster, tempBuf);
sectorToWrite2 = (openedWrite[index].currentCluster - 2) * sectorsPerCluster + dataStarts;
openedWrite[index].sectorCount = 0;
}
else
{
return -2; // memory card full
}
}
else
{
// cross sector write
sectorToWrite2 = sectorToWrite + 1;
openedWrite[index].sectorCount++;
}
writePartialMultiSector(sectorToWrite, sectorToWrite2, openedWrite[index].byteCount, nByte, buf);
openedWrite[index].byteCount += nByte;
openedWrite[index].byteCount -= SECTOR_SIZE;
openedWrite[index].fileSize += nByte;
// Uncomment next line if you want FAT constantly updated, instead of using fat_flush():
//updateDirectory(openedWrite[index].dirLocation, openedWrite[index].firstCluster, openedWrite[index].fileSize, tempBuf);
openedWrite[index].updateDir = TRUE;
return nByte;
}
else
{
// single sector write
writePartialSector(sectorToWrite, openedWrite[index].byteCount, nByte, buf);
openedWrite[index].byteCount += nByte;
openedWrite[index].fileSize += nByte;
// Uncomment next line if you want FAT constantly updated, instead of using fat_flush():
//updateDirectory(openedWrite[index].dirLocation, openedWrite[index].firstCluster, openedWrite[index].fileSize, tempBuf);
openedWrite[index].updateDir = TRUE;
return nByte;
}
return -32768;
}
/**
* updates the file size in the directory table for all files with the update flag set
**/
void fat_flush(void)
{
int i;
char tempBuf[SECTOR_SIZE];
for(i = 0; i < filesOpenedWrite; i++)
{
if(openedWrite[i].updateDir == TRUE)
{
updateDirectory(openedWrite[i].dirLocation, openedWrite[i].firstCluster, openedWrite[i].fileSize, tempBuf);
openedWrite[i].updateDir = FALSE;
}
}
}
/**
* updates the file size and date/time in the directory table of the file identified by the input first cluster.
*
* @param buf the buffer to be used to access the MMC/SD card
* @param dirCluster location of the cluster where the directory table is store
* @param firstCluster the location of the first cluster of the file being updated
**/
static void updateDirectory(unsigned long dirCluster, unsigned long firstCluster, unsigned long filesize, unsigned char *buf)
{
unsigned long sector;
unsigned char sectorCount = 0;
unsigned char i;
unsigned int offset;
unsigned long cluster;
boolean done = FALSE;
if((dirCluster == 1)&&(fileSys == FAT16))
{
sector = rootDirectory;
}
else
{
sector = (dirCluster - 2) * sectorsPerCluster + dataStarts;
}
while((!done) && (sectorCount < sectorsPerCluster))
{
readSector(sector, buf);
for(i = 0; i < 16; i++)
{
offset = i * 32;
cluster = buf[26+offset];
cluster |= (unsigned long int)buf[27+offset] << 8;
if(cluster == firstCluster)
{
done = TRUE;
buf[28+offset] = (filesize) & 0x000000FF;
buf[29+offset] = (filesize >> 8) & 0x000000FF;
buf[30+offset] = (filesize >> 16) & 0x000000FF;
buf[31+offset] = (filesize >> 24) & 0x000000FF;
/** Set access date to March 04, 2005 23:15:18 . **/
// If a real time clock is available, we could use it.
buf[offset+22] = (18 >> 1) & 0x1F; // Seconds.
buf[offset+22] |= 15 << 5; // Part of minutes.
buf[offset+23] = (15 >> 3) & 0x07; // More of inutes.
buf[offset+23] |= 23 << 3; // Hours.
buf[offset+18] = 04 & 0x1F; // Day.
buf[offset+18] |= (03 << 5) & 0xE0; // Part of month.
buf[offset+24] = buf[offset+18];
buf[offset+19] = (03 >> 3) & 0x01; // More of month.
buf[offset+19] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE; // Year.
buf[offset+25] = buf[offset+19];
writeSector(sector, buf);
}
}
sector++;
sectorCount++;
}
}
// *** updateAccessDate() is not called right now. It should probably be
// *** called when a file is opened for reading, and closed in read mode.
/**
* updates the access date of the file specified by the input parameters
*
* @param buf the buffer to be used to access the MMC/SD card
* @param dirCluster location of the cluster where the directory table is store
* @param firstCluster the location of the first cluster of the file being updated
**/
static void updateAccessDate(unsigned long dirCluster, unsigned long firstCluster, unsigned char *buf)
{
unsigned long sector;
unsigned char sectorCount = 0;
unsigned char i;
unsigned int offset;
unsigned long cluster;
boolean done = FALSE;
if((dirCluster == 1)&&(fileSys == FAT16))
{
sector = rootDirectory;
}
else
{
sector = (dirCluster - 2) * sectorsPerCluster + dataStarts;
}
while((!done) && (sectorCount < sectorsPerCluster))
{
readSector(sector, buf);
for(i = 0; i < 16; i++)
{
offset = i * 32;
cluster = buf[26+offset];
cluster |= (unsigned long int)buf[27+offset] << 8;
if(cluster == firstCluster)
{
done = TRUE;
/** set access date to February 03, 2005. **/
// If a real time clock is available, we could use it.
buf[offset+18] = 03 & 0x1F; // Day.
buf[offset+18] |= (02 << 5) & 0xE0; // Part of month.
buf[offset+19] = (02 >> 3) & 0x01; // More of month.
buf[offset+19] |= (((2005 - 1980) & 0xFF) << 1) & 0xFE;
writeSector(sector, buf);
}
}
sector++;
sectorCount++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -