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

📄 file_system.c

📁 能够在单片机等小型处理器上使用的fat16文件系统
💻 C
📖 第 1 页 / 共 3 页
字号:
  for( i = 0; i < 10; i++) 
    findinfo->direntry->sfn.reserved[i] = 0;
  findinfo->direntry->sfn.time = findinfo->direntry->sfn.date = 0;
  if(direntry_num==1)
  {
		findinfo->direntry->sfn.starting_cluster = 2;
  }
  else if(direntry_num==2)
  {
	  pre_dir_entry=(dir_entry *)(Scratch);
	  start_cluster=pre_dir_entry->sfn.starting_cluster+pre_dir_entry->sfn.filesize/Sect_Cluster_Size()+1;//bytesper_cluster
	  findinfo->direntry->sfn.starting_cluster =start_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);

  //update fat 10-25
 memcpy(Scratch_temp,Scratch,512);
  if(direntry_num==1)
  { 
	  Sect_Read(Sect_Fat1());
	  sect_start=(unsigned short *)Scratch;
	  *(sect_start+0)=LSB_to_MSB(0xff8f);
      *(sect_start+1)=LSB_to_MSB(0xffff);
	  *(sect_start+2)=LSB_to_MSB(0xffff);
	  Sect_Write(Sect_Fat1());
  }
  else if(direntry_num==2)
  {
	  Sect_Read(Sect_Fat1()+start_cluster/256);
	  sect_start=(unsigned short *)Scratch;
	  *(sect_start+start_cluster%256)=LSB_to_MSB(0xffff);
	  Sect_Write(Sect_Fat1()+start_cluster/256);
  }
  memcpy(Scratch,Scratch_temp,512);
	return 1;
}



//-----------------------------------------------------------------------------
// m_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 m_fopen(M_FILE* f,char* filename,char* mode) 
{
	f->isopen = 0;

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


  m_fcreate(&findinfo, filename);

  f->sector_direntry=findinfo.block;
  f->offset_direntry=findinfo.offset;
  f->cluster_start=f->sector_current=
  (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;
}
int mm_fopen(M_FILE* f,char * filename,char * mode)
{
	int i=0;
	int j;
///////////////creat_file;
	int dir_offset;
	dir_entry * dir_entry_t;
	unsigned short * fat_list;
	int start_cluster;
	int last_start_cluster;
	int last_used_cluster;
	dir_entry * last_dir_entry;

	Sect_Read(0x100);

	for(i=0;i<16;i++)//max file num is 16
	{
		dir_entry_t = (dir_entry*)(Scratch+i*0x20);
		dir_offset=i*0x20;
		if(dir_entry_t->sfn.name[0]==0)
			break;
	}
	  // Fill in the filename
	  for( i = 0; i < 11; i++ ) 
		dir_entry_t->sfn.name[i] = ' ';
	  for( j = 0; j < 20; j++ ) {
		if(!filename[j] || filename[j] == '.') 
		  break;
		if( j < 8 ) 
		  dir_entry_t->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;
		  dir_entry_t->sfn.name[8+i] =toupper(filename[j+i+1]);
		}
	  }
	  //
	  dir_entry_t->sfn.attrib=ATTRIB_ARCHIVE;
	  dir_entry_t->sfn.filesize=0;
	  dir_entry_t->sfn.date=0;
	  dir_entry_t->sfn.time=0;
	  //find a free fat block
	  fat_list=(unsigned short *)(get_vfile_add()+Sect_Fat1()*512);
	  if(dir_offset==0)
	  {
		  start_cluster=2;
		  *(fat_list+0)=0xff8f;
		  *(fat_list+1)=0xffff;
	  }
	  else
	  {
			last_dir_entry=(dir_entry*)(Scratch+dir_offset-0x20);
			last_start_cluster=last_dir_entry->sfn.starting_cluster;
			last_used_cluster=(last_dir_entry->sfn.filesize/512+1);
			start_cluster=last_start_cluster+last_used_cluster;
	  }
	  *(fat_list+start_cluster)=0xffff;
	  dir_entry_t->sfn.starting_cluster=start_cluster;
	Sect_Write(0x100);
  ///////////open file
	f->attrib=ATTRIB_ARCHIVE;
	f->cluster_start=start_cluster;
	f->offset_direntry=dir_offset;
	f->pos=0;
	f->sector_direntry=0x100;
	f->sector_current=start_cluster;
	f->size=0;
	f->isopen=1;
	 

	//while(1);
	return 0;
}
//-----------------------------------------------------------------------------
// m_feof
//-----------------------------------------------------------------------------
//
// Return Value : End of file value
// Parameters   : f - pointer to file info structure
//
// This function printout size of file
//-----------------------------------------------------------------------------

int m_feof(M_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,ulong nr) 
{
  uint*  fat_table=(uint *)Scratch;
  uint  sect,sect_prev=0;
  ulong  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);
    }

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

    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(ulong from) 
{
  uint*  fat_table=(uint *)Scratch;
  uint  sect,sect_prev=0;
  ulong  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 ulong fat_chain_alloc(ulong from,ulong nr) 
{
  uint*  fat_table=(uint *)Scratch;
  uint  sect,sect_prev=0;
  ulong  index;
  ulong  alloced=0xFFFF;

	// Find free FAT entries, allocate them, and link them together.
  for(sect=Sect_Fat1();nr && sect<Sect_Fat2();sect++) {
    Sect_Read(sect);
		// (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;
      }
    }
    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;
}

//-----------------------------------------------------------------------------
// m_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
//-----------------------------------------------------------------------------

ulong m_fread(M_FILE* f,BYTE* buffer,ulong count) 
{
  ulong  cnt,total_cnt=0;
  if(!f->isopen || !count) return 0;

  // If you use the Scratch buffer as m_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.

⌨️ 快捷键说明

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