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

📄 fat_file.c

📁 fat16文件系统源码。需要的请下
💻 C
📖 第 1 页 / 共 3 页
字号:
		    fat_dchain_nb_clust++;                /* one more cluster read */
		}
		//fat_dir_current_sect = fat_ptr_data + ((Uint32)(next_cluster) * fat_cluster_size);
		//phy_read_open(fat_dir_current_sect);
  	}
    fat_dclust_byte_count += fat_sector_size;                  /* one more byte read */
    phy_read_sector();
}

/*F**************************************************************************
* NAME: fat_dir_seek
*----------------------------------------------------------------------------
* PARAMS:
*   offset: offset to current position in signed word value
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Seek from the current position to a new offset computing relative 
*   poisition +/- scan size limited to a 16 bit offset
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   We consider here that the seek size is minor to the cluster size !!!
*   if you want to do a more than a cluster seek, issue two successive 
*   dseek commands
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/ 
Byte fat_dir_seek (Uint32 offset)
{
	Uint16   nb_sect;                     /* number of sectors to seek */
	Uint32   next_cluster;                /* the possible next cluster to load */
	Uint16   target_cluster;              /* the cluster to reach */
	Uint16   i;

//  	fat_dir_current_offs = 0;
  	fat_dir_current_offs = offset;     /* Calculate the absolute byte pos */
  	nb_sect = (Uint16)((fat_dir_current_offs) / fat_sector_size);
	if(fat_type_id != FAT_IS_32)
  		fat_dir_current_sect = fat_ptr_rdir + nb_sect;
  	fat_dir_sector_offset = fat_dir_current_offs % (((Uint32)fat_sector_size) * fat_cluster_size);
  	fat_dclust_byte_count = fat_dir_sector_offset; //offset in a cluster 
  	fat_dir_sector_offset %= fat_sector_size;                   

  	if ((dir_is_root == FALSE) || (fat_type_id == FAT_IS_32))                 // Sub-directory   /
  	{  
	  	// Find the # cluster 
     	target_cluster = (nb_sect / fat_cluster_size);
     	fat_dchain_index = 0;
		if(fat_type_id == FAT_IS_32)
     		next_cluster = dclusters[fat_dchain_index].cluster.l;
	 	else
			next_cluster = dclusters[fat_dchain_index].cluster.w[0]; ///////w[1]//////////////////////

     	fat_dchain_nb_clust = 1;
    	for (i = 0; i < target_cluster; i++)
    	{
      		if (dclusters[fat_dchain_index].number <= fat_dchain_nb_clust)
        	{ // new fragment 
          		fat_dchain_index++;
          		fat_dchain_nb_clust = 1;
          		if(fat_type_id == FAT_IS_32)
     	      		next_cluster = dclusters[fat_dchain_index].cluster.l;
	      		else
		      		next_cluster = dclusters[fat_dchain_index].cluster.w[0];///////w[1]//////////////////////
        	}
       		else
        	{ // not new fragment 
          		//next_cluster = dclusters[fat_dchain_index].cluster + fat_dchain_nb_clust;
		  		if(fat_type_id == FAT_IS_32)
     	      		next_cluster = dclusters[fat_dchain_index].cluster.l;
	      		else
		      		next_cluster = dclusters[fat_dchain_index].cluster.w[0];///////w[1]//////////////////////
          
				next_cluster += fat_dchain_nb_clust;
          		fat_dchain_nb_clust++;
        	}
    	}

    	fat_dir_current_sect = (((Uint32)(next_cluster) * fat_cluster_size)
                           + fat_ptr_data + (nb_sect % fat_cluster_size));
  	}
  
    phy_read_open(fat_dir_current_sect);
    return OK;  
}
/*F**************************************************************************
* NAME: fat_get_dir
*----------------------------------------------------------------------------
* PARAMS:
*   id: file extension or directory to select
*
* return:
*   - OK: file available
*   - KO: no requested file found
*   - KO: low_level memory error
*----------------------------------------------------------------------------
* PURPOSE:
*   Select first available file/dir in current diretory
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   Fill all the cache information for the first time
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte fat_get_dir(Uint32 id)
{
	/* select first dir entry */
  	fat_dclust_byte_count = 0;
  	fat_dir_sector_offset = 0;
 	fat_global_id = id;

  	fat_scan_dir(TRUE);

  	if(((id & FILE_DIR) == FILE_DIR)&&(dir_is_root == FALSE))
 	{
    	if(fat_dir_list_last <= 2)
        	return KO;
	 	fat_dir_list_index = 1;                 /* point ".." entry */
	 	if (fat_dir_seek(DIR_SIZE) == OK)
	 	{
  	     	fat_get_dir_entry(&fat_cache.parent); /* update parent dir info */
	     	return fat_goto_next();               /* update first file info */
	 	}
		else
		{
	     	return KO;/* low level error */
		}                            
 	}
 	else
 	{
    	if(fat_dir_list_last == 0)
        	return KO;
    	fat_dir_list_index = 0;                   /* point on first root entry */
    	fat_scan_dir(FALSE);
    	/* extract info from table */
    	if (fat_dir_seek(((Uint32)fat_dir_all_count) * DIR_SIZE) == OK)
    	{
      		fat_get_dir_entry(&fat_cache.current);  /* update current file info */
	   	 	if(dir_is_root == TRUE)
	   		{
	         	/* parent dir is also root */
	          	fat_cache.parent.start_cluster.l = 0;   
	          	fat_cache.parent.attributes = ATTR_ROOT_DIR;  /* mark as root dir */
	   		}
			return OK;
    	}
 	}  
 	return KO;                              /* low level error */
}

