⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f34x_msd_file_system.c

📁 C8051F340读写SD卡的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// F34x_MSD_File_System.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// File contains the basic functions for file system commands.
//
//
//
// How To Test:    See Readme.txt
//
//
// FID:            34X000035
// Target:         C8051F34x
// Tool chain:     Keil
// Command Line:   See Readme.txt
// Project Name:   F34x_USB_MSD
//
// Release 1.1
//    -All changes by PKC
//    -09 JUN 2006
//    -No changes; incremented revision number to match project revision
//
// Release 1.0
//    -Initial Release
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include "F34x_MSD_Definitions.h"
#include "F34x_MSD_File_System.h"
#include "F34x_MSD_Sect_Serv.h"
#include "F34x_MSD_Util.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>

extern bootrecord_small xdata MBR;
void Print_File(FILE *file);

//-----------------------------------------------------------------------------
// file_name_match
//-----------------------------------------------------------------------------
//
// Return Value : 1 if they match
// Parameters   : filename - pointer to file name
//     			  direntryname - pointer to enterd directory name
//
// Compares the file name and directory name
//-----------------------------------------------------------------------------

static BYTE file_name_match(char* filename,char* direntryname)
{
  xdata BYTE i,j = filename[0];
  for(i=0;i<8;i++) {
    if(direntryname[i] == ' ' && (filename[i] == '\0' || filename[i] == '.')) 
	{
	  if(!(j == '.' && filename[i] == '.')) 
	      break;
	}
    if(tolower(direntryname[i])!=filename[i]) 
      return 0;
  }
  j = i+1;
  for(i = 8; i < 11; i++) {
    if( filename[j] == '\0' && direntryname[i] != ' ') 
      return 0;
    if( direntryname[i] == ' ' && (filename[j] == '\0' || filename[j] == '.' 
        || filename[j-1] == '\0'))
      break;
    if(tolower(direntryname[i]) != filename[j]) 
      return 0;
    j++;
  }
  return 1;
}


//-------------------------------------------------------------------------------
// Functions only for F340 device
//-------------------------------------------------------------------------------


#ifdef __F340_VER__

xdata unsigned char Path_Name[200];
xdata unsigned long Current_Dir_Block;
//xdata char current_dir_name[40];
static find_info xdata findinfo; // Shared find_info for fopen() and fdelete() 
static unsigned fat_chain_alloc(unsigned from,unsigned nr) ;
static unsigned long fat_chain(unsigned long from,unsigned nr) ;
static void fat_chain_free(unsigned from);

//-----------------------------------------------------------------------------
// write_current_dir
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function printout current directory name
//-----------------------------------------------------------------------------
void write_current_dir()
{
	printf("%s",Path_Name);
}


//-----------------------------------------------------------------------------
// GetClusterOfParentDirectory
//-----------------------------------------------------------------------------
//
// Return Value : cluster number
// Parameters   : None
//
// Function returns cluster number which begins current directory
//-----------------------------------------------------------------------------
static unsigned GetClusterOfParentDirectory()
{
	if(Current_Dir_Block == Sect_Root_Dir())  return 0;
	return (Current_Dir_Block - Sect_File_Data()) / MBR.sectors_per_cluster;
}

//-----------------------------------------------------------------------------
// Get_Cluster_From_Sector
//-----------------------------------------------------------------------------
//
// Return Value : cluster number
// Parameters   : sector - sector which belongs to returned cluster
//
// Function returns cluster number which contains sector
//-----------------------------------------------------------------------------
static unsigned Get_Cluster_From_Sector(unsigned long sector)
{
	if(sector < (Sect_File_Data() + 2*MBR.sectors_per_cluster)) return 0;
	return ((sector - Sect_File_Data()) / MBR.sectors_per_cluster);
}

//-----------------------------------------------------------------------------
// Get_First_Sector
//-----------------------------------------------------------------------------
//
// Return Value : sector address
// Parameters   : cluster - cluster number
//
// Function returns first sector which belongs to the cluster
//-----------------------------------------------------------------------------
static unsigned long Get_First_Sector(unsigned cluster)
{
	if(cluster >= 2) return Sect_File_Data() + cluster*MBR.sectors_per_cluster;
	else return Sect_Root_Dir();
}

//-----------------------------------------------------------------------------
// Get_First_Block_Of_Next_Cluster
//-----------------------------------------------------------------------------
//
// Return Value : first block of next cluster in chain or 0xFFFFFFFF if cluster 
//                is last in chain
//
// Parameters   : cluster - searching cluster 
//
// Function returns number of first sector in next cluster in cluster chain
//-----------------------------------------------------------------------------
static unsigned long Get_First_Block_Of_Next_Cluster(unsigned cluster)
{
	xdata unsigned long ret = fat_chain(cluster,MBR.sectors_per_cluster);
	if(ret != 0xFFFFFFFF)
		return ret + Sect_File_Data();
	return ret;
}

