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

📄 fat_misc.c

📁 s3c2410开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "fs_fat.h"
#include "fs_clib.h"
#include "lbl.h"
#include "sdi.h"


#define FS_MEMBLOCK_NUM  (FS_MAXOPEN+FS_DIR_MAXOPEN)*2

typedef    struct{
 
      U8 status;
      U8 memory[FAT_SEC_SIZE];
}_FS_FAT_block_type;

static  _FS_FAT_block_type  _FS_memblock[FS_MEMBLOCK_NUM];

void    FS__fat_block_init(void)
{
        U32 i;
        for(i=0;i<FS_MEMBLOCK_NUM;i++)
        {
        	_FS_memblock[i].status=0;
        }
}

U8      *FS__fat_malloc(U32 Size)
{
		U32 i;
		if(Size<=FAT_SEC_SIZE)
		{
			for(i=0;i<FS_MEMBLOCK_NUM;i++)
			{
				if(_FS_memblock[i].status==0)
				{
					_FS_memblock[i].status=1;
					FS__CLIB_memset((void *)_FS_memblock[i].memory,0,(U32)FAT_SEC_SIZE);
					return (_FS_memblock[i].memory);
				}
			}
		}
		return (U8 *)BUFFER_ERR;
}

void    FS__fat_free(void *pBuffer)
{
		U32 i;
		for(i=0;i<FS_MEMBLOCK_NUM;i++)
		{
			if(((void *)_FS_memblock[i].memory)==pBuffer)
			{
				_FS_memblock[i].status=0;
			}
		}
}

static S32 _FS_ReadBPB(void) {
  U8 *buffer;
  buffer = FS__fat_malloc(FAT_SEC_SIZE);
  if ((S32)BUFFER_ERR==(S32)buffer) {
    return BUFFER_ERR;
  }
 
	if(FS__lb_read(FS__pDevInfo[0].harddisk_driver,0,0,(void *)buffer)!=SD_NO_ERR)
  	{
  	   FS__fat_free(buffer);
  	   return FS_ERR;
  	}
  		    

  if((buffer[FAT_SEC_SIZE-2]+ 256 * buffer[FAT_SEC_SIZE-1])!=0xaa55)
  {
      FS__fat_free(buffer);
      return BPB_ERR;
  }
  if(buffer[0]!=0xeb)
  {
        FS__pDiskInfo[0].StartSec=((buffer[0x01c9]<<24)+(buffer[0x01c8]<<16)+(buffer[0x01c7]<<8)+buffer[0x01c6]);
        if(FS__lb_read(FS__pDevInfo[0].harddisk_driver,FS__pDiskInfo[0].StartSec,0,(void *)buffer)!=SD_NO_ERR)
  		{
  		    FS__pDiskInfo[0].StartSec=0;
  		    FS__fat_free(buffer);
  		    return FS_ERR;
  		}
             
  }
  else
  {
        FS__pDiskInfo[0].StartSec=0;
  }
  if(buffer[0]!=0xeb)
  {
      FS__fat_free(buffer);
      return BPB_ERR;
  }    
  FS__pDiskInfo[0].SecPerClus   =buffer[0x0d];
  FS__pDiskInfo[0].NumFATs      =buffer[0x10];
  FS__pDiskInfo[0].SecPerDisk   =(buffer[0x13]+(buffer[0x14]<<8));
  if(FS__pDiskInfo[0].SecPerDisk==0)
  {
  		FS__pDiskInfo[0].SecPerDisk=(buffer[0x20]+(buffer[0x21]<<8)+(buffer[0x22]<<16)+(buffer[0x23]<<24));
  }
  FS__pDiskInfo[0].BytsPerSec  = (buffer[0x0b]+(buffer[0x0c]<<8));
  FS__pDiskInfo[0].FATSecCnt   = (buffer[0x16]+(buffer[0x17]<<8));
  FS__pDiskInfo[0].FATStartSec =FS__pDiskInfo[0].StartSec+(buffer[0x0e]+(buffer[0x0f]<<8));
  FS__pDiskInfo[0].RootDirTable=FS__pDiskInfo[0].FATStartSec +FS__pDiskInfo[0].FATSecCnt*FS__pDiskInfo[0].NumFATs;
  FS__pDiskInfo[0].RootSecCnt  =((buffer[0x11]+(buffer[12]<<8))*0x20)/0x200;
  FS__pDiskInfo[0].DataStartSec=FS__pDiskInfo[0].RootDirTable+FS__pDiskInfo[0].RootSecCnt;
  FS__pDiskInfo[0].ClusPerData=(FS__pDiskInfo[0].SecPerDisk-(FS__pDiskInfo[0].DataStartSec-FS__pDiskInfo[0].StartSec))/FS__pDiskInfo[0].SecPerClus;
  FS__pDiskInfo[0].FATType    =FS__fat_which_type();
  FS__pDiskInfo[0].Drive_unit=1;
  FS__fat_free(buffer);
 return FS_NO_ERR;
}

U8   FS__fat_which_type(void)
{
     if(FS__pDiskInfo[0].ClusPerData<(0xfff-0xa))
     {
     		return FAT12;
     }
     else if(FS__pDiskInfo[0].ClusPerData<(0xffff-0xa))
     {
     		return FAT16;
     }
     return FAT32;
}



/*********************************************************************
*
*             _FS__fat_FindFreeCluster
*
  Description:
  FS internal function. Find the next free entry in the FAT.

  Parameters:
  pFATSector  - 空闲簇所在的FAT扇区号. 
  pLastSector - Returns the sector number of the sector in pBuffer.
  pFATOffset  - Returns the offset of the free FAT entry within the
                sector pFATSector.
  LastClust   - Cluster, which will be used to link the new allocated
                cluster to. Here it is used at hint for where to start
                in the FAT.
  pBuffer     - Pointer to a sector buffer.
  FSysType    - ==1 => FAT12
                ==0 => FAT16
                ==2 => FAT32
  FATSize     - Size of one FAT ind sectors.
  BytesPerSec - Number of bytes in each sector.
 
  Return value:
  >=0         - Number of the free cluster.
  <0          - An error has occured.
*/


static S32 _FS__fat_FindFreeCluster( U32 *pFATSector, S32 *pLastSector, U32 *pFATOffset, 
                                       S32 LastClust, U8 *pBuffer,  U8 FAT_type,   U32 FATSize, U32 BytesPerSec) {
  U32 totclst;
  U32 curclst;
  U32 fatindex;
  int scan;
  U8 fatentry;//簇使用标志!=0说明非空闲
  U8 a;
  U8 b;
  
  if (LastClust >= 2) {
    curclst = LastClust + 1;  /* Start scan after the previous allocated sector */
  }
  else {
    curclst = 2;  /*  Start scan at the beginning of the media */
  }
  scan          = 0;
  *pFATSector   = 0;                    //计算curclst所在的FAT表开始的扇区
  *pLastSector  = -1;                    //当前缓冲区中的扇区号
  fatentry      = 0xff;                 //簇使用标志!=0说明非空闲
  /* Calculate total number of data clusters on the media */
  totclst = (FS__pDiskInfo[0].ClusPerData);
  while (1) {
    if (curclst >= totclst) {
      scan++;
      if (scan > 1) {
        break;  /* End of clusters reached after 2nd scan */
      }
      if (LastClust <= 2) {
        break;  /* 1st scan started already at zero */
      }
      curclst   = 2;  /* Try again starting at the beginning of the FAT */
      fatentry  = 0xff;
    }
    if (fatentry == 0) {
      break;  /* Free entry found */
    }
     if(FAT_type==FAT16)
     {
        fatindex = curclst * 2; /* FAT16 */
     }              
    *pFATSector = FS__pDiskInfo[0].FATStartSec + (fatindex / BytesPerSec);//计算curclst所在的FAT表开始的扇区
    *pFATOffset = fatindex % BytesPerSec;
    
    
    if (*pFATSector != *pLastSector) {//查看所需的FAT是否存在于缓冲区中
        if(FS__lb_read(FS__pDevInfo[0].harddisk_driver,0,(*pFATSector),(void *)pBuffer)!=SD_NO_ERR)
        {
         if(FS__lb_read(FS__pDevInfo[0].harddisk_driver,0,((*pFATSector)+FS__pDiskInfo[0].FATSecCnt),(void *)pBuffer)!=SD_NO_ERR)
        {
          return FS_ERR;
        }
        /* Try to repair original FAT sector with contents of copy */
       FS__lb_write(FS__pDevInfo[0].harddisk_driver,0,(*pFATSector),(void *)pBuffer);
      }
      *pLastSector = *pFATSector;
    }
    if(FAT_type==FAT16){
      a = pBuffer[*pFATOffset];
      b = pBuffer[*pFATOffset + 1];
      fatentry = a | b;
    }
    if (fatentry != 0) {
      curclst++;  /* Cluster is in use or defect, so try the next one */
    }
  }
  if (fatentry == 0) {
    return curclst;  /* Free cluster found */
  }
  return FS_ERR;
}



