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

📄 f34x_msd_file_system.c

📁 有关单片机的学习文档
💻 C
📖 第 1 页 / 共 3 页
字号:
				findfirst(&findinfo,0);
				dir_deep++;
				}
			 }
			 else
			 {
			  	  // Mark the direntry as "deleted" before freeing the fat chain.
				  // At this point, the findinfo is still valid in the 'Scratch'
              // buffer.
				  // fat_chain_free() would overwrite the Scratch buffer.
				  findinfo.direntry->sfn.name[0]=0xE5; // Mark as "deleted"
			  	  Sect_Write(findinfo.block);
				  fat_chain_free(ntohs(findinfo.direntry->sfn.starting_cluster));
				  Sect_Read(findinfo.block);
			  }
		  }
	  }
	  if(!findnext(&findinfo))
	  {
	  	if(dir_deep)
		{
			dir_deep--;
			chngdir("..");
			findinfo.block = prev_dir_block[dir_deep].block;
			findinfo.offset = prev_dir_block[dir_deep].offset ;
			Sect_Read(findinfo.block);
			findinfo.direntry=(dir_entry*)(Scratch+findinfo.offset);
 		    findinfo.direntry->sfn.name[0]=0xE5; // Mark as "deleted"
		  	Sect_Write(findinfo.block);
			fat_chain_free(ntohs(findinfo.direntry->sfn.starting_cluster));
			Sect_Read(findinfo.block);
			findinfo.direntry=(dir_entry*)(Scratch+findinfo.offset);
		} else
		{
			chngdir("..");
			break;
		}
	  }
  }
  findfirst(&findinfo,0);
  while(!file_name_match(first_part_of_dir,findinfo.direntry->sfn.name)) {
    if(!findnext(&findinfo)) {
      return 0;
    }
  }
  findinfo.direntry->sfn.name[0]=0xE5; // Mark as "deleted"
  Sect_Write(findinfo.block);
  fat_chain_free(ntohs(findinfo.direntry->sfn.starting_cluster));
  return 1;
}


//-----------------------------------------------------------------------------
// fcreate
//-----------------------------------------------------------------------------
//
// Return Value : If ok returns TRUE
// Parameters   : find_info - pointer to info about file
//				  filename  - pointer to file name
//
// This function creates file
//-----------------------------------------------------------------------------

static BYTE fcreate(find_info* findinfo,char* filename)
{
  xdata BYTE i,j;
  // Find the first empty directory entry
  if(!findfirst(findinfo,1)) return 0;

  // Fill in the direntry
  for( i = 0; i < 10; i++)
    findinfo->direntry->sfn.reserved[i] = 0;
  findinfo->direntry->sfn.time.i = findinfo->direntry->sfn.date.i = 0;
  findinfo->direntry->sfn.starting_cluster =
  findinfo->direntry->sfn.filesize = 0;

  // Fill in the filename
  for( i = 0; i < 11; i++ )
    findinfo->direntry->sfn.name[i] = ' ';
  for( j = 0; j < 20; j++ ) {
    if(!filename[j] || filename[j] == '.')
      break;
    if( j < 8 )
      findinfo->direntry->sfn.name[j] = toupper(filename[j]);
  }
  if( filename[j] == '.' ) {
    for( i = 0; i < 3; i++ ) {
      if(!filename[j+i+1] || filename[j+i+1]=='.')
        break;
      findinfo->direntry->sfn.name[8+i] = toupper(filename[j+i+1]);
    }
  }
  //for(i=0;i<11;i++) findinfo->direntry->sfn.name[i]=
  //toupper(findinfo->direntry->sfn.name[i]);

  // Don't forget to set the attrib:
  findinfo->direntry->sfn.attrib = ATTRIB_ARCHIVE;
	// Write the new data to MMC
  Sect_Write(findinfo->block);

	return 1;
}



//-----------------------------------------------------------------------------
// fopen
//-----------------------------------------------------------------------------
//
// Return Value : TRUE if file is open
// Parameters   : f - pointer to file structure info
//  			  filename - pointer to file name
//				  mode - pointer to opened file mode (read, write etc.)
//
// This function opens file
//-----------------------------------------------------------------------------

