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

📄 fatfs_supp.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    diag_printf("FAT: FBR fat name:       '%.8s'\n",  fbr->fat_name);
    diag_printf("FAT: FBR exe mark:        0x%02X 0x%02X\n", 
                fbr->exe_marker[0], fbr->exe_marker[1]);
}
#endif // TFT

// -------------------------------------------------------------------------
// read_boot_record()
// Reads FAT boot record from disk.
 
static int 
read_boot_record(fatfs_disk_t *disk, fat_boot_record_t *fbr)
{
    int len, err;
    unsigned char data[0x3E];
    
    len = 0x3E;
    err = cyg_blib_read(&disk->blib, (void*)data, &len, 0, 0);
    if (err != ENOERR)
        return err;
   
    GET_WORD(data,  fbr->jump,           0x00);
    GET_BYTES(data, fbr->oem_name, 8,    0x03);
    GET_WORD(data,  fbr->bytes_per_sec,  0x0B);
    GET_BYTE(data,  fbr->sec_per_clust,  0x0D);
    GET_WORD(data,  fbr->res_sec_num,    0x0E);
    GET_BYTE(data,  fbr->fat_tbls_num,   0x10);
    GET_WORD(data,  fbr->max_root_dents, 0x11);
    GET_WORD(data,  fbr->sec_num_32,     0x13);
    GET_BYTE(data,  fbr->media_desc,     0x15);
    GET_WORD(data,  fbr->sec_per_fat,    0x16);
    GET_WORD(data,  fbr->sec_per_track,  0x18);
    GET_WORD(data,  fbr->heads_num,      0x1A);
    GET_DWORD(data, fbr->hsec_num,       0x1C);
    GET_DWORD(data, fbr->sec_num,        0x20);
    GET_WORD(data,  fbr->ldrv_num,       0x24);
    GET_BYTE(data,  fbr->ext_sig,        0x26);
    GET_DWORD(data, fbr->ser_num,        0x27);
    GET_BYTES(data, fbr->vol_name, 11,   0x2B);
    GET_BYTES(data, fbr->fat_name, 8,    0x36);

    // Skip the exe code and read the end marker
    len = 0x02;
    err = cyg_blib_read(&disk->blib, (void*)data, &len, 0, 0x1FE);
    if (err != ENOERR)
        return err;

    GET_BYTES(data, fbr->exe_marker, 2,  0);

    // Zero terminate strings
    fbr->oem_name[8]  = '\0';
    fbr->vol_name[11] = '\0';
    fbr->fat_name[8]  = '\0';
  
#if TFT 
    print_boot_record(fbr);
#endif
    
    return ENOERR;
}

//==========================================================================
// FAT table entry functions 

// -------------------------------------------------------------------------
// read_tentry()
// Reads FAT table entry from disk.

static int
read_tentry_fat12(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    unsigned char data[2];
    cyg_uint32 pos, num3;
    cyg_uint16 e;
    int len, err;

    num3 = num * 3;
    pos  = disk->fat_tbl_pos + (num3 >> 1);
    len  = 2;
    
    err = cyg_blib_read(&disk->blib, (void*)data, &len, 0, pos);
    if (err != ENOERR)
        return err;

    GET_WORD(data, e, 0x00);

    if (0 == (num3 & 1))
        *entry = e & 0x0FFF;
    else
        *entry = (e >> 4) & 0x0FFF;
        
    CYG_TRACE3(TFT, "tentry=%x num=%d at %d", *entry, num, pos);
    
    return ENOERR;
}

static int
read_tentry_fat16(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    unsigned char data[2];
    cyg_uint32 pos;
    cyg_uint16 e;
    int len, err;

    pos = disk->fat_tbl_pos + (num << 1);
    len = 2;
    
    err = cyg_blib_read(&disk->blib, (void*)data, &len, 0, pos);
    if (err != ENOERR)
        return err;

    GET_WORD(data, e, 0x00);
    *entry = e;

    CYG_TRACE3(TFT, "tentry=%x num=%d at %d", *entry, num, pos);
    
    return ENOERR;
}

static int
read_tentry(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    switch (disk->fat_type)
    {
        case FATFS_FAT12: return read_tentry_fat12(disk, num, entry);
        case FATFS_FAT16: return read_tentry_fat16(disk, num, entry);
        default: return EINVAL;                  
    }
}

// -------------------------------------------------------------------------
// write_tentry()
// Writes FAT table entry to disk (to all copies of FAT).
 
static int
write_tentry_fat12(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    unsigned char data[2];
    cyg_uint32 pos, num3; 
    cyg_uint16 e;
    int i, len, err;

    num3 = num * 3;
    pos  = disk->fat_tbl_pos + (num3 >> 1);
    len  = 2;
   
    err = cyg_blib_read(&disk->blib, (void*)data, &len, 0, pos);
    if (err != ENOERR)
        return err;

    GET_WORD(data, e, 0x00);
  
    if (0 == (num3 & 1)) 
        e = (e & 0xF000) | (*entry & 0x0FFF);
    else
        e = (e & 0x000F) | ((*entry & 0x0FFF) << 4);
    
    SET_WORD(data, e, 0x00);

    for (i = 0; i < disk->fat_tbls_num; i++)
    {
        err = cyg_blib_write(&disk->blib, (void*)data, &len, 0, pos);
        if (err != ENOERR)
            return err;

        CYG_TRACE4(TFT, "tentry=%x num=%d at %d tbl=%d", *entry, num, pos, i);

        pos += disk->fat_tbl_size;
    }
    
    return ENOERR;
}

static int
write_tentry_fat16(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    unsigned char data[2];
    cyg_uint32 pos; 
    cyg_uint16 e;
    int i, len, err;

    pos = disk->fat_tbl_pos + (num << 1);
    len = 2;
    
    e = *entry;
    SET_WORD(data, e, 0x00);

    for (i = 0; i < disk->fat_tbls_num; i++)
    {
        err = cyg_blib_write(&disk->blib, (void*)data, &len, 0, pos);
        if (err != ENOERR)
            return err;

        CYG_TRACE4(TFT, "tentry=%x num=%d at %d tbl=%d", *entry, num, pos, i);

        pos += disk->fat_tbl_size;
    }
    
    return ENOERR;
}

static int
write_tentry(fatfs_disk_t *disk, cyg_uint32 num, cyg_uint32 *entry)
{
    switch (disk->fat_type)
    {
        case FATFS_FAT12: return write_tentry_fat12(disk, num, entry);
        case FATFS_FAT16: return write_tentry_fat16(disk, num, entry);
        default: return EINVAL;                  
    }
}

// -------------------------------------------------------------------------
// get_tentry_type()
// Gets the type of FAT table entry.
 
static int
get_tentry_type_fat12(fatfs_disk_t *disk, cyg_uint32 entry)
{
    int type;

    if (entry < 0x0FF0)
    {
        if (0x0000 == entry)  type = TENTRY_FREE;
        else                  type = TENTRY_REGULAR;
    }
    else if (entry >= 0x0FF8) type = TENTRY_LAST;
    else if (0x0FF7 == entry) type = TENTRY_BAD;
    else                      type = TENTRY_RESERVED;

#if TFT
    CYG_TRACE2(TFT, "tentry=%04X type=%s", entry, tentry_type_name[type]);
#endif

    return type;
}

static int
get_tentry_type_fat16(fatfs_disk_t *disk, cyg_uint32 entry)
{
    int type;

    if (entry < 0xFFF0)
    {
        if (0x0000 == entry)  type = TENTRY_FREE;
        else                  type = TENTRY_REGULAR;
    }
    else if (entry >= 0xFFF8) type = TENTRY_LAST;
    else if (0xFFF7 == entry) type = TENTRY_BAD;
    else                      type = TENTRY_RESERVED;

#if TFT
    CYG_TRACE2(TFT, "tentry=%04X type=%s", entry, tentry_type_name[type]);
#endif

    return type;
}

static int
get_tentry_type(fatfs_disk_t *disk, cyg_uint32 entry)
{
    switch (disk->fat_type)
    {
        case FATFS_FAT12: return get_tentry_type_fat12(disk, entry);
        case FATFS_FAT16: return get_tentry_type_fat16(disk, entry);
        default: return TENTRY_BAD;
    }
}

// -------------------------------------------------------------------------
// set_tentry_type()
// Sets the type of FAT table entry.
 
static void 
set_tentry_type_fat12(fatfs_disk_t *disk, cyg_uint32 *entry, cyg_uint32 type)
{
    switch (type)
    {
        case TENTRY_FREE:     *entry = 0x0000; break;
        case TENTRY_LAST:     *entry = 0x0FF8; break;
        case TENTRY_RESERVED: *entry = 0x0FF0; break;
        case TENTRY_BAD:      *entry = 0x0FF7; break;      
        default:
            CYG_ASSERT(false, "Unknown tentry type");
    }
}