/*********************************************************************
*
*             _FS__fat_SetEOFMark
*
  Description:
  FS internal function. Set the EOF mark in the FAT for a cluster.
  The function does not write the FAT sector. An exception is FAT12,
  if the FAT entry is in two sectors. 

  Parameters:
  FATSector   - FAT sector, where the cluster is located. 
  pLastSector - Pointer to an FS_i32, which contains the number of the 
                sector in pBuffer.
  FATOffset   - Offset of the cluster in the FAT sector.
  Cluster     - Cluster number, where to set the EOF mark.
  pBuffer     - Pointer to a sector buffer.
  FSysType    - ==1 => FAT12
                ==0 => FAT16
                ==2 => FAT32
  FATSize     - Size of one FAT ind sectors.
  BytesPerSec - Number of bytes in each sector.
 
  Return value:
  >=0         - EOF mark set.
  <0          - An error has occured.
*/

static S32 _FS__fat_SetEOFMark(U32 FATOffset, U8 *pBuffer,U16 FAT_type) {
  
  if(FAT_type==FAT16) { /* FAT16 */
    pBuffer[FATOffset]      = (U8)0xff;
    pBuffer[FATOffset + 1]  = (U8)0xff;
    return FS_NO_ERR;
  }
  return FS_ERR;
}



/*********************************************************************
*
*             _FS__fat_LinkCluster
*
  Description:
  FS internal function. Link the new cluster with the EOF mark to the 
  cluster list.

  Parameters:
  pLastSector - Pointer to an FS_i32, which contains the number of the 
                sector in pBuffer.
  Cluster     - Cluster number of the new cluster with the EOF mark.
  LastClust   - Number of cluster, to which the new allocated cluster
                is linked to.
  pBuffer     - Pointer to a sector buffer.
  FSysType    - ==1 => FAT12
                ==0 => FAT16
                ==2 => FAT32
  FATSize     - Size of one FAT ind sectors.
  BytesPerSec - Number of bytes in each sector.
 
  Return value:
  >=0         - Link has been made.
  <0          - An error has occured.
*/

static S32 _FS__fat_LinkCluster(S32 *pLastSector, U32 Cluster,
                                S32 LastClust, U8 *pBuffer, U8 FAT_type, 
                                U32 FATSize, U32 BytesPerSec) {
  U32 fatindex;
  U32 fatoffs;
  U32 fatsec;
  U8 a;
  U8 b;
  U8 err1;
  U8 err2;

  /* Link old last cluster to this one */
 
  if(FAT_type==FAT16){
    fatindex = LastClust * 2;               /* FAT16 */
  }
  fatsec =FS__pDiskInfo[0].FATStartSec + (fatindex / BytesPerSec);
  fatoffs = fatindex % BytesPerSec;
  if (fatsec != *pLastSector) {
    /* 
       FAT entry, which has to be modified is not in the same FAT sector, which is
       currently in the buffer. So write it to the media now.
    */
    err1 = FS__lb_write(FS__pDevInfo[0].harddisk_driver,0,(*pLastSector),(void *)pBuffer);
     
    err2 = FS__lb_write(FS__pDevInfo[0].harddisk_driver,0,((*pLastSector)+FS__pDiskInfo[0].FATSecCnt),(void *)pBuffer);
    if((err1!=SD_NO_ERR)||(err2!=SD_NO_ERR))
    {
    	  return FS_ERR;
    }

⌨️ 快捷键说明

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