362 lines
19 KiB
C
362 lines
19 KiB
C
// DOM-IGNORE-BEGIN
|
|
/*******************************************************************************
|
|
Copyright 2015 Microchip Technology Inc. (www.microchip.com)
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
|
please contact mla_licensing@microchip.com
|
|
*******************************************************************************/
|
|
//DOM-IGNORE-END
|
|
|
|
#ifndef _FSDEF__H
|
|
#define _FSDEF__H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "fileio.h"
|
|
|
|
// Private search parameters
|
|
typedef enum
|
|
{
|
|
FILEIO_SEARCH_ENTRY_EMPTY = 0x01,
|
|
FILEIO_SEARCH_ENTRY_MATCH = 0x02,
|
|
FILEIO_SEARCH_PARTIAL_STRING_SEARCH = 0x04,
|
|
FILEIO_SEARCH_ENTRY_ATTRIBUTES = 0x08
|
|
} FILEIO_SEARCH_TYPE;
|
|
|
|
typedef enum
|
|
{
|
|
FILEIO_NAME_INVALID,
|
|
FILEIO_NAME_SHORT,
|
|
FILEIO_NAME_LONG,
|
|
FILEIO_NAME_DOT
|
|
} FILEIO_NAME_TYPE;
|
|
|
|
typedef enum
|
|
{
|
|
FILEIO_BUFFER_DATA,
|
|
FILEIO_BUFFER_FAT
|
|
} FILEIO_BUFFER_ID;
|
|
|
|
#define FILEIO_DIRECTORY_ENTRIES_PER_SECTOR 0x0f // Mask for the number of directory entries in a sector
|
|
#define FILEIO_DIRECTORY_ENTRY_SIZE 32 // Directory entry size, in bytes
|
|
#define FILEIO_DIRECTORY_ENTRY_EMPTY 0 // Value to indicate that a directory entry is empty
|
|
#define FILEIO_DIRECTORY_ENTRY_DELETED 0xE5 // Value to indicate that a directory entry has been deleted
|
|
|
|
#define FILEIO_FIXED_ROOT_DIRECTORY_CLUSTER_NUMBER 0 // Value of the root directory cluster for non-FAT32 file systems
|
|
|
|
#define FILEIO_CLUSTER_VALUE_EMPTY 0x0000 // FAT entry for an empty cluster
|
|
#define FILEIO_CLUSTER_VALUE_FAT12_EOF 0xff8 // End-of-file cluster value for FAT12
|
|
#define FILEIO_CLUSTER_VALUE_FAT16_EOF 0xfff8 // End-of-file cluster value for FAT16
|
|
#define FILEIO_CLUSTER_VALUE_FAT32_EOF 0x0ffffff8 // End-of-file cluster value for FAT32
|
|
#define FILEIO_CLUSTER_VALUE_FAT12_FAIL 0xfff // Return value indicating failure for FAT12
|
|
#define FILEIO_CLUSTER_VALUE_FAT16_FAIL 0xffff // Return value indicating failure for FAT16
|
|
#define FILEIO_CLUSTER_VALUE_FAT32_FAIL 0x0fffffff // Return value indicating failure for FAT32
|
|
#define FILEIO_CLUSTER_VALUE_FAT12_END 0xff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT12
|
|
#define FILEIO_CLUSTER_VALUE_FAT16_END 0xfff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT16
|
|
#define FILEIO_CLUSTER_VALUE_FAT32_END 0x0ffffff7 // Comparison value to determine if the firmware has reached the last allocatable cluster for FAT32
|
|
|
|
#define FILEIO_MEDIA_SECTOR_MBR 0ul // Master Boot Record sector number
|
|
|
|
#define FILEIO_FAT_GOOD_SIGN_0 0x55 // FAT signature byte 0
|
|
#define FILEIO_FAT_GOOD_SIGN_1 0xAA // FAT signatury byte 1
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t dataBufferCachedSector;
|
|
uint32_t fatBufferCachedSector;
|
|
struct
|
|
{
|
|
unsigned dataBufferNeedsWrite : 1;
|
|
unsigned fatBufferNeedsWrite : 1;
|
|
} flags;
|
|
void * driveOwner;
|
|
} FILEIO_BUFFER_STATUS;
|
|
|
|
// Structure containing information about a device
|
|
typedef struct
|
|
{
|
|
uint32_t firstPartitionSector; // Logical block address of the first sector of the FAT partition on the device
|
|
uint32_t firstFatSector; // Logical block address of the FAT
|
|
uint32_t firstRootSector; // Logical block address of the root directory
|
|
uint32_t firstRootCluster; // Cluster number of the root directory
|
|
uint32_t firstDataSector; // Logical block address of the data section of the device.
|
|
uint32_t partitionClusterCount; // The maximum number of clusters in the partition.
|
|
uint32_t sectorSize; // The size of a sector in bytes
|
|
uint32_t fatSectorCount; // The number of sectors in the FAT
|
|
uint8_t * dataBuffer; // Address of the global data buffer used to read and write file information
|
|
uint8_t * fatBuffer; // Address of the fat buffer used to read and write sectors of the FAT
|
|
FILEIO_BUFFER_STATUS * bufferStatusPtr; // Pointer to a buffer status structure
|
|
const FILEIO_DRIVE_CONFIG * driveConfig; // Configuration information for the drive
|
|
void * mediaParameters; // Parameters that describe which instance of the media to use (see [media].h for more information).
|
|
uint16_t rootDirectoryEntryCount; // The maximum number of entries in the root directory.
|
|
uint8_t fatCopyCount; // The number of copies of the FAT in the partition
|
|
uint8_t sectorsPerCluster; // The number of sectors per cluster in the data region
|
|
uint8_t type; // The file system type of the partition (FAT12, FAT16 or FAT32)
|
|
uint8_t mount; // Device mount flag (true if disk was mounted successfully, false otherwise)
|
|
uint8_t error; // Last error that occured for this drive
|
|
char driveId;
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_DRIVE;
|
|
#else
|
|
} FILEIO_DRIVE;
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t cluster;
|
|
FILEIO_DRIVE * drive;
|
|
} FILEIO_DIRECTORY;
|
|
|
|
// Directory entry structure
|
|
typedef struct
|
|
{
|
|
char name[FILEIO_FILE_NAME_LENGTH_8P3_NO_RADIX]; // File name and extension
|
|
uint8_t attributes; // File attributes
|
|
uint8_t reserved0; // Reserved byte
|
|
uint8_t createTimeMs; // Create time (millisecond field)
|
|
uint16_t createTime; // Create time (second, minute, hour field)
|
|
uint16_t createDate; // Create date
|
|
uint16_t accessDate; // Last access date
|
|
uint16_t firstClusterHigh; // High word of the entry's first cluster number
|
|
uint16_t writeTime; // Last update time
|
|
uint16_t writeDate; // Last update date
|
|
uint16_t firstClusterLow; // Low word of the entry's first cluster number
|
|
uint32_t fileSize; // The 32-bit file size
|
|
} FILEIO_DIRECTORY_ENTRY;
|
|
|
|
// Long File Name Entry
|
|
typedef struct
|
|
{
|
|
uint8_t sequenceNumber; // Sequence number,
|
|
uint8_t namePart1[10]; // File name part 1
|
|
uint8_t attributes; // File attribute
|
|
uint8_t type; // LFN Type
|
|
uint8_t checksum; // Checksum
|
|
uint16_t namePart2[6]; // File name part 2
|
|
uint16_t reserved0; // Reserved for future use
|
|
uint16_t namePart3[2]; // File name part 3
|
|
} FILEIO_DIRECTORY_ENTRY_LFN;
|
|
|
|
// BIOS Parameter Block for a FAT12 partition
|
|
typedef struct {
|
|
uint8_t jumpCommand[3]; // Jump Command
|
|
uint8_t oemName[8]; // OEM name
|
|
uint16_t bytesPerSector; // Number of bytes per sector
|
|
uint8_t sectorsPerCluster; // Number of sectors per cluster
|
|
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
|
|
uint8_t fatCount; // Number of FATs on the partition
|
|
uint16_t rootDirectoryEntryCount; // Number of root directory entries
|
|
uint16_t totalSectors; // Total number of sectors
|
|
uint8_t mediaDescriptor; // Media descriptor
|
|
uint16_t sectorsPerFat; // Number of sectors per FAT
|
|
uint16_t sectorsPerTrack; // Number of sectors per track
|
|
uint16_t headCount; // Number of heads
|
|
uint32_t hiddenSectorCount; // Number of hidden sectors
|
|
uint32_t reserved0; // Reserved space
|
|
uint8_t driveNumber; // Drive number
|
|
uint8_t reserved1; // Reserved space
|
|
uint8_t bootSignature; // Boot signature - equal to 0x29
|
|
uint8_t volumeId[4]; // Volume ID
|
|
uint8_t volLabel[11]; // Volume Label
|
|
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
|
|
#else
|
|
} FILEIO_BIOS_PARAMETER_BLOCK_FAT12;
|
|
#endif
|
|
|
|
// BIOS Parameter Block for a FAT16 partition
|
|
typedef struct {
|
|
uint8_t jumpCommand[3]; // Jump Command
|
|
uint8_t oemName[8]; // OEM name
|
|
uint16_t bytesPerSector; // Number of bytes per sector
|
|
uint8_t sectorsPerCluster; // Number of sectors per cluster
|
|
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
|
|
uint8_t fatCount; // Number of FATs on the partition
|
|
uint16_t rootDirectoryEntryCount; // Number of root directory entries
|
|
uint16_t totalSectors16; // Total number of sectors
|
|
uint8_t mediaDescriptor; // Media descriptor
|
|
uint16_t sectorsPerFat; // Number of sectors per FAT
|
|
uint16_t sectorsPerTrack; // Number of sectors per track
|
|
uint16_t headCount; // Number of heads
|
|
uint32_t hiddenSectorCount; // Number of hidden sectors
|
|
uint32_t totalSectors32; // Total sector count (32 bits)
|
|
uint8_t driveNumber; // Drive number
|
|
uint8_t reserved0; // Reserved space
|
|
uint8_t bootSignature; // Boot signature - equal to 0x29
|
|
uint8_t volumeId[4]; // Volume ID
|
|
uint8_t volumeLabel[11]; // Volume Label
|
|
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
|
|
#else
|
|
} FILEIO_BIOS_PARAMETER_BLOCK_FAT16;
|
|
#endif
|
|
|
|
// BIOS Parameter Block for a FAT32 parition
|
|
typedef struct {
|
|
uint8_t jumpCommand[3]; // Jump Command
|
|
uint8_t oemName[8]; // OEM name
|
|
uint16_t bytesPerSector; // Number of uint8_ts per sector
|
|
uint8_t sectorsPerCluster; // Number of sectors per cluster
|
|
uint16_t reservedSectorCount; // Number of reserved sectors at the beginning of the partition
|
|
uint8_t fatCount; // Number of FATs on the partition
|
|
uint16_t rootDirectoryEntryCount; // Number of root directory entries
|
|
uint16_t totalSectors16; // Total number of sectors
|
|
uint8_t mediaDescriptor; // Media descriptor
|
|
uint16_t sectorsPerFat16; // Number of sectors per FAT (16-bit)
|
|
uint16_t sectorsPerTrack; // Number of sectors per track
|
|
uint16_t headCount; // Number of heads
|
|
uint32_t hiddenSectorCount; // Number of hidden sectors
|
|
uint32_t totalSectors32; // Total sector count (32 bits)
|
|
uint32_t sectorsPerFat32; // Sectors per FAT (32 bits)
|
|
uint16_t mirroringFlags; // Presently active FAT. Defined by bits 0-3 if bit 7 is 1.
|
|
uint16_t fileSystemVersion; // FAT32 filesystem version. Should be 0:0
|
|
uint32_t firstClusterRootDirectory; // Start cluster of the root directory (should be 2)
|
|
uint16_t fileSystemInformation; // File system information
|
|
uint16_t backupBootSector; // Backup boot sector address.
|
|
uint8_t reserved0[12]; // Reserved space
|
|
uint8_t driveNumber; // Drive number
|
|
uint8_t reserved1; // Reserved space
|
|
uint8_t bootSignature; // Boot signature - 0x29
|
|
uint8_t volumeId[4]; // Volume ID
|
|
uint8_t volumeLabel[11]; // Volume Label
|
|
uint8_t fileSystemType[8]; // File system type in ASCII. Not used for determination
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
|
|
#else
|
|
} FILEIO_BIOS_PARAMETER_BLOCK_FAT32;
|
|
#endif
|
|
|
|
|
|
// A macro for the boot sector uint8_ts per sector value offset
|
|
#define BSI_BPS 11
|
|
// A macro for the boot sector sector per cluster value offset
|
|
#define BSI_SPC 13
|
|
// A macro for the boot sector reserved sector count value offset
|
|
#define BSI_RESRVSEC 14
|
|
// A macro for the boot sector FAT count value offset
|
|
#define BSI_FATCOUNT 16
|
|
// A macro for the boot sector root directory entry count value offset
|
|
#define BSI_ROOTDIRENTS 17
|
|
// A macro for the boot sector 16-bit total sector count value offset
|
|
#define BSI_TOTSEC16 19
|
|
// A macro for the boot sector sectors per FAT value offset
|
|
#define BSI_SPF 22
|
|
// A macro for the boot sector 32-bit total sector count value offset
|
|
#define BSI_TOTSEC32 32
|
|
// A macro for the boot sector boot signature offset
|
|
#define BSI_BOOTSIG 38
|
|
// A macro for the boot sector file system type string offset
|
|
#define BSI_FSTYPE 54
|
|
// A macro for the boot sector 32-bit sector per FAT value offset
|
|
#define BSI_FATSZ32 36
|
|
// A macro for the boot sector start cluster of root directory value offset
|
|
#define BSI_ROOTCLUS 44
|
|
// A macro for the FAT32 boot sector boot signature offset
|
|
#define BSI_FAT32_BOOTSIG 66
|
|
// A macro for the FAT32 boot sector file system type string offset
|
|
#define BSI_FAT32_FSTYPE 82
|
|
|
|
|
|
// Structure of a partition table entry
|
|
typedef struct
|
|
{
|
|
uint8_t bootDescriptor; // The boot descriptor (should be 0x00 in a non-bootable device)
|
|
uint8_t chsFirstParitionSector[3]; // The cylinder-head-sector address of the first sector of the partition
|
|
uint8_t fileSystemDescriptor; // The file system descriptor
|
|
uint8_t chsLastPartitionSector[3]; // The cylinder-head-sector address of the last sector of the partition
|
|
uint32_t lbaFirstSector; // The logical block address of the first sector of the partition
|
|
uint32_t sectorCount; // The number of sectors in a partition
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_MBR_PARTITION_TABLE_ENTRY;
|
|
#else
|
|
} FILEIO_MBR_PARTITION_TABLE_ENTRY;
|
|
#endif
|
|
|
|
// Strucure of a device's master boot record
|
|
typedef struct
|
|
{
|
|
uint8_t bootCode[446]; // Boot code
|
|
FILEIO_MBR_PARTITION_TABLE_ENTRY partition0; // The first partition table entry
|
|
FILEIO_MBR_PARTITION_TABLE_ENTRY partition1; // The second partition table entry
|
|
FILEIO_MBR_PARTITION_TABLE_ENTRY partition2; // The third partition table entry
|
|
FILEIO_MBR_PARTITION_TABLE_ENTRY partition3; // The fourth partition table entry
|
|
uint8_t signature0; // MBR signature code - equal to 0x55
|
|
uint8_t signature1; // MBR signature code - equal to 0xAA
|
|
#if defined __XC32__ || defined __XC16__
|
|
}__attribute__((packed)) FILEIO_MASTER_BOOT_RECORD;
|
|
#else
|
|
} FILEIO_MASTER_BOOT_RECORD;
|
|
#endif
|
|
|
|
// Structure matching the configuration of a FAT boot sector
|
|
typedef struct
|
|
{
|
|
// A union of different bios parameter blocks
|
|
union
|
|
{
|
|
FILEIO_BIOS_PARAMETER_BLOCK_FAT32 fat32;
|
|
FILEIO_BIOS_PARAMETER_BLOCK_FAT16 fat16;
|
|
FILEIO_BIOS_PARAMETER_BLOCK_FAT12 fat12;
|
|
} biosParameterBlock;
|
|
uint8_t reserved[512-sizeof(FILEIO_BIOS_PARAMETER_BLOCK_FAT32)-2]; // Reserved space
|
|
uint8_t signature0; // Boot sector signature code - equal to 0x55
|
|
uint8_t signature1; // Boot sector signature code - equal to 0xAA
|
|
#if defined __XC32__ || defined __XC16__
|
|
} __attribute__ ((packed)) FILEIO_BOOT_SECTOR;
|
|
#else
|
|
} FILEIO_BOOT_SECTOR;
|
|
#endif
|
|
|
|
|
|
|
|
|
|
FILEIO_ERROR_TYPE FILEIO_LoadMBR (FILEIO_DRIVE * drive);
|
|
FILEIO_ERROR_TYPE FILEIO_LoadBootSector (FILEIO_DRIVE * drive);
|
|
uint32_t FILEIO_FullClusterNumberGet(FILEIO_DIRECTORY_ENTRY * entry);
|
|
uint32_t FILEIO_ClusterToSector(FILEIO_DRIVE * disk, uint32_t cluster);
|
|
FILEIO_DRIVE * FILEIO_CharToDrive (char c);
|
|
const char * FILEIO_CacheDirectory (FILEIO_DIRECTORY * dir, const char * path, bool createDirectories);
|
|
uint16_t FILEIO_FindNextDelimiter(const char * path);
|
|
FILEIO_RESULT FILEIO_DirectoryMakeSingle (FILEIO_DIRECTORY * dir, const char * path);
|
|
FILEIO_RESULT FILEIO_DirectoryChangeSingle (FILEIO_DIRECTORY * dir, const char * path);
|
|
int FILEIO_DirectoryRemoveSingle (FILEIO_DIRECTORY * directory, char * path);
|
|
void FILEIO_FormatShortFileName (const char * fileName, FILEIO_OBJECT * filePtr);
|
|
uint8_t FILEIO_FileNameTypeGet (const char * fileName, bool partialStringSearch);
|
|
bool FILEIO_ShortFileNameCompare (uint8_t * fileName1, uint8_t * fileName2, uint8_t mode);
|
|
uint32_t FILEIO_FATWrite (FILEIO_DRIVE *disk, uint32_t currentCluster, uint32_t value, uint8_t forceWrite);
|
|
uint32_t FILEIO_FATRead (FILEIO_DRIVE * disk, uint32_t currentCluster);
|
|
FILEIO_DIRECTORY_ENTRY * FILEIO_DirectoryEntryCache (FILEIO_DIRECTORY * directory, FILEIO_ERROR_TYPE * error, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset);
|
|
bool FILEIO_FlushBuffer (FILEIO_DRIVE * disk, FILEIO_BUFFER_ID bufferId);
|
|
FILEIO_ERROR_TYPE FILEIO_EraseClusterChain (uint32_t cluster, FILEIO_DRIVE * disk);
|
|
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryCreate (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, bool allocateDataCluster);
|
|
FILEIO_ERROR_TYPE FILEIO_ClusterAllocate (FILEIO_DRIVE * drive, uint32_t * cluster, bool eraseCluster);
|
|
FILEIO_ERROR_TYPE FILEIO_EraseCluster (FILEIO_DRIVE * drive, uint32_t cluster);
|
|
uint32_t FILEIO_FindEmptyCluster (FILEIO_DRIVE * drive, uint32_t baseCluster);
|
|
uint32_t FILEIO_CreateFirstCluster (FILEIO_OBJECT * filePtr);
|
|
FILEIO_ERROR_TYPE FILEIO_FindShortFileName (FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr, uint8_t * fileName, uint32_t * currentCluster, uint16_t * currentClusterOffset, uint16_t entryOffset, uint16_t attributes, FILEIO_SEARCH_TYPE mode);
|
|
FILEIO_ERROR_TYPE FILEIO_EraseFile (FILEIO_OBJECT * filePtr, uint16_t * entryHandle, bool eraseData);
|
|
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryFindEmpty (FILEIO_OBJECT * filePtr, uint16_t * entryOffset);
|
|
FILEIO_ERROR_TYPE FILEIO_DirectoryEntryPopulate(FILEIO_OBJECT * filePtr, uint16_t * entryHandle, uint8_t attributes, uint32_t cluster);
|
|
FILEIO_ERROR_TYPE FILEIO_NextClusterGet (FILEIO_OBJECT * fo, uint32_t count);
|
|
int FILEIO_DotEntryWrite (FILEIO_DRIVE * drive, uint32_t dot, uint32_t dotdot, FILEIO_TIMESTAMP * timeStamp);
|
|
void FILEIO_ShortFileNameConvert (char * newFileName, char * oldFileName);
|
|
bool FILEIO_IsClusterAllocated(FILEIO_DIRECTORY * directory, FILEIO_OBJECT * filePtr);
|
|
int FILEIO_GetSingleBuffer (FILEIO_DRIVE * drive);
|
|
FILEIO_ERROR_TYPE FILEIO_ForceRecache (FILEIO_DRIVE * disk);
|
|
|
|
#endif
|