📄 fat16.c
字号:
unsigned char FilePutChar(File *file,char c)
{
unsigned long ul_temp = 0;
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
{
file->sector_index = 0;
AppendCluster(file); // append a new and free cluster at the end of the file.
}
FileBuffer[file->byte_index] = c; // write databyte into the buffer. The byte will be written to the device at once
file->filesize++; // a character has been written to the file so the size is inkremented
// if the buffer contains the complete sectordata.
if(file->byte_index < 511) // if the end of this sector is not reached yet
{
file->byte_index++; // the next byte will be written to the next byteposition in this sector.
}
else // otherwise the data in the sectorbuffer will be written to the device and the next sector will be selected.
{
ul_temp = (unsigned long)file->cluster_pointer;
ul_temp += (unsigned long)file->sector_index;
mmc_write_sector((unsigned long)ul_temp,&FileBuffer[0]);
file->byte_index=0; // and the next byte will be written at the beginning of this new sector.
file->sector_index++;
}
return(0);
}
unsigned char FileWriteSector(File *file,char *buf)
{
unsigned long ul_temp = 0;
file->filesize+=512;
ul_temp = (unsigned long)file->cluster_pointer;
ul_temp += (unsigned long)file->sector_index;
mmc_write_sector((unsigned long)ul_temp,buf);
file->byte_index=0; // and the next byte will be written at the beginning of this new sector.
file->sector_index++;
if(file->sector_index >= SectorsPerCluster) // if end of the cluster is reached, find next free cluster
{
file->sector_index = 0;
AppendCluster(file); // append a new and free cluster at the end of the file.
}
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: unsigned int SeekFileInDirectory(unsigned char*, unsigned long, File *)
//
// Description: this function searches all possible rootentries until the file is found or the end of the rootdirectory is reached
//
//________________________________________________________________________________________________________________________________________
unsigned int SeekFileInDirectory(unsigned char *fname,unsigned long dir_sector, File *fpoint)
{
unsigned int cluster=0; // Start search for file in the first sector of the rootdirectory.
unsigned int rootentry=0;
unsigned int cnt_enries_searched=0;
unsigned char i=0;
unsigned int sector_offset=0; // index to the sector of the Rootentry which is searched momentarily
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
#if USE_MMC
do
{ // search the next 16 rootentries in this sector of the roordirectory.
rootentry=0;
mmc_read_sector((unsigned long)((unsigned long)RootDirectory + (unsigned long)sector_offset),&FileBuffer[0]); // Read the Rootdirectory.
DirectoryEntry = (struct DirEntry *)&FileBuffer[0];
while((!cluster)&&(rootentry<16))
{
i=0;
while((i<10)&&(DirectoryEntry[rootentry].name[i] == fname[i]))
{
i++;
}
if(i==10) // file found!! -> reading startcluster of file from offset 26.
{
cluster = DirectoryEntry[rootentry].startcluster;
fpoint->filesize = (unsigned long) DirectoryEntry[rootentry].size;
fpoint->directory_sector = (unsigned long) (RootDirectory + sector_offset);
fpoint->directory_index = (unsigned char) rootentry;
}
rootentry++;
cnt_enries_searched++;
}
if(!cluster) // file not found in this sector so take next sector.
{
sector_offset++;
}
}
while((cnt_enries_searched<PossibleRootEntries) && (!cluster));
#endif
return(cluster);
}
//________________________________________________________________________________________________________________________________________
// Funtion: void SeperateFileName(unsigned char*);
//
// Description: This function seperates the filename and the fileattribute and brings them into the needed format ('test.txt' -> 'TEST TXT');
//
//________________________________________________________________________________________________________________________________________
void SeperateFileName(unsigned char *fname, unsigned char *name)
{
unsigned char readpointer = 0;
unsigned char writepointer = 0;
while((writepointer<=10) && (fname[readpointer]!=0)) // the rootdirectoryentry is 8bytes for filename and 3bytes for fileattribute.
{ // the filename in the rootdirectory is in the format "TEST TXT" without the dot.
if(fname[readpointer]=='.') // seperating filename and attribute.
{
readpointer++;
writepointer=8;
}
else
{
if((fname[readpointer]>96) && (fname[readpointer]<123))
{
name[writepointer] = fname[readpointer] - 32; // all characters must be upper case.
}
else name[writepointer]=fname[readpointer];
readpointer++;
writepointer++;
}
}
}
//________________________________________________________________________________________________________________________________________
// Funtion: FileClose(File *file);
//
// Description: This function closes the open file by writing the remaining data from the buffer to the device and entering the filesize
// in the directory entry.
//________________________________________________________________________________________________________________________________________
void FileClose(File *file)
{
#if USE_MMC
/*
if(file->mode =='a')
{
mmc_write_sector((unsigned long)(file->cluster_pointer + file->sector_index),&FileBuffer[0]); // save the data still in the buffer
mmc_read_sector((unsigned long)file->directory_sector,&FileBuffer[0]); // read the directoryentry for this file.
DirectoryEntry = (struct DirEntry *)&FileBuffer[0];
DirectoryEntry[file->directory_index].size = (unsigned long) file->filesize;
mmc_write_sector((unsigned long)file->directory_sector,&FileBuffer[0]);
}
*/
if(file && file->mode =='a') {
// If we have any data in the current FileBuffer (from FilePutChar()) we flush them to the disk first)
// This fixes the error that occurs if we call FilePutChar() with a number of bytes that will exactly fill the
// current cluster we are writing to, and FilePutChar() calls AppendCluster(), this will leave the FileBuffer with FAT data in
// hence we shold NOT write thoses data (FilePutChar() already wrote the correct data before it called AppendCluster())
if (file->byte_index > 0) {
// save the data still in the buffer
mmc_write_sector((unsigned int)(file->cluster_pointer + file->sector_index),&FileBuffer[0]);
}
// read and update the directory entry for this file
mmc_read_sector((unsigned int)file->directory_sector,&FileBuffer[0]);
DirectoryEntry = (struct DirEntry *)&FileBuffer[0];
DirectoryEntry[file->directory_index].size = (unsigned int) file->filesize;
mmc_write_sector((unsigned int)file->directory_sector,&FileBuffer[0]);
}
file=0;
#endif
}
//________________________________________________________________________________________________________________________________________
// Funtion: unsigned char fopen(unsigned char*, unsigned char *, File *);
//
// Description: This function looks for the specified file in the rootdirectory of the drive. If the file is found the number of the
// corrosponding datacluster is returned to main. Only modes 'r' (reading) and 'a' append are implemented yet.
//
// Return: 0 = open failed
// 1 = SUCCESS
//________________________________________________________________________________________________________________________________________
unsigned char FileOpen(unsigned char *fname, char mode, File *fpoint)
{
unsigned long cluster_temp = 0;
unsigned char name[11] = " ";
unsigned int temp;
if (fpoint == NULL) return(0); // Valid pointer ??
fpoint->start_cluster = 0; // File not opend yet.
fpoint->cluster_pointer = 0;
fpoint->sector_index = 0;
fpoint->byte_index = 0;
fpoint->mode = mode;
fpoint->filesize = 0;
SeperateFileName(&fname[0], &name[0]); // seperate the filename and attribute and bring them in the correct format.
cluster_temp = (unsigned long)SeekFileInDirectory(&name[0],(unsigned long)RootDirectory, fpoint);
if(cluster_temp) // if file was found
{
temp = (unsigned int)cluster_temp;
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= (unsigned long)SectorsPerCluster; // Calculate positon of first cluster.
fpoint->start_cluster = (FirstDataCluster + cluster_temp);
fpoint->cluster_pointer = fpoint->start_cluster; // start reading the file with the first cluster.
if(mode == 'a') // open existing file for writing (append data at the end of the file)
{
FindEndOfFile(fpoint);
}
return(1);
}
else
{
if(mode == 'a') // specified file doesn't exist so create new file for writing data.
{
cluster_temp = (unsigned long)FindNextFreeCluster(fpoint); // the next free cluster on the disk.
if(cluster_temp) // if a free cluster is available:
{
temp = (unsigned int)cluster_temp; // remember the index of the free datacluster found for the directory entry.
cluster_temp -=2; // Clusterposition is ((position in FAT)-2). first two entries in FAT are reserved.
cluster_temp *= SectorsPerCluster; // Calculate relative sectorindex of first datacluster.
fpoint->start_cluster = (FirstDataCluster + cluster_temp); // Calculate absolute sectorposition of first datacluster.
fpoint->cluster_pointer = fpoint->start_cluster; // start reading the file with the first sector of the first datacluster.
if(CreateFileInDirectory(&name[0],temp, fpoint)) // Could an entry for the new file in the rootdirectory be created?
{
return(1);
}
}
}
return(0);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -