📄 fat32.c
字号:
/*C**************************************************************************
* NAME: fat32.c
*----------------------------------------------------------------------------
* Copyright (c) 2003 Atmel.
*----------------------------------------------------------------------------
* RELEASE: snd1c-refd-nf-4_0_3
* REVISION: 1.4
*----------------------------------------------------------------------------
* PURPOSE:
* FAT32 file-system basics functions
*
* NOTES:
* Supports only the first partition
* Supports only 512 bytes sector size
* Supports only file fragmentation < MAX_FILE_FRAGMENT_NUMBER
* Supports only one file openned at a time
*
* Global Variables:
* - gl_buffer: array of bytes in pdata space
*****************************************************************************/
/*_____ I N C L U D E S ____________________________________________________*/
#include "config.h" /* system configuration */
#include "..\mem\hard.h" /* low level function definition */
#include "file.h" /* file function definition */
#include "fat32.h" /* fat32 file-system definition */
/*_____ M A C R O S ________________________________________________________*/
/*_____ D E F I N I T I O N ________________________________________________*/
extern pdata Byte gl_buffer[];
extern char pdata *lfn_name; /* long filename limited to MAX_FILENAME_LEN chars */
extern xdata Byte fat_buf_sector[]; /* 512 bytes buffer */
/* disk management */
extern data Uint32 fat_ptr_fats; /* address of the first byte of FAT */
extern data Uint32 fat_ptr_data; /* address of the first byte of data */
extern data Byte fat_cluster_size; /* cluster size (sector count) */
extern idata Byte fat_cluster_mask; /* mask for end of cluster test */
extern bdata bit dir_is_root; /* TRUE: point the root directory */
extern bdata bit fat_is_fat16; /* TRUE: FAT16 - FALSE: FAT12 */
extern bdata bit fat_is_fat32; /* TRUE: FAT32 - FALSE: FAT12/FAT16 */
extern bdata bit fat_open_mode; /* READ or WRITE */
extern bdata bit fat_2_is_present; /* TRUE: 2 FATs - FALSE: 1 FAT */
extern bdata bit flag_end_disk_file;
extern xdata Uint32 fat_count_of_clusters;/* number of cluster - 2 */
extern xdata Union32 fat_file_size;
extern xdata Uint32 fat_fat_size; /* FAT size in sector count */
/* directory management */
extern xdata fat_st_clust_chain dclusters[MAX_DIR_FRAGMENT_NUMBER];
/* cluster chain for the current directory */
extern idata Uint16 fat_dclust_byte_count;/* byte counter in directory sector */
extern idata Uint16 fat_dchain_index; /* the number of the fragment of the dir, in fact
the index of the table in the cluster chain */
extern idata Byte fat_dchain_nb_clust; /* the offset of the cluster from the first cluster
of the dir fragment */
extern xdata Byte fat_last_dclust_index;/* index of the last cluster in directory chain */
extern xdata Uint16 fat_dir_list_index; /* index of current entry in dir list */
extern xdata Uint16 fat_dir_list_last; /* index of last entry in dir list */
extern xdata Uint32 fat_dir_start_sect; /* start sector of dir list */
extern idata Uint32 fat_dir_current_sect; /* sector of selected entry in dir list */
extern xdata Uint32 fat_dir_current_offs; /* entry offset from fat_dir_current_sect */
extern xdata fat_st_cache fat_cache; /* The cache structure, see the .h for more info */
extern xdata char ext[3]; /* file extension (limited to 3 characters) */
/* file management */
extern xdata fat_st_clust_chain fclusters[MAX_FILE_FRAGMENT_NUMBER];
/* cluster chain for the current file */
extern idata Byte fat_last_clust_index; /* index of the last cluster in file chain */
extern data Uint16 fat_fclust_byte_count;/* byte counter in file cluster */
extern idata Byte fat_fchain_index; /* the number of the fragment of the file, in fact
the index of the table in the cluster chain */
extern idata Uint16 fat_fchain_nb_clust; /* the offset of the cluster from the first cluster
of the file fragment */
extern xdata Uint32 fat_current_file_size;
extern xdata Uint32 fat_rootclus_fat32; /* root cluster address */
extern bdata bit fat_last_dir_cluster_full;
extern bdata bit fat_no_entries_free;
extern xdata Uint16 fat_total_clusters;
extern xdata Uint32 last_free_cluster;
/* Mode repeat A/B variables */
extern xdata Byte fat_fchain_index_save;
extern xdata Byte fat_fchain_nb_clust_save;
extern xdata Uint16 fat_fclust_byte_count_save;
extern xdata Byte current_ext;
extern idata Uint16 fat_current_end_entry_position;
extern idata Uint16 fat_current_start_entry_position;
extern xdata Uint16 fat_nb_deleted_entries;
extern xdata Uint16 fat_nb_total_entries;
/*_____ D E C L A R A T I O N ______________________________________________*/
static void fat_get_dir_entry (fat_st_dir_entry xdata *);
static void fat_get_dir_file_list (Byte);
static bit fat_get_clusters (fat_st_clust_chain xdata *, Byte);
static bit fat_get_free_clusters (bit);
static bit fat_dseek (Int16);
static Byte fat_dgetc (void);
/*F**************************************************************************
* NAME: fat_install
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
* - OK: intallation succeeded
* - KO: - partition 1 not active
* - FAT type is not FAT16
* - sector size is not 512 bytes
* - MBR or PBR signatures are not correct
* - low level read open failure
*----------------------------------------------------------------------------
* PURPOSE:
* Install the fat system, read mbr, bootrecords...
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* if MBR not found, try to mount unpartitionned FAT
* sector size is fixed to 512 bytes to simplify low level drivers
* fat_ptr_fats = partition offset + nb_reserved_sector
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit fat_install (void)
{
Byte i;
Uint32 tot_sect;
Uint32 fat_nb_sector;
Uint16 bpb_rsvd_sec_cnt;
Byte bpb_num_fat;
Uint16 bpb_root_ent_count;
/* read and check usefull MBR info */
/* go to the first partition field */
Hard_read_open(MBR_ADDRESS);
Hard_load_sector();
Hard_read_close();
fat_ptr_fats = 0x01;
if ((fat_buf_sector[0] == 0xEB) && (fat_buf_sector[2] == 0x90)) /* Jump instruction to boot code */
{
if ((fat_buf_sector[21] & 0xF0) == 0xF0) /* Media byte */
{
if ((fat_buf_sector[510] == 0x55) && (fat_buf_sector[511] == 0xAA)) /* signature */
{
fat_ptr_fats = 0x00000000; /* disk may not be partitionned : first sector */
} /* is PBR */
else
{
return KO; /* no signature -> low level error */
}
}
}
if (fat_ptr_fats) /* if first sector is not a PBR */
{
if (Hard_read_open(MBR_ADDRESS) == OK)
{
for (i = 446/2; i != 0; i--)
{
Hard_read_byte(); /* go to first partition entry */
Hard_read_byte();
}
Hard_read_byte();
Hard_read_byte(); /* dummy reads */
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
/* read partition offset (in sectors) at offset 8 */
((Byte*)&fat_ptr_fats)[3] = Hard_read_byte();
((Byte*)&fat_ptr_fats)[2] = Hard_read_byte();
((Byte*)&fat_ptr_fats)[1] = Hard_read_byte();
((Byte*)&fat_ptr_fats)[0] = Hard_read_byte();
/* go to the MBR signature field */
for (i = 52; i != 0; i--)
{
Hard_read_byte(); /* dummy reads */
}
/* check MBR signature */
if ((Hard_read_byte() != LOW(BR_SIGNATURE)) &&
(Hard_read_byte() != HIGH(BR_SIGNATURE)))
{
fat_ptr_fats = 0x00000000; /* disk may not be partitionned */
}
Hard_read_close(); /* close physical read */
}
else
{ /* low level error */
return KO;
}
}
/* read and check usefull PBR info */
if (Hard_read_open(fat_ptr_fats) == OK)
{
/* go to sector size field */
for (i = 11; i != 0; i--)
{
Hard_read_byte(); /* dummy reads */
}
/* read sector size (in bytes) */
if ((Hard_read_byte() != LOW(SECTOR_SIZE)) ||
(Hard_read_byte() != HIGH(SECTOR_SIZE)))
{
Hard_read_close(); /* close physical read */
return KO;
}
/* read cluster size (in sector) */
fat_cluster_size = Hard_read_byte();
fat_cluster_mask = HIGH((Uint16)fat_cluster_size * SECTOR_SIZE) - 1;
/* reserved sector number */
((Byte*)&bpb_rsvd_sec_cnt)[1] = Hard_read_byte();
((Byte*)&bpb_rsvd_sec_cnt)[0] = Hard_read_byte();
/* number of FATs */
bpb_num_fat = Hard_read_byte();
if (bpb_num_fat == 2)
fat_2_is_present = TRUE;
else
fat_2_is_present = FALSE;
/* read number of dir entries*/
((Byte*)&bpb_root_ent_count)[3] = Hard_read_byte();
((Byte*)&bpb_root_ent_count)[2] = Hard_read_byte();
/* read number of sector in partition (<32Mb) */
((Byte*)&fat_nb_sector)[3] = Hard_read_byte();
((Byte*)&fat_nb_sector)[2] = Hard_read_byte();
((Byte*)&fat_nb_sector)[1] = 0x00;
((Byte*)&fat_nb_sector)[0] = 0x00;
Hard_read_byte();
Hard_read_byte(); /* FAT size for FAT12/16 */
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
Hard_read_byte();
/* read number of sector in partition (>32Mb) */
((Byte*)&fat_nb_sector)[3] += Hard_read_byte();
((Byte*)&fat_nb_sector)[2] += Hard_read_byte();
((Byte*)&fat_nb_sector)[1] += Hard_read_byte();
((Byte*)&fat_nb_sector)[0] += Hard_read_byte();
fat_is_fat16 = FALSE;
fat_is_fat32 = FALSE;
fat_ptr_data = (bpb_root_ent_count * DIR_SIZE) / SECTOR_SIZE;
/* Here start the structure for FAT32 */
/* Offset 36 : 32 bits size of fat */
((Byte*)&fat_fat_size)[3] = Hard_read_byte();
((Byte*)&fat_fat_size)[2] = Hard_read_byte();
((Byte*)&fat_fat_size)[1] = Hard_read_byte();
((Byte*)&fat_fat_size)[0] = Hard_read_byte();
tot_sect = fat_nb_sector - (Uint32)(((Uint32)(bpb_rsvd_sec_cnt) + (Uint32)((bpb_num_fat * (Uint32)(fat_fat_size))) + fat_ptr_data));
fat_count_of_clusters = tot_sect / fat_cluster_size;
/* Offset 40 : ExtFlags */
Hard_read_byte();
Hard_read_byte();
/* Offset 42 : FS Version */
Hard_read_byte();
Hard_read_byte();
/* Offset 44 : Root Cluster */
((Byte*)&fat_rootclus_fat32)[3] = Hard_read_byte();
((Byte*)&fat_rootclus_fat32)[2] = Hard_read_byte();
((Byte*)&fat_rootclus_fat32)[1] = Hard_read_byte();
((Byte*)&fat_rootclus_fat32)[0] = Hard_read_byte();
fat_ptr_fats += bpb_rsvd_sec_cnt;
fat_ptr_data = fat_ptr_fats + (bpb_num_fat * fat_fat_size);
/* Offset 48 : FS Info */
/* Offset 50 : Backup Boot Sector */
/* Offset 52 : Reserved */
/* Offset 64 - 89 : Data */
/* Offset 90 : 510 : Free */
for (i = 231; i != 0; i--)
{
Hard_read_byte();
Hard_read_byte();
}
/* check partition signature */
if ((Hard_read_byte() != LOW(BR_SIGNATURE)) &&
(Hard_read_byte() != HIGH(BR_SIGNATURE)))
{
Hard_read_close(); /* close physical read */
return KO;
}
Hard_read_close(); /* close physical read */
return OK;
}
else
{ /* low level error */
return KO;
}
}
#define UPLOAD 0
#define DOWNLOAD 1
#define FETCH_NEXT 0
#define FETCH_PREV 1
/*F**************************************************************************
* NAME: fat_calc_cluster
*----------------------------------------------------------------------------
* PARAMS:
*
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Calculate fat_dir_current_sect and update directory variable from the
* value of fat_dir_current_offs.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*
*****************************************************************************/
void fat_calc_cluster(void)
{
Uint32 i;
fat_dchain_index = 0;
fat_dchain_nb_clust = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -