]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/FreeRTOS-Plus-FAT/ff_error.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / FreeRTOS-Plus-FAT / ff_error.c
1 /*\r
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
5  *\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
12  *\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
15  *\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
22  *\r
23  * https://www.FreeRTOS.org\r
24  *\r
25  */\r
26 \r
27 /**\r
28  *      @file           ff_error.c\r
29  *      @ingroup        ERROR\r
30  *\r
31  *      @defgroup       ERR Error Message\r
32  *      @brief          Used to return human readable strings for FreeRTOS+FAT error codes.\r
33  *\r
34  **/\r
35 #include <stdio.h>\r
36 \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
40 \r
41 #include "ff_headers.h"\r
42 \r
43 #if !defined( ARRAY_SIZE )\r
44         #define ARRAY_SIZE( x ) ( int )( sizeof( x )/sizeof( x )[ 0 ] )\r
45 #endif\r
46 \r
47 \r
48 /* This if-block spans the rest of the source file.*/\r
49 #if( ffconfigDEBUG != 0 )\r
50 \r
51 const struct _FFMODULETAB\r
52 {\r
53         const char * const strModuleName;\r
54         const uint8_t ucModuleID;\r
55 } xFreeRTOSFATModuleTable[] =\r
56 {\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
69 };\r
70 \r
71 #if( ffconfigHAS_FUNCTION_TAB != 0 )\r
72 const struct _FFFUNCTIONTAB\r
73 {\r
74         const char * const strFunctionName;\r
75         const uint16_t ucFunctionID;\r
76 } xFreeRTOSFATFunctionTable[] =\r
77 {\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
95 \r
96 \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
112 \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
139 \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
146 \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
152 \r
153 /*----- FF_FORMAT - The FreeRTOS+FAT format routine */\r
154         { "FF_FormatPartition",       FF_GETMOD_FUNC( FF_FORMATPARTITION ) },\r
155 \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
159 };\r
160 #endif /* ffconfigHAS_FUNCTION_TAB */\r
161 \r
162 #define TPASTE2( a, b )  a##b\r
163 \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
167 #else\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
171 \r
172 const struct _FFERRTAB\r
173 {\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
177 {\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
200 \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
226 \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
233 };\r
234 \r
235 /**\r
236  *      @public\r
237  *      @brief  Returns a pointer to a string relating to a FreeRTOS+FAT error code.\r
238  *\r
239  *      @param  iErrorCode      The error code.\r
240  *\r
241  *      @return Pointer to a string describing the error.\r
242  *\r
243  **/\r
244 const char *FF_GetErrMessage( FF_Error_t iErrorCode )\r
245 {\r
246         uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATErrorTable );\r
247 \r
248         while( stCount-- )\r
249         {\r
250                 if( ( ( UBaseType_t )xFreeRTOSFATErrorTable[ stCount ].ucErrorCode ) == FF_GETERROR( iErrorCode ) )\r
251                 {\r
252                         break;\r
253                 }\r
254         }\r
255         return xFreeRTOSFATErrorTable[ stCount ].strErrorString;\r
256 }\r
257 \r
258 const char *FF_GetErrModule( FF_Error_t iErrorCode )\r
259 {\r
260         uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATModuleTable );\r
261         while( stCount-- )\r
262         {\r
263                 if( xFreeRTOSFATModuleTable[ stCount ].ucModuleID == ( uint8_t )FF_GETMODULE( iErrorCode ) )\r
264                 {\r
265                         break;\r
266                 }\r
267         }\r
268         return xFreeRTOSFATModuleTable[ stCount ].strModuleName;\r
269 }\r
270 \r
271 #if( ffconfigHAS_FUNCTION_TAB != 0 )\r
272         const char *FF_GetErrFunction( FF_Error_t iErrorCode )\r
273         {\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
278                 {\r
279                         if( xFreeRTOSFATFunctionTable[ stCount ].ucFunctionID == ModuleFunc )\r
280                         {\r
281                                 return xFreeRTOSFATFunctionTable[ stCount ].strFunctionName;\r
282                         }\r
283                 }\r
284                 snprintf( funcCode, sizeof( funcCode ), "Func %X", ModuleFunc );\r
285                 return ( const char * )funcCode;\r
286         }\r
287 #endif /* ffconfigHAS_FUNCTION_TAB */\r
288 \r
289 const char *FF_GetErrDescription( FF_Error_t iErrorCode, char *apBuf, int aMaxlen )\r
290 {\r
291         if( FF_isERR( iErrorCode ) )\r
292         {\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
298 #else\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
303         }\r
304         else\r
305         {\r
306                 snprintf (apBuf, ( size_t ) aMaxlen, "No error");\r
307         }\r
308         return apBuf;\r
309 }\r
310 \r
311 #endif  /* ffconfigDEBUG != 0 */\r