📄 fat16.c
字号:
#include <stdio.h>
#include "mmc.h"
#include "fat16.h"
#include "uart.h"
//________________________________________________________________________________________________________________________________________
// Module name: fat16.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 23.05.2006
// Version: 1.8
// Authors: Stephan Busker
// Description: Source files for FAT16 implementation with read and write-access using AVR-Mikrocontrollers
// Copyright (C) 2006 Stephan Busker
//........................................................................................................................................
// Functions: unsigned char InitFat16(void)
// File *FileOpen(unsigned char *fname, char *mode)
// char FileGetchar(FILE *file)
// char FilePutChar(FILE *file,char c)
// unsigned char FileRead(File *file,unsigned char*,unsigned char)
//
// ext. functions: extern unsigned char mmc_read_sector (unsigned long,unsigned char *);
// extern unsigned char mmc_write_sector (unsigned long,unsigned char *);
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
//________________________________________________________________________________________________________________________________________
//________________________________________________________________________________________________________________________________________
//
// Global variables needed read- or write-acces to the FAT16- filesystem.
//
//________________________________________________________________________________________________________________________________________
unsigned char SectorsPerCluster = 0; // how many sectors does a cluster contain?
unsigned char FatCopies = 0; // Numbers of copies of the FAT
unsigned int PossibleRootEntries = 0; // Possible number of entries in the root directory.
unsigned int SectorsPerFat = 0; // how many sectors does a fat16 contain?
unsigned long ReservedSectors = 0; // Sectors reserved by the filesystem.
unsigned long FirstPartitionSector = 0; // Distance in sectors between the first partition and the master bootrecord.
unsigned long FileAllocationTable = 0; // pointer to the first FAT
unsigned long RootDirectory = 0; // Pointer to the rootdirectory of the first partition.
unsigned long FirstDataCluster = 0; // Pointer to the first cluster containing data (cluster0).
//File fpoint; // memmory space allocation for the file that will be opend in main.
//unsigned char FileBuffer[512]; // Buffer for read and write operation from or to the mmc.
struct DirEntry *DirectoryEntry; // Pointer to an entry of the directory.
struct FatEntry *Fat; // Pointer to an entry of the fat (next clusterposition).
unsigned char *FileBuffer; // Pointer to the sectorbuffer for reading or writing.
#if USE_MMC
//________________________________________________________________________________________________________________________________________
// Funtion: InitFat16(void);
//
// Description: This function reads the Masterbootrecord and finds the position of the Volumebootrecord, the FAT and the Rootdirectory
// and stores the information in global variables.
//________________________________________________________________________________________________________________________________________
unsigned char InitFat16(void)
{
#if USE_MMC
mmc_read_sector((unsigned long)MBR_SECTOR,&FileBuffer[0]); // Read the master bootrecord from mmc.
FirstPartitionSector= *((unsigned long*)&FileBuffer[0x1C6]);
mmc_read_sector((unsigned long)FirstPartitionSector,&FileBuffer[0]); // Read the volume bootrecord from mmc.
SectorsPerCluster = FileBuffer[0x0D];
FatCopies = FileBuffer[0x10];
PossibleRootEntries = *((unsigned int*) &FileBuffer[0x11]);
SectorsPerFat = *((unsigned int*) &FileBuffer[0x16]);
ReservedSectors = *((unsigned int*)&FileBuffer[0x0E]);
// calculate the sectorpositon of the FAT, the Rootdirectory and the first Datacluster.
FileAllocationTable = (unsigned long)((unsigned long)FirstPartitionSector + (unsigned long)ReservedSectors);
RootDirectory = (unsigned long)((unsigned long)FileAllocationTable + (unsigned long)((unsigned long)SectorsPerFat*(unsigned long)FatCopies));
FirstDataCluster = (unsigned long)((unsigned long)RootDirectory + ((unsigned long)(PossibleRootEntries>>4)));
// printf("Init:\n\rRoot: %lu FAT: %lu 1:%lu r:%lu\n\r",RootDirectory, FileAllocationTable, FirstPartitionSector, ReservedSectors);
#endif
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: GetNextCluster(File *file);
//
// Description: This function finds the next datacluster of the file specified with File *file.
//
//________________________________________________________________________________________________________________________________________
unsigned int GetNextCluster(File *file)
{
unsigned long fat_pointer = 0;
unsigned long fat_sector_offset = 0;
unsigned long ul_tmp = 0;
fat_sector_offset = ((file->cluster_pointer) - (FirstDataCluster)); // Calculate index of actual cluster in FAT.
fat_sector_offset /= SectorsPerCluster;
fat_sector_offset += 2; // In Fat16 clusterpositions have an offset of two.
fat_pointer = (fat_sector_offset%0x100); // Calculate the clusterposition in the fat
fat_sector_offset = (fat_sector_offset>>8); // and the sectoroffset in relation to the beginning of the fat.
mmc_read_sector((unsigned long)(FileAllocationTable + fat_sector_offset),&FileBuffer[0]);
file->sector_in_buffer = (FileAllocationTable + fat_sector_offset); // Mark that new sector has been read.
ul_tmp = (unsigned long)FileBuffer[((fat_pointer << 1)+1)]; // Read next sector information from calculated clusterposition.
ul_tmp = (ul_tmp << 8);
ul_tmp |= (unsigned long)FileBuffer[(fat_pointer << 1)];
ul_tmp -=2; // next datacluster is clusterposition in fat - 2.
ul_tmp *= SectorsPerCluster; // calculate sectorposition of new cluster
ul_tmp += FirstDataCluster; // in relation to first datacluster of the disk.
file->cluster_pointer = (unsigned long) ul_tmp; // continue reading the file at the beginning of new datacluster.
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: unsigned int FileReadSector(File *file);
//
// Description: This function reads cnt bytes into the FileBuffer. The number of databytes available in the buffer is returned.
//
//________________________________________________________________________________________________________________________________________
unsigned int FileReadSector(File *file)
{
unsigned int cnt = 0;
unsigned long temp1 = 0;
if(file->filesize > 0) // wen the end of the file is not reached, get the next character.
{
file->byte_index=0; // reading at the beginning of new sector.
if(file->sector_index >= SectorsPerCluster) // When end of cluster is reached, the next datacluster has to be searched in the FAT.
{
file->sector_index = 0; // start reading new cluster at first sector of the cluster.
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster.
}
temp1 = (unsigned long)file->cluster_pointer; // calculate the sector to be read.
temp1 += (unsigned long)file->sector_index;
mmc_read_sector((unsigned long)temp1,FileBuffer); // Read the volume bootrecord from mmc.
if(file->filesize > 511)
{
cnt = 512; // 512 bytes of data are available in the filebuffer.
file->filesize-=512; // decrement the number of available
}
else
{
cnt = file->filesize; // cnt databytes are available in the filebuffer.
file->filesize = 0; // end of file reached.
}
file->sector_index++; // continue reading in next sector
}
return(cnt);
}
//________________________________________________________________________________________________________________________________________
// Funtion: FileGetchar(File *file);
//
// Description: This function reads and returns one character from the specified file. Is the end of the actual sector reached the
// next sector of the cluster be read. Is the last sector of the cluster read the next cluster will be searched in FAT.
//________________________________________________________________________________________________________________________________________
int FileGetchar(File *file)
{
int c = EOF;
unsigned long temp1;
// is the sector in the buffer still up to date?
if(file->filesize > 0) // wen the end of the file is not reached, get the next character.
{
temp1 = (unsigned long)file->cluster_pointer;
temp1 += (unsigned long)file->sector_index;
if(file->sector_in_buffer != temp1)
{
mmc_read_sector((unsigned long)temp1,FileBuffer); // Read the volume bootrecord from mmc.
file->sector_in_buffer = (unsigned long)temp1;
}
c = FileBuffer[file->byte_index];
file->filesize--; // decrement the number of available
if(file->byte_index < 511) // continue reading from this sector until the end of the sector is reached.
{
file->byte_index++;
}
else
{
file->byte_index=0; // reading at the beginning of new sector.
file->sector_index++; // continue reading in next sector
if(file->sector_index >= SectorsPerCluster) // When end of cluster is reached, the next datacluster has to be searched in the FAT.
{
file->sector_index = 0; // start reading new cluster at first sector of the cluster.
GetNextCluster(file); // Sets the clusterpointer of the file to the next datacluster.
}
}
}
return(c);
}
//-------------------------------------------------
char FileGetString(char *text, File *file, unsigned char count)
{
int c='0';
unsigned char i = 0;
while ((c != EOF))
{ c = FileGetchar(file);
//printf("%02X ",c);
text[i++] = (unsigned char) c;
if (c == '\n') break;
if (i == count) break;
}
text[i-1] = '\0';
if (c == EOF) return (0); else return(1);
}
//________________________________________________________________________________________________________________________________________
// Funtion: unsigned int CreateFileInDirectory(unsigned char *, unsigned int)
//
// Description: This function looks for the next free position in the directory and creates a file with the specified filename and enters the
// pointer to the first datacluster.
//________________________________________________________________________________________________________________________________________
unsigned char CreateFileInDirectory(unsigned char *fname, unsigned int cluster, File *fpoint)
{
unsigned int rootentry = 0; // index to an entry in the rootdirectory.
unsigned int cnt_enries_searched = 0; // count the number of rootentries which have been searched already.
unsigned char i = 0;
unsigned int sector_offset = 0; // index to the sector of the Rootentry which is searched momentarily
unsigned char retvalue = 0;
// directory starts at sector specified by dir_sector. This can be the rootdirectory or any other directory.
// printf("CreateFileInDirectory:\n\r");
do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -