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

📄 fat16.c

📁 SD卡调试所用的资料
💻 C
📖 第 1 页 / 共 5 页
字号:
        fd->pos += write_length;

        if(first_cluster_offset + write_length >= Cluster_Size)
        {
            /* we are on a cluster boundary, so get the next cluster */
            u16 cluster_num_next = Fat16_Get_Next_Cluster(fd->fs, cluster_num);
            if(!cluster_num_next && buffer_left > 0)
                /* we reached the last cluster, append a new one */
                cluster_num_next = Fat16_Append_Clusters(fd->fs, cluster_num, 1);
            if(!cluster_num_next)
            {
                fd->pos_cluster = 0;
                break;
            }

            cluster_num = cluster_num_next;
            first_cluster_offset = 0;
        }

        fd->pos_cluster = cluster_num;

    } while(buffer_left > 0); /* check if we are done */

    /* update directory entry */
    if(fd->pos > fd->dir_entry.File_Size)
    {
        u32 size_old = fd->dir_entry.File_Size;

        /* update file size */
        fd->dir_entry.File_Size = fd->pos;
        /* write directory entry */
        if(!Fat16_Write_Dir_Entry(fd->fs, &fd->dir_entry))
        {
            /* We do not return an error here since we actually wrote
             * some data to disk. So we calculate the amount of data
             * we wrote to disk and which lies within the old file size.
             */
            buffer_left = fd->pos - size_old;
            fd->pos = size_old;
        }
    }

    return buffer_len - buffer_left;

#else
    return -1;
#endif
}



/**********************************************************************
 *  函数 Fat16_Seek_File --- 从新定位文件游标。
 * Repositions the read/write file offset.
 *
 * Changes the file offset where the next call to fat16_read_file()
 * or fat16_write_file() starts reading/writing.
 *
 * If the new offset is beyond the end of the file, Fat16_Resize_File()
 * is implicitly called, i.e. the file is expanded.
 *
 * The new offset can be given in different ways determined by
 * the \c whence parameter:
 * - \b FAT16_SEEK_SET: \c *offset is relative to the beginning of the file.
 * - \b FAT16_SEEK_CUR: \c *offset is relative to the current file position.
 * - \b FAT16_SEEK_END: \c *offset is relative to the end of the file.
 *
 * The resulting absolute offset is written to the location the \c offset
 * parameter points to.
 *
 * \param[in] fd The file decriptor of the file on which to seek.
 * \param[in,out] offset A pointer to the new offset, as affected by the \c whence
 *                   parameter. The function writes the new absolute offset
 *                   to this location before it returns.
 * \param[in] whence Affects the way \c offset is interpreted, see above.
 * \returns 0 on failure, 1 on success.
**********************************************************************/
u8 
Fat16_Seek_File(struct Fat16_File_Struct* fd, s32* offset, u8 whence)
{
    if(!fd || !offset)
        return 0;

    u32 new_pos = fd->pos;
    switch(whence)
    {
        case FAT16_SEEK_SET:
            new_pos = *offset;
            break;
        case FAT16_SEEK_CUR:
            new_pos += *offset;
            break;
        case FAT16_SEEK_END:
            new_pos = fd->dir_entry.File_Size + *offset;
            break;
        default:
            return 0;
    }

    if(new_pos > fd->dir_entry.File_Size && !Fat16_Resize_File(fd, new_pos))
        return 0;

    fd->pos = new_pos;
    fd->pos_cluster = 0;

    *offset = new_pos;
    return 1;
}