int fopen(FILE* f,char* filename,char* mode)
{
	f->isopen = 0;

	if( mode[0] == 'w' ) {
    fdelete(filename);
  } // This is the most memory-efficient solution, not the most
    // time-efficient solution.

  findfirst(&findinfo, 0);
  while(!file_name_match(filename,findinfo.direntry->sfn.name)) {
    if(!findnext(&findinfo)) {
      if(mode[0] == 'r') {
        return 0; // File not found.
      }
      if( mode[0] == 'w' || mode[0] == 'a' ) {
        if(!fcreate(&findinfo, filename)) {
          return 0; // File cannot be created.
        } else {
          break;
        }
      }
    }
  }

  f->sector_direntry=findinfo.block;
  f->offset_direntry=findinfo.offset;
  f->cluster_start=f->sector_current=
  ntohs(findinfo.direntry->sfn.starting_cluster);//*MBR.sectors_per_cluster;
  f->attrib=findinfo.direntry->sfn.attrib;
  f->size=ntohl(findinfo.direntry->sfn.filesize);

  if(mode[0]=='a') f->pos=f->size; else f->pos=0;
//	Print_File(f);
  return 	f->isopen=1;
}

//-----------------------------------------------------------------------------
// feof
//-----------------------------------------------------------------------------
//
// Return Value : End of file value
// Parameters   : f - pointer to file info structure
//
// This function printout size of file
//-----------------------------------------------------------------------------

int feof(FILE* f)
{
  if(!f->isopen) return 1;
  return f->pos >= f->size;
}

//-----------------------------------------------------------------------------
// fat_chain
//-----------------------------------------------------------------------------
//
// Return Value : global number of sector
// Parameters   : from - starting number of sector
//				  nr - relative number of sector
//
// Find the 'nr'-th sector in the fat chain starting at 'from'
//-----------------------------------------------------------------------------

static unsigned long fat_chain(unsigned long from,unsigned nr)
{
  unsigned* xdata fat_table=Scratch;
  unsigned xdata sect,sect_prev=0;
  unsigned xdata cluster;
  unsigned long temp_from;

  cluster = nr/MBR.sectors_per_cluster;

  while(cluster) {
    sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
    if(sect!=sect_prev) {
      Sect_Read(sect_prev=sect);
    }

    temp_from = ntohs(fat_table[from%(Sect_Block_Size()/2)]);

    if (temp_from == 0xFFFF)
    {
      break;
    }

    from=temp_from;

    if(!(from>=2 && from<=0xFFEF)) {
      return 0xFFFFFFFF;
    }

    cluster--;
  }

  from *= MBR.sectors_per_cluster;
  from += nr%MBR.sectors_per_cluster;
  return from;
}

//-----------------------------------------------------------------------------
// fat_chain_free
//-----------------------------------------------------------------------------
//
// Return Value :
// Parameters   : from - starting number of sector
//
// Function frees an entire fat chain, starting at 'from' until the end of the chain
//-----------------------------------------------------------------------------

static void fat_chain_free(unsigned from)
{
  unsigned* xdata fat_table=Scratch;
  unsigned xdata sect,sect_prev=0;
  unsigned xdata index;

  if(from<2) return;

  sect = Sect_Fat1() + from/(Sect_Block_Size()/2);

  while(1) {
    if(sect!=sect_prev) {
      Sect_Read(sect_prev=sect);
    }

    index = from%(Sect_Block_Size()/2);

    from=ntohs(fat_table[index]);

    fat_table[index]=0x0000; // Free it

    if(!(from>=2 && from<=0xFFEF)) {
      Sect_Write_Multi_Fat(sect_prev);
      break;
    }

    sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
    if(sect!=sect_prev) {
      Sect_Write_Multi_Fat(sect_prev);
    }
  }
}


//-----------------------------------------------------------------------------
// fat_chain_alloc
//-----------------------------------------------------------------------------
//
// Return Value : numer of allocated sector
// Parameters   : from - starting number of sector
//				  nr - relative number of sector
//
// Allocate 'nr' of extra FAT blocks at the end of the chain that starts at 'from'
//-----------------------------------------------------------------------------

static unsigned fat_chain_alloc(unsigned from,unsigned nr)
{
  unsigned* xdata fat_table=Scratch;
  unsigned xdata sect,sect_prev=0;
  unsigned xdata index;
  unsigned xdata alloced=0xFFFF;
  unsigned xdata sectcount;


   // Code added by Parker Dorris onn 10/4/2007
   // The following counter allows the for loops below
   // to determine when the last sector of the FAT table
   // has been reached
   sectcount = MBR.sectors_per_fat;

	// Find free FAT entries, allocate them, and link them together.
  for(sect=Sect_Fat1();nr && sect<Sect_Fat2();sect++) {
    Sect_Read(sect);


    if(--sectcount) // if this isn't the last sector of FAT
    {
     	 // (Skip first two FAT entries when looking for free blocks)
       for(index=((sect==Sect_Fat1())?2:0);index<Sect_Block_Size()/2;index++)
       {
         if(fat_table[index]==0x0000) { 		// It's free
           fat_table[index]=ntohs(alloced);// Allocate it (refer to previously
                                           //   alloc'ed FAT entry).
           alloced = 						// Remember which FAT entry was alloc'ed
             (sect-Sect_Fat1()) * (Sect_Block_Size()/2) + index;
           if(!--nr) break;
         }
       }
    }
    else // Last entry in FAT table, need to use different index termination value
    {
     	 // (Skip first two FAT entries when looking for free blocks)
       for(index=((sect==Sect_Fat1())?2:0);index<MBR.index_of_last_cluster;index++)
       {
         if(fat_table[index]==0x0000) { 		// It's free
           fat_table[index]=ntohs(alloced);// Allocate it (refer to previously
                                           //   alloc'ed FAT entry).
           alloced = 						// Remember which FAT entry was alloc'ed
             (sect-Sect_Fat1()) * (Sect_Block_Size()/2) + index;
           if(!--nr) break;
         }
       }
    }
    if(alloced!=0xFFFF) Sect_Write_Multi_Fat(sect);	// Write all FAT copies
  }

  // When we get here, 'alloced' contains the first FAT block in the alloc'ed chain
  // Find the end of the current FAT chain.
  // Make the end of the current FAT chain refer to the newly allocated FAT chain
  while(from>=2 && from<=0xFFEF && alloced!=0xFFFF) {
    sect = Sect_Fat1() + from/(Sect_Block_Size()/2);
    if(sect!=sect_prev) {
      Sect_Read(sect_prev=sect);
    }
    index = from%(Sect_Block_Size()/2);
    from=ntohs(fat_table[index]);

    if(from>=0xFFF8) {
      fat_table[index]=ntohs(alloced);
      Sect_Write_Multi_Fat(sect);
    }
  }

  return alloced;
}

//-----------------------------------------------------------------------------
// fread
//-----------------------------------------------------------------------------
//
// Return Value : amount of read bytes
// Parameters   : f - pointer to file structure
//				  buffer - pinter to buffer
//				  count - number of bytes to read
//
// This function reads the file
//-----------------------------------------------------------------------------

unsigned fread(FILE* f,BYTE* buffer,unsigned count)
{
  unsigned xdata cnt,total_cnt=0;
  if(!f->isopen || !count) return 0;

  // If you use the Scratch buffer as fread buffer, then
  // we cannot possibly support transfers consisting of
  // multiple Sect_Read() operations. The second Sect_Read
  // would overwrite the stored bytes from the first one.
  if(buffer>=Scratch && buffer<Scratch+Sect_Block_Size())
    count=min(count,Sect_Block_Size()-f->pos%Sect_Block_Size());

  while(count && !feof(f)) {
    f->sector_current = fat_chain(f->cluster_start,f->pos/Sect_Block_Size());

    Sect_Read(Sect_File_Data() + f->sector_current);

    cnt=min(Sect_Block_Size()-f->pos%Sect_Block_Size(),count);
    cnt=min(cnt,f->size-f->pos);

    memmove(buffer,Scratch+f->pos%Sect_Block_Size(),cnt); // MUST be overlap-safe
                                                          // copy operation!
    total_cnt+=cnt;
    f->pos+=cnt;
    count-=cnt;
    buffer+=cnt;
  }

  return total_cnt;
}

