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

📄 fat.c

📁 文件系统,运行硬件环境:单片机,软件环境:keilc
💻 C
📖 第 1 页 / 共 5 页
字号:
函数返回:
-------------------------------------------------------------------------------
函数作用:检查长文件名的短文件名检验和
-------------------------------------------------------------------------------
==============================================================================*/
UINT8 chk_file_name_sum (UINT8 *p)
{
    UINT8 FcbNameLen;
    UINT8 Sum;
    Sum = 0;
    for (FcbNameLen=0; FcbNameLen!=11; FcbNameLen++)
    {
        Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *p++;
    }
    return (Sum);
}
#endif

/*==============================================================================
函数名: fat_find_file_dir
-------------------------------------------------------------------------------
参数:f_mode分打开文件模式(F_OPEN_MODE )和搜索模式(F_FIND_MODE)
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:查找文件名或目录名/枚举文件,成功则读取目录的开始簇号或文件开始簇号及长度
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 fat_find_file_dir(BOOL f_mode)
{
UINT8  i;
UINT8  k;
UINT8  temp8;
UINT32 temp32;
#if F_EN_LONG_NAME ==1
UINT8  lname_offset;                    /*长文件名在目录项里的偏移*/
UINT8  lname_sec;                       /*长文件名偏移扇区量*/
#endif

BOOL  find_sign;                        /*找到文件标志位*/
BOOL  enum_sign;                        /*进入枚举文件模式*/
UINT8  aloc;                            /*纪录 * 号位置*/
UINT8  fat_sect_offset;                 /*在当前扇区里的偏移量*/
UINT32 count_sector;                    /*纪录读取了多少个扇区*/
UINT32 fat_total_sector;                /*此结构体簇数包含扇区数*/


    enum_sign =F_FALSE;                 /*默认不是枚举文件*/
    aloc =11;                           /*默认*位置*/

    if(f_mode==F_OPEN_MODE)             /*打开文件模式*/
    {
        if(fat_dir_now_l!=fat_dir_all_l)/*不能超过要打开的总目录深度*/
        {
            temp8=0;
            fat_dir_now_l++;
            for(i=0;i<11;i++)
                f[i]=0x20;              /*初始化缓冲区*/
            for(i=0;i<FAT_CMD_BUF_LEN;i++)
            {
                if((fat_cmd.open.buffer[i]=='\\')||(fat_cmd.open.buffer[i]=='/'))
                {
                    temp8++;
                    if(temp8==fat_dir_now_l)
                    {
                        i++;            /*指向目录数据开始位置*/
                        break;
                    }
                }
            }

            #ifdef FAT_DEBUG
            com_prints("fat_dir_now_l:",0);
            com_send_arry(&fat_dir_now_l,1,1);
            com_prints("fat_dir_all_l:",0);
            com_send_arry(&fat_dir_all_l,1,1);
            #endif

            k=i;                        /*保存"\\" "/"的前一个字节偏移*/
            find_sign = F_FALSE;        /*没有找到文件名*/
            for(;i!=FAT_CMD_BUF_LEN;i++)
            {
                if((fat_cmd.open.buffer[i] == 0x00)||(fat_cmd.open.buffer[i] == '\\')
                    ||(fat_cmd.open.buffer[i] == '/'))
                    break;
                if(fat_cmd.open.buffer[i]=='.')
                {
                    find_sign = F_TRUE;
                    break;
                }
            }/*计算出'.'离"//" "/"的偏移*/

            if(find_sign!=F_TRUE)
            {
                for(temp8 = 0;temp8 < 11;temp8++)
                {
                    if((fat_cmd.open.buffer[k]=='\\')||(fat_cmd.open.buffer[k]=='/')
                    ||(fat_cmd.open.buffer[k]==0))      /*结尾或文件分割符跳出*/
                        break;                          /*到下一个目录项开始或文件结束*/
                    f[temp8]=fat_cmd.open.buffer[k++];

                }
            }
            else    /*找到了'.'注意在计算机上是可以打开带点的文件夹,所以遇到'.'并没有到结尾*/
            {
            UINT8 j;

                for(j=0;(k+j)!=i;j++)
                {
                    f[j] =fat_cmd.open.buffer[k+j];
                }
                if(fat_cmd.open.buffer[i+1] !=0)
                {
                    f[8] =fat_cmd.open.buffer[i+1];
                    if(fat_cmd.open.buffer[i+2] !=0)
                    {
                        f[9] =fat_cmd.open.buffer[i+2];
                        if(fat_cmd.open.buffer[i+3] !=0)
                            f[10] =fat_cmd.open.buffer[i+3];
                    }
                }
            }

            for(i=0; i!=11; i++)
            {
                if(f[i] =='*')
                {
                    if(fat_dir_now_l!=fat_dir_all_l)        /*只支持最后一级的枚举*/
                        return PARAMETER_CMD_ERR;
                    enum_sign =F_TRUE;
                    aloc =i;
                    break;
                }
            }

        }
        else
            return PARAMETER_CMD_ERR;
    }
    #ifdef FAT_DEBUG
    com_prints("f_data:",0);
    com_send_arry(&f,11,1);
    com_prints("fat_chain_index:",0);
    com_send_arry(&fat_chain_index,1,1);
    com_prints("fat_count_offset_cluster:",0);
    com_send_arry(&fat_count_offset_cluster,1,1);
    com_prints("fat_count_offset_sector:",0);
    com_send_arry(&fat_count_offset_sector,1,1);
    #endif
                                                    /*FAT32或FAT12/16不在根目录*/
    if((fat_type_sign==F_TYPE_FAT32)||(fat_dir_now_l!=1))
    {
        fat_total_sector=ini_chain_arry(F_TRUE);    /*得到此数组包含的扇区数*/
        #ifdef FAT_DEBUG
        com_prints("fat_total_sector: ",0);
        com_send_arry(&fat_total_sector,4,1);
        com_prints("chain:",0);
        com_send_arry(&(chain[0].cluster),12,1);
        #endif
    }
    else    /*FAT12/16,并处在根目录下*/
    {                                               /*等于数据开始扇区减去根目录开始*/
        fat_total_sector=(UINT16)(fat_data_start_sector-fat_dir_sector_clus32);
        fat_current_sect=fat_dir_sector_clus32 - 1; /*得到根目录开始扇区数*/
    }

    find_sign=F_FALSE;                              /*默认没有找到文件*/
    count_sector=0;                                 /*读取扇区数初始化*/
    temp32 =0;                                      /*枚举文件序号*/
    do
    {
        i=fat_read_sector(F_OPEN_DIR,0);            /*读取目录扇区数据到缓冲区*/
        if(i!=F_OK)
            return i;
        fat_sect_offset=0;                          /*从扇区的开始位置搜索*/
        #ifdef FAT_DEBUG
        com_prints("f_data:",0);
        com_send_arry(&f,11,1);
        com_prints("sector_data:",1);
        com_send_arry(&fat_disk_buffer,512,1);
        #endif

        do
        {                                           /*根据FAT协议查找到此结束*/
            if(fat_disk_buffer[fat_sect_offset*DIR_SIZE]==FILE_EMPTY)
            {
                if(fat_dir_now_l==fat_dir_all_l)            /*到最后目录*/
                {
                    fat_dir_full_bit=F_DIR_NOT_FUL;         /*写入标志有空间创建文件*/
                    fat_file_sect_offset =fat_sect_offset;  /*保存此文件在此扇区的偏移*/
                    fat_file_dir_sector =fat_current_sect;  /*保存文件的所处扇区*/
                    return NOT_FIND_FILE_ERR;
                }
                else
                    return NOT_FIND_DIR_ERR;                /*没有发现目录*/
            }

            if(fat_dir_now_l==fat_dir_all_l)
            {
                if(fat_disk_buffer[fat_sect_offset*DIR_SIZE]==FILE_DELETED)
                {
                    fat_dir_fdelete_bit=F_FIND_DELETEF;     /*发现删除文件*/
                    if(f_mode==F_FIND_MODE)
                    {
                        fat_file_sect_offset=fat_sect_offset;   /*保存此文件在此扇区的偏移*/
                        fat_file_dir_sector=fat_current_sect;   /*保存文件的所处扇区*/
                        return F_OK;                            /*找到第一个删除的文件*/
                    }
                }
            }

            if(f_mode==F_OPEN_MODE)
            {
                fat_file_attr =fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+11];
                if(aloc ==0)                                    /*处理如\\*.mp3的文件*/
                {
                    if((fat_disk_buffer[fat_sect_offset*DIR_SIZE] !=FILE_DELETED)
                        &&(fat_file_attr !=ATTR_LFN_ENTRY))     /*不是长文件名的枚举*/
                    {
                        for(i=0; i!=3; i++)
                        {
                            if(f[8+i] ==0X20)
                            {
                                find_sign=F_TRUE;
                                break;
                            }
                            if(fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+8+i] !=f[8+i])
                                break;

                            if(i ==2)
                                find_sign=F_TRUE;               /*对比完成,都没有跳出,则找到文件*/
                        }
                    }
                }
                else                                            /*处理如\\CH375*的文件*/
                {
                    for(i=0; i!=aloc; i++)
                    {
                        if(f[i] !=fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+i])
                            break;
                        if(i==(aloc-1))                         /*对比到最后*/
                            find_sign=F_TRUE;                   /*找到文件或目录*/
                    }
                }

                if((enum_sign ==F_TRUE) && (find_sign ==F_TRUE))
                {
                UINT8 cont;

                    cont =0;
                    if(temp32 ==fat_file_length)                /*在枚举时,fat_file_length为枚举序号*/
                    {
                        for(i=0; i!=FAT_CMD_BUF_LEN; i++)
                        {
                            if((fat_cmd.open.buffer[i] == '\\') || (fat_cmd.open.buffer[i] == '/'))
                            {
                                cont++;
                                if(cont ==fat_dir_all_l)
                                {
                                    k =i;                       /*保存位置*/
                                    break;
                                }
                            }
                        }

                        for(i=0; i!=8; i++)
                        {
                            if(fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+i] !=0x20)
                            {
                                if(++k >(FAT_CMD_BUF_LEN-1))        /*超过命令缓冲区长度*/
                                    return CMDBUF_OVERFLOW_ERR;
                                fat_cmd.open.buffer[k] =fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+i];

                            }
                        }

                                                                    /*以下枚举通常属性文件和存档属性类文件*/
                        if((fat_file_attr ==ATTR_FILE) || (fat_file_attr ==ATTR_ARCHIVE)
                            || (fat_file_attr ==ATTR_READ_ONLY) || (fat_file_attr ==ATTR_HIDDEN)
                            || (fat_file_attr ==ATTR_SYSTEM))
                        {
                            if(++k >(FAT_CMD_BUF_LEN-1))
                                return CMDBUF_OVERFLOW_ERR;
                            fat_cmd.open.buffer[k] ='.';
                        }

                        for(i=0; i!=3; i++)
                        {
                            if(fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+8+i] !=0x20)
                            {
                                if(++k >(FAT_CMD_BUF_LEN-1))
                                    return CMDBUF_OVERFLOW_ERR;
                                fat_cmd.open.buffer[k] =fat_disk_buffer[(fat_sect_offset*DIR_SIZE)+8+i];
                            }
                        }
                        if(++k >(FAT_CMD_BUF_LEN-1))
                            return CMDBUF_OVERFLOW_ERR;
                        fat_cmd.open.buffer[k] =0;          /*赋予字符串结尾标志*/

                        #if F_EN_ENUM_BACK ==1
                        file_enum_call_back();              /*调用回调函数,继续搜索*/
                        #else
                        return ENUM_FILE_OK;
                        #endif
                    }
                    temp32++;
                    find_sign=F_FALSE;                      /*没有找到文件*/
                }
                else if(find_sign==F_TRUE)
                {
                UINT16 tem;
                UINT16 temp16;

                    tem=fat_sect_offset*DIR_SIZE;       /*计算此目录在此扇区的偏移*/
                    temp16=ushort_read_data(tem+20);    /*得到簇号的高2字节*/
                    fat_start_cluster=(UINT32)temp16;
                    fat_start_cluster<<=16;
                    temp16=ushort_read_data(tem+26);    /*得到簇号的低2字节*/
                    fat_start_cluster|=(UINT32)temp16;  /*得到文件的开始簇号*/

                    fat_file_attr=uchar_read_data(tem+11);      /*取文件(或目录)属性*/
                    if(fat_dir_now_l==fat_dir_all_l)            /*到打开目录最后*/
                    {
                        fat_file_length=ulong_read_data(tem+28);/*读取文件(或目录)长度*/
                        fat_file_sect_offset=fat_sect_offset;   /*保存此文件在此扇区的偏移*/
                        fat_file_dir_sector=fat_current_sect;   /*保存文件的所处扇区*/

                        #if F_EN_LONG_NAME ==1
                        fat_gath_name_sign = NO_LONG_NAME_ERR;
                        lname_offset = fat_sect_offset;
                        lname_sec =1;
                        temp8 = chk_file_name_sum(&fat_disk_buffer[

⌨️ 快捷键说明

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