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

📄 fat.c

📁 文件系统,运行硬件环境:单片机,软件环境:keilc
💻 C
📖 第 1 页 / 共 5 页
字号:
                    {
                        cluster_number=fat_fsi_nxt_free;    /*下一个可用簇号,不一定真的可用*/
                    }                                       /*以下函数要求得到剩余空簇数*/
                    if((fat_fsi_free_count!=0xFFFFFFFF)&&(g_mode==F_COUNT_FREEC))
                        return fat_fsi_free_count;
                }
                temp8=hard_read_sector(fat_start_sector + (cluster_number / (SECTOR_SIZE / 4)));
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            temp16 = cluster_number % (SECTOR_SIZE / 4);    /*计算此簇在此扇区的偏移簇*/
            temp16 *=4;                                     /*计算其在扇区里偏移量*/
            temp32=fat_read_cluster(0,temp16);              /*读此簇的数据*/
        }
        #endif

        #if F_USE_FAT16 == 1
        if (fat_type_sign==F_TYPE_FAT16)
        {
            if(cluster_number % (SECTOR_SIZE / 2)==0)
            {
                temp8=hard_read_sector(fat_start_sector + (cluster_number / (SECTOR_SIZE / 2)));
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            temp16 = cluster_number % (SECTOR_SIZE / 2);
            temp16*=2;
            temp32 =fat_read_cluster(0,temp16);
        }
        #endif

        #if F_USE_FAT12 == 1
        if (fat_type_sign==F_TYPE_FAT12)
        {
        UINT8 sector;

            temp16=(UINT16)(cluster_number+cluster_number/2);   /*计算出簇号在扇区中的位置*/
            sector =temp16/SECTOR_SIZE;
            if(f_in12==0)                                       /*第一次进入读扇区数据*/
            {
                f_in12=1;                                       /*计算次簇所处扇区*/
                temp8 =hard_read_sector(fat_start_sector +sector);
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            #ifdef FAT_DEBUG
            com_prints("temp16_0: ",0);
            com_send_arry(&temp16,2,1);
            #endif
            if(((temp16+1)%512 !=0))                            /*此簇不在两扇区之间*/
            {
                temp16 %=SECTOR_SIZE;                           /*计算此簇在此扇区的偏移*/
                #ifdef FAT_DEBUG
                com_prints("temp160: ",0);
                com_send_arry(&temp16,2,1);
                #endif
                temp32 = fat_read_cluster((BOOL)(cluster_number&0x00000001),temp16);
                #ifdef FAT_DEBUG
                com_prints("temp32: ",1);
                com_send_arry(&temp32,4,1);
                #endif
                if(((temp16+2)%512 ==0)&&((sector ==2)||(sector ==5)
                    ||(sector ==8)||(sector ==11)))                 /*在FAT的偏移2 5 8 11扇区,读新扇区*/
                {
                    temp8 =hard_read_sector(fat_start_sector +sector +1);
                    if(temp8!=F_OK)
                        return READ_DATA_ERR;
                    #ifdef FAT_DEBUG
                    com_prints("come...**",1);
                    com_send_arry(&fat_disk_buffer,512,0);
                    #endif
                }
            }
            else    /*此簇数据在两FAT之间*/
            {
            UINT16 temp;

                temp =fat12_divid_cluster(temp16);
                if(temp ==F_ERROR)
                    return READ_DATA_ERR;
                temp32 =(UINT32)temp;
                #ifdef FAT_DEBUG
                com_prints("temp32_$$: ",1);
                com_send_arry(&temp32,4,1);
                #endif
            }
        }
        #endif

        if (temp32 == EMPTY_CLUSTER)                        /*查找空的簇号*/
        {
            free_bit = 1;
            if(g_mode==F_GET_CLUSTER_ARRY)                  /*构建一个链表*/
            {
                if(f_inc==0)
                {
                    f_inc=1;
                    chain[fat_chain_index].cluster =cluster_number;
                    chain[fat_chain_index].number =1;
                    cc=1;
                    if(cc ==c_num)
                    {
                        fat_last_chain_index =fat_chain_index;
                        #ifdef FAT_DEBUG
                        com_prints("fat_last_chain_index0:",0);
                        com_send_arry(&fat_last_chain_index,1,1);
                        com_prints("chain0:",0);
                        com_send_arry(&(chain[0].cluster),12,1);
                        #endif
                        return F_OK;
                    }
                }
                else
                {

                    if ((chain[fat_chain_index].cluster+(UINT32)(chain[fat_chain_index].number)
                        == cluster_number) && (chain[fat_chain_index].number != MAX_CL_PER_FRAG))
                    {
                        chain[fat_chain_index].number++;
                    }
                    else
                    {
                        fat_chain_index++;
                        if (fat_chain_index == FAT_CHAIN_LENGTH)   /*簇缓冲取满*/
                        {
                            return BUFFER_OVERFLOW_ERR;
                        }
                        chain[fat_chain_index].number = 1;
                        chain[fat_chain_index].cluster = cluster_number;
                    }
                    cc++;
                    if(cc==c_num)
                    {
                        fat_last_chain_index =fat_chain_index;
                        #ifdef FAT_DEBUG
                        com_prints("fat_last_chain_index1:",0);
                        com_send_arry(&fat_last_chain_index,1,1);
                        com_prints("chain1:",0);
                        com_send_arry(&(chain[0].cluster),12,1);
                        #endif
                        return F_OK;
                    }
                }
            }
            else if(g_mode==F_COUNT_FREEC)              /*用于统计当前有多是可用簇*/
            {
                count_free_cluster++;
            }
            else if(g_mode==F_GET_A_CLUSTER)            /*得到一个空簇*/
                return  cluster_number;
            else
                return  PARAMETER_CMD_ERR;
        }
    }                                                   /*计算总簇数不包括FAT开始的0,1两簇*/
    while(cluster_number != (fat_total_clusters+1));

    if(g_mode==F_COUNT_FREEC)       /*返回可用簇数*/
        return count_free_cluster;

    if(g_mode==F_GET_CLUSTER_ARRY)
        return NO_FREE_ROOM_ERR;

    if(free_bit==0)                 /*找完所有的簇,没有发现空的簇*/
    {
        fat_disk_end_bit=F_DISK_END;
    }
    return  F_ERROR;
}
#endif