//-----------------------------------------------------------------------------
// fwrite
//-----------------------------------------------------------------------------
//
// Return Value : amount of written bytes
// Parameters   : f - pointer to file structure
//				  buffer - pinter to buffer
//				  count - number of bytes to write
//
// This function writes the file
//-----------------------------------------------------------------------------

unsigned fwrite(FILE* f,BYTE* buffer,unsigned count)
{
  xdata unsigned cnt,total_cnt=0,xtra,alloced;
  xdata dir_entry* entry;

  if(!f->isopen || !count) return 0;

  // First, extend the file so it can hold all the data:
  if(f->pos+count>f->size) {
    // If the new EOF ends up in the next FAT block, an extra block must be allocated.
    // The number of blocks needed to store X bytes = 1+(X-1)/512 if X!=0, or =0 if X==0.
    // We will need to store 'pos+count' bytes after the write operation
    // This means we need 1+(pos+count-1)/512 blocks after the write operation
    // We currently have 'size' bytes in the file, or 1+(size-1)/512 blocks (or 0 if size==0).
    // So, we need to allocate (1+(pos+count-1)/512) - (1+(size-1)/512) extra blocks
    xtra=(1+((f->pos+count-1)/Sect_Block_Size())/MBR.sectors_per_cluster);
    if ( f->size )
      xtra -= ( 1 +(( f->size - 1 ) / Sect_Block_Size() ) / MBR.sectors_per_cluster );


    if(xtra) {

      f->sector_current = fat_chain(f->cluster_start,f->pos/Sect_Block_Size());

      if(0xFFFF==(alloced=fat_chain_alloc(f->sector_current/MBR.sectors_per_cluster,xtra)))
        return 0;
    }

		// Modify the direntry for this file:
    Sect_Read(f->sector_direntry);
    entry = (dir_entry*)(Scratch+f->offset_direntry);
    if((entry->sfn.filesize==0) && (entry->sfn.starting_cluster<2 ||
                                entry->sfn.starting_cluster>=0xFFF0)) {
      entry->sfn.starting_cluster=ntohs(f->cluster_start=alloced);
    }
    entry->sfn.filesize=ntohl(f->size=f->pos+count);
    f->attrib=(entry->sfn.attrib|=ATTRIB_ARCHIVE);
    Sect_Write(f->sector_direntry);
  }

  // Now we are sure the fwrite() operation can be performed
  // in the existing file data blocks. Either because the file
  // was big enough to start with, or because we have just
  // allocated extra blocks for the new data.
  while(count && !feof(f)) {
    f->sector_current = fat_chain(f->cluster_start,f->pos/Sect_Block_Size());


    Sect_Read(Sect_File_Data() + f->sector_current);
  //	Print_File(f);
  //	print_scratch();

    cnt=min(Sect_Block_Size()-f->pos%Sect_Block_Size(),count);
    cnt=min(cnt,f->size-f->pos);

    memmove(Scratch+f->pos%Sect_Block_Size(),buffer,cnt);

  //	print_scratch();
    Sect_Write(Sect_File_Data() + f->sector_current);

    total_cnt+=cnt;
    f->pos+=cnt;
    count-=cnt;
    buffer+=cnt;
  }

  return total_cnt;
}

//-----------------------------------------------------------------------------
// fclose
//-----------------------------------------------------------------------------
//
// Return Value :
// Parameters   : f - pointer to file structure

//
// This function closes the file
//-----------------------------------------------------------------------------

void fclose(FILE* f)
{
  f->isopen=0;
}

//-----------------------------------------------------------------------------
// fdelete
//-----------------------------------------------------------------------------
//
// Return Value :TRUE if everything is ok
// Parameters   : name - pointer to filename
//
//
// This function deletes the file
//-----------------------------------------------------------------------------

int fdelete(char* name)
{
  findfirst(&findinfo,0);
  while(!file_name_match(name,findinfo.direntry->sfn.name)) {
    if(!findnext(&findinfo)) {
      return 0;
    }
  }

  // Do not delete subdirectories or labels:

⌨️ 快捷键说明

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