📄 fatfs_supp.c
字号:
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 = ReadBlock( (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 intread_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 = ReadBlock( (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; printf( "tentry=%x num=%d at %d", *entry, num, pos); return ENOERR;}static intread_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 = ReadBlock( (void*)data, &len, 0, pos); if (err != ENOERR) return err; GET_WORD(data, e, 0x00); *entry = e; printf( "tentry=%x num=%d at %d", *entry, num, pos); return ENOERR;}static intread_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 intwrite_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 = ReadBlock((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 = WriteBlock((void*)data, &len, 0, pos); if (err != ENOERR) return err; printf( "tentry=%x num=%d at %d tbl=%d", *entry, num, pos, i); pos += disk->fat_tbl_size; } return ENOERR;}static intwrite_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 = WriteBlock( (void*)data, &len, 0, pos); if (err != ENOERR) return err; printf( "tentry=%x num=%d at %d tbl=%d", *entry, num, pos, i); pos += disk->fat_tbl_size; } return ENOERR;}static intwrite_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 intget_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 printf( "tentry=%04X type=%s", entry, tentry_type_name[type]);#endif return type;}static intget_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 printf( "tentry=%04X type=%s", entry, tentry_type_name[type]);#endif return type;}static intget_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 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 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 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 interase_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); printf( "cluster=%d", cluster); for (i = 0; i < (disk->cluster_size >> 5); i++) { err = WriteBlock( (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 intmark_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); printf( "cluster=%d type=%d tentry=%d", cluster, type, tentry); return err;}// -------------------------------------------------------------------------// link_cluster()// Links two clusters.static intlink_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); printf( "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 intfind_next_free_cluster(fatfs_disk_t *disk, cyg_uint32 start_cluster, cyg_uint32 *free_cluster, cluster_opts_t opts){ cyg_uint32 c, tentry; int err; if (start_cluster < 2) c = 2; else c = start_cluster + 1; *free_cluster = 0; printf( "c=%d", c); // Search from the starting cluster to the end of FAT and // from start of FAT to the starting cluster while (c != start_cluster) { // End of FAT check if (c >= disk->fat_tbl_nents) { c = 2; if (c >= start_cluster) break; } err = read_tentry(disk, c, &tentry); if (err != ENOERR) return err; if (TENTRY_FREE == get_tentry_type(disk, tentry)) { printf( "free_cluster=%d", c); *free_cluster = c; if (opts & CO_MARK_LAST) err = mark_cluster(disk, c, TENTRY_LAST); if ((err == ENOERR) && (opts & CO_ERASE_NEW)) err = erase_cluster(disk, c); return err; } c++; } // No free clusters found printf( "!!! no free clusters found"); // Return out of space return ENOSPC;}// -------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -