📄 fat16.c
字号:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <string.h>
#include "ata.h"
#include "rprintf.h"
#include "fat.h"
#include "fatconf.h"
// globals
unsigned char *SectorBuffer = (unsigned char *) SECTOR_BUFFER1_ADDR;
unsigned char *LongNameBuffer = (unsigned char *) LONGNAME_BUFFER_ADDR;
unsigned char *DirNameBuffer = (unsigned char *) DIRNAME_BUFFER_ADDR;
struct partrecord PartInfo;
unsigned char Fat32Enabled;
unsigned long FirstDataSector;
unsigned int BytesPerSector;
unsigned int SectorsPerCluster;
unsigned long FirstFATSector;
unsigned long FirstDirSector;
unsigned long FileSize;
unsigned long FatInCache = 0;
/*************************************************************************/
/*************************************************************************/
00054
00055 unsigned long fatClustToSect(unsigned long clust)//数据存放的簇=>扇区
00056 {
00057 return ((clust-2) * SectorsPerCluster) + FirstDataSector;
00058 }
00059
00060 unsigned int fatClusterSize(void)
00061 {
00062 // return the number of sectors in a disk cluster
00063 return SectorsPerCluster;
00064 }
00065
00066 unsigned char fatInit( unsigned char device)
00067 {
00068 //struct partrecord *pr;
00069 struct bpb710 *bpb;
00071 // read partition table
00072 // TODO.... error checking
00073 ataReadSectors(DRIVE0, 0, 1, SectorBuffer);//读driver的扇区到buffer
00074 // map first partition record
00075 // save partition information to global PartInfo
00076 PartInfo = *((struct partrecord *) ((struct partsector *) SectorBuffer)->psPart);
00077 // PartInfo = *pr;
00078
00079 // Read the Partition BootSector
00080 // **first sector of partition in PartInfo.prStartLBA
00081 ataReadSectors( DRIVE0, PartInfo.prStartLBA, 1, SectorBuffer );
00082 bpb = (struct bpb710 *) ((struct bootsector710 *) SectorBuffer)->bsBPB;
00083
00084 // setup global disk constants
00085 FirstDataSector = PartInfo.prStartLBA;
00086 if(bpb->bpbFATsecs)
00087 {
00088 // bpbFATsecs is non-zero and is therefore valid
00089 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
00090 }
00091 else
00092 {
00093 // bpbFATsecs is zero, real value is in bpbBigFATsecs
00094 FirstDataSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbBigFATsecs;
00095 }
00096 SectorsPerCluster = bpb->bpbSecPerClust;
00097 BytesPerSector = bpb->bpbBytesPerSec;
00098 FirstFATSector = bpb->bpbResSectors + PartInfo.prStartLBA;
00099
00100 switch (PartInfo.prPartType)
00101 {
00102 case PART_TYPE_DOSFAT16:
00103 case PART_TYPE_FAT16:
00104 case PART_TYPE_FAT16LBA:
00105 // first directory cluster is 2 by default (clusters range 2->big)
00106 FirstDirSector = CLUST_FIRST;
00107 // push data sector pointer to end of root directory area
00108 //FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
00109 Fat32Enabled = FALSE;
00110 break;
00111 case PART_TYPE_FAT32LBA:
00112 case PART_TYPE_FAT32:
00113 // bpbRootClust field exists in FAT32 bpb710, but not in lesser bpb's
00114 FirstDirSector = bpb->bpbRootClust;
00115 // push data sector pointer to end of root directory area
00116 // need this? FirstDataSector += (bpb->bpbRootDirEnts)/DIRENTRIES_PER_SECTOR;
00117 Fat32Enabled = TRUE;
00118 break;
00119 default:
00120 rprintfProgStrM("Found: No Partition!\r\n");
00121 //return 1;
00122 break;
00123 }
00124
00125
00126 #ifdef DEBUG_FAT
00127 switch (PartInfo.prPartType)
00128 {
00129 case PART_TYPE_DOSFAT16:
00130 rprintfProgStrM("Found: DOSFAT 16\r\n");
00131 break;
00132 case PART_TYPE_FAT16:
00133 rprintfProgStrM("Found: FAT16\r\n");
00134 break;
00135 case PART_TYPE_FAT16LBA:
00136 rprintfProgStrM("Found: FAT16 LBA\r\n");
00137 break;
00138 case PART_TYPE_FAT32LBA:
00139 rprintfProgStrM("Found: FAT32 LBA\r\n");
00140 break;
00141 case PART_TYPE_FAT32:
00142 rprintfProgStrM("Found: FAT32\r\n");
00143 //return 1;
00144 break;
00145 default:
00146 rprintfProgStrM("Found: No Partition!\r\n");
00147 //return 1;
00148 break;
00149 }
00150
00151 rprintfProgStrM("First sector : "); rprintfu32(PartInfo.prStartLBA); rprintfCRLF();
00152 rprintfProgStrM("Size : "); rprintfu32(PartInfo.prSize); rprintfCRLF();
00153 rprintfProgStrM("bytes/sector : "); rprintfu16(bpb->bpbBytesPerSec); rprintfCRLF();
00154 rprintfProgStrM("sectors/cluster : "); rprintfu08(bpb->bpbSecPerClust); rprintfCRLF();
00155 rprintfProgStrM("reserved sectors: "); rprintfu16(bpb->bpbResSectors); rprintfCRLF();
00156 rprintfProgStrM("FatSectors : "); rprintfu16(bpb->bpbFATsecs); rprintfCRLF();
00157 rprintfProgStrM("BigFatSectors : "); rprintfu32(bpb->bpbBigFATsecs); rprintfCRLF();
00158 rprintfProgStrM("Number of Fats : "); rprintfu08(bpb->bpbFATs); rprintfCRLF();
00159 rprintfProgStrM("First Fat Sector: "); rprintfu32(FirstFATSector); rprintfCRLF();
00160 rprintfProgStrM("First Data Sect : "); rprintfu32(FirstDataSector); rprintfCRLF();
00161 rprintfProgStrM("First Dir Clust : "); rprintfu32(FirstDirSector); rprintfCRLF();
00162 #endif
00163
00164 return 0;
00165 }
00166
00167 //////////////////////////////////////////////////////////////
00168
00169
00170 unsigned int baseentry = 0;
00171 unsigned int entrycount = 0;
00172
00173
00174 unsigned long fatGetDirEntry(unsigned int entry, unsigned int count)
00175 {
00176 unsigned long sector;
00177 struct direntry *de = 0; // avoid compiler warning by initializing
00178 struct winentry *we;
00179 unsigned int hasBuffer;
00180 unsigned int b;
00181 int i,index;
00182 char *p;
00183
00184 if(count == 0)
00185 {
00186 entrycount = 0;
00187 DirNameBuffer = 0;
00188 }
00189
00190 // read dir data
00191 sector = fatClustToSect(FirstDirSector);
00192
00193 hasBuffer = 0;
00194
00195 index = 16; // crank it up
00196 do
00197 {
00198 if(index == 16) // time for next sector ?
00199 {
00200 ataReadSectors( DRIVE0, sector++, 1, SectorBuffer);
00201 de = (struct direntry *) SectorBuffer;
00202 index = 0;
00203 }
00204
00205 if(*de->deName != 0xE5)
00206 {
00207 // if not a deleted entry
00208 if(de->deAttributes == ATTR_LONG_FILENAME)
00209 {
00210 // we have a long name entry
00211 we = (struct winentry *) de;
00212 b = 13 *( (we->weCnt-1) & 0x0f); // index into string
00213 p = &LongNameBuffer[b];
00214 for (i=0;i<5;i++) *p++ = we->wePart1[i*2]; // copy first part
00215 for (i=0;i<6;i++) *p++ = we->wePart2[i*2]; // second part
00216 for (i=0;i<2;i++) *p++ = we->wePart3[i*2]; // and third part
00217 if (we->weCnt & 0x40) *p = 0; // in case dirnamelength is multiple of 13
00218 if ((we->weCnt & 0x0f) == 1) hasBuffer = 1; // mark that we have a long entry
00219 }
00220 else
00221 {
00222 // we have a short name entry
00223 // check if this is the end of a multi-part long name entry
00224 if(hasBuffer)
00225 {
00226 // a long entry name has been collected
00227 // is it a directory ?
00228 if(de->deAttributes == ATTR_DIRECTORY)
00229 {
00230 unsigned long save = FirstDirSector;
00231 unsigned int save2 = baseentry;
00232 unsigned long rval;
00233
00234 strcpy(DirNameBuffer,LongNameBuffer);
00235 strcat(DirNameBuffer,"/");
00236
00237 // rprintfStr(LongNameBuffer); rprintfProgStrM("/"); //EOL();
00238
00239 // call recursively
00240 FirstDirSector = ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00241 rval = fatGetDirEntry(entry,1);
00242 FirstDirSector = save;
00243 baseentry = save2;
00244 if (rval)
00245 return rval;
00246 else
00247 {
00248 // reload original sector
00249 ataReadSectors( DRIVE0, sector-1, 1, SectorBuffer);
00250 entrycount--; // decrement entry counter
00251 *DirNameBuffer = 0;
00252 }
00253 }
00254 else // normal file entry
00255 if(entrycount == entry)
00256 break;
00257 hasBuffer = 0; // clear buffer
00258 entrycount++; // increment entry counter
00259 }
00260 // else ignore short_name_only entries
00261 }
00262 }
00263 de++;
00264 index++;
00265 } while (*de->deName || index == 16); // 0 in de->deName[0] if no more entries
00266
00267 if (hasBuffer == 0) // end of entries
00268 return 0;
00269
00270 FileSize = de->deFileSize;
00271 return (unsigned long) ((unsigned long)de->deHighClust << 16) + de->deStartCluster;
00272 }
00273
00274
00275 // return the size of the last directory entry
00276 unsigned long fatGetFilesize(void)
00277 {
00278 return FileSize;
00279 }
00280
00281
00282 // return the long name of the last directory entry
00283 char* fatGetFilename(void)
00284 {
00285 return LongNameBuffer;
00286 }
00287
00288
00289 // return the directory of the last directory entry
00290 char* fatGetDirname(void)
00291 {
00292 return DirNameBuffer;
00293 }
00294
00295
00296 // load a clusterfull of data
00297 void fatLoadCluster(unsigned long cluster, unsigned char *buffer)
00298 {
00299 register unsigned char i;
00300 // read cluster
00301 //while ( ataReadSectors( DRIVE0, clust2sect(cluster), SectorsPerCluster, buffer) != 0);
00302 for(i=0; i<SectorsPerCluster; i++)
00303 {
00304 // ataReadSectors( DRIVE0, clust2sect(cluster)+i, 1, buffer+(i<<9) );
00305 // temporary fix for wierd misaligned cluster problem
00306 // (only when using FAT16?)
00307 ataReadSectors( DRIVE0, fatClustToSect(cluster+8)+i, 1, buffer+(i<<9) );
00308 }
00309 }
00310
00311
00312 // find next cluster in the FAT chain
00313 unsigned long fatNextCluster(unsigned long cluster)
00314 {
00315 unsigned long nextCluster;
00316 unsigned long fatMask;
00317 unsigned long fatOffset;
00318 unsigned long sector;
00319 unsigned int offset;
00320
00321 // get fat offset in bytes
00322 if(Fat32Enabled)
00323 {
00324 // four FAT bytes (32 bits) for every cluster
00325 fatOffset = cluster << 2;
00326 // set the FAT bit mask
00327 fatMask = FAT32_MASK;
00328 }
00329 else
00330 {
00331 // two FAT bytes (16 bits) for every cluster
00332 fatOffset = cluster << 1;
00333 // set the FAT bit mask
00334 fatMask = FAT16_MASK;
00335 }
00336
00337 // calculate the FAT sector that we're interested in
00338 sector = FirstFATSector + (fatOffset / BytesPerSector);
00339 // calculate offset of the our entry within that FAT sector
00340 offset = fatOffset % BytesPerSector;
00341
00342 // if we don't already have this FAT chunk loaded, go get it
00343 if (sector != FatInCache)
00344 {
00345 // read sector of FAT table
00346 while (ataReadSectors( DRIVE0, sector, 1, (unsigned char*)FAT_CACHE_ADDR) != 0);
00347 FatInCache = sector;
00348 }
00349
00350 // read the nextCluster value
00351 nextCluster = (*((unsigned long*) &((char*)FAT_CACHE_ADDR)[offset])) & fatMask;
00352
00353 // check to see if we're at the end of the chain
00354 if (nextCluster == (CLUST_EOFE & fatMask))
00355 nextCluster = 0;
00356
00357 #ifdef DEBUG_FAT
00358 rprintfProgStrM(">");
00359 rprintfu32(nextCluster);
00360 rprintfCRLF();
00361 #endif
00362
00363 return nextCluster;
00364 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -