]> git.sur5r.net Git - freertos/blob - FreeRTOS-Labs/Source/FreeRTOS-Plus-FAT/ff_dev_support.c
Add the Labs projects provided in the V10.2.1_191129 zip file.
[freertos] / FreeRTOS-Labs / Source / FreeRTOS-Plus-FAT / ff_dev_support.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 #include <stdio.h>\r
28 #include <string.h>\r
29 \r
30 /* FreeRTOS includes. */\r
31 #include "FreeRTOS.h"\r
32 #include "task.h"\r
33 #include "portable.h"\r
34 \r
35 #include "ff_headers.h"\r
36 #include "ff_devices.h"\r
37 \r
38 #ifndef ARRAY_SIZE\r
39 #       define  ARRAY_SIZE( x ) ( int )( sizeof( x ) / sizeof( x )[ 0 ] )\r
40 #endif\r
41 \r
42 #if( ffconfigDEV_SUPPORT == 0 )\r
43         #error No use to include this module if ffconfigDEV_SUPPORT is disabled\r
44 #endif /* ffconfigDEV_SUPPORT == 0 */\r
45 \r
46 struct SFileCache\r
47 {\r
48         char pcFileName[16];\r
49         uint32_t ulFileLength;\r
50         uint32_t ulFilePointer;\r
51 };\r
52 \r
53 struct SFileCache xFiles[ 16 ];\r
54 \r
55 enum eCACHE_ACTION\r
56 {\r
57         eCACHE_LOOKUP,\r
58         eCACHE_ADD,\r
59         eCACHE_REMOVE,\r
60 };\r
61 \r
62 const char pcDevicePath[] = ffconfigDEV_PATH;\r
63 \r
64 struct SFileCache *pxFindFile( const char *pcFname, enum eCACHE_ACTION eAction )\r
65 {\r
66 BaseType_t xIndex, xFreeIndex = -1;\r
67 struct SFileCache *pxResult = NULL;\r
68 \r
69         for( xIndex = 0; xIndex < ARRAY_SIZE( xFiles ); xIndex++ )\r
70         {\r
71                 if( xFiles[ xIndex ].pcFileName[ 0 ] == '\0' )\r
72                 {\r
73                         if( xFreeIndex < 0 )\r
74                         {\r
75                                 xFreeIndex = xIndex;\r
76                         }\r
77                 }\r
78                 else if( strcmp( xFiles[ xIndex ].pcFileName, pcFname ) == 0 )\r
79                 {\r
80                         if( eAction == eCACHE_REMOVE )\r
81                         {\r
82                                 xFiles[ xIndex ].pcFileName[ 0 ] = '\0';\r
83                         }\r
84 \r
85                         pxResult = xFiles + xIndex;\r
86                         break;\r
87                 }\r
88         }\r
89 \r
90         if( ( pxResult == NULL ) && ( eAction == eCACHE_ADD ) && ( xFreeIndex >= 0 ) )\r
91         {\r
92                 pxResult = xFiles + xFreeIndex;\r
93                 snprintf( pxResult->pcFileName, sizeof( pxResult->pcFileName ), "%s", pcFname );\r
94                 pxResult->ulFileLength = 0;\r
95                 pxResult->ulFilePointer = 0;\r
96         }\r
97 \r
98         return pxResult;\r
99 }\r
100 \r
101 BaseType_t xCheckDevicePath( const char *pcPath )\r
102 {\r
103 BaseType_t xDevLength;\r
104 BaseType_t xPathLength;\r
105 BaseType_t xIsDevice;\r
106 \r
107         xDevLength = sizeof( pcDevicePath ) - 1;\r
108         xPathLength = strlen( pcPath );\r
109 \r
110         /* System "/dev" should not match with "/device/etc". */\r
111         if( ( xPathLength >= xDevLength ) &&\r
112                 ( memcmp( pcDevicePath, pcPath, xDevLength ) == 0 ) &&\r
113                 ( ( pcPath[ xDevLength ] == '\0' ) || ( pcPath[ xDevLength ] == '/' ) ) )\r
114         {\r
115                 xIsDevice = FF_DEV_CHAR_DEV;\r
116         }\r
117         else\r
118         {\r
119                 xIsDevice = FF_DEV_NO_DEV;\r
120         }\r
121 \r
122         return xIsDevice;\r
123 }\r
124 \r
125 BaseType_t FF_Device_Open( const char *pcPath, FF_FILE *pxStream )\r
126 {\r
127 uint8_t ucIsDevice;\r
128 \r
129         ucIsDevice = xCheckDevicePath( pcPath );\r
130         if( ucIsDevice != pdFALSE )\r
131         {\r
132         const char *pcBaseName = pcPath;\r
133 \r
134                 if( memcmp( pcBaseName, pcDevicePath, sizeof( pcDevicePath ) - 1 ) == 0 )\r
135                 {\r
136                         pcBaseName = pcBaseName + sizeof( pcDevicePath );\r
137                 }\r
138 \r
139                 pxStream->pxDevNode = pxFindFile( pcBaseName, eCACHE_ADD );\r
140                 if( pxStream->pxDevNode != NULL )\r
141                 {\r
142                         pxStream->pxDevNode->ulFilePointer = 0;\r
143                         if( ( pxStream->ucMode & ( FF_MODE_WRITE | FF_MODE_APPEND | FF_MODE_CREATE ) ) == 0 )\r
144                         {\r
145                                 pxStream->ulFileSize = pxStream->pxDevNode->ulFileLength;\r
146                         }\r
147                 }\r
148         }\r
149 \r
150         return ucIsDevice;\r
151 }\r
152 \r
153 void FF_Device_Close( FF_FILE * pxStream )\r
154 {\r
155         if( pxStream->pxDevNode != NULL )\r
156         {\r
157                 pxStream->ulFileSize = 0ul;\r
158                 pxStream->ulFilePointer = 0ul;\r
159         }\r
160 }\r
161 \r
162 size_t FF_Device_Read( void *pvBuf, size_t lSize, size_t lCount, FF_FILE * pxStream )\r
163 {\r
164         lCount *= lSize;\r
165         return lCount;\r
166 }\r
167 \r
168 size_t FF_Device_Write( const void *pvBuf, size_t lSize, size_t lCount, FF_FILE * pxStream )\r
169 {\r
170         lCount *= lSize;\r
171 \r
172         if( pxStream->pxDevNode != NULL )\r
173         {\r
174 \r
175                 pxStream->pxDevNode->ulFilePointer += lCount;\r
176                 if( pxStream->pxDevNode->ulFileLength < pxStream->pxDevNode->ulFilePointer )\r
177                 {\r
178                         pxStream->pxDevNode->ulFileLength = pxStream->pxDevNode->ulFilePointer;\r
179                 }\r
180         }\r
181         return lCount;\r
182 }\r
183 \r
184 int FF_Device_Seek( FF_FILE *pxStream, long lOffset, int iWhence )\r
185 {\r
186         if( pxStream->pxDevNode != NULL )\r
187         {\r
188                 if( iWhence == FF_SEEK_SET )\r
189                 {\r
190                         pxStream->pxDevNode->ulFilePointer = lOffset;\r
191                 }\r
192                 else if( iWhence == FF_SEEK_END )\r
193                 {\r
194                         pxStream->pxDevNode->ulFilePointer = pxStream->pxDevNode->ulFileLength - lOffset;\r
195                 }\r
196         }\r
197 \r
198         return 0;\r
199 }\r
200 \r
201 int FF_Device_GetDirEnt( const char *pcPath, FF_DirEnt_t *pxDirEnt )\r
202 {\r
203 BaseType_t xIsDotDir = 0;\r
204         if( pxDirEnt->pcFileName[ 0 ] == '.' )\r
205         {\r
206                 if( ( pxDirEnt->pcFileName[ 1 ] == '.' ) &&\r
207                         ( pxDirEnt->pcFileName[ 2 ] == '\0' ) )\r
208                 {\r
209                         xIsDotDir = 2;\r
210                 }\r
211                 else if( pxDirEnt->pcFileName[ 1 ] == '\0' )\r
212                 {\r
213                         xIsDotDir = 1;\r
214                 }\r
215         }\r
216         if( xIsDotDir == 0 )\r
217         {\r
218         struct SFileCache *pxDevNode;\r
219 \r
220                 pxDevNode = pxFindFile( pxDirEnt->pcFileName, eCACHE_LOOKUP );\r
221 \r
222                 pxDirEnt->ucIsDeviceDir = FF_DEV_CHAR_DEV;\r
223                 if( pxDevNode != NULL )\r
224                 {\r
225                         pxDirEnt->ulFileSize = pxDevNode->ulFileLength;\r
226                 }\r
227                 else if( pxDirEnt->ulFileSize < 2048 )\r
228                 {\r
229                         pxDirEnt->ulFileSize = 2048;\r
230                 }\r
231         }\r
232 \r
233         return 1024;\r
234 }\r
235 \r