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

📄 fatfs_supp.c

📁 嵌入式FAT文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        cpos.cluster = disk->fat_root_dir_cluster;
 
    CYG_TRACE3(TDE, "cluster=%d snum=%d pos=%d", 
                    pos->cluster, pos->cluster_snum, pos->cluster_pos);
    cpos1=cpos;
    while (true)
    {
        // FAT12/16 root dir check
        if (0 == cpos.cluster) 
        {
            if (cpos.cluster_pos >= disk->fat_root_dir_size)
                err = ENOSPC;
        }
        else
        { 
            // Change cluster if needed
            if (cpos.cluster_pos >= disk->cluster_size)
                err = get_next_cluster(disk, &cpos, CO_EXTEND | CO_ERASE_NEW);
        }

        if (err != ENOERR)
            return err;

        err = read_raw_dentry(disk, &cpos, &raw_dentry);
        if (err != ENOERR)
            return err;

        if (DENTRY_IS_DELETED(&raw_dentry))
        {
            CYG_TRACE3(TDE, "deleted dentry at cluster=%d snum=%d pos=%d",
                            cpos.cluster, cpos.cluster_snum, cpos.cluster_pos);

          	cpos.cluster_pos+=DENTRY_SIZE;
			len-=13;
			if(len<=0) 
			{
				*pos=cpos1;
				break;
			}
			continue;
        }
        else if (DENTRY_IS_ZERO(&raw_dentry))
        {
            CYG_TRACE3(TDE, "zero dentry at cluster=%d snum=%d pos=%d",
                            cpos.cluster, cpos.cluster_snum, cpos.cluster_pos);

         	cpos.cluster_pos+=DENTRY_SIZE;
			len-=13;
			if(len<=0) 
			{
				*pos=cpos1;
				break;
			}
			continue;
        }
        else
	{
		len=namelen;
		cpos1.cluster_pos+=DENTRY_SIZE;
		cpos=cpos1;
		continue;	
	}
      
    }
    return ENOERR;	
}
 
// -------------------------------------------------------------------------
// raw_to_dentry()
// Converts raw FAT dir entry to dir entry. 
 
static void
raw_to_dentry(fat_raw_short_dir_entry_t *raw_dentry,
              fatfs_data_pos_t    *raw_dentry_pos,
              fatfs_dir_entry_t   *dentry)
{
    get_raw_dentry_filename(raw_dentry, dentry->filename);

    if (DENTRY_IS_DIR(raw_dentry))
        dentry->mode = __stat_mode_DIR;
    else
        dentry->mode = __stat_mode_REG;
    
#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
    dentry->attrib = raw_dentry->attr;
#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES

    date_dos2unix(raw_dentry->crt_time, raw_dentry->crt_date, &dentry->ctime);
    date_dos2unix(0,                    raw_dentry->acc_date, &dentry->atime);
    date_dos2unix(raw_dentry->wrt_time, raw_dentry->wrt_date, &dentry->mtime);
    
    dentry->size       = raw_dentry->size;
    dentry->priv_data  = raw_dentry->nt_reserved;
    dentry->cluster    = raw_dentry->cluster | (raw_dentry->cluster_HI << 16);
    dentry->disk_pos   = *raw_dentry_pos;
}

// -------------------------------------------------------------------------
// dentry_to_raw()
// Converts dir entry to raw FAT dir entry. 
 
static void
dentry_to_raw(fatfs_dir_entry_t *dentry, fat_raw_short_dir_entry_t *raw_dentry)
{
    set_raw_dentry_filename(raw_dentry, dentry->filename, 0);

    if (__stat_mode_DIR == dentry->mode)
        raw_dentry->attr = S_FATFS_DIR;
    else
        raw_dentry->attr = S_FATFS_ARCHIVE;
#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
    raw_dentry->attr = dentry->attrib;
#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES

        
    date_unix2dos(dentry->ctime, &raw_dentry->crt_time, &raw_dentry->crt_date);
    date_unix2dos(dentry->atime, NULL,                  &raw_dentry->acc_date);
    date_unix2dos(dentry->mtime, &raw_dentry->wrt_time, &raw_dentry->wrt_date);
    
    raw_dentry->crt_sec_100 = 0; //FIXME
    raw_dentry->size        = dentry->size;
    raw_dentry->nt_reserved = dentry->priv_data;
    raw_dentry->cluster     = dentry->cluster & 0xFFFF;
    raw_dentry->cluster_HI  = dentry->cluster >> 16;
}

static int dentry_to_longraw(fatfs_dir_entry_t  *dentry,
		fat_raw_long_dir_entry_t *raw_dentry,
		int namepos,cyg_uint8 ldir_ord)
{
     int i;
     int clen;	 
     cyg_uint16 tmp=0;
     int num_transfer=namepos;	 
     for(i=0;i<5;i++)
     {
     	    if(namepos>=512||dentry->longfilename[namepos]==0)
	    {
	    	tmp=0;
	    }
	    else
	    {
	       	clen=fatfs_utf8_table->char2uni(dentry->longfilename+namepos,512,&tmp);
                if(clen>0)
		   namepos+=clen;
		else
		   return  clen;
	    }
	    raw_dentry->LDIR_Name1[i]=tmp;
     }
     raw_dentry->attr=S_FATFS_LONG_NAME;
     raw_dentry->LDIR_Type=0;
     raw_dentry->LDIR_Chksum=fatfs_chksum(dentry->filename);
     for(i=0;i<6;i++)
     {
     	    if(namepos>=512||dentry->longfilename[namepos]==0)
	    {
	    	tmp=0;
	    }
	    else
	    {
	        clen=fatfs_utf8_table->char2uni(dentry->longfilename+namepos,512,&tmp);
                if(clen>0)
		    namepos+=clen;
		else
		   return  clen;
	    }
	    raw_dentry->LDIR_Name2[i]=tmp;
     }
     raw_dentry->LDIR_FstClusLO=0;
     for(i=0;i<2;i++)
     {
     	  if(namepos>=512||dentry->longfilename[namepos]==0)
	    {
	    	tmp=0;
	    }
	    else
	    {
	       	clen=fatfs_utf8_table->char2uni(dentry->longfilename+namepos,512,&tmp);
                if(clen>0)
		   namepos+=clen;
		else
		   return  clen;
	    }
	    raw_dentry->LDIR_Name3[i]=tmp;
     }
     if(namepos>=512||
	 dentry->longfilename[namepos]==0||
	 dentry->longfilename[namepos+1]==0)
	 {	 
	      raw_dentry->LDIR_Ord=ldir_ord|0x40;
     	}
    else
    	{
	      raw_dentry->LDIR_Ord=ldir_ord;
	}
     return namepos-num_transfer;	 

}
//==========================================================================
// FAT data functions 

// -------------------------------------------------------------------------
// read_data()
// Reads data from given position. 
 
static int
read_data(fatfs_disk_t     *disk,
          void             *data,
          cyg_uint32       *len,
          fatfs_data_pos_t *pos)
{
    cyg_uint8   *buf   = (cyg_uint8 *) data;
    cyg_uint32   size  = *len;
    int          err   = ENOERR;

    CYG_TRACE4(TDO, "len=%d cluster=%d snum=%d pos=%d",
                    *len, pos->cluster, pos->cluster_snum, 
                    pos->cluster_pos);

    while (size > 0)
    {
        cyg_uint32 csize;

        // Check if we are still inside current cluster
        if (pos->cluster_pos >= disk->cluster_size)
        {
            // Get next cluster of file 
            err = get_next_cluster(disk, pos, CO_NONE);
            if (err != ENOERR)
                goto out;
        }
        
        // Adjust the data chunk size to be read to the cluster boundary
        if (size > (disk->cluster_size - pos->cluster_pos))
            csize = disk->cluster_size - pos->cluster_pos;
        else
            csize = size;

        CYG_TRACE4(TDO, "-- len=%d cluster=%d snum=%d pos=%d",
                        csize, pos->cluster, pos->cluster_snum,
                        pos->cluster_pos);

        err = disk_cluster_read(disk, (void*)buf, &csize, 
                                pos->cluster, pos->cluster_pos);
        if (err != ENOERR)
            goto out;

        // Adjust running variables

        buf              += csize;
        pos->cluster_pos += csize;
        size             -= csize;    
    }
    
out:
    *len -= size;

    CYG_TRACE1(TDO, "total len=%d", *len);

    return err;
}

// -------------------------------------------------------------------------
// write_data()
// Writes data to given position. 
 
