/**************************************************************************//** * @file nvtfat_fat.h * @version V3.00 * @brief N9H20 series NVTFAT driver header file * * SPDX-License-Identifier: Apache-2.0 * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #ifndef _NVTFAT_FAT_H_ #define _NVTFAT_FAT_H_ /* Defined for long filenames */ #define LFN_MAX_FILENAME 514 /* maximum length of LFN in bytes */ /* Macro to convert Cluster number to logical sector number */ #define ClustNo2SecNo(n) ((UINT32)(n - 2) * ptLDisk->tFatInfo.uBpbSecPerClus + ptLDisk->tFatInfo.uDataSecStart) #define SECTOR_TYPE_FILE 0 #define SECTOR_TYPE_DIR 1 #define SECTOR_TYPE_FAT 2 #define SECTOR_TYPE_PART 3 typedef struct sector_buf_S { UINT8 *pucData; /* cached sector contents */ LDISK_T *ptLDisk; /* LDISK_T * associated with this sector */ UINT32 uSectorNo; /* logical sector number */ BOOL bIsDirty; /* dirty or not */ INT nReaderCnt; /* how many threads are reading it */ UINT32 jiffy; /* access time stamp */ VOID *os_owner; /* for OS */ VOID *os_priv; /* for OS */ } SEC_BUFF_T; /* For FAT and DATA sector check out */ #define READ_ACCESS 0 #define WRITE_ACCESS 1 /*======================================================== FAT information ==*/ typedef struct fat_info_S { /*- The followings are BPB fields commonly used by FAT16/FAT32 -*/ UINT32 uBpbBytesPerSec; /* BPB[11], size:2 */ UINT32 uBpbSecPerClus; /* BPB[13], size:1 */ UINT16 usBpbRsvdSecCnt; /* BPB[14], size:2 */ UINT8 ucBpbNumFATs; /* BPB[16], size:1 */ UINT16 usBpbRootEntCnt; /* BPB[17], size:2 */ UINT32 uBpbTotalSectors; /* FAT12/FAT16 - BPB[19], size:2 */ /* FAT32 - BPB[32], size: 4 */ UINT8 ucBpbMedia; /* BPB[21], size:1 */ UINT32 uBpbFatSize; /* FAT12/FAT16 - BPB[22], size:2 */ /* FAT32 - BPB[36], size:4 */ UINT16 usBpbSecPerTrk; /* BPB[24], size:2 */ UINT16 usBpbNumHeads; /* BPB[26], size:2 */ UINT32 uBpbHiddSec; /* BPB[28], size:4 */ UINT32 uBsVolID; /* FAT12/FAT16 - BPB[39], size:4 */ /* FAT32 - BPB[67], size:4 */ CHAR sBsVolLab[12]; /* FAT12/FAT16 - BPB[43], size:11 */ /* FAT32 - BPB[71], size:4 */ UINT32 uBpbRootClus; /* BPB[44], size:4 */ UINT16 usBpbFsInfo; /* BPB[48], size:2 */ /*- The following is FAT32 structure start from offset 36 -*/ /* UINT32 uBpbBytesPerSec; */ /* BPB[36], size:4 */ /* UINT16 usBsDrvNum; */ /* BPB[40], size:2 */ /* UINT16 usBpbFsVer; */ /* BPB[42], size:2 */ /* UINT16 usBpbBkBootSec; */ /* BPB[50], size:2 */ /* bpb_Reserved */ /* BPB[52], size:12 */ /* usBsDrvNum */ /* BPB[64], size:1 */ /* bs_Reserved1 */ /* BPB[65], size:1 */ /* bs_BootSig */ /* BPB[66], size:1 */ /*- The followings are proprietary used by our driver -*/ UINT32 uEndClusMark; /* FAT12 = 0xFF7, FAT16 = 0xFFF7, FAT32 = 0x0FFFFFF7 */ UINT8 ucFatType; /* TYPE_FAT12/TYPE_FAT16/TYPE_FAT32 */ UINT32 uSecSzMask; /* uBpbBytesPerSec - 1 */ UINT32 uBytesPerClus; /* uBpbBytesPerSec * uBpbSecPerClus */ UINT32 uLastSecNo; /* the last physical sector number on this partition */ UINT32 uLastClusNo; /* last cluster number on this partition */ UINT32 uFatSecStart; /* sector number of the first FAT sector */ UINT32 uDataSecStart; /* sector number of first data sector */ UINT32 uRootDirStartSec; /* FAT12/16 first sector number of the root directory */ UINT32 uFsInfoSecNo; /* FAT32 - the sector number of pucFSInfo sector */ UINT32 uFreeClusSearchIdx; /* the next start point to search a free cluster */ UINT32 uTotalFreeClus; /* total number of free clusters */ UINT8 pucFSInfo[512]; /* pucFSInfo sector */ } FAT_INFO_T; #define FAT12_END_CLUS_MARK 0xFF8 #define FAT16_END_CLUS_MARK 0xFFF8 #define FAT32_END_CLUS_MARK 0x0FFFFFF8 #define FAT12_BAD_CLUS_MARK 0xFF7 #define FAT16_BAD_CLUS_MARK 0xFFF7 #define FAT32_BAD_CLUS_MARK 0x0FFFFFF7 #define TYPE_FAT12 12 #define TYPE_FAT16 16 #define TYPE_FAT32 32 /*================================================ FAT directory structure ==*/ /* * A FAT directory entry size is 32 bytes and sector size is 512 bytes. * So, it must be word-aligned. */ /* physical file name entry */ typedef struct dir_ent_S { UINT8 pucDirName[8]; /* Offset: 0, Size: 11 */ UINT8 pucDirExtName[3]; UINT8 ucDirAttrib; /* Offset: 11, Size: 1 */ UINT8 ucDirNTRes; /* Offset: 12, Size: 1 */ UINT8 ucDirCTimeTenth; /* Offset: 13, Size: 1 */ UINT8 pucDirCTime[2]; /* Offset: 14, Size: 2 */ UINT8 pucDirCDate[2]; /* Offset: 16, Size: 2 */ UINT8 pucDirLADate[2]; /* Offset: 18, Size: 2 */ UINT8 pucDirFirstClusHi[2];/* Offset: 20, Size: 2 */ UINT8 pucDirWTime[2]; /* Offset: 22, Size: 2 */ UINT8 pucDirWDate[2]; /* Offset: 24, Size: 2 */ UINT8 pucDirFirstClusLo[2];/* Offset: 26, Size: 2 */ UINT8 pucDirFileSize[4]; /* Offset: 28, Size: 4 */ } DIR_ENT_T; /* physical long file name entry */ typedef struct lfn_ent_S { UINT8 ucLDirOrd; /* Offset: 0, Size: 1 */ UINT8 pucLDirName1[10]; /* Offset: 1, Size: 10, Unicode Chars 1~5 */ UINT8 ucLDirAttrib; /* Offset: 11, Size: 1, always 0x0F */ UINT8 ucLDirType; /* Offset: 12, Size: 1 */ UINT8 ucLDirChksum; /* Offset: 13, Size: 1, Checksum of 8.3 name */ UINT8 pucLDirName2[12]; /* Offset: 14, Size: 12, Unicode Chars 6-11 */ UINT8 pucLDirFirstClusLo[2]; /* Offset: 26, Size: 2, always 0 */ UINT8 pucLDirName3[4]; /* Offset: 28, Size: 4, Unicode Chars 12-13 */ } LFN_ENT_T; /* FAT file attributes */ #define A_NORMAL 0x00 /* Normal file, no attributes */ #define A_RDONLY 0x01 /* Read only attribute */ #define A_HIDDEN 0x02 /* Hidden file */ #define A_SYSTEM 0x04 /* System file */ #define A_LABEL 0x08 /* Volume label */ #define A_DIR 0x10 /* Directory */ #define A_ARCHIVE 0x20 /* Archive */ #define A_LFN 0x0F /* (A_RDONLY | A_HIDDEN | A_SYSTEM | A_LABEL) */ #define A_LFN_MASK 0x3F /* (A_LFN | A_DIR | A_ARCHIVE) */ /*================================================ Run-time data structure ==*/ /* * Each FILE_T has its own FAT configuration on a FAT file system. Refer to the * FILE_T defined in nvtfat.h. */ typedef struct file_control_block_S { /* For directory entry */ //CHAR suLongName[LFN_MAX_FILENAME]; CHAR szShortName[14]; UINT8 ucDirAttrib; /* file attribute */ UINT8 ucDirNTRes; UINT8 ucDirCTimeTenth; /* Millisecond stamp at file creation time */ UINT16 dirCtime; /* Time file was created */ UINT16 usDirCDate; /* Date file was created */ UINT16 usDirLDate; /* Last access date */ UINT16 usDirWTime; /* Time of last write. Note that file creation is considered a write. */ UINT16 usDirWDate; /* Date of last write. Note that file creation is considered a write. */ UINT32 uDirEntSecNo; /* Number of the sector where this directory entry is located. */ INT nDirEntInSecOffset; /* Directory entry offset of this file in <uDirEntSecNo> sector. */ /* for run-time file operation */ BOOL bIsFat16Root; /* is FAT12/FAT16 root directory */ BOOL bIsRWBuffDirty; /* read/write buffer is dirty or not */ UINT8 *pucRWBuff; /* file r/w buffer */ INT64 n64RWBuffMapPos; /* the file position of the r/w buffer mapped to */ UINT32 uRWBuffSecNo; /* the start sector number of r/w buffer */ INT nRWBuffSecCnt; /* the start sector number of r/w buffer */ INT nClusCnt; /* number of clusters cached in r/w buffer */ UINT32 uRWBuffSize; /* the size of read/write buffer */ UINT32 *pucCCBuff; /* cluster chain buffer */ UINT32 uCCBuffSize; /* cluster chain buffer size */ UINT32 uCCEntCnt; /* cluster chain entry count */ UINT32 uCCDoneFPos; /* cluster chain done file position */ UINT32 uFirstClusNo; /* first cluster number of this file */ UINT32 uLastClusNo; UINT32 uCurClusNo; /* the number of the cluster currently used */ INT64 n64FileSize; /* The total length of this file */ INT64 n64FilePos; /* current position in file */ } FAT_FCB_T; #ifdef ECOS extern cyg_mutex_t _fat_mutex; #define FAT_MUTEX_INIT() cyg_mutex_init(&_fat_mutex) #define FAT_MUTEX_LOCK() cyg_mutex_lock(&_fat_mutex) #define FAT_MUTEX_UNLOCK() cyg_mutex_unlock(&_fat_mutex) #else /* Non-OS */ #define FAT_MUTEX_INIT() #define FAT_MUTEX_LOCK() #define FAT_MUTEX_UNLOCK() #endif /*====================================== External reference in library only ==*/ extern DISK_OP_T _fs_tFatDiskOperation; extern FILE_OP_T _fs_tFatFileOperation; extern BOOL _fs_bLockFileSystem; extern INT fs_fat_parse_partition(PDISK_T *ptPDisk, PARTITION_T *ptPartition, UINT32 uBpbSecNo); extern INT fs_fat_format_partition(PDISK_T *ptPDisk, PARTITION_T *ptPartition, INT nType); extern INT fs_fat32_scan_disk(LDISK_T *ptLDisk); extern INT fs_fat32_defragment_disk(LDISK_T *ptLDisk); /* Cache */ extern VOID fs_fat_init_sector_cache(VOID); extern VOID fs_fat_debug_sector_cache(VOID); extern INT fs_fat_check_out_sec(LDISK_T *ptLDisk, UINT32 uSectorNo, INT nAccess, SEC_BUFF_T **ptSecBuff); extern VOID fs_fat_check_in_sec(SEC_BUFF_T *ptSecBuff, INT nAccess, BOOL bIsDirty); extern INT fs_fat_flush_sector_cache(LDISK_T *ptLDisk); extern VOID fs_fat_clear_sector_cache(LDISK_T *ptLDisk); /* FAT32 pucFSInfo sector */ //extern INT fs_fat_update_fs_info(LDISK_T *ptLDisk); extern INT fsScanDisk(INT nDriveNo); /* FAT table */ extern INT read_fs_info(LDISK_T *ptLDisk); extern INT fs_read_fat_table(LDISK_T *ptLDisk, UINT32 uClusNo, UINT32 *puEntryValue); extern INT fs_write_fat_table(LDISK_T *ptLDisk, UINT32 uClusNo, UINT32 uEntryValue); extern INT fs_fat_reclaim_clusters(LDISK_T *ptLDisk, UINT32 uStartClusNo); extern INT fs_fat_allocate_cluster(FILE_T *ptFile); /* directory entry */ extern INT fs_fat_delete_file(LDISK_T *ptLDisk, CHAR *suFullName, CHAR *szAsciiName, BOOL bIsDirectory); extern INT fs_fat_create_file(FILE_T *ptFile, CHAR *suFullName, CHAR *szAsciiName, UINT32 *uClusNoOfParent); extern INT fs_fat_merge_file(LDISK_T *ptLDisk, CHAR *suFileNameA, CHAR *szAsciiNameA, CHAR *suFileNameB, CHAR *szAsciiNameB); extern INT fs_fat_get_next_dir_entry(FILE_T *ptFile, UINT8 *pucBuff, CHAR **szLongName, DIR_ENT_T *ptDirEnt, UINT32 *uStartPos); extern VOID fs_fat_set_dire_mtime(FAT_FCB_T *ptFcb, DIR_ENT_T *ptDire, INT bType); extern VOID fs_fat_set_sdir_name(CHAR *szShortName, DIR_ENT_T *ptDire); extern VOID fs_fat_get_sdir_name(CHAR *szShortName, DIR_ENT_T *ptDire); extern UINT8 *fs_fat_get_ldir_name(UINT8 *pucNameBuff, LFN_ENT_T *ptLDire); extern VOID fs_fat_set_dire_info(FAT_FCB_T *ptFcb, DIR_ENT_T *ptDire); extern VOID fs_fat_get_dire_info(FAT_FCB_T *ptFcb, DIR_ENT_T *ptDire); extern INT fs_fat_search_file(FILE_T *ptFile, CHAR *szFileName); extern INT fs_fat_delete_tree(LDISK_T *ptLDisk, CHAR *suFullName, CHAR *szAsciiName); extern INT fs_update_first_cluster(FILE_T *ptFile, UINT32 uClusNo); extern VOID fs_fat_dump_fcb(FAT_FCB_T *ptFcb); extern VOID fsDumpUniStr(UINT8 *suStr); #endif /* _NVTFAT_FAT_H_ */