static void 
set_tentry_type_fat16(fatfs_disk_t *disk, cyg_uint32 *entry, cyg_uint32 type)
{
    switch (type)
    {
        case TENTRY_FREE:     *entry = 0x0000; break;
        case TENTRY_LAST:     *entry = 0xFFF8; break;
        case TENTRY_RESERVED: *entry = 0xFFF0; break;
        case TENTRY_BAD:      *entry = 0xFFF7; break;      
        default:
            CYG_ASSERT(false, "Unknown tentry type");
    }
}

static void 
set_tentry_type(fatfs_disk_t *disk, cyg_uint32 *entry, cyg_uint32 type)
{
    switch (disk->fat_type)
    {
        case FATFS_FAT12: set_tentry_type_fat12(disk, entry, type);
        case FATFS_FAT16: set_tentry_type_fat16(disk, entry, type);
    }
}

// -------------------------------------------------------------------------
// get_tentry_next_cluster()
// Gets the the next file cluster number from FAT table entry.
 
static __inline__ cyg_uint32 
get_tentry_next_cluster(fatfs_disk_t *disk, cyg_uint32 entry)
{
    return entry;
}

// -------------------------------------------------------------------------
// set_tentry_next_cluster()
// Sets the the next cluster number to FAT table entry.
 
static __inline__ void 
set_tentry_next_cluster(fatfs_disk_t *disk, 
                        cyg_uint32   *entry, 
                        cyg_uint32    next_cluster)
{
    *entry = next_cluster;
}

//==========================================================================
// FAT cluster functions 

// -------------------------------------------------------------------------
// is_pos_inside_cluster()
// Checks if the given position is inside cluster size.

static __inline__ bool 
is_pos_inside_cluster(fatfs_disk_t *disk, cyg_uint32 pos)
{
    return (pos < disk->cluster_size);
}

// -------------------------------------------------------------------------
// erase_cluster()
// Erases cluster (fills with 0x00). 

static int
erase_cluster(fatfs_disk_t *disk, cyg_uint32 cluster)
{
    unsigned char data[32];
    cyg_uint32 apos;
    int err, len, i;
    
    len = 32;
    memset((void*)data, 0x00, len);
    apos = get_data_disk_apos(disk, cluster, 0);
    
    CYG_TRACE1(TCL, "cluster=%d", cluster);

    for (i = 0; i < (disk->cluster_size >> 5); i++)
    {
        err = cyg_blib_write(&disk->blib, (void*)data, &len, 0, apos);
        if (err != ENOERR)
            return err;
        apos += len;
    }
    
    return ENOERR;
}

// -------------------------------------------------------------------------
// mark_cluster()
// Marks cluster (sets the cluster's FAT table entry to given type). 

static int
mark_cluster(fatfs_disk_t *disk, cyg_uint32 cluster, cyg_uint32 type)
{
    cyg_uint32 tentry;
    int err;
 
    set_tentry_type(disk, &tentry, type);
    err = write_tentry(disk, cluster, &tentry);

    CYG_TRACE3(TCL, "cluster=%d type=%d tentry=%d", 
                    cluster, type, tentry);
    return err;
}

// -------------------------------------------------------------------------
// link_cluster()
// Links two clusters.

static int
link_cluster(fatfs_disk_t *disk, cyg_uint32 cluster1, cyg_uint32 cluster2)
{
    cyg_uint32 tentry;
    int err;
    
    set_tentry_next_cluster(disk, &tentry, cluster2);
    err = write_tentry(disk, cluster1, &tentry);
 
    CYG_TRACE3(TCL, "cluster1=%d cluster2=%d tentry=%d", 
                    cluster1, cluster2, tentry);
    return err;
}

// -------------------------------------------------------------------------
// find_next_free_cluster()
// Finds first free cluster starting from given cluster.
// If none is available free_cluster is set to 0.
// If mark_as_last is set the found cluster is marked as LAST.

static int
find_next_free_cluster(fatfs_disk_t  *disk,
                       cyg_uint32     start_cluster, 
                       cyg_uint32    *free_cluster,
                       cluster_opts_t opts)
{

⌨️ 快捷键说明

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