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
30 /* FreeRTOS includes. */
\r
31 #include "FreeRTOS.h"
\r
33 #include "portable.h"
\r
35 #include "ff_headers.h"
\r
36 #include "ff_devices.h"
\r
39 # define ARRAY_SIZE( x ) ( int )( sizeof( x ) / sizeof( x )[ 0 ] )
\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
48 char pcFileName[16];
\r
49 uint32_t ulFileLength;
\r
50 uint32_t ulFilePointer;
\r
53 struct SFileCache xFiles[ 16 ];
\r
62 const char pcDevicePath[] = ffconfigDEV_PATH;
\r
64 struct SFileCache *pxFindFile( const char *pcFname, enum eCACHE_ACTION eAction )
\r
66 BaseType_t xIndex, xFreeIndex = -1;
\r
67 struct SFileCache *pxResult = NULL;
\r
69 for( xIndex = 0; xIndex < ARRAY_SIZE( xFiles ); xIndex++ )
\r
71 if( xFiles[ xIndex ].pcFileName[ 0 ] == '\0' )
\r
73 if( xFreeIndex < 0 )
\r
75 xFreeIndex = xIndex;
\r
78 else if( strcmp( xFiles[ xIndex ].pcFileName, pcFname ) == 0 )
\r
80 if( eAction == eCACHE_REMOVE )
\r
82 xFiles[ xIndex ].pcFileName[ 0 ] = '\0';
\r
85 pxResult = xFiles + xIndex;
\r
90 if( ( pxResult == NULL ) && ( eAction == eCACHE_ADD ) && ( xFreeIndex >= 0 ) )
\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
101 BaseType_t xCheckDevicePath( const char *pcPath )
\r
103 BaseType_t xDevLength;
\r
104 BaseType_t xPathLength;
\r
105 BaseType_t xIsDevice;
\r
107 xDevLength = sizeof( pcDevicePath ) - 1;
\r
108 xPathLength = strlen( pcPath );
\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
115 xIsDevice = FF_DEV_CHAR_DEV;
\r
119 xIsDevice = FF_DEV_NO_DEV;
\r
125 BaseType_t FF_Device_Open( const char *pcPath, FF_FILE *pxStream )
\r
127 uint8_t ucIsDevice;
\r
129 ucIsDevice = xCheckDevicePath( pcPath );
\r
130 if( ucIsDevice != pdFALSE )
\r
132 const char *pcBaseName = pcPath;
\r
134 if( memcmp( pcBaseName, pcDevicePath, sizeof( pcDevicePath ) - 1 ) == 0 )
\r
136 pcBaseName = pcBaseName + sizeof( pcDevicePath );
\r
139 pxStream->pxDevNode = pxFindFile( pcBaseName, eCACHE_ADD );
\r
140 if( pxStream->pxDevNode != NULL )
\r
142 pxStream->pxDevNode->ulFilePointer = 0;
\r
143 if( ( pxStream->ucMode & ( FF_MODE_WRITE | FF_MODE_APPEND | FF_MODE_CREATE ) ) == 0 )
\r
145 pxStream->ulFileSize = pxStream->pxDevNode->ulFileLength;
\r
153 void FF_Device_Close( FF_FILE * pxStream )
\r
155 if( pxStream->pxDevNode != NULL )
\r
157 pxStream->ulFileSize = 0ul;
\r
158 pxStream->ulFilePointer = 0ul;
\r
162 size_t FF_Device_Read( void *pvBuf, size_t lSize, size_t lCount, FF_FILE * pxStream )
\r
168 size_t FF_Device_Write( const void *pvBuf, size_t lSize, size_t lCount, FF_FILE * pxStream )
\r
172 if( pxStream->pxDevNode != NULL )
\r
175 pxStream->pxDevNode->ulFilePointer += lCount;
\r
176 if( pxStream->pxDevNode->ulFileLength < pxStream->pxDevNode->ulFilePointer )
\r
178 pxStream->pxDevNode->ulFileLength = pxStream->pxDevNode->ulFilePointer;
\r
184 int FF_Device_Seek( FF_FILE *pxStream, long lOffset, int iWhence )
\r
186 if( pxStream->pxDevNode != NULL )
\r
188 if( iWhence == FF_SEEK_SET )
\r
190 pxStream->pxDevNode->ulFilePointer = lOffset;
\r
192 else if( iWhence == FF_SEEK_END )
\r
194 pxStream->pxDevNode->ulFilePointer = pxStream->pxDevNode->ulFileLength - lOffset;
\r
201 int FF_Device_GetDirEnt( const char *pcPath, FF_DirEnt_t *pxDirEnt )
\r
203 BaseType_t xIsDotDir = 0;
\r
204 if( pxDirEnt->pcFileName[ 0 ] == '.' )
\r
206 if( ( pxDirEnt->pcFileName[ 1 ] == '.' ) &&
\r
207 ( pxDirEnt->pcFileName[ 2 ] == '\0' ) )
\r
211 else if( pxDirEnt->pcFileName[ 1 ] == '\0' )
\r
216 if( xIsDotDir == 0 )
\r
218 struct SFileCache *pxDevNode;
\r
220 pxDevNode = pxFindFile( pxDirEnt->pcFileName, eCACHE_LOOKUP );
\r
222 pxDirEnt->ucIsDeviceDir = FF_DEV_CHAR_DEV;
\r
223 if( pxDevNode != NULL )
\r
225 pxDirEnt->ulFileSize = pxDevNode->ulFileLength;
\r
227 else if( pxDirEnt->ulFileSize < 2048 )
\r
229 pxDirEnt->ulFileSize = 2048;
\r