1 /*****************************************************************************
2 * FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
3 * Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
5 * This program is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 3 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
20 * Alternative Licensing is available directly from the Copyright holder, *
21 * (James Walmsley). For more information consult LICENSING.TXT to obtain *
22 * a Commercial license. *
24 * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
26 * Removing the above notice is illegal and will invalidate this license. *
27 *****************************************************************************
28 * See http://worm.me.uk/fullfat for more information. *
29 * Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
30 *****************************************************************************/
34 * @author James Walmsley
41 #include <stdlib.h> // Use of malloc()
43 #include "ff_config.h"
45 #include "ff_safety.h" // Provide thread-safety via semaphores.
46 #include "ff_memory.h" // Memory access routines for ENDIAN independence.
49 //#define FF_MAX_PARTITION_NAME 5 ///< Partition name length.
51 #define FF_T_FAT12 0x0A
52 #define FF_T_FAT16 0x0B
53 #define FF_T_FAT32 0x0C
55 #define FF_MODE_READ 0x01 ///< Buffer / FILE Mode for Read Access.
56 #define FF_MODE_WRITE 0x02 ///< Buffer / FILE Mode for Write Access.
57 #define FF_MODE_APPEND 0x04 ///< FILE Mode Append Access.
58 #define FF_MODE_CREATE 0x08 ///< FILE Mode Create file if not existing.
59 #define FF_MODE_TRUNCATE 0x10 ///< FILE Mode Truncate an Existing file.
60 #define FF_MODE_DIR 0x80 ///< Special Mode to open a Dir. (Internal use ONLY!)
62 #define FF_BUF_MAX_HANDLES 0xFFFF ///< Maximum number handles sharing a buffer. (16 bit integer, we don't want to overflow it!)
65 * I/O Driver Definitions
66 * Provide access to any Block Device via the following interfaces.
67 * Returns the number of blocks actually read or written.
71 * A special information structure for the FullFAT mass storage device
76 FF_T_UINT32 TotalBlocks
;
79 typedef FF_T_SINT32 (*FF_WRITE_BLOCKS
) (FF_T_UINT8
*pBuffer
, FF_T_UINT32 SectorAddress
, FF_T_UINT32 Count
, void *pParam
);
80 typedef FF_T_SINT32 (*FF_READ_BLOCKS
) (FF_T_UINT8
*pBuffer
, FF_T_UINT32 SectorAddress
, FF_T_UINT32 Count
, void *pParam
);
82 #define FF_ERR_DRIVER_BUSY -10
83 #define FF_ERR_DRIVER_FATAL_ERROR -11
87 * @brief Describes the block device driver interface to FullFAT.
90 FF_WRITE_BLOCKS fnWriteBlocks
; ///< Function Pointer, to write a block(s) from a block device.
91 FF_READ_BLOCKS fnReadBlocks
; ///< Function Pointer, to read a block(s) from a block device.
92 FF_T_UINT16 devBlkSize
; ///< Block size that the driver deals with.
93 void *pParam
; ///< Pointer to some parameters e.g. for a Low-Level Driver Handle
98 * @brief FullFAT handles memory with buffers, described as below.
99 * @note This may change throughout development.
102 FF_T_UINT32 Sector
; ///< The LBA of the Cached sector.
103 FF_T_UINT8 Mode
; ///< Read or Write mode.
104 FF_T_UINT16 NumHandles
; ///< Number of objects using this buffer.
105 FF_T_UINT16 Persistance
; ///< For the persistance algorithm.
106 FF_T_UINT32 LRU
; ///< For the Least Recently Used algorithm.
107 FF_T_BOOL Modified
; ///< If the sector was modified since read.
108 FF_T_BOOL Valid
; ///< Initially FALSE.
109 FF_T_UINT8
*pBuffer
; ///< Pointer to the cache block.
113 FF_T_INT8 Path
[FF_MAX_PATH
];
114 FF_T_UINT32 DirCluster
;
115 #ifdef FF_HASH_TABLE_SUPPORT
116 FF_HASH_TABLE pHashTable
;
123 * @brief FullFAT identifies a partition with the following data.
124 * @note This may shrink as development and optimisation goes on.
127 //FF_T_UINT8 ID; ///< Partition Incremental ID number.
128 FF_T_UINT8 Type
; ///< Partition Type Identifier.
129 FF_T_UINT16 BlkSize
; ///< Size of a Sector Block in bytes.
130 FF_T_UINT8 BlkFactor
; ///< Scale Factor for blocksizes above 512!
131 //FF_T_INT8 Name[FF_MAX_PARTITION_NAME]; ///< Partition Identifier e.g. c: sd0: etc.
132 //FF_T_INT8 VolLabel[12]; ///< Volume Label of the partition.
133 FF_T_UINT32 BeginLBA
; ///< LBA start address of the partition.
134 FF_T_UINT32 PartSize
; ///< Size of Partition in number of sectors.
135 FF_T_UINT32 FatBeginLBA
; ///< LBA of the FAT tables.
136 FF_T_UINT8 NumFATS
; ///< Number of FAT tables.
137 FF_T_UINT32 SectorsPerFAT
; ///< Number of sectors per Fat.
138 FF_T_UINT8 SectorsPerCluster
; ///< Number of sectors per Cluster.
139 FF_T_UINT32 TotalSectors
;
140 FF_T_UINT32 DataSectors
;
141 FF_T_UINT32 RootDirSectors
;
142 FF_T_UINT32 FirstDataSector
;
143 FF_T_UINT16 ReservedSectors
;
144 FF_T_UINT32 ClusterBeginLBA
; ///< LBA of first cluster.
145 FF_T_UINT32 NumClusters
; ///< Number of clusters.
146 FF_T_UINT32 RootDirCluster
; ///< Cluster number of the root directory entry.
147 FF_T_UINT32 LastFreeCluster
;
148 FF_T_UINT32 FreeClusterCount
; ///< Records free space on mount.
149 FF_T_BOOL PartitionMounted
; ///< FF_TRUE if the partition is mounted, otherwise FF_FALSE.
151 FF_PATHCACHE PathCache
[FF_PATH_CACHE_DEPTH
];
160 * @brief FF_IOMAN Object description.
162 * FullFAT functions around an object like this.
164 #define FF_FAT_LOCK 0x01 ///< Lock bit mask for FAT table locking.
165 #define FF_DIR_LOCK 0x02 ///< Lock bit mask for DIR modification locking.
166 //#define FF_PATHCACHE_LOCK 0x04
170 * @brief FF_IOMAN Object. A developer should not touch these values.
172 * In the commercial version these values are encapsulated. In the open-source
173 * version they are left completely open, in case someone really "needs" :P to
174 * do something stupid and access their members themselves. Also to help the
175 * open-source community help me improve FullFAT, and aid understanding.
177 * THIS WOULD BE VERY STUPID, SO DON'T DO IT. Unless your're writing a patch or
182 FF_BLK_DEVICE
*pBlkDevice
; ///< Pointer to a Block device description.
183 FF_PARTITION
*pPartition
; ///< Pointer to a partition description.
184 FF_BUFFER
*pBuffers
; ///< Pointer to the first buffer description.
185 FF_T_UINT32 LastReplaced
; ///< Marks which sector was last replaced in the cache.
186 FF_T_UINT16 BlkSize
; ///< The Block size that IOMAN is configured to.
187 FF_T_UINT8
*pCacheMem
; ///< Pointer to a block of memory for the cache.
188 FF_T_UINT16 CacheSize
; ///< Size of the cache in number of Sectors.
189 FF_T_UINT8 MemAllocation
; ///< Bit-Mask identifying allocated pointers.
190 FF_T_UINT8 Locks
; ///< Lock Flag for FAT & DIR Locking etc (This must be accessed via a semaphore).
191 void *pSemaphore
; ///< Pointer to a Semaphore object. (For buffer description modifications only!).
192 void *FirstFile
; ///< Pointer to the first File object.
195 // Bit-Masks for Memory Allocation testing.
196 #define FF_IOMAN_ALLOC_BLKDEV 0x01 ///< Flags the pBlkDevice pointer is allocated.
197 #define FF_IOMAN_ALLOC_PART 0x02 ///< Flags the pPartition pointer is allocated.
198 #define FF_IOMAN_ALLOC_BUFDESCR 0x04 ///< Flags the pBuffers pointer is allocated.
199 #define FF_IOMAN_ALLOC_BUFFERS 0x08 ///< Flags the pCacheMem pointer is allocated.
200 #define FF_IOMAN_ALLOC_RESERVED 0xF0 ///< Reserved Section.
203 //---------- PROTOTYPES (in order of appearance)
205 // PUBLIC (Interfaces):
206 FF_IOMAN
*FF_CreateIOMAN (FF_T_UINT8
*pCacheMem
, FF_T_UINT32 Size
, FF_T_UINT16 BlkSize
, FF_ERROR
*pError
);
207 FF_ERROR
FF_DestroyIOMAN (FF_IOMAN
*pIoman
);
208 FF_ERROR
FF_RegisterBlkDevice (FF_IOMAN
*pIoman
, FF_T_UINT16 BlkSize
, FF_WRITE_BLOCKS fnWriteBlocks
, FF_READ_BLOCKS fnReadBlocks
, void *pParam
);
209 FF_ERROR
FF_UnregisterBlkDevice (FF_IOMAN
*pIoman
);
210 FF_ERROR
FF_MountPartition (FF_IOMAN
*pIoman
, FF_T_UINT8 PartitionNumber
);
211 FF_ERROR
FF_UnmountPartition (FF_IOMAN
*pIoman
);
212 FF_ERROR
FF_FlushCache (FF_IOMAN
*pIoman
);
213 FF_T_SINT32
FF_GetPartitionBlockSize(FF_IOMAN
*pIoman
);
215 #ifdef FF_64_NUM_SUPPORT
216 FF_T_UINT64
FF_GetVolumeSize(FF_IOMAN
*pIoman
);
218 FF_T_UINT32
FF_GetVolumeSize(FF_IOMAN
*pIoman
);
221 // PUBLIC (To FullFAT Only):
222 FF_ERROR
FF_IncreaseFreeClusters (FF_IOMAN
*pIoman
, FF_T_UINT32 Count
);
223 FF_ERROR
FF_DecreaseFreeClusters (FF_IOMAN
*pIoman
, FF_T_UINT32 Count
);
224 FF_BUFFER
*FF_GetBuffer (FF_IOMAN
*pIoman
, FF_T_UINT32 Sector
, FF_T_UINT8 Mode
);
225 void FF_ReleaseBuffer (FF_IOMAN
*pIoman
, FF_BUFFER
*pBuffer
);
227 // PRIVATE (For this module only!):