static int
write_data(fatfs_disk_t     *disk,
           void             *data,
           cyg_uint32       *len,
           fatfs_data_pos_t *pos)
{
    cyg_uint8   *buf   = (cyg_uint8 *) data;
    cyg_uint32   size  = *len;
    int          err   = ENOERR;

    CYG_TRACE4(TDO, "len=%d cluster=%d snum=%d pos=%d",
                    *len, pos->cluster, pos->cluster_snum, 
                    pos->cluster_pos);

    while (size > 0)
    {
        cyg_uint32 csize;

        // Check if we are still inside current cluster
        if (pos->cluster_pos >= disk->cluster_size)
        {
            // Get next cluster of file, if at the last 
            // cluster try to extend the cluster chain 
            err = get_next_cluster(disk, pos, CO_EXTEND);
            if (err != ENOERR)
                goto out;
        }
        
        // Adjust the data chunk size to be read to the cluster boundary
        if (size > (disk->cluster_size - pos->cluster_pos))
            csize = disk->cluster_size - pos->cluster_pos;
        else
            csize = size;
 
        CYG_TRACE4(TDO, "-- len=%d cluster=%d snum=%d pos=%d",
                        csize, pos->cluster, pos->cluster_snum, 
                        pos->cluster_pos);

        err = disk_cluster_write(disk, (void*)buf, &csize, 
                                 pos->cluster, pos->cluster_pos);
        if (err != ENOERR)
            goto out;

        // Adjust running variables
        
        buf              += csize;
        pos->cluster_pos += csize;
        size             -= csize;    
    }
    
out:
    *len -= size;

    CYG_TRACE1(TDO, "total len=%d", *len);

    return err;
}

//==========================================================================
// Misc functions 

// -------------------------------------------------------------------------
// init_dir_entry()
// Initializes attributes of a new dir entry. 
 
static void
init_dir_entry(fatfs_dir_entry_t *dentry, 
		const char        *shortname, 
               int               shortnamelen,
	       const char *longname,
	       int               longnamelen,
	       mode_t             mode,
               cyg_uint32         parent_cluster, 
               cyg_uint32         first_cluster, 
               fatfs_data_pos_t  *pos)
{
    int i;
    if (0 == shortnamelen)
        shortnamelen = 12;
 //   if(0==longnamelen)
//	    longnamelen=512;
    memset(dentry,0,sizeof(fatfs_dir_entry_t));	
    strncpy(dentry->filename, shortname, shortnamelen);
    dentry->filename[shortnamelen] = '\0';
    for(i=0;i<longnamelen;i++)
    {
    	dentry->longfilename[i]=longname[i];
    }
    dentry->longfilename[longnamelen]=0;
    dentry->mode  = mode;

#ifdef CYGCFG_FS_FAT_USE_ATTRIBUTES
    if (S_ISDIR(dentry->mode))
        dentry->attrib = S_FATFS_DIR;
    else
        dentry->attrib = S_FATFS_ARCHIVE;
#endif // CYGCFG_FS_FAT_USE_ATTRIBUTES

    dentry->ctime = 
    dentry->atime =
    dentry->mtime = cyg_timestamp();

    dentry->priv_data      = 0;
    dentry->size           = 0;
    dentry->cluster        = first_cluster;
    dentry->parent_cluster = parent_cluster;
    dentry->disk_pos       = *pos;
}

// -------------------------------------------------------------------------
// is_root_dir_entry()
// Check if the given dir entry is the root dir entry. 
 
static __inline__ bool
is_root_dir_entry(fatfs_dir_entry_t *dentry)
{
    return ('\0' == dentry->filename[0] && 0 == dentry->cluster);
}

//==========================================================================
//==========================================================================
// Exported functions 

// -------------------------------------------------------------------------
// fatfs_init()
// Gets disk info. 
 
int
fatfs_init(fatfs_disk_t *disk)
{
    cyg_uint32        sec_num, sec_per_fat, root_dir_sec_num;
    cyg_uint32        data_sec_num, data_clu_num;
    fat_boot_record_t boot_rec;
    int               err;

    CYG_CHECK_DATA_PTRC(disk);
    err = read_boot_record(disk, &boot_rec);
    if (err != ENOERR)    
        return err;

    // Check some known boot record values
    if (0x29 != boot_rec.ext_sig       ||
        0x55 != boot_rec.exe_marker[0] ||
        0xAA != boot_rec.exe_marker[1])
        return EINVAL;

    // Sector and cluster sizes 
    disk->sector_size       = boot_rec.bytes_per_sec;
    disk->sector_si

⌨️ 快捷键说明

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