/*F**************************************************************************
* NAME: fat_scan_dir
*----------------------------------------------------------------------------
* PARAMS:
*   id: file extension to select
* return: none
*----------------------------------------------------------------------------
* PURPOSE:
*   Construct the file directory list
*----------------------------------------------------------------------------
* NOTE:
*   The value are relative position with the previous file.
*   Call to this function assume that the dir fragment chain has been created
*----------------------------------------------------------------------------
* REQUIREMENTS:
*   Maximum of 256 entries between 2 authorized file (id extension)
*   because the relative position is stored on one byte.
*   To allow more than 256 entries (-> 32768), change type of
*   fat_dir_entry_list[] from Byte to Uint16 (no overflow management)
*   and change MAX_DIRECTORY_GAP_FILE from 255 to 32767
*****************************************************************************/
void fat_scan_dir(Byte flag)
{
	Uint16 counter_entry;                       /* entry counter: 0..MAX_DIRECTORY_FILE */
	//data Uint16 entry_pos;                    /* relative entry position */
	//data Uint16 entry_pos_saved;              /* used when the file is not the id extension */
 	Byte   i;
 	Uint16 num=0;
 	Uint16 nb_cluster;
 	Uint16 counter_dir;
 	Byte ready;
	// bit del_exist;
 	Uint16 j;
 	Uint16 dir_count;
 	Uint16 dir_offset;
	
	// del_exist = 0;
	//  index = 0;
  	ready = 0;
  	counter_entry = 0;
  	dir_count = 0;
		
	if((dir_is_root == TRUE) && (fat_type_id != FAT_IS_32))
	{
	    phy_read_open(fat_ptr_rdir);
	    counter_dir = fat_root_entries;
	}
	else
	{
		nb_cluster = 0;
		fat_dclust_byte_count = 0;
		fat_dchain_nb_clust = 0;
		fat_dchain_index = 0;
	    for(i=0;i<MAX_DIR_FRAGMENT_NUMBER;i++)
		{
			if(dclusters[i].number == 0)
			{
				nb_cluster++;
			   	break;
			}
			else
			{
			   	nb_cluster = nb_cluster + dclusters[i].number;
			}
		}
		counter_dir = ((Uint32)nb_cluster * fat_cluster_size * fat_sector_size) / 32;
	}

   	do /* scan all entries */
   	{
	    if ((dir_is_root == TRUE) && (fat_type_id != FAT_IS_32))
	    { 
			if(num%fat_sector_size==0)
			{
				phy_read_sector();
				num=0;
			}	
		}
	    else
	    { /* subdir can be fragmented -> dgetc() */
			if(num % fat_sector_size == 0 )
			{
		         fat_dgetsector();
				 num=0;
			}
	    } 
  		j = num;
		num += DIR_SIZE;
		
		if((gl_buffer[0+j] != FILE_DELETED) && (gl_buffer[0+j] != FILE_NOT_EXIST))
		{	
			dir_count++;
//			index++;
            dir_offset = counter_entry;
			while (gl_buffer[11+j] == ATTR_LFN_ENTRY) /* LFN entry ?                  */
		    {	                                       /* then read all the LFN entry  */
		        if (dir_is_root == TRUE)
		        { /* root dir is linear */
					if(num%fat_sector_size==0)
					{
						phy_read_sector();
						num = 0;
					}
		        }
		        else
		        { /* subdir can be fragmented -> dgetc() */
					if(num % fat_sector_size == 0 )
					{
				        fat_dgetsector();
						num=0;
					}
		        }
				j=num;
		        num += DIR_SIZE;
				counter_entry++;
            }
			/* filter on the file type */
			fat_cache.current.attributes = gl_buffer[11+j];
			ext[0] = gl_buffer[8+j];
			ext[1] = gl_buffer[9+j];
			ext[2] = gl_buffer[10+j];

			if ((fat_check_ext() & fat_global_id) == FILE_XXX)
			{                                     /* Don't valid the entry */
			    dir_count--;                                              			          
			}
		      
			if((flag == 0)&&(ready == 0))
			{
			   	if(dir_count == (fat_dir_list_index + 1))
				{
					fat_dir_all_count = dir_offset;//counter_entry;
 					ready = 1;
				}
			}
		}
	    counter_entry++;
				
		if ((gl_buffer[0+j] == FILE_NOT_EXIST) || (counter_dir == counter_entry)) 
			break;

	}while(1);

	fat_dir_list_last = dir_count;
	if(flag == 1)
	{
		fat_dir_all_count = counter_entry;
			
		if(gl_buffer[0+j] == FILE_NOT_EXIST)
	        fat_dir_all_count--;

		if(fat_dir_list_last == 0)
	      fat_no_file = 1;
	    else
	      fat_no_file = 0; 
	}
  	phy_read_close();						
}