/**********************************************************************
*  函数 Fat16_Resize_File --- 调整文件大小。
*  仅分配文件磁盘空间,不清除数据,如需清楚,请手动清楚数据
*   输入参数 fd:The file decriptor of the file which to resize           
*            size:The new size of the file
*   返回值  0 --- 失败 
*           1 --- 成功
**********************************************************************/
u8 
Fat16_Resize_File(struct Fat16_File_Struct* fd, u32 size)
{
#if FAT16_WRITE_SUPPORT
    if(!fd)
        return 0;

    u16 cluster_num = fd->dir_entry.Cluster;
    u16 Cluster_Size = fd->fs->header.Cluster_Size;
    u32 size_new = size;

    do
    {
        if(cluster_num == 0 && size_new == 0)
            /* the file stays empty */
            break;

        /* seek to the next cluster as long as we need the space */
        while(size_new > Cluster_Size)
        {
            /* get next cluster of file */
            u16 cluster_num_next = Fat16_Get_Next_Cluster(fd->fs, cluster_num);
            if(cluster_num_next)
            {
                cluster_num = cluster_num_next;
                size_new -= Cluster_Size;
            }
            else
            {
                break;
            }
        }

        if(size_new > Cluster_Size || cluster_num == 0)
        {
            /* Allocate new cluster chain and append
             * it to the existing one, if available.
             */
            u16 cluster_count = size_new / Cluster_Size;
            if((u32) cluster_count * Cluster_Size < size_new)
                ++cluster_count;
            u16 cluster_new_chain = Fat16_Append_Clusters(fd->fs, cluster_num, cluster_count);
            if(!cluster_new_chain)
                return 0;

            if(!cluster_num)
            {
                cluster_num = cluster_new_chain;
                fd->dir_entry.Cluster = cluster_num;
            }
        }

        /* write new directory entry */
        fd->dir_entry.File_Size = size;
        if(size == 0)
            fd->dir_entry.Cluster = 0;
        if(!Fat16_Write_Dir_Entry(fd->fs, &fd->dir_entry))
            return 0;

        if(size == 0)
        {
            /* free all clusters of file */
            Fat16_Free_Clusters(fd->fs, cluster_num);
        }
        else if(size_new <= Cluster_Size)
        {
            /* free all clusters no longer needed */
            Fat16_Terminate_Clusters(fd->fs, cluster_num);
        }

    } while(0);

    /* correct file position */
    if(size < fd->pos)
    {
        fd->pos = size;
        fd->pos_cluster = 0;
    }

    return 1;
#else
    return 0;
#endif
}



/**********************************************************************
*  函数 Fat16_Open_Dir --- 打开路径。
*  
*   输入参数 fd:The filesystem on which the directory to open resides           
*            dir_entry:The directory entry which stands for the directory to open
*   返回值  0 --- 失败 
*           或者打开路径信息
**********************************************************************/
struct Fat16_Dir_Struct* 
Fat16_Open_Dir(struct Fat16_FS_Struct* fs, const struct Fat16_Dir_Entry_Struct* dir_entry)
{
    if(!fs || !dir_entry || !(dir_entry->Attributes & FAT16_ATTRIB_DIR))
        return 0;

#if USE_DYNAMIC_MEMORY
    struct Fat16_Dir_Struct* dd = malloc(sizeof(*dd));
    if(!dd)
        return 0;
#else
    struct Fat16_Dir_Struct* dd = fat16_dir_handlers;
    u8 i;
    for(i = 0; i < FAT16_DIR_COUNT; ++i)
    {
        if(!dd->fs)
            break;

        ++dd;
    }
    if(i >= FAT16_DIR_COUNT)
        return 0;
#endif

    memcpy(&dd->dir_entry, dir_entry, sizeof(*dir_entry));
    dd->fs = fs;
    dd->entry_next = 0;

    return dd;
}




/**********************************************************************
*  函数 Fat16_Close_Dir --- 关闭已打开的路径
*  
*   输入参数  dd:The directory descriptor to close.           
*   返回值   无
**********************************************************************/
void 
Fat16_Close_Dir(struct Fat16_Dir_Struct* dd)
{
    if(dd)
#if USE_DYNAMIC_MEMORY
        free(dd);
#else
        dd->fs = 0;
#endif
}



/**********************************************************************
*  函数 Fat16_Read_Dir --- 读取下一个路径。
*  
*   输入参数 dd:父路径           
*   输出参数 dir_entry:读取的下一个路径
*   返回值  0 --- 失败 
*           1 --- 成功
**********************************************************************/
u8 
Fat16_Read_Dir(struct Fat16_Dir_Struct* dd, struct Fat16_Dir_Entry_Struct* dir_entry)
{
    if(!dd || !dir_entry)
        return 0;

    if(dd->dir_entry.Cluster == 0)
    {
        /* read entry from root directory */
        if(Fat16_Read_Root_Dir_Entry(dd->fs, dd->entry_next, dir_entry))
        {
            ++dd->entry_next;
            return 1;
        }
    }
    else
    {
        /* read entry from a subdirectory */
        if(Fat16_Read_Sub_Dir_Entry(dd->fs, dd->entry_next, &dd->dir_entry, dir_entry))
        {
            ++dd->entry_next;
            return 1;
        }
    }

    /* restart reading */
    dd->entry_next = 0;

    return 0;
}



/**********************************************************************
*  函数 Fat16_Reset_Dir --- 重置目录句柄。
* Resets the directory handle such that reading restarts
* with the first directory entry.
*
*   输入参数 dd:The directory handle to reset           
*   返回值  0 --- 失败 
*           1 --- 成功
**********************************************************************/
u8 
Fat16_Reset_Dir(struct Fat16_Dir_Struct* dd)
{
    if(!dd)
        return 0;

    dd->entry_next = 0;
    return 1;
}



/**********************************************************************
*  函数 Fat16_Find_Offset_For_Dir_Entry --- 寻找新路径的储存空间
* Searches for space where to store a directory entry.
*
*   输入参数 fs:The filesystem on which to operate  
*            dir_entry:The directory entry for which to search space
*   返回值  0 --- 失败 
*           或者 a device offset on success
**********************************************************************/
u32 
Fat16_Find_Offset_For_Dir_Entry(const struct Fat16_FS_Struct*         fs,
                                const struct Fat16_Dir_Struct*        parent,
                                const struct Fat16_Dir_Entry_Struct*  dir_entry)
{
#if FAT16_WRITE_SUPPORT
    if(!fs || !dir_entry)
        return 0;

    /* search for a place where to write the directory entry to disk */
    u8 free_dir_entries_needed = (strlen(dir_entry->Long_Name) + 12) / 13 + 1;
    u8 free_dir_entries_found = 0;
    u16 cluster_num = parent->dir_entry.Cluster;
    u32 Dir_Entry_Offset = 0;
    u32 offset = 0;
    u32 offset_to = 0;

    if(cluster_num == 0)
    {
        /* we read/write from the root directory entry */
        offset = fs->header.Root_Dir_Offset;
        offset_to = fs->header.Cluster_Zero_Offset;
        Dir_Entry_Offset = offset;
    }

    while(1)
    {
        if(offset == offset_to)
        {
            if(cluster_num == 0)
                /* We iterated through the whole root directory entry
                 * and could not find enough space for the directory entry.
                 */
                return 0;

            if(offset)
            {
                /* We reached a cluster boundary and have to
                 * switch to the next cluster.
                 */

                u16 cluster_next = Fat16_Get_Next_Cluster(fs, cluster_num);
                if(!cluster_next)
                {
                    cluster_next = Fat16_Append_Clusters(fs, cluster_num, 1);
                    if(!cluster_next)
                        return 0;

                    /* we appended a new cluster and know it is free */
                    Dir_Entry_Offset = fs->header.Cluster_Zero_Offset +
                                       (u32) (cluster_next - 2) * fs->header.Cluster_Size;

                    /* clear cluster to avoid garbage directory entries */
                    Fat16_Clear_Cluster(fs, cluster_next);

                    break;
                }
                cluster_num = cluster_next;
            }

            offset = fs->header.Cluster_Zero_Offset +
                     (u32) (cluster_num - 2) * fs->header.Cluster_Size;
            offset_to = offset + fs->header.Cluster_Size;
            Dir_Entry_Offset = offset;
            free_dir_entries_found = 0;
        }

        /* read next lfn or 8.3 entry */
        u8 first_char;

⌨️ 快捷键说明

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