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

📄 fatfs_supp.c

📁 该工程是从ecos嵌入式系统下移植过来的一个小型的fat16文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
// find_and_append_cluster()// Finds a free cluster on disk and appends it to the given cluster. // New cluster is marked as LAST. static intfind_and_append_cluster(fatfs_disk_t  *disk,                         cyg_uint32     cluster,                         cyg_uint32    *new_cluster,                        cluster_opts_t opts){    cyg_uint32 free_cluster;    int err;    printf("cluster=%d", cluster);        err = find_next_free_cluster(disk, cluster,             &free_cluster, opts | CO_MARK_LAST);    if (err != ENOERR)        return err;    printf( "free_cluster=%d", free_cluster);        // Link clusters        err = link_cluster(disk, cluster, free_cluster);    if (err != ENOERR)        return err;    *new_cluster = free_cluster;    printf( "new_cluster=%d", free_cluster);        return ENOERR;}// -------------------------------------------------------------------------// find_nth_cluster0()// Finds nth cluster in chain (ie nth cluster of file).// Searching from given position. static intfind_nth_cluster0(fatfs_disk_t     *disk,                  fatfs_data_pos_t *dpos,                   cyg_uint32        n,                  fatfs_tcache_t   *tcache){    cyg_uint32 cluster, cluster_snum;    int err = ENOERR;    // Trivial case check    if (dpos->cluster_snum == n)        return ENOERR;    // First look in cache    if (NULL != tcache)    {        cyg_uint32 c, ln;        if (fatfs_tcache_get(disk, tcache, n, &c))        {            // Cluster in cache            dpos->cluster = c;            dpos->cluster_snum = n;            printf( "cluster=%d cluster_snum=%d in cache", c, n);            return ENOERR;        }        else if (fatfs_tcache_get_last(disk, tcache, &ln, &c))        {            // Cluster not in cache - get last            // in cache and search from there            dpos->cluster = c;            dpos->cluster_snum = ln;              printf( "cluster=%d cluster_snum=%d last in cache", c, ln);        }        else        {            // Empty cache - put first cluster in            fatfs_tcache_set(disk, tcache, dpos->cluster_snum, dpos->cluster);        }    }       cluster      = dpos->cluster;    cluster_snum = dpos->cluster_snum;       printf( "cluster=%d cluster_snum=%d n=%d n_to_search=%d",                    cluster, cluster_snum, n, n-cluster_snum);       // Adjust t    while (n > 0)    {        cyg_uint32 tentry;        err = read_tentry(disk, cluster, &tentry);        if (err != ENOERR)            return err;        switch (get_tentry_type(disk, tentry))        {            case TENTRY_REGULAR:                break;            case TENTRY_LAST:                // Oops early last cluster                printf( "chain end n=%d", n);                err = EEOF; // File has less clusters than given n                            // this err should be caught by the                             // calling function                 goto out;            default:                // Inconsistant FAT table state !!!                printf("!!! inconsistant FAT tentry=%x n=%d",                                 tentry, n);                err = EIO;                                 goto out;        }        cluster = get_tentry_next_cluster(disk, tentry);        cluster_snum++;        if (NULL != tcache)            fatfs_tcache_set(disk, tcache, cluster_snum, cluster);        n--;    }    out:    dpos->cluster      = cluster;    dpos->cluster_snum = cluster_snum;    printf( "nth cluster=%d cluster_snum=%d", cluster, cluster_snum);    return err;}// -------------------------------------------------------------------------// find_nth_cluster()// Finds nth cluster in chain (ie nth cluster of file) searching // from given position. If the chain ends one cluster before the // given nth cluster and the CO_EXTEND is specifide, than the // chain is extended by one cluster. static intfind_nth_cluster(fatfs_disk_t     *disk,                 fatfs_data_pos_t *dpos,                  cyg_uint32        n,                 fatfs_tcache_t   *tcache,                 cluster_opts_t    opts){    int err;       // Find nth cluster     err = find_nth_cluster0(disk, dpos, n, tcache);        // EEOF meens that the cluster chain ended early    if ((err != EEOF) || !(opts & CO_EXTEND))        return err;        printf( "cluster_snum=%d n=%d", dpos->cluster_snum, n);        // Check if one cluster short    if (dpos->cluster_snum == (n - 1))    {        // Extend the chain for one cluster        cyg_uint32 new_cluster;        // Append new cluster to the end of chain        err = find_and_append_cluster(disk, dpos->cluster,                                       &new_cluster, opts);        if (err != ENOERR)            return err;        // Update position        dpos->cluster = new_cluster;        dpos->cluster_snum++;        dpos->cluster_pos = 0;        printf( "cluster=%d cluster_snum=%d",                         dpos->cluster, dpos->cluster_snum);                // Update cache        if (NULL != tcache)            fatfs_tcache_set(disk, tcache, dpos->cluster_snum, dpos->cluster);    }        return err;}// -------------------------------------------------------------------------// get_next_cluster()// Gets next cluster in chain (ie next cluster of file).// If CO_EXTEND is specified and the current cluster is last in // chain then the chain is extended by one cluster.static intget_next_cluster(fatfs_disk_t     *disk,                 fatfs_data_pos_t *dpos,                 fatfs_tcache_t   *tcache,                 cluster_opts_t    opts){    int err;    printf( "cluster=%d cluster_snum=%d",                     dpos->cluster, dpos->cluster_snum);    err = find_nth_cluster(disk, dpos, dpos->cluster_snum + 1, tcache, opts);    if (err != ENOERR)        return err;    // Update position    dpos->cluster_pos = 0;     printf( "cluster=%d cluster_snum=%d",                     dpos->cluster, dpos->cluster_snum);        return ENOERR;}// -------------------------------------------------------------------------// get_data_position_from_off()// Gets data position from given file offset.// If CO_EXTEND is specified the file is extended if // one cluster too short.  static int get_data_position_from_off(fatfs_disk_t     *disk,                           cyg_uint32        first_cluster,                            cyg_uint32        offset,                            fatfs_data_pos_t *dpos,                           fatfs_tcache_t   *tcache,                           cluster_opts_t    opts){    cyg_uint32 n;    int err;    // Position inside the cluster    dpos->cluster_pos = offset & (disk->cluster_size - 1);    // Cluster seq number to be searched for    n = offset >> disk->cluster_size_log2;    // Start searching from first cluster    dpos->cluster      = first_cluster;    dpos->cluster_snum = 0;    printf( "off=%d first_cluster=%d cluster_pos=%d n=%d\n",                    offset, first_cluster, dpos->cluster_pos, n);    err = find_nth_cluster(disk, dpos, n, tcache, opts);    // Err could be EEOF wich means that the given     // offset if out of given file (cluster chain)    return err;}// -------------------------------------------------------------------------// free_cluster_chain()// Marks all clusters FREE from given cluster to the last cluster in chain.static intfree_cluster_chain(fatfs_disk_t *disk, cyg_uint32 start_cluster){    cyg_uint32 c, next_c, tentry;    bool last;    int err;    printf( "start_cluster=%d", start_cluster);    c = next_c = start_cluster;    last = false;    while (!last)    {        err = read_tentry(disk, c, &tentry);        if (err != ENOERR)            return err;        switch (get_tentry_type(disk, tentry))        {            case TENTRY_LAST:                // Last cluster in chain                last = true;                break;            case TENTRY_REGULAR:                // Get next cluster in chain                next_c = get_tentry_next_cluster(disk, tentry);                break;            default:                printf( "!!! inconsistant FAT tentry=%x c=%d",                                 tentry, c);                return EIO;        }        // Set the current tentry to FREE         set_tentry_type(disk, &tentry, TENTRY_FREE);        err = write_tentry(disk, c, &tentry);        if (err != ENOERR)            return err;        // Next cluster in chain        c = next_c;     }    printf( "last_cluster=%d", c);        return ENOERR;}//==========================================================================// FAT dir entry functions // -------------------------------------------------------------------------// print_dentry()// Prints FAT directory entry. #if TDEstatic voidprint_dentry(fat_dir_entry_t* fde){    if (DENTRY_IS_DELETED(fde))        diag_printf("FAT: FDE name:    '?%.7s'\n", &fde->name[1]);    else            diag_printf("FAT: FDE name:    '%.8s'\n", fde->name);    diag_printf("FAT: FDE ext:     '%.3s'\n", fde->ext);    diag_printf("FAT: FDE attr:     %c%c%c%c%c%c\n",                 (DENTRY_IS_RDONLY(fde)  ? 'R' : '-'),                (DENTRY_IS_HIDDEN(fde)  ? 'H' : '-'),                (DENTRY_IS_SYSTEM(fde)  ? 'S' : '-'),                (DENTRY_IS_VOLUME(fde)  ? 'V' : '-'),                (DENTRY_IS_DIR(fde)     ? 'D' : '-'),                (DENTRY_IS_ARCHIVE(fde) ? 'A' : '-'));    diag_printf("FAT: FDE crt time: %u\n", fde->crt_time);    diag_printf("FAT: FDE crt date: %u\n", fde->crt_date);    diag_printf("FAT: FDE acc date: %u\n", fde->acc_date);    diag_printf("FAT: FDE wrt time: %u\n", fde->wrt_time);    diag_printf("FAT: FDE wrt date: %u\n", fde->wrt_date);    diag_printf("FAT: FDE cluster:  %u\n", fde->cluster);    diag_printf("FAT: FDE size:     %u\n", fde->size);}#endif // TDE// -------------------------------------------------------------------------// read_dentry()// Reads dir entry from disk. // If cluster is 0 reads from root dir. static intread_dentry(fatfs_disk_t     *disk,            fatfs_data_pos_t *dpos,             fat_dir_entry_t  *fde){    unsigned char data[DENTRY_SIZE];    cyg_uint32 apos;    int len, err;       // Check if we are reading the root directory    if (0 == dpos->cluster)        apos = disk->fat_root_dir_pos + dpos->cluster_pos;    else        apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos);           printf( "cluster=%d pos=%d apos=%d",                    dpos->cluster, dpos->cluster_pos, apos);         len = DENTRY_SIZE;    err = ReadBlock( (void*)data, &len, 0, apos);    if (err != ENOERR)        return err;    GET_BYTES(data, fde->name,     8, 0x00);    GET_BYTES(data, fde->ext,      3, 0x08);    GET_BYTE(data,  fde->attr,        0x0B);    GET_BYTE(data,  fde->nt_reserved, 0x0C);    GET_BYTE(data,  fde->crt_sec_100, 0x0D);    GET_WORD(data,  fde->crt_time,    0x0E);    GET_WORD(data,  fde->crt_date,    0x10);    GET_WORD(data,  fde->acc_date,    0x12);    GET_WORD(data,  fde->cluster_HI,  0x14);    GET_WORD(data,  fde->wrt_time,    0x16);    GET_WORD(data,  fde->wrt_date,    0x18);    GET_WORD(data,  fde->cluster,     0x1A);    GET_DWORD(data, fde->size,        0x1C);     // Zero terminate strings    fde->name[8] = '\0';        fde->ext[3]  = '\0';          // Store position    fde->pos = *dpos;       #if TDE        print_dentry(fde);#endif    return ENOERR;}// -------------------------------------------------------------------------// write_dentry()// Writes dir entry to disk. // If cluster is 0 writes to root dir. static intwrite_dentry(fatfs_disk_t     *disk,             fatfs_data_pos_t *dpos,              fat_dir_entry_t  *fde){    unsigned char data[DENTRY_SIZE];    cyg_uint32 apos;    int len, err;        // Check if we are writting to the root directory    if (0 == dpos->cluster)        apos = disk->fat_root_dir_pos + dpos->cluster_pos;    else        apos = get_data_disk_apos(disk, dpos->cluster, dpos->cluster_pos);         printf( "cluster=%d pos=%d apos=%d",                    dpos->cluster, dpos->cluster_pos, apos);     SET_BYTES(data, fde->name,     8, 0x00);    SET_BYTES(data, fde->ext,      3, 0x08);    SET_BYTE(data,  fde->attr,        0x0B);    SET_BYTE(data,  fde->nt_reserved, 0x0C);    SET_BYTE(data,  fde->crt_sec_100, 0x0D);    SET_WORD(data,  fde->crt_time,    0x0E);    SET_WORD(data,  fde->crt_date,    0x10);    SET_WORD(data,  fde->acc_date,    0x12);    SET_WORD(data,  fde->cluster_HI,  0x14);    SET_WORD(data,  fde->wrt_time,    0x16);    SET_WORD(data,  fde->wrt_date,    0x18);    SET_WORD(data,  fde->cluster,     0x1A);    SET_DWORD(data, fde->size,        0x1C);       len = DENTRY_SIZE;    err = WriteBlock( (void*)data, &len, 0, apos);    if (err != ENOERR)        return err;#if TDE        print_dentry(fde);#endif    return ENOERR;}// -------------------------------------------------------------------------// dentry_set_deleted()// Sets the dentry filename first char to 0xE5 (ie deleted).  static void dentry_set_deleted(fatfs_disk_t *disk, fat_dir_entry_t *dentry)

⌨️ 快捷键说明

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