/*F**************************************************************************
* NAME: fat_check_ext
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
*   Return the type of the file
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint32 fat_check_ext (void)
{
//  char ext_bak[3];
   if ((fat_cache.current.attributes & ATTR_DIRECTORY) == ATTR_DIRECTORY)
   {
      return FILE_DIR;
   }

   if ((ext[0] == 'M') &&
       (ext[1] == 'P') &&
       (ext[2] == '3'))
   {
      return FILE_MP3;
   }
  

   if(((ext[0] == 'W')&&
       (ext[1] == 'M')&& 
	   (ext[2] == 'A'))||
      ((ext[0] == 'A')&&
      (ext[1] == 'S')&& 
	  (ext[2] == 'F'))||
	  ((ext[0] == 'W')&&
      (ext[1] == 'M')&& 
	  (ext[2] == 'V')))
	  
   {
       return FILE_WMA;
   }

   if((ext[0] == 'W')&&
      (ext[1] == 'A')&& 
      (ext[2] == 'V'))
   {
   		return FILE_WAV;
   }  


    if ((ext[0] == 'M') &&
        (ext[1] == 'I') &&
        (ext[2] == 'D'))
    {
      return FILE_MID;
    }

	if ((ext[0] == 'A') &&
        (ext[1] == 'A') &&
        (ext[2] == 'C'))
    {
      return FILE_AAC;
    }


	if ((ext[0] == 'O') &&
        (ext[1] == 'G') &&
        (ext[2] == 'G'))
    {
      return FILE_OGG;
    }

    return FILE_XXX;
}



void fat_count_sector(void)
{
	if(fat_buf_count == fat_sector_size)
	{
		fat_buf_count=0;
	    phy_read_sector(); 
	}
}

/*F**************************************************************************
* NAME: fat_get_clusters
*----------------------------------------------------------------------------
* PARAMS:
*   chain:   allocation list address
*   nb_frag: maximum number of fragment 
*
* return:
*   - OK: allocation done
*   - KO: allocation done but truncated: file too much fragmented
*----------------------------------------------------------------------------
* PURPOSE:
*   Prepare a list of the file clusters:
*     chain[n].cluster contains the starting cluster number of a fragment
*     chain[n].number contains the number of contiguous clusters in fragment
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   File cluster list is limited by the nb_frag parameter.
*   If memory is too much fragmented, file may not be fully played.
*   Last list item always has single cluster
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
#if COMPILE_FAT_16 == TRUE
byte fat16_get_clusters (fat_st_clust_chain  *chain, Byte nb_frag)
{
	Byte   index; 
	/* index in chain */
	Uint16 new_cluster;
	Uint16 old_cluster;
	nb_frag = nb_frag - 1;                    /* set limit (index start at 0) */

  	/* build the first entry of the allocation list */
  	chain[0].number = 1;
  	chain[0].cluster.l = fat_cache.current.start_cluster.l - 2; /* 2 = 1st cluster */
  	old_cluster = fat_cache.current.start_cluster.l;
  	index = 0;

   	fat_buf_count = (old_cluster % (fat_sector_size >> 1)) << 1;
	phy_read_open(fat_ptr_fats + (old_cluster / (fat_sector_size >> 1)));
	/* read first entry */
	phy_read_sector();

	//((Byte*)&new_cluster)[1] = gl_buffer[fat_buf_count];
	//((Byte*)&new_cluster)[0] = gl_buffer[fat_buf_count + 1];
	
    new_cluster = fat_U8_to_U16_LH(gl_buffer[fat_buf_count], gl_buffer[fat_buf_count + 1]);

	while (new_cluster != LAST_CLUSTER16)   /* loop until last cluster found */
	{
  		if ((new_cluster == (old_cluster + 1)) && (chain[index].number != MAX_CL_PER_FRAG))
  		{ /* contiguous cluster up to 255 */
	        chain[index].number++;
			fat_buf_count = fat_buf_count + 2;
			fat_count_sector();
  		}
  		else
  		{ /* compute fragmentation */
	        index++;
	        chain[index].number = 1;
	        chain[index].cluster.w[0] = new_cluster - 2;  /* 2 = 1st cluster */  ///////w[1]//////////////////////

	        fat_buf_count=(new_cluster % (fat_sector_size >> 1)) << 1;
			phy_read_close();  
		    phy_read_open(fat_ptr_fats + (new_cluster / (fat_sector_size >> 1)));
		    phy_read_sector();      
  		}

⌨️ 快捷键说明

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