/*==============================================================================
函数名: get_start_clusters
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:根据开始簇(或查找到的第一个空簇)构建簇链表
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 get_start_clusters (void)
{
UINT16 i;
UINT8  temp8;
UINT32 temp32;
BOOL   tcheck;    /*用于检测新簇与旧簇是否在同一个扇区*/
UINT8  index;
UINT32 new_cluster;
UINT32 old_cluster;

    if(fat_start_cluster==EMPTY_CLUSTER) /*文件开始簇为0,说明文件里没有数据,簇链为空*/
    {
       chain[0].number = 0;             /*约定是簇链为空的文件*/
       return F_OK;
    }
    chain[0].cluster = fat_start_cluster;
    chain[0].number = 1;
    old_cluster = fat_start_cluster;
    index =0;
    tcheck =1;      /*第一次进入需要重新读扇区数据*/
    do
    {
        #if F_USE_FAT32 == 1
        if (fat_type_sign == F_TYPE_FAT32)
        {
            if(tcheck ==1)                            /*计算此簇离第一个FAT的偏移扇区,并读取此扇区*/
            {
                tcheck =0;
                temp8=hard_read_sector(fat_start_sector + (old_cluster / (SECTOR_SIZE / 4)));
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            i =old_cluster % (SECTOR_SIZE / 4);     /*计算此簇在此扇区的偏移簇*/
            i *=4;                                  /*计算其在扇区里偏移量*/
            new_cluster =fat_read_cluster(0,i);     /*读区下一个簇*/
            temp32 =LAST_CLUSTER_32;
        }
        #endif

        #if F_USE_FAT16 == 1
        if (fat_type_sign==F_TYPE_FAT16)
        {
            if(tcheck ==1)
            {
                tcheck =0;
                temp8 =hard_read_sector(fat_start_sector + (old_cluster / (SECTOR_SIZE / 2)));
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            i = old_cluster % (SECTOR_SIZE / 2);
            i *=2;
            new_cluster = fat_read_cluster(0,i);
            temp32 = LAST_CLUSTER_16;
        }
        #endif

        #if F_USE_FAT12 == 1
        if (fat_type_sign==F_TYPE_FAT12)
        {
        UINT16 j;

            i=(UINT16)old_cluster+((UINT16)old_cluster)/2;            /*计算离FAT开始偏移*/
            j =i+1;
            if(tcheck ==1)
            {
                tcheck =0;
                temp8=hard_read_sector(fat_start_sector + (UINT32)i/SECTOR_SIZE);
                if(temp8!=F_OK)
                    return READ_DATA_ERR;
            }
            #ifdef FAT_DEBUG
            com_prints("old_cluster:",0);
            com_send_arry(&old_cluster,4,1);
            com_prints("j:",0);
            com_send_arry(&j,2,1);
            #endif
            if((j%512) !=0)                         /*此簇不在两扇区之间*/
            {
                i%=SECTOR_SIZE;                     /*计算此簇在此扇区的偏移*/
                new_cluster = fat_read_cluster((BOOL)(old_cluster&0x00000001),i);
            }
            else    /*此簇数据在两FAT之间*/
            {
            UINT16 temp16;

                temp16 =fat12_divid_cluster(i);
                if(temp16 ==F_ERROR)
                    return READ_DATA_ERR;
                new_cluster =(UINT32)temp16;
            }
            temp32 = LAST_CLUSTER_12;
        }
        #endif

        if(new_cluster >= temp32)                   /*到达文件或目录末*/
        {
            break;                                  /*到达文件的最后一簇,程序跳出*/
        }

        if((new_cluster==0) || (new_cluster==old_cluster))/*指向空簇或指向自身,返回错误*/
            return FILE_DIR_FAT_ERR;

        if ((new_cluster == (old_cluster + 1)) && (chain[index].number != MAX_CL_PER_FRAG))
        {
            chain[index].number++;
        }
        else
        {
            index++;
            if (index == FAT_CHAIN_LENGTH)           /*簇缓冲取满*/
            {
                return  BUFFER_OVERFLOW_ERR;
                #ifdef FAT_DEBUG
                com_prints("chain_O:",0);
                com_send_arry(&(chain[0].cluster),12,1);
                #endif
            }
            chain[index].number = 1;
            chain[index].cluster = new_cluster;
        }

        /*以下判断新簇是否处在当前扇区*/
        tcheck=0;                                   /*默认上下两簇在一个扇区*/
        #if F_USE_FAT32 == 1
        if (fat_type_sign==F_TYPE_FAT32)
        {
            if((new_cluster/128)!=(old_cluster/128))
                tcheck =1;
        }
        #endif

        #if F_USE_FAT16 == 1
        if(fat_type_sign==F_TYPE_FAT16)
        {
            if((new_cluster/256)!=(old_cluster/256))
                tcheck =1;
        }
        #endif

        #if F_USE_FAT12 == 1
        if(fat_type_sign==F_TYPE_FAT12)
        {                                  /*计算旧簇与新簇是否在同一个扇区*/
            if(((new_cluster+new_cluster/2)/SECTOR_SIZE)
                !=((old_cluster+old_cluster/2)/SECTOR_SIZE))
                tcheck =1;
        }
        #endif
        old_cluster = new_cluster;
    }
    while(1);
    fat_last_chain_index = index;               /*收集到多少个连续的簇*/
    #ifdef FAT_DEBUG
    com_prints("chain:",0);
    com_send_arry(&(chain[0].cluster),20,1);
    #endif

⌨️ 快捷键说明

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