//-----------------------------------------------------------------------------
// Get_Next_Cluster
//-----------------------------------------------------------------------------
//
// Return Value : cluster number
// Parameters   : next cluster in chain
//
// Function returns number of next cluster in chain
//-----------------------------------------------------------------------------
static unsigned Get_Next_Cluster(unsigned cluster)
{
	unsigned* xdata fat_table=Scratch;

    Sect_Read(Sect_Fat1() + cluster/(Sect_Block_Size()/2));

    return ntohs(fat_table[cluster%(Sect_Block_Size()/2)]);
}

//-----------------------------------------------------------------------------
// Get_File_Name
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : file_name - name of file [out] (must be allocated outside
//                            this function)
//				      direntry_name - name used in direntry [in]
//
// Function gets file name from direntry
//-----------------------------------------------------------------------------
static void Get_File_Name(char* direntry_name,char* file_name)
{
	unsigned i,j = 0,k = 0;
	for(i=0;i<11;i++)
	{
		if(direntry_name[i] == ' ')
		{
			j = 1;
			continue;
		}
		if(j)
		{
			file_name[k++] = '.';
			j = 0;
		}
		file_name[k++] = tolower(direntry_name[i]);
	}
	file_name[k] = 0;
}

//-----------------------------------------------------------------------------
// Get_First_Block_Directory_Cluster
//-----------------------------------------------------------------------------
//
// Return Value : first sector of cluster which belongs to current directory 
//                fat chain
// Parameters   : sector - sector to check				
//
// Function returns first sector of cluster which contains sector if this
// cluster belongs to FAT chain of current directory
//-----------------------------------------------------------------------------
static unsigned long Get_First_Block_Directory_Cluster(unsigned long sector)
{
	xdata unsigned cluster = Get_Cluster_From_Sector(sector);
	xdata unsigned next_dir_cluster = GetClusterOfParentDirectory();
	while(next_dir_cluster != cluster)
	{
		next_dir_cluster = Get_Next_Cluster(next_dir_cluster);
		if(next_dir_cluster >= 0xfff8) return next_dir_cluster;
	}
	return Get_First_Sector(cluster);
}


//-----------------------------------------------------------------------------
// Clear_Cluster
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : cluster - cluster number				
//
// Function is used to clear all sectors of cluster
//-----------------------------------------------------------------------------
static void Clear_Cluster(unsigned cluster)
{
	xdata unsigned long sector = Get_First_Sector(cluster);
	xdata unsigned i;
	memset(Scratch,0,512);
	for(i=0;i<MBR.sectors_per_cluster;i++)
	{
		Sect_Write(sector+i);
	}

}

//-----------------------------------------------------------------------------
// FillDirEntry
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : direntry - dir entry
//				  dir_name - file/directory name							
//
// Function fills dir entry with file name
//-----------------------------------------------------------------------------
static void FillDirEntry(dir_entry* direntry,char* dir_name)
{
  xdata BYTE i;
  for( i = 0; i < 10; i++) 
    direntry->sfn.reserved[i] = 0;
  
  direntry->sfn.time.i = findinfo.direntry->sfn.date.i = 0;
  direntry->sfn.filesize = 0;

  // Fill in the filename
  for( i = 0; i < 11; i++ ) 
    direntry->sfn.name[i] = ' ';
 
  for( i = 0; i < 11; i++ ) {
    if(!dir_name[i])
	     break;
    direntry->sfn.name[i] = toupper(dir_name[i]);
  }
}

//-----------------------------------------------------------------------------
// FileSys_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None							
//
// Function initializes some data used to navigate over directories
//-----------------------------------------------------------------------------
void FileSys_Init()
{
	Current_Dir_Block = Sect_Root_Dir();
	strcpy(Path_Name,"\\");
}

//-----------------------------------------------------------------------------
// chngdir
//-----------------------------------------------------------------------------
//
// Return Value : 0 - if such directory not exists in current directory 1 
//                    otherwise
// Parameters   : dirname - directory name to create							
//
// Function tries to find and opens directory in current directory
//-----------------------------------------------------------------------------
BYTE chngdir(char* dirname)
{
  findfirst(&findinfo, 0);
  while(!file_name_match(dirname,findinfo.direntry->sfn.name)) {
    if(!findnext(&findinfo)) {
      return 0;
    }
  }
  if(findinfo.direntry->sfn.attrib & ATTRIB_SUBDIR) 
  {
  	if(findinfo.direntry->sfn.starting_cluster == 0x00)
		Current_Dir_Block = Sect_Root_Dir();
	else
	  	Current_Dir_Block = Sect_File_Data() + 
			(htons(findinfo.direntry->sfn.starting_cluster) * MBR.sectors_per_cluster);
	if(!strcmp(dirname,"."))	return 1;
	if(!strcmp(dirname,".."))
	{
		xdata unsigned char* next,*pos = strstr(Path_Name,"\\");

		while((next = strstr(pos,"\\")) != (NULL))
			pos = next+1;
		
		if(pos!=(Path_Name+1))
		pos--;
		
			*pos = '\0';
	}
	else
	{
		xdata unsigned len = strlen(Path_Name);
		if(Path_Name[len-1] != '\\')
		{	
			strcpy(&Path_Name[len],"\\");
			len++;
		}
		strcpy(&Path_Name[len],dirname);
	}
	return 1;	
  }
  return 0;
}

//-----------------------------------------------------------------------------
// mkdir
//-----------------------------------------------------------------------------
//
// Return Value : 0 if function succeeds other value if error occurs
// Parameters   : dir_name - directory name							
//
// Function creates directory 
//-----------------------------------------------------------------------------
BYTE mkdir(char* dir_name)
{
   
   xdata unsigned long dir_sectors;
   xdata dir_entry* entry;
   xdata unsigned start_cluster;
   unsigned max_len = strlen(dir_name);

   
  if((dir_name == NULL) || (max_len == 0) || (max_len > 8))
  {
	return DIRNAME_LENGTH_ERROR;
  }
  start_cluster = fat_chain_alloc(0,1);
  // try to find directory with such name
  findfirst(&findinfo, 0);
  while(findnext(&findinfo)) {
    if(file_name_match(dir_name,findinfo.direntry->sfn.name)) {
      return DIRECTORY_EXISTS;
    }
  }	
  if(!findfirst(&findinfo,1)) return NO_PLACE_FOR_DIRECTORY;;
  
   // Fill in the direntry
  FillDirEntry(findinfo.direntry,dir_name);

  findinfo.direntry->sfn.starting_cluster = htons(start_cluster);
  // Don't forget to set the attrib:
  findinfo.direntry->sfn.attrib = ATTRIB_SUBDIR;

	// Write the new data to MMC
  Sect_Write(findinfo.block);

  // Clear dir_entry of directory and create dot and dotdot directory inside
  Clear_Cluster(start_cluster);
  dir_sectors = Sect_File_Data() + (start_cluster * MBR.sectors_per_cluster);
  
  entry = (dir_entry*)Scratch;
  FillDirEntry(entry,".");

  entry->sfn.starting_cluster = htons(start_cluster);
  entry->sfn.attrib = ATTRIB_SUBDIR;

  entry = (dir_entry*)&Scratch[32];

  FillDirEntry(entry,"..");	

  entry->sfn.starting_cluster = htons(GetClusterOfParentDirectory());
  entry->sfn.attrib = ATTRIB_SUBDIR;


  Sect_Write(dir_sectors);
  return 0;
}

//-----------------------------------------------------------------------------
// rmdir
//-----------------------------------------------------------------------------
//
// Return Value : 1 if function suceeds other value if error occurs
// Parameters   : dir_name - directory name							
//
// Function removes directory 
//-----------------------------------------------------------------------------
BYTE rmdir(char* dir_name)
{
  unsigned dir_deep = 0;
  PREV_SEARCH prev_dir_block[40];
  char  first_part_of_dir[20];
  char  dir_tmp_name[20];
  char* tmp;
  
  // error if someone tries to removw root directory
  if(!strcmp(dir_name,"\\")) return 0;

  if((tmp = strstr(dir_name,"\\")) == NULL)
  {
  	strcpy(first_part_of_dir,dir_name);
  }
  else
  {
  	if(tmp == dir_name)
	{
		tmp = strstr(&dir_name[1],"\\");
		if(tmp != NULL)
			*tmp = 0;
		strcpy(first_part_of_dir,&dir_name[1]);
		if(tmp != NULL)
			*tmp = '\\';
	}
	else
	{
		*tmp = 0;
		strcpy(first_part_of_dir,dir_name);
		*tmp = '\\';
	}
  }

  if(!chngdir(dir_name)) return 0; 	
  if(!findfirst(&findinfo,0)) return 0;
  while(1)
  {
  	 if(findinfo.direntry->sfn.name[0]!=(char)0xE5)
	 {
	  	 if(!(findinfo.direntry->sfn.attrib & ATTRIB_LABEL))
		 {
			 if(findinfo.direntry->sfn.attrib & (ATTRIB_SUBDIR)) 
			 {
			 	if(!file_name_match(".",findinfo.direntry->sfn.name) && 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -