2 * FreeRTOS+FAT build 191128 - Note: FreeRTOS+FAT is still in the lab!
\r
3 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
4 * Authors include James Walmsley, Hein Tibosch and Richard Barry
\r
6 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
7 * this software and associated documentation files (the "Software"), to deal in
\r
8 * the Software without restriction, including without limitation the rights to
\r
9 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
10 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
11 * subject to the following conditions:
\r
13 * The above copyright notice and this permission notice shall be included in all
\r
14 * copies or substantial portions of the Software.
\r
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
18 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
19 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
23 * https://www.FreeRTOS.org
\r
31 * @defgroup ERR Error Message
\r
32 * @brief Used to return human readable strings for FreeRTOS+FAT error codes.
\r
37 /* _HT_ with the new GNU settings, the prototype of [v]snprintf()
\r
38 is not included in stdio.h Don't know why. */
\r
39 int snprintf( char *, size_t, const char *, ... );
\r
41 #include "ff_headers.h"
\r
43 #if !defined( ARRAY_SIZE )
\r
44 #define ARRAY_SIZE( x ) ( int )( sizeof( x )/sizeof( x )[ 0 ] )
\r
48 /* This if-block spans the rest of the source file.*/
\r
49 #if( ffconfigDEBUG != 0 )
\r
51 const struct _FFMODULETAB
\r
53 const char * const strModuleName;
\r
54 const uint8_t ucModuleID;
\r
55 } xFreeRTOSFATModuleTable[] =
\r
57 { "Unknown Module", 1}, /* 1 here is ok, as the GetError functions start at the end of the table. */
\r
58 { "ff_ioman.c", FF_GETMODULE( FF_MODULE_IOMAN ) },
\r
59 { "ff_dir.c", FF_GETMODULE( FF_MODULE_DIR ) },
\r
60 { "ff_file.c", FF_GETMODULE( FF_MODULE_FILE ) },
\r
61 { "ff_fat.c", FF_GETMODULE( FF_MODULE_FAT ) },
\r
62 { "ff_crc.c", FF_GETMODULE( FF_MODULE_CRC ) },
\r
63 { "ff_format.c", FF_GETMODULE( FF_MODULE_FORMAT ) },
\r
64 { "ff_memory.c", FF_GETMODULE( FF_MODULE_MEMORY ) },
\r
65 { "ff_string.c", FF_GETMODULE( FF_MODULE_STRING ) },
\r
66 { "ff_locking.c", FF_GETMODULE( FF_MODULE_LOCKING ) },
\r
67 { "ff_time.c", FF_GETMODULE( FF_MODULE_TIME ) },
\r
68 { "Platform Driver", FF_GETMODULE( FF_MODULE_DRIVER ) },
\r
71 #if( ffconfigHAS_FUNCTION_TAB != 0 )
\r
72 const struct _FFFUNCTIONTAB
\r
74 const char * const strFunctionName;
\r
75 const uint16_t ucFunctionID;
\r
76 } xFreeRTOSFATFunctionTable[] =
\r
78 { "Unknown Function", 1},
\r
79 /*----- FF_IOManager_t - The FreeRTOS+FAT I/O Manager */
\r
80 { "FF_CreateIOManger", FF_GETMOD_FUNC( FF_CREATEIOMAN ) },
\r
81 { "FF_DeleteIOManager", FF_GETMOD_FUNC( FF_DESTROYIOMAN ) },
\r
82 { "FF_Mount", FF_GETMOD_FUNC( FF_MOUNT ) },
\r
83 { "FF_Unmount", FF_GETMOD_FUNC( FF_UNMOUNT ) },
\r
84 { "FF_FlushCache", FF_GETMOD_FUNC( FF_FLUSHCACHE ) },
\r
85 { "FF_GetPartitionBlockSize", FF_GETMOD_FUNC( FF_GETPARTITIONBLOCKSIZE ) },
\r
86 { "FF_BlockRead", FF_GETMOD_FUNC( FF_BLOCKREAD ) },
\r
87 { "FF_BlockWrite", FF_GETMOD_FUNC( FF_BLOCKWRITE ) },
\r
88 { "FF_DetermineFatType", FF_GETMOD_FUNC( FF_DETERMINEFATTYPE ) },
\r
89 { "FF_GetEfiPartitionEntry", FF_GETMOD_FUNC( FF_GETEFIPARTITIONENTRY ) },
\r
90 { "FF_UserDriver", FF_GETMOD_FUNC( FF_USERDRIVER ) },
\r
91 { "FF_DecreaseFreeClusters", FF_GETMOD_FUNC( FF_DECREASEFREECLUSTERS ) },
\r
92 { "FF_IncreaseFreeClusters", FF_GETMOD_FUNC( FF_INCREASEFREECLUSTERS ) },
\r
93 { "FF_PartitionSearch", FF_GETMOD_FUNC( FF_PARTITIONSEARCH ) },
\r
94 { "FF_ParseExtended", FF_GETMOD_FUNC( FF_PARSEEXTENDED ) },
\r
97 /*----- FF_DIR - The FreeRTOS+FAT directory handling routines */
\r
98 { "FF_FetchEntryWithContext", FF_GETMOD_FUNC( FF_FETCHENTRYWITHCONTEXT ) },
\r
99 { "FF_PushEntryWithContext", FF_GETMOD_FUNC( FF_PUSHENTRYWITHCONTEXT ) },
\r
100 { "FF_GetEntry", FF_GETMOD_FUNC( FF_GETENTRY ) },
\r
101 { "FF_FindFirst", FF_GETMOD_FUNC( FF_FINDFIRST ) },
\r
102 { "FF_FindNext", FF_GETMOD_FUNC( FF_FINDNEXT ) },
\r
103 { "FF_RewindFind", FF_GETMOD_FUNC( FF_REWINDFIND ) },
\r
104 { "FF_FindFreeDirent", FF_GETMOD_FUNC( FF_FINDFREEDIRENT ) },
\r
105 { "FF_PutEntry", FF_GETMOD_FUNC( FF_PUTENTRY ) },
\r
106 { "FF_CreateShortName", FF_GETMOD_FUNC( FF_CREATESHORTNAME ) },
\r
107 { "FF_CreateLFNs", FF_GETMOD_FUNC( FF_CREATELFNS ) },
\r
108 { "FF_ExtendDirectory", FF_GETMOD_FUNC( FF_EXTENDDIRECTORY ) },
\r
109 { "FF_MkDir", FF_GETMOD_FUNC( FF_MKDIR ) },
\r
110 { "FF_Traverse", FF_GETMOD_FUNC( FF_TRAVERSE ) },
\r
111 { "FF_FindDir", FF_GETMOD_FUNC( FF_FINDDIR ) },
\r
113 /*----- FF_FILE - The FreeRTOS+FAT file handling routines */
\r
114 { "FF_GetModeBits", FF_GETMOD_FUNC( FF_GETMODEBITS ) },
\r
115 { "FF_Open", FF_GETMOD_FUNC( FF_OPEN ) },
\r
116 { "FF_isDirEmpty", FF_GETMOD_FUNC( FF_ISDIREMPTY ) },
\r
117 { "FF_RmDir", FF_GETMOD_FUNC( FF_RMDIR ) },
\r
118 { "FF_RmFile", FF_GETMOD_FUNC( FF_RMFILE ) },
\r
119 { "FF_Move", FF_GETMOD_FUNC( FF_MOVE ) },
\r
120 { "FF_isEOF", FF_GETMOD_FUNC( FF_ISEOF ) },
\r
121 { "FF_GetSequentialClusters", FF_GETMOD_FUNC( FF_GETSEQUENTIALCLUSTERS ) },
\r
122 { "FF_ReadClusters", FF_GETMOD_FUNC( FF_READCLUSTERS ) },
\r
123 { "FF_ExtendFile", FF_GETMOD_FUNC( FF_EXTENDFILE ) },
\r
124 { "FF_WriteClusters", FF_GETMOD_FUNC( FF_WRITECLUSTERS ) },
\r
125 { "FF_Read", FF_GETMOD_FUNC( FF_READ ) },
\r
126 { "FF_GetC", FF_GETMOD_FUNC( FF_GETC ) },
\r
127 { "FF_GetLine", FF_GETMOD_FUNC( FF_GETLINE ) },
\r
128 { "FF_Tell", FF_GETMOD_FUNC( FF_TELL ) },
\r
129 { "FF_Write", FF_GETMOD_FUNC( FF_WRITE ) },
\r
130 { "FF_PutC", FF_GETMOD_FUNC( FF_PUTC ) },
\r
131 { "FF_Seek", FF_GETMOD_FUNC( FF_SEEK ) },
\r
132 { "FF_Invalidate", FF_GETMOD_FUNC( FF_INVALIDATE ) },
\r
133 { "FF_CheckValid", FF_GETMOD_FUNC( FF_CHECKVALID ) },
\r
134 { "FF_Close", FF_GETMOD_FUNC( FF_CLOSE ) },
\r
135 { "FF_SetTime", FF_GETMOD_FUNC( FF_SETTIME ) },
\r
136 { "FF_BytesLeft", FF_GETMOD_FUNC( FF_BYTESLEFT ) },
\r
137 { "FF_SetFileTime", FF_GETMOD_FUNC( FF_SETFILETIME ) },
\r
138 { "FF_InitBuf", FF_GETMOD_FUNC( FF_INITBUF ) },
\r
140 /*----- FF_FAT - The FreeRTOS+FAT FAT handling routines */
\r
141 { "FF_getFATEntry", FF_GETMOD_FUNC( FF_GETFATENTRY ) },
\r
142 { "FF_ClearCluster", FF_GETMOD_FUNC( FF_CLEARCLUSTER ) },
\r
143 { "FF_putFATEntry", FF_GETMOD_FUNC( FF_PUTFATENTRY ) },
\r
144 { "FF_FindFreeCluster", FF_GETMOD_FUNC( FF_FINDFREECLUSTER ) },
\r
145 { "FF_CountFreeClusters", FF_GETMOD_FUNC( FF_COUNTFREECLUSTERS ) },
\r
147 /*----- FF_UNICODE - The FreeRTOS+FAT hashing routines */
\r
148 { "FF_Utf8ctoUtf16c", FF_GETMOD_FUNC( FF_UTF8CTOUTF16C ) },
\r
149 { "FF_Utf16ctoUtf8c", FF_GETMOD_FUNC( FF_UTF16CTOUTF8C ) },
\r
150 { "FF_Utf32ctoUtf16c", FF_GETMOD_FUNC( FF_UTF32CTOUTF16C ) },
\r
151 { "FF_Utf16ctoUtf32c", FF_GETMOD_FUNC( FF_UTF16CTOUTF32C ) },
\r
153 /*----- FF_FORMAT - The FreeRTOS+FAT format routine */
\r
154 { "FF_FormatPartition", FF_GETMOD_FUNC( FF_FORMATPARTITION ) },
\r
156 /*----- FF_STDIO - The FreeRTOS+FAT stdio front-end */
\r
157 { "ff_chmod", FF_GETMOD_FUNC( FF_CHMOD ) },
\r
158 { "ff_stat", FF_GETMOD_FUNC( FF_STAT_FUNC ) },
\r
160 #endif /* ffconfigHAS_FUNCTION_TAB */
\r
162 #define TPASTE2( a, b ) a##b
\r
164 #if( ffconfigLONG_ERR_MSG != 0 )
\r
165 /* To get the full error msg: "Not enough memory (malloc( ) returned NULL )" */
\r
166 #define ERR_ENTRY( M, E ) { M, TPASTE2( FF_ERR_, E ) }
\r
168 /* To get a shorter msg: "NOT_ENOUGH_MEMORY" */
\r
169 #define ERR_ENTRY( M, E ) { #E, TPASTE2( FF_ERR_, E ) }
\r
170 #endif /* ffconfigLONG_ERR_MSG */
\r
172 const struct _FFERRTAB
\r
174 const char * const strErrorString;
\r
175 const uint8_t ucErrorCode; /* Currently there are less then 256 errors, so lets keep this table small. */
\r
176 } xFreeRTOSFATErrorTable[] =
\r
178 {"Unknown or Generic Error!", 1},
\r
179 ERR_ENTRY( "No Error", NONE ),
\r
180 ERR_ENTRY( "Null Pointer provided, (probably for IOMAN)", NULL_POINTER ),
\r
181 ERR_ENTRY( "Not enough memory (malloc() returned NULL)", NOT_ENOUGH_MEMORY ),
\r
182 ERR_ENTRY( "Device Driver returned a FATAL error!", DEVICE_DRIVER_FAILED ),
\r
183 ERR_ENTRY( "The blocksize is not 512 multiple", IOMAN_BAD_BLKSIZE ),
\r
184 ERR_ENTRY( "The memory size, is not a multiple of the blocksize. (Atleast 2 Blocks)", IOMAN_BAD_MEMSIZE ),
\r
185 ERR_ENTRY( "Device is already registered, use FF_UnregisterBlkDevice() first", IOMAN_DEV_ALREADY_REGD ),
\r
186 ERR_ENTRY( "No mountable partition was found on the specified device", IOMAN_NO_MOUNTABLE_PARTITION ),
\r
187 ERR_ENTRY( "The format of the MBR was unrecognised", IOMAN_INVALID_FORMAT ),
\r
188 ERR_ENTRY( "The provided partition number is out-of-range (0 - 3)", IOMAN_INVALID_PARTITION_NUM ),
\r
189 ERR_ENTRY( "The selected partition / volume doesn't appear to be FAT formatted", IOMAN_NOT_FAT_FORMATTED ),
\r
190 ERR_ENTRY( "Cannot register device. (BlkSize not a multiple of 512)", IOMAN_DEV_INVALID_BLKSIZE ),
\r
191 ERR_ENTRY( "Cannot unregister device, a partition is still mounted", IOMAN_PARTITION_MOUNTED ),
\r
192 ERR_ENTRY( "Cannot unmount the partition while there are active FILE handles", IOMAN_ACTIVE_HANDLES ),
\r
193 ERR_ENTRY( "The GPT partition header appears to be corrupt, refusing to mount", IOMAN_GPT_HEADER_CORRUPT ),
\r
194 ERR_ENTRY( "Disk full", IOMAN_NOT_ENOUGH_FREE_SPACE ),
\r
195 ERR_ENTRY( "Attempted to Read a sector out of bounds", IOMAN_OUT_OF_BOUNDS_READ ),
\r
196 ERR_ENTRY( "Attempted to Write a sector out of bounds", IOMAN_OUT_OF_BOUNDS_WRITE ),
\r
197 ERR_ENTRY( "I/O driver is busy", IOMAN_DRIVER_BUSY ),
\r
198 ERR_ENTRY( "I/O driver returned fatal error", IOMAN_DRIVER_FATAL_ERROR ),
\r
199 ERR_ENTRY( "I/O driver returned \"no medium error\"", IOMAN_DRIVER_NOMEDIUM ),
\r
201 ERR_ENTRY( "Cannot open the file, file already in use", FILE_ALREADY_OPEN ),
\r
202 ERR_ENTRY( "The specified file could not be found", FILE_NOT_FOUND ),
\r
203 ERR_ENTRY( "Cannot open a Directory", FILE_OBJECT_IS_A_DIR ),
\r
204 ERR_ENTRY( "Cannot open for writing: File is marked as Read-Only", FILE_IS_READ_ONLY ),
\r
205 ERR_ENTRY( "Path not found", FILE_INVALID_PATH ),
\r
206 ERR_ENTRY( "File operation failed - the file was not opened for writing", FILE_NOT_OPENED_IN_WRITE_MODE ),
\r
207 ERR_ENTRY( "File operation failed - the file was not opened for reading", FILE_NOT_OPENED_IN_READ_MODE ),
\r
208 ERR_ENTRY( "File operation failed - could not extend file", FILE_EXTEND_FAILED ),
\r
209 ERR_ENTRY( "Destination file already exists", FILE_DESTINATION_EXISTS ),
\r
210 ERR_ENTRY( "Source file was not found", FILE_SOURCE_NOT_FOUND ),
\r
211 ERR_ENTRY( "Destination path (dir) was not found", FILE_DIR_NOT_FOUND ),
\r
212 ERR_ENTRY( "Failed to create the directory Entry", FILE_COULD_NOT_CREATE_DIRENT ),
\r
213 ERR_ENTRY( "A file handle was invalid", FILE_BAD_HANDLE ),
\r
214 #if( ffconfigREMOVABLE_MEDIA != 0 )
\r
215 ERR_ENTRY( "File handle got invalid because media was removed", FILE_MEDIA_REMOVED ),
\r
216 #endif /* ffconfigREMOVABLE_MEDIA */
\r
217 ERR_ENTRY( "A file or folder of the same name already exists", DIR_OBJECT_EXISTS ),
\r
218 ERR_ENTRY( "DIR_DIRECTORY_FULL", DIR_DIRECTORY_FULL ),
\r
219 ERR_ENTRY( "DIR_END_OF_DIR", DIR_END_OF_DIR ),
\r
220 ERR_ENTRY( "The directory is not empty", DIR_NOT_EMPTY ),
\r
221 ERR_ENTRY( "Could not extend File or Folder - No Free Space!", FAT_NO_FREE_CLUSTERS ),
\r
222 ERR_ENTRY( "Could not find the directory specified by the path", DIR_INVALID_PATH ),
\r
223 ERR_ENTRY( "The Root Dir is full, and cannot be extended on Fat12 or 16 volumes", DIR_CANT_EXTEND_ROOT_DIR ),
\r
224 ERR_ENTRY( "Not enough space to extend the directory.", DIR_EXTEND_FAILED ),
\r
225 ERR_ENTRY( "Name exceeds the number of allowed characters for a filename", DIR_NAME_TOO_LONG ),
\r
227 #if( ffconfigUNICODE_UTF16_SUPPORT != 0 )
\r
228 ERR_ENTRY( "An invalid Unicode character was provided!", UNICODE_INVALID_CODE ),
\r
229 ERR_ENTRY( "Not enough space in the UTF-16 buffer to encode the entire sequence", UNICODE_DEST_TOO_SMALL ),
\r
230 ERR_ENTRY( "An invalid UTF-16 sequence was encountered", UNICODE_INVALID_SEQUENCE ),
\r
231 ERR_ENTRY( "Filename exceeds MAX long-filename length when converted to UTF-16", UNICODE_CONVERSION_EXCEEDED ),
\r
232 #endif /* ffconfigUNICODE_UTF16_SUPPORT */
\r
237 * @brief Returns a pointer to a string relating to a FreeRTOS+FAT error code.
\r
239 * @param iErrorCode The error code.
\r
241 * @return Pointer to a string describing the error.
\r
244 const char *FF_GetErrMessage( FF_Error_t iErrorCode )
\r
246 uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATErrorTable );
\r
250 if( ( ( UBaseType_t )xFreeRTOSFATErrorTable[ stCount ].ucErrorCode ) == FF_GETERROR( iErrorCode ) )
\r
255 return xFreeRTOSFATErrorTable[ stCount ].strErrorString;
\r
258 const char *FF_GetErrModule( FF_Error_t iErrorCode )
\r
260 uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATModuleTable );
\r
263 if( xFreeRTOSFATModuleTable[ stCount ].ucModuleID == ( uint8_t )FF_GETMODULE( iErrorCode ) )
\r
268 return xFreeRTOSFATModuleTable[ stCount ].strModuleName;
\r
271 #if( ffconfigHAS_FUNCTION_TAB != 0 )
\r
272 const char *FF_GetErrFunction( FF_Error_t iErrorCode )
\r
274 uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATFunctionTable );
\r
275 uint16_t ModuleFunc = FF_GETMOD_FUNC( iErrorCode );
\r
276 static char funcCode[32];
\r
277 while( stCount-- != 0 )
\r
279 if( xFreeRTOSFATFunctionTable[ stCount ].ucFunctionID == ModuleFunc )
\r
281 return xFreeRTOSFATFunctionTable[ stCount ].strFunctionName;
\r
284 snprintf( funcCode, sizeof( funcCode ), "Func %X", ModuleFunc );
\r
285 return ( const char * )funcCode;
\r
287 #endif /* ffconfigHAS_FUNCTION_TAB */
\r
289 const char *FF_GetErrDescription( FF_Error_t iErrorCode, char *apBuf, int aMaxlen )
\r
291 if( FF_isERR( iErrorCode ) )
\r
293 #if( ffconfigHAS_FUNCTION_TAB != 0 )
\r
294 snprintf (apBuf, ( size_t ) aMaxlen, "%s::%s::%s",
\r
295 FF_GetErrModule( iErrorCode ),
\r
296 FF_GetErrFunction( iErrorCode ),
\r
297 FF_GetErrMessage( iErrorCode ));
\r
299 snprintf (apBuf, ( size_t ) aMaxlen, "%s::%s",
\r
300 FF_GetErrModule( iErrorCode ),
\r
301 FF_GetErrMessage( iErrorCode ));
\r
302 #endif /* ffconfigHAS_FUNCTION_TAB */
\r
306 snprintf (apBuf, ( size_t ) aMaxlen, "No error");
\r
311 #endif /* ffconfigDEBUG != 0 */
\r