CARPLAY版本整理

This commit is contained in:
2025-01-21 16:49:37 +08:00
commit f0fb64e4e6
26542 changed files with 13719676 additions and 0 deletions

View File

@ -0,0 +1,258 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_crc.c
* @ingroup CRC
*
* @defgroup CRC CRC Checksums for Strings
* @brief Provides fast hashing functions.
*
**/
#include "ff_headers.h"
/*static*/ const uint32_t crc32_table[ 256 ] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
uint32_t FF_GetCRC32( uint8_t * pbyData,
uint32_t stLength )
{
register uint32_t crc = 0xFFFFFFFF;
while( stLength-- != 0 )
{
crc = ( ( crc >> 8 ) & 0x00FFFFFF ) ^ crc32_table[ ( crc ^ *( pbyData++ ) ) & 0x000000FF ];
}
return crc ^ 0xFFFFFFFF;
}
static const uint8_t crc16_table_low[ 256 ] =
{
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
};
static const uint8_t crc16_table_high[ 256 ] =
{
0x000, 0x0c0, 0x0c1, 0x001, 0x0c3, 0x003, 0x002, 0x0c2,
0x0c6, 0x006, 0x007, 0x0c7, 0x005, 0x0c5, 0x0c4, 0x004,
0x0cc, 0x00c, 0x00d, 0x0cd, 0x00f, 0x0cf, 0x0ce, 0x00e,
0x00a, 0x0ca, 0x0cb, 0x00b, 0x0c9, 0x009, 0x008, 0x0c8,
0x0d8, 0x018, 0x019, 0x0d9, 0x01b, 0x0db, 0x0da, 0x01a,
0x01e, 0x0de, 0x0df, 0x01f, 0x0dd, 0x01d, 0x01c, 0x0dc,
0x014, 0x0d4, 0x0d5, 0x015, 0x0d7, 0x017, 0x016, 0x0d6,
0x0d2, 0x012, 0x013, 0x0d3, 0x011, 0x0d1, 0x0d0, 0x010,
0x0f0, 0x030, 0x031, 0x0f1, 0x033, 0x0f3, 0x0f2, 0x032,
0x036, 0x0f6, 0x0f7, 0x037, 0x0f5, 0x035, 0x034, 0x0f4,
0x03c, 0x0fc, 0x0fd, 0x03d, 0x0ff, 0x03f, 0x03e, 0x0fe,
0x0fa, 0x03a, 0x03b, 0x0fb, 0x039, 0x0f9, 0x0f8, 0x038,
0x028, 0x0e8, 0x0e9, 0x029, 0x0eb, 0x02b, 0x02a, 0x0ea,
0x0ee, 0x02e, 0x02f, 0x0ef, 0x02d, 0x0ed, 0x0ec, 0x02c,
0x0e4, 0x024, 0x025, 0x0e5, 0x027, 0x0e7, 0x0e6, 0x026,
0x022, 0x0e2, 0x0e3, 0x023, 0x0e1, 0x021, 0x020, 0x0e0,
0x0a0, 0x060, 0x061, 0x0a1, 0x063, 0x0a3, 0x0a2, 0x062,
0x066, 0x0a6, 0x0a7, 0x067, 0x0a5, 0x065, 0x064, 0x0a4,
0x06c, 0x0ac, 0x0ad, 0x06d, 0x0af, 0x06f, 0x06e, 0x0ae,
0x0aa, 0x06a, 0x06b, 0x0ab, 0x069, 0x0a9, 0x0a8, 0x068,
0x078, 0x0b8, 0x0b9, 0x079, 0x0bb, 0x07b, 0x07a, 0x0ba,
0x0be, 0x07e, 0x07f, 0x0bf, 0x07d, 0x0bd, 0x0bc, 0x07c,
0x0b4, 0x074, 0x075, 0x0b5, 0x077, 0x0b7, 0x0b6, 0x076,
0x072, 0x0b2, 0x0b3, 0x073, 0x0b1, 0x071, 0x070, 0x0b0,
0x050, 0x090, 0x091, 0x051, 0x093, 0x053, 0x052, 0x092,
0x096, 0x056, 0x057, 0x097, 0x055, 0x095, 0x094, 0x054,
0x09c, 0x05c, 0x05d, 0x09d, 0x05f, 0x09f, 0x09e, 0x05e,
0x05a, 0x09a, 0x09b, 0x05b, 0x099, 0x059, 0x058, 0x098,
0x088, 0x048, 0x049, 0x089, 0x04b, 0x08b, 0x08a, 0x04a,
0x04e, 0x08e, 0x08f, 0x04f, 0x08d, 0x04d, 0x04c, 0x08c,
0x044, 0x084, 0x085, 0x045, 0x087, 0x047, 0x046, 0x086,
0x082, 0x042, 0x043, 0x083, 0x041, 0x081, 0x080, 0x040,
};
/*****************************************************************************
* Description: Function to 16 bit CRC check a block of memory
*
*
* Parameters: pbyData - Pointer to the source data
* stLength - The length to CRC
*
* Return value: The 16 bit CRC value
*
*****************************************************************************/
uint16_t FF_GetCRC16( uint8_t * pbyData,
uint32_t stLength )
{
uint8_t bTableValue;
uint16_t wCRC = 0;
while( stLength-- != 0 )
{
bTableValue = ( uint8_t ) ( ( wCRC & 0x00FF ) ^ *pbyData++ );
wCRC = ( uint16_t ) ( ( ( crc16_table_high[ bTableValue ] ) << 8 ) +
( crc16_table_low[ bTableValue ] ^ ( ( wCRC >> 8 ) & 0x00FF ) ) );
}
return wCRC;
}
static const uint8_t crc8_table[ 256 ] =
{
0, 94, 188, 226, 97, 63, 221, 131,
194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30,
95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160,
225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61,
124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197,
132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88,
25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230,
167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123,
58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15,
78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146,
211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44,
109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177,
240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73,
8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212,
149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106,
43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247,
182, 232, 10, 84, 215, 137, 107, 53
};
/*****************************************************************************
* Description: Function to CRC check a block of memory
*
* Parameters: pbyData - Pointer to the source data
* stLength - The length to CRC
*
* Return value: The 8 bit CRC value
*
*****************************************************************************/
uint8_t FF_GetCRC8( uint8_t * pbyData,
uint32_t stLength )
{
uint8_t byCRC = 0, byData;
while( stLength-- != 0 )
{
byData = *pbyData++;
byCRC = crc8_table[ ( byCRC ^ byData ) ];
}
return byCRC;
}

View File

@ -0,0 +1,252 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <stdio.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "portable.h"
#include "ff_headers.h"
#include "ff_devices.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE( x ) ( int ) ( sizeof( x ) / sizeof( x )[ 0 ] )
#endif
#if ( ffconfigDEV_SUPPORT == 0 )
#error No use to include this module if ffconfigDEV_SUPPORT is disabled
#endif /* ffconfigDEV_SUPPORT == 0 */
struct SFileCache
{
char pcFileName[ 16 ];
uint32_t ulFileLength;
uint32_t ulFilePointer;
};
struct SFileCache xFiles[ 16 ];
enum eCACHE_ACTION
{
eCACHE_LOOKUP,
eCACHE_ADD,
eCACHE_REMOVE,
};
const char pcDevicePath[] = ffconfigDEV_PATH;
struct SFileCache * pxFindFile( const char * pcFname,
enum eCACHE_ACTION eAction )
{
BaseType_t xIndex, xFreeIndex = -1;
struct SFileCache * pxResult = NULL;
for( xIndex = 0; xIndex < ARRAY_SIZE( xFiles ); xIndex++ )
{
if( xFiles[ xIndex ].pcFileName[ 0 ] == '\0' )
{
if( xFreeIndex < 0 )
{
xFreeIndex = xIndex;
}
}
else if( strcmp( xFiles[ xIndex ].pcFileName, pcFname ) == 0 )
{
if( eAction == eCACHE_REMOVE )
{
xFiles[ xIndex ].pcFileName[ 0 ] = '\0';
}
pxResult = xFiles + xIndex;
break;
}
}
if( ( pxResult == NULL ) && ( eAction == eCACHE_ADD ) && ( xFreeIndex >= 0 ) )
{
pxResult = xFiles + xFreeIndex;
snprintf( pxResult->pcFileName, sizeof( pxResult->pcFileName ), "%s", pcFname );
pxResult->ulFileLength = 0;
pxResult->ulFilePointer = 0;
}
return pxResult;
}
BaseType_t xCheckDevicePath( const char * pcPath )
{
BaseType_t xDevLength;
BaseType_t xPathLength;
BaseType_t xIsDevice;
xDevLength = sizeof( pcDevicePath ) - 1;
xPathLength = strlen( pcPath );
/* System "/dev" should not match with "/device/etc". */
if( ( xPathLength >= xDevLength ) &&
( memcmp( pcDevicePath, pcPath, xDevLength ) == 0 ) &&
( ( pcPath[ xDevLength ] == '\0' ) || ( pcPath[ xDevLength ] == '/' ) ) )
{
xIsDevice = FF_DEV_CHAR_DEV;
}
else
{
xIsDevice = FF_DEV_NO_DEV;
}
return xIsDevice;
}
BaseType_t FF_Device_Open( const char * pcPath,
FF_FILE * pxStream )
{
uint8_t ucIsDevice;
ucIsDevice = xCheckDevicePath( pcPath );
if( ucIsDevice != pdFALSE )
{
const char * pcBaseName = pcPath;
if( memcmp( pcBaseName, pcDevicePath, sizeof( pcDevicePath ) - 1 ) == 0 )
{
pcBaseName = pcBaseName + sizeof( pcDevicePath );
}
pxStream->pxDevNode = pxFindFile( pcBaseName, eCACHE_ADD );
if( pxStream->pxDevNode != NULL )
{
pxStream->pxDevNode->ulFilePointer = 0;
if( ( pxStream->ucMode & ( FF_MODE_WRITE | FF_MODE_APPEND | FF_MODE_CREATE ) ) == 0 )
{
pxStream->ulFileSize = pxStream->pxDevNode->ulFileLength;
}
}
}
return ucIsDevice;
}
void FF_Device_Close( FF_FILE * pxStream )
{
if( pxStream->pxDevNode != NULL )
{
pxStream->ulFileSize = 0ul;
pxStream->ulFilePointer = 0ul;
}
}
size_t FF_Device_Read( void * pvBuf,
size_t lSize,
size_t lCount,
FF_FILE * pxStream )
{
lCount *= lSize;
return lCount;
}
size_t FF_Device_Write( const void * pvBuf,
size_t lSize,
size_t lCount,
FF_FILE * pxStream )
{
lCount *= lSize;
if( pxStream->pxDevNode != NULL )
{
pxStream->pxDevNode->ulFilePointer += lCount;
if( pxStream->pxDevNode->ulFileLength < pxStream->pxDevNode->ulFilePointer )
{
pxStream->pxDevNode->ulFileLength = pxStream->pxDevNode->ulFilePointer;
}
}
return lCount;
}
int FF_Device_Seek( FF_FILE * pxStream,
long lOffset,
int iWhence )
{
if( pxStream->pxDevNode != NULL )
{
if( iWhence == FF_SEEK_SET )
{
pxStream->pxDevNode->ulFilePointer = lOffset;
}
else if( iWhence == FF_SEEK_END )
{
pxStream->pxDevNode->ulFilePointer = pxStream->pxDevNode->ulFileLength - lOffset;
}
}
return 0;
}
int FF_Device_GetDirEnt( const char * pcPath,
FF_DirEnt_t * pxDirEnt )
{
BaseType_t xIsDotDir = 0;
if( pxDirEnt->pcFileName[ 0 ] == '.' )
{
if( ( pxDirEnt->pcFileName[ 1 ] == '.' ) &&
( pxDirEnt->pcFileName[ 2 ] == '\0' ) )
{
xIsDotDir = 2;
}
else if( pxDirEnt->pcFileName[ 1 ] == '\0' )
{
xIsDotDir = 1;
}
}
if( xIsDotDir == 0 )
{
struct SFileCache * pxDevNode;
pxDevNode = pxFindFile( pxDirEnt->pcFileName, eCACHE_LOOKUP );
pxDirEnt->ucIsDeviceDir = FF_DEV_CHAR_DEV;
if( pxDevNode != NULL )
{
pxDirEnt->ulFileSize = pxDevNode->ulFileLength;
}
else if( pxDirEnt->ulFileSize < 2048 )
{
pxDirEnt->ulFileSize = 2048;
}
}
return 1024;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_error.c
* @ingroup ERROR
*
* @defgroup ERR Error Message
* @brief Used to return human readable strings for FreeRTOS+FAT error codes.
*
**/
#include <stdio.h>
#include "ff_headers.h"
#if !defined( ARRAY_SIZE )
#define ARRAY_SIZE( x ) ( int ) ( sizeof( x ) / sizeof( x )[ 0 ] )
#endif
/* This if-block spans the rest of the source file.*/
#if ( ffconfigDEBUG != 0 )
const struct _FFMODULETAB
{
const char * const strModuleName;
const uint8_t ucModuleID;
}
xFreeRTOSFATModuleTable[] =
{
{ "Unknown Module", 1 }, /* 1 here is ok, as the GetError functions start at the end of the table. */
{ "ff_ioman.c", FF_GETMODULE( FF_MODULE_IOMAN ) },
{ "ff_dir.c", FF_GETMODULE( FF_MODULE_DIR ) },
{ "ff_file.c", FF_GETMODULE( FF_MODULE_FILE ) },
{ "ff_fat.c", FF_GETMODULE( FF_MODULE_FAT ) },
{ "ff_crc.c", FF_GETMODULE( FF_MODULE_CRC ) },
{ "ff_format.c", FF_GETMODULE( FF_MODULE_FORMAT ) },
{ "ff_memory.c", FF_GETMODULE( FF_MODULE_MEMORY ) },
{ "ff_string.c", FF_GETMODULE( FF_MODULE_STRING ) },
{ "ff_locking.c", FF_GETMODULE( FF_MODULE_LOCKING ) },
{ "ff_time.c", FF_GETMODULE( FF_MODULE_TIME ) },
{ "Platform Driver", FF_GETMODULE( FF_MODULE_DRIVER ) },
};
#if ( ffconfigHAS_FUNCTION_TAB != 0 )
const struct _FFFUNCTIONTAB
{
const char * const strFunctionName;
const uint16_t ucFunctionID;
}
xFreeRTOSFATFunctionTable[] =
{
{ "Unknown Function", 1 },
/*----- FF_IOManager_t - The FreeRTOS+FAT I/O Manager */
{ "FF_CreateIOManger", FF_GETMOD_FUNC( FF_CREATEIOMAN ) },
{ "FF_DeleteIOManager", FF_GETMOD_FUNC( FF_DESTROYIOMAN ) },
{ "FF_Mount", FF_GETMOD_FUNC( FF_MOUNT ) },
{ "FF_Unmount", FF_GETMOD_FUNC( FF_UNMOUNT ) },
{ "FF_FlushCache", FF_GETMOD_FUNC( FF_FLUSHCACHE ) },
{ "FF_GetPartitionBlockSize", FF_GETMOD_FUNC( FF_GETPARTITIONBLOCKSIZE ) },
{ "FF_BlockRead", FF_GETMOD_FUNC( FF_BLOCKREAD ) },
{ "FF_BlockWrite", FF_GETMOD_FUNC( FF_BLOCKWRITE ) },
{ "FF_DetermineFatType", FF_GETMOD_FUNC( FF_DETERMINEFATTYPE ) },
{ "FF_GetEfiPartitionEntry", FF_GETMOD_FUNC( FF_GETEFIPARTITIONENTRY ) },
{ "FF_UserDriver", FF_GETMOD_FUNC( FF_USERDRIVER ) },
{ "FF_DecreaseFreeClusters", FF_GETMOD_FUNC( FF_DECREASEFREECLUSTERS ) },
{ "FF_IncreaseFreeClusters", FF_GETMOD_FUNC( FF_INCREASEFREECLUSTERS ) },
{ "FF_PartitionSearch", FF_GETMOD_FUNC( FF_PARTITIONSEARCH ) },
{ "FF_ParseExtended", FF_GETMOD_FUNC( FF_PARSEEXTENDED ) },
/*----- FF_DIR - The FreeRTOS+FAT directory handling routines */
{ "FF_FetchEntryWithContext", FF_GETMOD_FUNC( FF_FETCHENTRYWITHCONTEXT ) },
{ "FF_PushEntryWithContext", FF_GETMOD_FUNC( FF_PUSHENTRYWITHCONTEXT ) },
{ "FF_GetEntry", FF_GETMOD_FUNC( FF_GETENTRY ) },
{ "FF_FindFirst", FF_GETMOD_FUNC( FF_FINDFIRST ) },
{ "FF_FindNext", FF_GETMOD_FUNC( FF_FINDNEXT ) },
{ "FF_RewindFind", FF_GETMOD_FUNC( FF_REWINDFIND ) },
{ "FF_FindFreeDirent", FF_GETMOD_FUNC( FF_FINDFREEDIRENT ) },
{ "FF_PutEntry", FF_GETMOD_FUNC( FF_PUTENTRY ) },
{ "FF_CreateShortName", FF_GETMOD_FUNC( FF_CREATESHORTNAME ) },
{ "FF_CreateLFNs", FF_GETMOD_FUNC( FF_CREATELFNS ) },
{ "FF_ExtendDirectory", FF_GETMOD_FUNC( FF_EXTENDDIRECTORY ) },
{ "FF_MkDir", FF_GETMOD_FUNC( FF_MKDIR ) },
{ "FF_Traverse", FF_GETMOD_FUNC( FF_TRAVERSE ) },
{ "FF_FindDir", FF_GETMOD_FUNC( FF_FINDDIR ) },
/*----- FF_FILE - The FreeRTOS+FAT file handling routines */
{ "FF_GetModeBits", FF_GETMOD_FUNC( FF_GETMODEBITS ) },
{ "FF_Open", FF_GETMOD_FUNC( FF_OPEN ) },
{ "FF_isDirEmpty", FF_GETMOD_FUNC( FF_ISDIREMPTY ) },
{ "FF_RmDir", FF_GETMOD_FUNC( FF_RMDIR ) },
{ "FF_RmFile", FF_GETMOD_FUNC( FF_RMFILE ) },
{ "FF_Move", FF_GETMOD_FUNC( FF_MOVE ) },
{ "FF_isEOF", FF_GETMOD_FUNC( FF_ISEOF ) },
{ "FF_GetSequentialClusters", FF_GETMOD_FUNC( FF_GETSEQUENTIALCLUSTERS ) },
{ "FF_ReadClusters", FF_GETMOD_FUNC( FF_READCLUSTERS ) },
{ "FF_ExtendFile", FF_GETMOD_FUNC( FF_EXTENDFILE ) },
{ "FF_WriteClusters", FF_GETMOD_FUNC( FF_WRITECLUSTERS ) },
{ "FF_Read", FF_GETMOD_FUNC( FF_READ ) },
{ "FF_GetC", FF_GETMOD_FUNC( FF_GETC ) },
{ "FF_GetLine", FF_GETMOD_FUNC( FF_GETLINE ) },
{ "FF_Tell", FF_GETMOD_FUNC( FF_TELL ) },
{ "FF_Write", FF_GETMOD_FUNC( FF_WRITE ) },
{ "FF_PutC", FF_GETMOD_FUNC( FF_PUTC ) },
{ "FF_Seek", FF_GETMOD_FUNC( FF_SEEK ) },
{ "FF_Invalidate", FF_GETMOD_FUNC( FF_INVALIDATE ) },
{ "FF_CheckValid", FF_GETMOD_FUNC( FF_CHECKVALID ) },
{ "FF_Close", FF_GETMOD_FUNC( FF_CLOSE ) },
{ "FF_SetTime", FF_GETMOD_FUNC( FF_SETTIME ) },
{ "FF_BytesLeft", FF_GETMOD_FUNC( FF_BYTESLEFT ) },
{ "FF_SetFileTime", FF_GETMOD_FUNC( FF_SETFILETIME ) },
{ "FF_InitBuf", FF_GETMOD_FUNC( FF_INITBUF ) },
/*----- FF_FAT - The FreeRTOS+FAT FAT handling routines */
{ "FF_getFATEntry", FF_GETMOD_FUNC( FF_GETFATENTRY ) },
{ "FF_ClearCluster", FF_GETMOD_FUNC( FF_CLEARCLUSTER ) },
{ "FF_putFATEntry", FF_GETMOD_FUNC( FF_PUTFATENTRY ) },
{ "FF_FindFreeCluster", FF_GETMOD_FUNC( FF_FINDFREECLUSTER ) },
{ "FF_CountFreeClusters", FF_GETMOD_FUNC( FF_COUNTFREECLUSTERS ) },
/*----- FF_UNICODE - The FreeRTOS+FAT hashing routines */
{ "FF_Utf8ctoUtf16c", FF_GETMOD_FUNC( FF_UTF8CTOUTF16C ) },
{ "FF_Utf16ctoUtf8c", FF_GETMOD_FUNC( FF_UTF16CTOUTF8C ) },
{ "FF_Utf32ctoUtf16c", FF_GETMOD_FUNC( FF_UTF32CTOUTF16C ) },
{ "FF_Utf16ctoUtf32c", FF_GETMOD_FUNC( FF_UTF16CTOUTF32C ) },
/*----- FF_FORMAT - The FreeRTOS+FAT format routine */
{ "FF_FormatPartition", FF_GETMOD_FUNC( FF_FORMATPARTITION ) },
/*----- FF_STDIO - The FreeRTOS+FAT stdio front-end */
{ "ff_chmod", FF_GETMOD_FUNC( FF_CHMOD ) },
{ "ff_stat", FF_GETMOD_FUNC( FF_STAT_FUNC ) },
};
#endif /* ffconfigHAS_FUNCTION_TAB */
#define TPASTE2( a, b ) a ## b
#if ( ffconfigLONG_ERR_MSG != 0 )
/* To get the full error msg: "Not enough memory (malloc( ) returned NULL )" */
#define ERR_ENTRY( M, E ) { M, TPASTE2( FF_ERR_, E ) }
#else
/* To get a shorter msg: "NOT_ENOUGH_MEMORY" */
#define ERR_ENTRY( M, E ) { # E, TPASTE2( FF_ERR_, E ) }
#endif /* ffconfigLONG_ERR_MSG */
const struct _FFERRTAB
{
const char * const strErrorString;
const uint8_t ucErrorCode; /* Currently there are less then 256 errors, so lets keep this table small. */
}
xFreeRTOSFATErrorTable[] =
{
{ "Unknown or Generic Error!", 1 },
ERR_ENTRY( "No Error", NONE ),
ERR_ENTRY( "Null Pointer provided, (probably for IOMAN)", NULL_POINTER ),
ERR_ENTRY( "Not enough memory (malloc() returned NULL)", NOT_ENOUGH_MEMORY ),
ERR_ENTRY( "Device Driver returned a FATAL error!", DEVICE_DRIVER_FAILED ),
ERR_ENTRY( "The blocksize is not 512 multiple", IOMAN_BAD_BLKSIZE ),
ERR_ENTRY( "The memory size, is not a multiple of the blocksize. (Atleast 2 Blocks)", IOMAN_BAD_MEMSIZE ),
ERR_ENTRY( "Device is already registered, use FF_UnregisterBlkDevice() first", IOMAN_DEV_ALREADY_REGD ),
ERR_ENTRY( "No mountable partition was found on the specified device", IOMAN_NO_MOUNTABLE_PARTITION ),
ERR_ENTRY( "The format of the MBR was unrecognised", IOMAN_INVALID_FORMAT ),
ERR_ENTRY( "The provided partition number is out-of-range (0 - 3)", IOMAN_INVALID_PARTITION_NUM ),
ERR_ENTRY( "The selected partition / volume doesn't appear to be FAT formatted", IOMAN_NOT_FAT_FORMATTED ),
ERR_ENTRY( "Cannot register device. (BlkSize not a multiple of 512)", IOMAN_DEV_INVALID_BLKSIZE ),
ERR_ENTRY( "Cannot unregister device, a partition is still mounted", IOMAN_PARTITION_MOUNTED ),
ERR_ENTRY( "Cannot unmount the partition while there are active FILE handles", IOMAN_ACTIVE_HANDLES ),
ERR_ENTRY( "The GPT partition header appears to be corrupt, refusing to mount", IOMAN_GPT_HEADER_CORRUPT ),
ERR_ENTRY( "Disk full", IOMAN_NOT_ENOUGH_FREE_SPACE ),
ERR_ENTRY( "Attempted to Read a sector out of bounds", IOMAN_OUT_OF_BOUNDS_READ ),
ERR_ENTRY( "Attempted to Write a sector out of bounds", IOMAN_OUT_OF_BOUNDS_WRITE ),
ERR_ENTRY( "I/O driver is busy", IOMAN_DRIVER_BUSY ),
ERR_ENTRY( "I/O driver returned fatal error", IOMAN_DRIVER_FATAL_ERROR ),
ERR_ENTRY( "I/O driver returned \"no medium error\"", IOMAN_DRIVER_NOMEDIUM ),
ERR_ENTRY( "Cannot open the file, file already in use", FILE_ALREADY_OPEN ),
ERR_ENTRY( "The specified file could not be found", FILE_NOT_FOUND ),
ERR_ENTRY( "Cannot open a Directory", FILE_OBJECT_IS_A_DIR ),
ERR_ENTRY( "Cannot open for writing: File is marked as Read-Only", FILE_IS_READ_ONLY ),
ERR_ENTRY( "Path not found", FILE_INVALID_PATH ),
ERR_ENTRY( "File operation failed - the file was not opened for writing", FILE_NOT_OPENED_IN_WRITE_MODE ),
ERR_ENTRY( "File operation failed - the file was not opened for reading", FILE_NOT_OPENED_IN_READ_MODE ),
ERR_ENTRY( "File operation failed - could not extend file", FILE_EXTEND_FAILED ),
ERR_ENTRY( "Destination file already exists", FILE_DESTINATION_EXISTS ),
ERR_ENTRY( "Source file was not found", FILE_SOURCE_NOT_FOUND ),
ERR_ENTRY( "Destination path (dir) was not found", FILE_DIR_NOT_FOUND ),
ERR_ENTRY( "Failed to create the directory Entry", FILE_COULD_NOT_CREATE_DIRENT ),
ERR_ENTRY( "A file handle was invalid", FILE_BAD_HANDLE ),
#if ( ffconfigREMOVABLE_MEDIA != 0 )
ERR_ENTRY( "File handle got invalid because media was removed", FILE_MEDIA_REMOVED ),
#endif /* ffconfigREMOVABLE_MEDIA */
ERR_ENTRY( "A file or folder of the same name already exists", DIR_OBJECT_EXISTS ),
ERR_ENTRY( "DIR_DIRECTORY_FULL", DIR_DIRECTORY_FULL ),
ERR_ENTRY( "DIR_END_OF_DIR", DIR_END_OF_DIR ),
ERR_ENTRY( "The directory is not empty", DIR_NOT_EMPTY ),
ERR_ENTRY( "Could not extend File or Folder - No Free Space!", FAT_NO_FREE_CLUSTERS ),
ERR_ENTRY( "Could not find the directory specified by the path", DIR_INVALID_PATH ),
ERR_ENTRY( "The Root Dir is full, and cannot be extended on Fat12 or 16 volumes", DIR_CANT_EXTEND_ROOT_DIR ),
ERR_ENTRY( "Not enough space to extend the directory.", DIR_EXTEND_FAILED ),
ERR_ENTRY( "Name exceeds the number of allowed characters for a filename", DIR_NAME_TOO_LONG ),
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
ERR_ENTRY( "An invalid Unicode character was provided!", UNICODE_INVALID_CODE ),
ERR_ENTRY( "Not enough space in the UTF-16 buffer to encode the entire sequence", UNICODE_DEST_TOO_SMALL ),
ERR_ENTRY( "An invalid UTF-16 sequence was encountered", UNICODE_INVALID_SEQUENCE ),
ERR_ENTRY( "Filename exceeds MAX long-filename length when converted to UTF-16", UNICODE_CONVERSION_EXCEEDED ),
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
};
/**
* @public
* @brief Returns a pointer to a string relating to a FreeRTOS+FAT error code.
*
* @param iErrorCode The error code.
*
* @return Pointer to a string describing the error.
*
**/
const char * FF_GetErrMessage( FF_Error_t iErrorCode )
{
uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATErrorTable );
while( stCount-- )
{
if( ( ( UBaseType_t ) xFreeRTOSFATErrorTable[ stCount ].ucErrorCode ) == FF_GETERROR( iErrorCode ) )
{
break;
}
}
return xFreeRTOSFATErrorTable[ stCount ].strErrorString;
}
const char * FF_GetErrModule( FF_Error_t iErrorCode )
{
uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATModuleTable );
while( stCount-- )
{
if( xFreeRTOSFATModuleTable[ stCount ].ucModuleID == ( uint8_t ) FF_GETMODULE( iErrorCode ) )
{
break;
}
}
return xFreeRTOSFATModuleTable[ stCount ].strModuleName;
}
#if ( ffconfigHAS_FUNCTION_TAB != 0 )
const char * FF_GetErrFunction( FF_Error_t iErrorCode )
{
uint32_t stCount = ARRAY_SIZE( xFreeRTOSFATFunctionTable );
uint16_t ModuleFunc = FF_GETMOD_FUNC( iErrorCode );
static char funcCode[ 32 ];
while( stCount-- != 0 )
{
if( xFreeRTOSFATFunctionTable[ stCount ].ucFunctionID == ModuleFunc )
{
return xFreeRTOSFATFunctionTable[ stCount ].strFunctionName;
}
}
snprintf( funcCode, sizeof( funcCode ), "Func %X", ModuleFunc );
return ( const char * ) funcCode;
}
#endif /* ffconfigHAS_FUNCTION_TAB */
const char * FF_GetErrDescription( FF_Error_t iErrorCode,
char * apBuf,
int aMaxlen )
{
if( FF_isERR( iErrorCode ) )
{
#if ( ffconfigHAS_FUNCTION_TAB != 0 )
snprintf( apBuf, ( size_t ) aMaxlen, "%s::%s::%s",
FF_GetErrModule( iErrorCode ),
FF_GetErrFunction( iErrorCode ),
FF_GetErrMessage( iErrorCode ) );
#else
snprintf( apBuf, ( size_t ) aMaxlen, "%s::%s",
FF_GetErrModule( iErrorCode ),
FF_GetErrMessage( iErrorCode ) );
#endif /* ffconfigHAS_FUNCTION_TAB */
}
else
{
snprintf( apBuf, ( size_t ) aMaxlen, "No error" );
}
return apBuf;
}
#endif /* ffconfigDEBUG != 0 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,348 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "ff_headers.h"
#include "event_groups.h"
#ifndef configUSE_RECURSIVE_MUTEXES
#error configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h
#else
#if ( configUSE_RECURSIVE_MUTEXES != 1 )
#error configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h
#endif
#endif /* configUSE_RECURSIVE_MUTEXES */
#if ( INCLUDE_vTaskDelay != 1 )
#error Missing some FreeRTOS define
#endif
/* There are two areas which are protected with a semaphore:
* Directories and the FAT area.
* The masks below are used when calling Group Event functions. */
#define FF_FAT_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_FAT_LOCK )
#define FF_DIR_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_DIR_LOCK )
/* This is not a real lock: it is a bit (or semaphore) will will be given
* each time when a sector buffer is released. */
#define FF_BUF_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_BUF_LOCK )
#ifndef FF_TIME_TO_WAIT_FOR_EVENT_TICKS
/* The maximum time to wait for a event group bit to come high,
* which gives access to a "critical section": either directories,
* or the FAT. */
#define FF_TIME_TO_WAIT_FOR_EVENT_TICKS pdMS_TO_TICKS( 10000UL )
#endif
/*-----------------------------------------------------------*/
BaseType_t FF_TrySemaphore( void * pxSemaphore,
uint32_t ulTime_ms )
{
BaseType_t xReturn;
/* HT: Actually FF_TrySemaphore is never used. */
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
return 0;
}
configASSERT( pxSemaphore );
xReturn = xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) pxSemaphore, pdMS_TO_TICKS( ulTime_ms ) );
return xReturn;
}
/*-----------------------------------------------------------*/
void FF_PendSemaphore( void * pxSemaphore )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* No need to take the semaphore. */
return;
}
configASSERT( pxSemaphore );
xSemaphoreTakeRecursive( ( SemaphoreHandle_t ) pxSemaphore, portMAX_DELAY );
}
/*-----------------------------------------------------------*/
void FF_ReleaseSemaphore( void * pxSemaphore )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
configASSERT( pxSemaphore );
xSemaphoreGiveRecursive( ( SemaphoreHandle_t ) pxSemaphore );
}
/*-----------------------------------------------------------*/
void FF_Sleep( uint32_t ulTime_ms )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* This sleep is used as a kind of yield.
* Not necessary while the Scheduler does not run. */
return;
}
vTaskDelay( pdMS_TO_TICKS( ulTime_ms ) );
}
/*-----------------------------------------------------------*/
void FF_DeleteEvents( FF_IOManager_t * pxIOManager )
{
if( pxIOManager->xEventGroup != NULL )
{
vEventGroupDelete( pxIOManager->xEventGroup );
}
}
/*-----------------------------------------------------------*/
BaseType_t FF_CreateEvents( FF_IOManager_t * pxIOManager )
{
BaseType_t xResult;
pxIOManager->xEventGroup = xEventGroupCreate();
if( pxIOManager->xEventGroup != NULL )
{
xEventGroupSetBits( pxIOManager->xEventGroup,
FF_FAT_LOCK_EVENT_BITS | FF_DIR_LOCK_EVENT_BITS | FF_BUF_LOCK_EVENT_BITS );
xResult = pdTRUE;
}
else
{
xResult = pdFALSE;
}
return xResult;
}
/*-----------------------------------------------------------*/
void FF_LockDirectory( FF_IOManager_t * pxIOManager )
{
EventBits_t xBits;
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
for( ; ; )
{
/* Called when a task want to make changes to a directory.
* It waits for the desired bit to come high, and clears the
* bit so that other tasks can not take it. */
xBits = xEventGroupWaitBits( pxIOManager->xEventGroup,
FF_DIR_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
pdTRUE, /* xClearOnExit */
pdFALSE, /* xWaitForAllBits n.a. */
FF_TIME_TO_WAIT_FOR_EVENT_TICKS );
if( ( xBits & FF_DIR_LOCK_EVENT_BITS ) != 0 )
{
/* This task has cleared the desired bit.
* It now 'owns' the resource. */
break;
}
}
}
/*-----------------------------------------------------------*/
void FF_UnlockDirectory( FF_IOManager_t * pxIOManager )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
configASSERT( ( xEventGroupGetBits( pxIOManager->xEventGroup ) & FF_DIR_LOCK_EVENT_BITS ) == 0 );
xEventGroupSetBits( pxIOManager->xEventGroup, FF_DIR_LOCK_EVENT_BITS );
}
/*-----------------------------------------------------------*/
int FF_Has_Lock( FF_IOManager_t * pxIOManager,
uint32_t aBits )
{
int iReturn;
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return 0;
}
void * handle = xTaskGetCurrentTaskHandle();
if( ( aBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
{
if( ( pxIOManager->pvFATLockHandle != NULL ) && ( pxIOManager->pvFATLockHandle == handle ) )
{
iReturn = pdTRUE;
}
else
{
iReturn = pdFALSE;
}
}
else
{
iReturn = pdFALSE;
}
return iReturn;
}
void FF_Assert_Lock( FF_IOManager_t * pxIOManager,
uint32_t aBits )
{
void * handle;
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
handle = xTaskGetCurrentTaskHandle();
if( ( aBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
{
configASSERT( ( pxIOManager->pvFATLockHandle != NULL ) && ( pxIOManager->pvFATLockHandle == handle ) );
/* In case configASSERT() is not defined. */
( void ) pxIOManager;
( void ) handle;
}
}
void FF_LockFAT( FF_IOManager_t * pxIOManager )
{
EventBits_t xBits;
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
configASSERT( FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE );
for( ; ; )
{
/* Called when a task want to make changes to the FAT area.
* It waits for the desired bit to come high, and clears the
* bit so that other tasks can not take it. */
xBits = xEventGroupWaitBits( pxIOManager->xEventGroup,
FF_FAT_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
pdTRUE, /* xClearOnExit */
pdFALSE, /* xWaitForAllBits n.a. */
FF_TIME_TO_WAIT_FOR_EVENT_TICKS );
if( ( xBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
{
/* This task has cleared the desired bit.
* It now 'owns' the resource. */
pxIOManager->pvFATLockHandle = xTaskGetCurrentTaskHandle();
break;
}
}
}
/*-----------------------------------------------------------*/
void FF_UnlockFAT( FF_IOManager_t * pxIOManager )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
configASSERT( ( xEventGroupGetBits( pxIOManager->xEventGroup ) & FF_FAT_LOCK_EVENT_BITS ) == 0 );
pxIOManager->pvFATLockHandle = NULL;
xEventGroupSetBits( pxIOManager->xEventGroup, FF_FAT_LOCK_EVENT_BITS );
}
/*-----------------------------------------------------------*/
BaseType_t FF_BufferWait( FF_IOManager_t * pxIOManager,
uint32_t xWaitMS )
{
EventBits_t xBits;
BaseType_t xReturn;
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return pdTRUE;
}
/* This function is called when a task is waiting for a sector buffer
* to become available. Each time when a sector buffer becomes available,
* the bit will be set ( see FF_BufferProceed() here below ). */
xBits = xEventGroupWaitBits( pxIOManager->xEventGroup,
FF_BUF_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
pdTRUE, /* xClearOnExit */
pdFALSE, /* xWaitForAllBits n.a. */
pdMS_TO_TICKS( xWaitMS ) );
if( ( xBits & FF_BUF_LOCK_EVENT_BITS ) != 0 )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}
/*-----------------------------------------------------------*/
void FF_BufferProceed( FF_IOManager_t * pxIOManager )
{
if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )
{
/* Scheduler not yet active. */
return;
}
/* Wake-up a task that is waiting for a sector buffer to become available. */
xEventGroupSetBits( pxIOManager->xEventGroup, FF_BUF_LOCK_EVENT_BITS );
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,117 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_memory.c
* @ingroup MEMORY
*
* @defgroup MEMORY FreeRTOS+FAT Memory Access Routines
* @brief Handles memory access in a portable way.
*
* Provides simple, fast, and portable access to memory routines.
* These are only used to read data from buffers. That are LITTLE ENDIAN
* due to the FAT specification.
*
* These routines may need to be modified to your platform.
*
**/
#include "ff_headers.h"
/*
* Here below 3 x 2 access functions that allow the code
* not to worry about the endianness of the MCU.
*/
#if ( ffconfigINLINE_MEMORY_ACCESS == 0 )
uint8_t FF_getChar( const uint8_t * pBuffer,
uint32_t aOffset )
{
return ( uint8_t ) ( pBuffer[ aOffset ] );
}
uint16_t FF_getShort( const uint8_t * pBuffer,
uint32_t aOffset )
{
FF_T_UN16 u16;
pBuffer += aOffset;
u16.bytes.u8_1 = pBuffer[ 1 ];
u16.bytes.u8_0 = pBuffer[ 0 ];
return u16.u16;
}
uint32_t FF_getLong( const uint8_t * pBuffer,
uint32_t aOffset )
{
FF_T_UN32 u32;
pBuffer += aOffset;
u32.bytes.u8_3 = pBuffer[ 3 ];
u32.bytes.u8_2 = pBuffer[ 2 ];
u32.bytes.u8_1 = pBuffer[ 1 ];
u32.bytes.u8_0 = pBuffer[ 0 ];
return u32.u32;
}
void FF_putChar( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
pBuffer[ aOffset ] = ( uint8_t ) Value;
}
void FF_putShort( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
FF_T_UN16 u16;
u16.u16 = ( uint16_t ) Value;
pBuffer += aOffset;
pBuffer[ 0 ] = u16.bytes.u8_0;
pBuffer[ 1 ] = u16.bytes.u8_1;
}
void FF_putLong( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
FF_T_UN32 u32;
u32.u32 = Value;
pBuffer += aOffset;
pBuffer[ 0 ] = u32.bytes.u8_0;
pBuffer[ 1 ] = u32.bytes.u8_1;
pBuffer[ 2 ] = u32.bytes.u8_2;
pBuffer[ 3 ] = u32.bytes.u8_3;
}
#endif /* if ( ffconfigINLINE_MEMORY_ACCESS == 0 ) */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,784 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_string.c
* @ingroup STRING
*
* @defgroup STRING FreeRTOS+FAT String Library
* @brief Portable String Library for FreeRTOS+FAT
*
*
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ff_headers.h"
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
#include <wchar.h>
#include <wctype.h>
#endif
/*
* These will eventually be moved into a platform independent string
* library. Which will be optional. (To allow the use of system specific versions).
*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_cstrntowcs( FF_T_WCHAR * wcsDest,
const char * szpSource,
uint32_t ulLength )
{
while( ( *szpSource != '\0' ) && ( ulLength-- != 0 ) )
{
*( wcsDest++ ) = *( szpSource++ );
}
*wcsDest = '\0';
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/*-----------------------------------------------------------*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_cstrtowcs( FF_T_WCHAR * wcsDest,
const char * szpSource )
{
while( *szpSource != '\0' )
{
*wcsDest++ = ( FF_T_WCHAR ) *( szpSource++ );
}
*wcsDest = '\0';
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/*-----------------------------------------------------------*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_wcstocstr( char * szpDest,
const FF_T_WCHAR * wcsSource )
{
while( *wcsSource != '\0' )
{
*szpDest++ = ( int8_t ) *( wcsSource++ );
}
*szpDest = '\0';
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/*-----------------------------------------------------------*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_wcsntocstr( char * szpDest,
const FF_T_WCHAR * wcsSource,
uint32_t ulLength )
{
while( ( *wcsSource != '\0' ) && ( ulLength-- != 0 ) )
{
*( szpDest++ ) = ( int8_t ) *( wcsSource++ );
}
*szpDest = '\0';
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_toupper( FF_T_WCHAR * string,
uint32_t ulLength )
{
uint32_t i;
for( i = 0; i < ulLength; i++ )
{
string[ i ] = towupper( string[ i ] );
}
}
/*-----------------------------------------------------------*/
void FF_tolower( FF_T_WCHAR * string,
uint32_t ulLength )
{
uint32_t i;
for( i = 0; i < ulLength; i++ )
{
string[ i ] = towlower( string[ i ] );
}
}
/*-----------------------------------------------------------*/
#else /* ffconfigUNICODE_UTF16_SUPPORT */
void FF_toupper( char * string,
uint32_t ulLength )
{
uint32_t i;
for( i = 0; i < ulLength; i++ )
{
if( ( string[ i ] >= 'a' ) && ( string[ i ] <= 'z' ) )
{
string[ i ] -= 32;
}
if( string[ i ] == '\0' )
{
break;
}
}
}
/*-----------------------------------------------------------*/
void FF_tolower( char * string,
uint32_t ulLength )
{
uint32_t i;
for( i = 0; i < ulLength; i++ )
{
if( ( string[ i ] >= 'A' ) && ( string[ i ] <= 'Z' ) )
{
string[ i ] += 32;
}
if( string[ i ] == '\0' )
{
break;
}
}
}
/*-----------------------------------------------------------*/
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/**
* @private
* @brief Compares 2 strings for the specified length, and returns pdTRUE is they are identical
* otherwise pdFALSE is returned.
*
**/
#if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
BaseType_t FF_strmatch( const char * str1,
const char * str2,
BaseType_t xLength )
{
register BaseType_t i;
register char char1, char2;
if( xLength == 0 )
{
xLength = strlen( str1 );
if( xLength != ( BaseType_t ) strlen( str2 ) )
{
return pdFALSE;
}
}
for( i = 0; i < xLength; i++ )
{
char1 = str1[ i ];
char2 = str2[ i ];
if( ( char1 >= 'A' ) && ( char1 <= 'Z' ) )
{
char1 += 32;
}
if( ( char2 >= 'A' ) && ( char2 <= 'Z' ) )
{
char2 += 32;
}
if( char1 != char2 )
{
return pdFALSE;
}
}
return pdTRUE;
}
#else /* ffconfigUNICODE_UTF16_SUPPORT */
BaseType_t FF_strmatch( const FF_T_WCHAR * str1,
const FF_T_WCHAR * str2,
BaseType_t xLength )
{
register BaseType_t i;
register FF_T_WCHAR char1, char2;
if( xLength == 0 )
{
xLength = wcslen( str1 );
if( xLength != wcslen( str2 ) )
{
return pdFALSE;
}
}
for( i = 0; i < xLength; i++ )
{
char1 = towlower( str1[ i ] );
char2 = towlower( str2[ i ] );
if( char1 != char2 )
{
return pdFALSE;
}
}
return pdTRUE;
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/**
* @private
* @brief A re-entrant Strtok function. No documentation is provided :P
* Use at your own risk. (This is for FreeRTOS+FAT's use only).
**/
#if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
char * FF_strtok( const char * string,
char * token,
uint16_t * tokenNumber,
BaseType_t * last,
BaseType_t xLength )
{
uint16_t i, y, tokenStart, tokenEnd = 0;
i = 0;
y = 0;
if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
{
i++;
}
tokenStart = i;
while( i < xLength )
{
if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
{
y++;
if( y == *tokenNumber )
{
tokenStart = ( uint16_t ) ( i + 1 );
}
if( y == ( *tokenNumber + 1 ) )
{
tokenEnd = i;
break;
}
}
i++;
}
if( tokenEnd == 0 )
{
if( *last == pdTRUE )
{
return NULL;
}
else
{
*last = pdTRUE;
}
tokenEnd = i;
}
if( ( tokenEnd - tokenStart ) < ffconfigMAX_FILENAME )
{
memcpy( token, ( string + tokenStart ), ( uint32_t ) ( tokenEnd - tokenStart ) );
token[ tokenEnd - tokenStart ] = '\0';
}
else
{
memcpy( token, ( string + tokenStart ), ( uint32_t ) ( ffconfigMAX_FILENAME ) );
token[ ffconfigMAX_FILENAME - 1 ] = '\0';
}
/*token[tokenEnd - tokenStart] = '\0'; */
*tokenNumber += 1;
return token;
}
#else /* ffconfigUNICODE_UTF16_SUPPORT */
FF_T_WCHAR * FF_strtok( const FF_T_WCHAR * string,
FF_T_WCHAR * token,
uint16_t * tokenNumber,
BaseType_t * last,
BaseType_t xLength )
{
uint16_t i, y, tokenStart, tokenEnd = 0;
i = 0;
y = 0;
if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
{
i++;
}
tokenStart = i;
while( i < xLength )
{
if( ( string[ i ] == '\\' ) || ( string[ i ] == '/' ) )
{
y++;
if( y == *tokenNumber )
{
tokenStart = ( uint16_t ) ( i + 1 );
}
if( y == ( *tokenNumber + 1 ) )
{
tokenEnd = i;
break;
}
}
i++;
}
if( tokenEnd == 0 )
{
if( *last == pdTRUE )
{
return NULL;
}
else
{
*last = pdTRUE;
}
tokenEnd = i;
}
if( ( tokenEnd - tokenStart ) < ffconfigMAX_FILENAME )
{
memcpy( token, ( string + tokenStart ), ( uint32_t ) ( tokenEnd - tokenStart ) * sizeof( FF_T_WCHAR ) );
token[ tokenEnd - tokenStart ] = '\0';
}
else
{
memcpy( token, ( string + tokenStart ), ( uint32_t ) ( ffconfigMAX_FILENAME ) * sizeof( FF_T_WCHAR ) );
token[ ffconfigMAX_FILENAME - 1 ] = '\0';
}
/*token[tokenEnd - tokenStart] = '\0'; */
*tokenNumber += 1;
return token;
}
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/* UTF-8 Routines */
/*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
* 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
*/
#if ( ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
UBaseType_t FF_GetUtf16SequenceLen( uint16_t usLeadChar )
{
UBaseType_t uxReturn;
if( ( usLeadChar & 0xFC00 ) == 0xD800 )
{
uxReturn = 2;
}
else
{
uxReturn = 1;
}
return uxReturn;
} /* FF_GetUtf16SequenceLen() */
#endif /* if ( ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 ) */
/*-----------------------------------------------------------*/
/*
* Returns the number of UTF-8 units read.
* Will not exceed ulSize UTF-16 units. (ulSize * 2 bytes).
*/
/*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 0000 0000-0000 007F 0xxxxxxx
* 0000 0080-0000 07FF 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
* 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
*/
#if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
int32_t FF_Utf8ctoUtf16c( uint16_t * utf16Dest,
const uint8_t * utf8Source,
uint32_t ulSize )
{
uint32_t ulUtf32char;
uint16_t utf16Source = 0;
register int32_t lSequenceNumber = 0;
/* Count number of set bits before a zero. */
while( ( ( *utf8Source != '\0' ) & ( 0x80 >> ( lSequenceNumber ) ) ) )
{
lSequenceNumber++;
}
if( lSequenceNumber == 0UL )
{
lSequenceNumber++;
}
if( ulSize == 0UL )
{
/* Returned value becomes an error, with the highest bit set. */
lSequenceNumber = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF8CTOUTF16C;
}
else
{
switch( lSequenceNumber )
{
case 1:
utf16Source = ( uint16_t ) *utf8Source;
memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
break;
case 2:
utf16Source = ( uint16_t ) ( ( *utf8Source & 0x1F ) << 6 ) | ( ( *( utf8Source + 1 ) & 0x3F ) );
memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
break;
case 3:
utf16Source = ( uint16_t ) ( ( *utf8Source & 0x0F ) << 12 ) | ( ( *( utf8Source + 1 ) & 0x3F ) << 6 ) | ( ( *( utf8Source + 2 ) & 0x3F ) );
memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
break;
case 4:
if( ulSize < 2 )
{
/* Returned value becomes an error. */
lSequenceNumber = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF8CTOUTF16C;
}
else
{
/* Convert to UTF-32 and then into UTF-16 */
ulUtf32char = ( uint16_t )
( ( *utf8Source & 0x0F ) << 18 ) |
( ( *( utf8Source + 1 ) & 0x3F ) << 12 ) |
( ( *( utf8Source + 2 ) & 0x3F ) << 6 ) |
( ( *( utf8Source + 3 ) & 0x3F ) );
utf16Source = ( uint16_t ) ( ( ( ulUtf32char - 0x10000 ) & 0xFFC00 ) >> 10 ) | 0xD800;
memcpy( utf16Dest, &utf16Source, sizeof( uint16_t ) );
utf16Source = ( uint16_t ) ( ( ( ulUtf32char - 0x10000 ) & 0x003FF ) >> 00 ) | 0xDC00;
memcpy( utf16Dest + 1, &utf16Source, sizeof( uint16_t ) );
}
break;
default:
break;
}
}
return lSequenceNumber;
} /* FF_Utf8ctoUtf16c() */
#endif /* ffconfigUNICODE_UTF8_SUPPORT */
/*-----------------------------------------------------------*/
/*
* Returns the number of UTF-8 units required to encode the UTF-16 sequence.
* Will not exceed ulSize UTF-8 units. (ulSize * 1 bytes).
*/
#if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
int32_t FF_Utf16ctoUtf8c( uint8_t * utf8Dest,
const uint16_t * utf16Source,
uint32_t ulSize )
{
uint32_t ulUtf32char;
uint16_t ulUtf16char;
int32_t lReturn = 0L;
do
{
if( ulSize == 0UL )
{
lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
break;
}
memcpy( &ulUtf16char, utf16Source, sizeof( uint16_t ) );
/* A surrogate sequence was encountered. Must transform to UTF32 first. */
if( ( ulUtf16char & 0xF800 ) == 0xD800 )
{
ulUtf32char = ( ( uint32_t ) ( ulUtf16char & 0x003FF ) << 10 ) + 0x10000;
memcpy( &ulUtf16char, utf16Source + 1, sizeof( uint16_t ) );
if( ( ulUtf16char & 0xFC00 ) != 0xDC00 )
{
/* Invalid UTF-16 sequence. */
lReturn = FF_ERR_UNICODE_INVALID_SEQUENCE | FF_UTF16CTOUTF8C;
break;
}
ulUtf32char |= ( ( uint32_t ) ( ulUtf16char & 0x003FF ) );
}
else
{
ulUtf32char = ( uint32_t ) ulUtf16char;
}
/* Now convert to the UTF-8 sequence. */
/* Single byte UTF-8 sequence. */
if( ulUtf32char < 0x00000080 )
{
*( utf8Dest + 0 ) = ( uint8_t ) ulUtf32char;
lReturn = 1;
break;
}
/* Double byte UTF-8 sequence. */
if( ulUtf32char < 0x00000800 )
{
if( ulSize < 2 )
{
lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
}
else
{
*( utf8Dest + 0 ) = ( uint8_t ) ( 0xC0 | ( ( ulUtf32char >> 6 ) & 0x1F ) );
*( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
lReturn = 2;
}
break;
}
/* Triple byte UTF-8 sequence. */
if( ulUtf32char < 0x00010000 )
{
if( ulSize < 3 )
{
lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
}
else
{
*( utf8Dest + 0 ) = ( uint8_t ) ( 0xE0 | ( ( ulUtf32char >> 12 ) & 0x0F ) );
*( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 6 ) & 0x3F ) );
*( utf8Dest + 2 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
lReturn = 3;
}
break;
}
/* Quadruple byte UTF-8 sequence. */
if( ulUtf32char < 0x00200000 )
{
if( ulSize < 4 )
{
lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF16CTOUTF8C;
}
else
{
*( utf8Dest + 0 ) = ( uint8_t ) ( 0xF0 | ( ( ulUtf32char >> 18 ) & 0x07 ) );
*( utf8Dest + 1 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 12 ) & 0x3F ) );
*( utf8Dest + 2 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 6 ) & 0x3F ) );
*( utf8Dest + 3 ) = ( uint8_t ) ( 0x80 | ( ( ulUtf32char >> 0 ) & 0x3F ) );
lReturn = 4;
}
break;
}
lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF16CTOUTF8C; /* Invalid Character */
}
while( pdFALSE );
return lReturn;
} /* FF_Utf16ctoUtf8c() */
#endif /* ffconfigUNICODE_UTF8_SUPPORT */
/*-----------------------------------------------------------*/
/* UTF-16 Support Functions */
/* Converts a UTF-32 Character into its equivalent UTF-16 sequence. */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF )
int32_t FF_Utf32ctoUtf16c( uint16_t * utf16Dest,
uint32_t utf32char,
uint32_t ulSize )
{
int32_t lReturn;
/* Check that its a valid UTF-32 wide-char! */
/* This range is not a valid Unicode code point. */
if( ( utf32char >= 0xD800 ) && ( utf32char <= 0xDFFF ) )
{
lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF32CTOUTF16C; /* Invalid character. */
}
else if( utf32char < 0x10000 )
{
*utf16Dest = ( uint16_t ) utf32char; /* Simple conversion! Char comes within UTF-16 space (without surrogates). */
lReturn = 1;
}
else if( ulSize < 2 )
{
lReturn = FF_ERR_UNICODE_DEST_TOO_SMALL | FF_UTF32CTOUTF16C; /* Not enough UTF-16 units to record this character. */
}
else if( utf32char < 0x00200000 )
{
/* Conversion to a UTF-16 Surrogate pair! */
/*valueImage = utf32char - 0x10000; */
*( utf16Dest + 0 ) = ( uint16_t ) ( ( ( utf32char - 0x10000 ) & 0xFFC00 ) >> 10 ) | 0xD800;
*( utf16Dest + 1 ) = ( uint16_t ) ( ( ( utf32char - 0x10000 ) & 0x003FF ) >> 00 ) | 0xDC00;
lReturn = 2; /* Surrogate pair encoded value. */
}
else
{
/* Invalid Character */
lReturn = FF_ERR_UNICODE_INVALID_CODE | FF_UTF32CTOUTF16C;
}
return lReturn;
} /* FF_Utf32ctoUtf16c() */
#endif /* #if( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) */
/*-----------------------------------------------------------*/
/* Converts a UTF-16 sequence into its equivalent UTF-32 code point. */
#if ( ffconfigNOT_USED_FOR_NOW != 0 )
int32_t FF_Utf16ctoUtf32c( uint32_t * utf32Dest,
const uint16_t * utf16Source )
{
int32_t lReturn;
/*Not a surrogate sequence. */
if( ( *utf16Source & 0xFC00 ) != 0xD800 )
{
*utf32Dest = ( uint32_t ) *utf16Source;
lReturn = 1; /* A single UTF-16 item was used to represent the character. */
}
else
{
*utf32Dest = ( ( uint32_t ) ( *( utf16Source + 0 ) & 0x003FF ) << 10 ) + 0x10000;
if( ( *( utf16Source + 1 ) & 0xFC00 ) != 0xDC00 )
{
lReturn = FF_ERR_UNICODE_INVALID_SEQUENCE | FF_UTF16CTOUTF32C; /* Invalid UTF-16 sequence. */
}
else
{
*utf32Dest |= ( ( uint32_t ) ( *( utf16Source + 1 ) & 0x003FF ) );
lReturn = 2; /* 2 utf-16 units make up the Unicode code-point. */
}
}
return lReturn;
} /* FF_Utf16ctoUtf32c() */
#endif /* ffconfigNOT_USED_FOR_NOW */
/*-----------------------------------------------------------*/
/*
* Returns the total number of UTF-16 items required to represent
* the provided UTF-32 string in UTF-16 form.
*/
/*
* UBaseType_t FF_Utf32GetUtf16Len( const uint32_t *utf32String )
* {
* UBaseType_t utf16len = 0;
*
* while( *utf32String )
* {
* if( *utf32String++ <= 0xFFFF )
* {
* utf16len++;
* }
* else
* {
* utf16len += 2;
* }
* }
*
* return utf16len;
* }
*/
/*-----------------------------------------------------------*/
/* String conversions */
#if ( ffconfigNOT_USED_FOR_NOW != 0 )
int32_t FF_Utf32stoUtf8s( uint8_t * Utf8String,
uint32_t * Utf32String )
{
int i = 0, y = 0;
uint16_t utf16buffer[ 2 ];
while( Utf32String[ i ] != '\0' )
{
/* Convert to a UTF16 char. */
FF_Utf32ctoUtf16c( utf16buffer, Utf32String[ i ], 2 );
/* Now convert the UTF16 to UTF8 sequence. */
y += FF_Utf16ctoUtf8c( &Utf8String[ y ], utf16buffer, 4 );
i++;
}
Utf8String[ y ] = '\0';
return 0;
} /* FF_Utf32stoUtf8s() */
#endif /* ffconfigNOT_USED_FOR_NOW */
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,286 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <stdio.h>
#include <string.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "portable.h"
#include "ff_headers.h"
#include "ff_sys.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE( x ) ( int ) ( sizeof( x ) / sizeof( x )[ 0 ] )
#endif
/*
* Define a collection of 'file systems' as a simple array
*/
typedef struct xSYSTEM
{
FF_SubSystem_t xSystems[ ffconfigMAX_FILE_SYS ];
volatile BaseType_t xFileSystemCount;
} ff_sys_t;
static ff_sys_t file_systems;
static const char rootDir[] = "/";
int FF_FS_Count( void )
{
return ( int ) file_systems.xFileSystemCount;
}
/*-----------------------------------------------------------*/
void FF_FS_Init( void )
{
memset( &file_systems, '\0', sizeof( file_systems ) );
/* There is always a root file system, even if it doesn't have a
* IO manager. */
file_systems.xFileSystemCount = ( BaseType_t ) 1;
/* Set to "/", second byte is already zero. */
file_systems.xSystems[ 0 ].pcPath[ 0 ] = ( char ) '/';
file_systems.xSystems[ 0 ].xPathlen = 1;
}
/*-----------------------------------------------------------*/
int FF_FS_Add( const char * pcPath,
FF_Disk_t * pxDisk )
{
int iReturn = pdFALSE;
configASSERT( pxDisk );
if( *pcPath != ( char ) '/' )
{
FF_PRINTF( "FF_FS_Add: Need a \"/\": '%s'\n", pcPath );
}
else
{
BaseType_t xUseIndex = -1;
size_t uxPathLength = strlen( pcPath );
vTaskSuspendAll();
{
if( file_systems.xFileSystemCount == ( BaseType_t ) 0 )
{
FF_FS_Init();
}
if( uxPathLength == ( size_t ) 1u )
{
/* This is the "/" path
* and will always be put at index 0 */
xUseIndex = ( BaseType_t ) 0;
}
else
{
BaseType_t xIndex, xFreeIndex = -1;
FF_SubSystem_t * pxSubSystem = file_systems.xSystems + 1; /* Skip the root entry */
for( xIndex = ( BaseType_t ) 1; xIndex < file_systems.xFileSystemCount; xIndex++, pxSubSystem++ )
{
if( ( pxSubSystem->xPathlen == ( BaseType_t ) uxPathLength ) &&
( memcmp( pxSubSystem->pcPath, pcPath, uxPathLength ) == 0 ) )
{
/* A system is updated with a new handler. */
xUseIndex = xIndex;
break;
}
if( ( pxSubSystem->pxManager == NULL ) && ( xFreeIndex < 0 ) )
{
/* Remember the first free slot. */
xFreeIndex = xIndex;
}
}
if( xUseIndex < ( BaseType_t ) 0 )
{
if( xFreeIndex >= ( BaseType_t ) 0 )
{
/* Use the first free slot. */
xUseIndex = xFreeIndex;
}
else if( file_systems.xFileSystemCount < ARRAY_SIZE( file_systems.xSystems ) )
{
/* Fill a new entry. */
xUseIndex = file_systems.xFileSystemCount++;
}
}
} /* uxPathLength != 1 */
if( xUseIndex >= ( BaseType_t ) 0 )
{
iReturn = pdTRUE;
strncpy( file_systems.xSystems[ xUseIndex ].pcPath, pcPath, sizeof( file_systems.xSystems[ xUseIndex ].pcPath ) );
file_systems.xSystems[ xUseIndex ].xPathlen = uxPathLength;
file_systems.xSystems[ xUseIndex ].pxManager = pxDisk->pxIOManager;
}
}
xTaskResumeAll();
if( iReturn == pdFALSE )
{
FF_PRINTF( "FF_FS_Add: Table full '%s' (max = %d)\n", pcPath, ( int ) ARRAY_SIZE( file_systems.xSystems ) );
}
}
return iReturn;
}
/*-----------------------------------------------------------*/
void FF_FS_Remove( const char * pcPath )
{
BaseType_t xUseIndex, xIndex;
size_t uxPathLength;
if( pcPath[ 0 ] == ( char ) '/' )
{
xUseIndex = -1;
uxPathLength = strlen( pcPath );
/* Is it the "/" path ? */
if( uxPathLength == ( size_t ) 1u )
{
xUseIndex = 0;
}
else
{
FF_SubSystem_t * pxSubSystem = file_systems.xSystems + 1;
for( xIndex = 1; xIndex < file_systems.xFileSystemCount; xIndex++, pxSubSystem++ )
{
if( ( pxSubSystem->xPathlen == ( BaseType_t ) uxPathLength ) &&
( memcmp( pxSubSystem->pcPath, pcPath, uxPathLength ) == 0 ) )
{
xUseIndex = xIndex;
break;
}
}
}
if( xUseIndex >= 0 )
{
vTaskSuspendAll();
{
file_systems.xSystems[ xUseIndex ].pxManager = NULL;
file_systems.xSystems[ xUseIndex ].xPathlen = ( BaseType_t ) 0;
for( xIndex = file_systems.xFileSystemCount - 1; xIndex > 0; xIndex-- )
{
if( file_systems.xSystems[ xIndex ].pxManager != NULL )
{
/* The slot at 'xIndex' is still in use. */
break;
}
}
file_systems.xFileSystemCount = xIndex + 1;
}
xTaskResumeAll();
}
}
}
/*-----------------------------------------------------------*/
int FF_FS_Find( const char * pcPath,
FF_DirHandler_t * pxHandler )
{
FF_SubSystem_t * pxSubSystem;
size_t uxPathLength;
BaseType_t xUseIndex;
int iReturn;
pxSubSystem = file_systems.xSystems + 1;
uxPathLength = strlen( pcPath );
memset( pxHandler, '\0', sizeof( *pxHandler ) );
for( xUseIndex = 1; xUseIndex < file_systems.xFileSystemCount; xUseIndex++, pxSubSystem++ )
{
if( ( uxPathLength >= ( size_t ) pxSubSystem->xPathlen ) &&
( memcmp( pxSubSystem->pcPath, pcPath, ( size_t ) pxSubSystem->xPathlen ) == 0 ) &&
( ( pcPath[ pxSubSystem->xPathlen ] == '\0' ) || ( pcPath[ pxSubSystem->xPathlen ] == '/' ) ) ) /* System "/ram" should not match with "/ramc/etc". */
{
if( pcPath[ pxSubSystem->xPathlen ] == '\0' )
{
pxHandler->pcPath = rootDir;
}
else
{
pxHandler->pcPath = pcPath + pxSubSystem->xPathlen;
}
pxHandler->pxManager = pxSubSystem->pxManager;
break;
}
}
if( xUseIndex == file_systems.xFileSystemCount )
{
pxHandler->pcPath = pcPath;
pxHandler->pxManager = file_systems.xSystems[ 0 ].pxManager;
}
if( FF_Mounted( pxHandler->pxManager ) )
{
iReturn = pdTRUE;
}
else
{
iReturn = pdFALSE;
}
return iReturn;
}
/*-----------------------------------------------------------*/
int FF_FS_Get( int xIndex,
FF_SubSystem_t * pxSystem )
{
int iReturn;
/* Get a copy of a fs info. */
if( ( xIndex < 0 ) || ( xIndex >= file_systems.xFileSystemCount ) )
{
iReturn = pdFALSE;
}
else
{
/* Note: it will copy the contents of 'FF_SubSystem_t'. */
*pxSystem = file_systems.xSystems[ xIndex ];
iReturn = pdTRUE;
}
return iReturn;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,302 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "ff_time.h"
/**
* @file ff_time.c
* @ingroup TIME
*
* @defgroup TIME Real-Time Clock Interface
* @brief Allows FreeRTOS+FAT to time-stamp files.
*
* Provides a means for receiving the time on any platform.
**/
#if ( ffconfigTIME_SUPPORT != 0 ) /* This if-block spans the rest of the source file. */
/**
* @public
* @brief Populates an FF_SystemTime_t object with the current time from the system.
*
* The developer must modify this function so that it is suitable for their platform.
* The function must return with 0, and if the time is not available all elements of the
* FF_SystemTime_t object must be zero'd, as in the examples provided.
*
* @param pxTime Pointer to an FF_TIME object.
*
* @return Always returns 0.
**/
int32_t FF_GetSystemTime( FF_SystemTime_t * pxTime )
{
FF_TimeStruct_t xTimeStruct;
/* Fetch the current time. */
time_t secs = FreeRTOS_time( NULL );
/* Fill the fields in 'xTimeStruct'. */
FreeRTOS_gmtime_r( &secs, &xTimeStruct );
pxTime->Hour = xTimeStruct.tm_hour;
pxTime->Minute = xTimeStruct.tm_min;
pxTime->Second = xTimeStruct.tm_sec;
pxTime->Day = xTimeStruct.tm_mday;
pxTime->Month = xTimeStruct.tm_mon + 1;
pxTime->Year = xTimeStruct.tm_year + 1900;
return 0;
} /* FF_GetSystemTime() */
/*-----------------------------------------------------------*/
/*
* FreeRTOS+FAT
* Time conversion functions:
*
* FF_TimeStruct_t *FreeRTOS_gmtime_r( const time_t *pxTime, FF_TimeStruct_t *pxTimeBuf )
* time_t FreeRTOS_mktime(FF_TimeStruct_t *pxTimeBuf)
*/
#define GMTIME_FIRST_YEAR ( 1970 )
#define TM_STRUCT_FIRST_YEAR ( 1900 )
#define SECONDS_PER_MINUTE ( 60 )
#define MINUTES_PER_HOUR ( 60 )
#define HOURS_PER_DAY ( 24 )
#define SECONDS_PER_HOUR ( MINUTES_PER_HOUR * SECONDS_PER_MINUTE )
#define SECONDS_PER_DAY ( HOURS_PER_DAY * SECONDS_PER_HOUR )
/* The first weekday in 'FF_TimeStruct_t' is Sunday. */
#define WEEK_DAY_SUNDAY 0
#define WEEK_DAY_MONNDAY 1
#define WEEK_DAY_TUESDAY 2
#define WEEK_DAY_WEDNESDAY 3
#define WEEK_DAY_THURSDAY 4
#define WEEK_DAY_FRIDAY 5
#define WEEK_DAY_SATURDAY 6
/* Make a bitmask with a '1' for each 31-day month. */
#define _MM( month ) ( 1u << ( month - 1 ) )
#define MASK_LONG_MONTHS ( _MM( 1 ) | _MM( 3 ) | _MM( 5 ) | _MM( 7 ) | _MM( 8 ) | _MM( 10 ) | _MM( 12 ) )
#define DAYS_UNTIL_1970 ( ( 1970 * 365 ) + ( 1970 / 4 ) - ( 1970 / 100 ) + ( 1970 / 400 ) )
#define DAYS_BEFORE_MARCH ( 59 )
static portINLINE int iIsLeapyear( int iYear )
{
int iReturn;
if( ( iYear % 4 ) != 0 )
{
/* Not a multiple of 4 years. */
iReturn = pdFALSE;
}
else if( ( iYear % 400 ) == 0 )
{
/* Every 4 centuries there is a leap year */
iReturn = pdTRUE;
}
else if( ( iYear % 100 ) == 0 )
{
/* Other centuries are not a leap year */
iReturn = pdFALSE;
}
else
{
/* Otherwise every fourth year. */
iReturn = pdTRUE;
}
return iReturn;
}
static portINLINE unsigned long ulDaysPerYear( int iYear )
{
int iDays;
if( iIsLeapyear( iYear ) )
{
iDays = 366;
}
else
{
iDays = 365;
}
return iDays;
}
static int iDaysPerMonth( int iYear,
int iMonth )
{
int iDays;
/* Month is zero-based, 1 is February. */
if( iMonth != 1 )
{
/* 30 or 31 days? */
if( ( MASK_LONG_MONTHS & ( 1u << iMonth ) ) != 0 )
{
iDays = 31;
}
else
{
iDays = 30;
}
}
else if( iIsLeapyear( iYear ) == pdFALSE )
{
/* February, non leap year. */
iDays = 28;
}
else
{
/* February, leap year. */
iDays = 29;
}
return iDays;
}
FF_TimeStruct_t * FreeRTOS_gmtime_r( const time_t * pxTime,
FF_TimeStruct_t * pxTimeBuf )
{
time_t xTime = *pxTime;
unsigned long ulDaySeconds, ulDayNumber;
int iYear = GMTIME_FIRST_YEAR;
int iMonth;
/* Clear all fields, some might not get set here. */
memset( ( void * ) pxTimeBuf, '\0', sizeof( *pxTimeBuf ) );
/* Seconds since last midnight. */
ulDaySeconds = ( unsigned long ) ( xTime % SECONDS_PER_DAY );
/* Days since 1 Jan 1970. */
ulDayNumber = ( unsigned long ) ( xTime / SECONDS_PER_DAY );
/* Today's HH:MM:SS */
pxTimeBuf->tm_hour = ulDaySeconds / SECONDS_PER_HOUR;
pxTimeBuf->tm_min = ( ulDaySeconds % SECONDS_PER_HOUR ) / 60;
pxTimeBuf->tm_sec = ulDaySeconds % 60;
/* Today's week day, knowing that 1-1-1970 was a THursday. */
pxTimeBuf->tm_wday = ( ulDayNumber + WEEK_DAY_THURSDAY ) % 7;
for( ; ; )
{
/* Keep subtracting 365 (or 366) days while possible. */
unsigned long ulDays = ulDaysPerYear( iYear );
if( ulDayNumber < ulDays )
{
break;
}
ulDayNumber -= ulDays;
iYear++;
}
/* Subtract 1900. */
pxTimeBuf->tm_year = iYear - TM_STRUCT_FIRST_YEAR;
/* The day within this year. */
pxTimeBuf->tm_yday = ulDayNumber;
/* Month are counted as 0..11 */
iMonth = 0;
for( ; ; )
{
unsigned long ulDays = iDaysPerMonth( iYear, iMonth );
/* Keep subtracting 30 (or 28, 29, or 31) days while possible. */
if( ulDayNumber < ulDays )
{
break;
}
ulDayNumber -= ulDays;
iMonth++;
}
pxTimeBuf->tm_mon = iMonth;
/* Month days are counted as 1..31 */
pxTimeBuf->tm_mday = ulDayNumber + 1;
return pxTimeBuf;
}
time_t FreeRTOS_mktime( const FF_TimeStruct_t * pxTimeBuf )
{
/* Get year AD. */
int iYear = 1900 + pxTimeBuf->tm_year; /* 20xx */
/* Get month zero-based. */
int iMonth = pxTimeBuf->tm_mon; /* 0..11 */
uint32_t ulDays;
uint32_t ulResult;
ulDays = pxTimeBuf->tm_mday - 1; /* 1..31 */
/* Make March the first month. */
iMonth -= 2;
if( iMonth < 0 )
{
/* January or February: leap day has yet to come for this year. */
iYear--;
iMonth += 12;
}
/* Add the number of days past until this month. */
ulDays += ( ( 306 * iMonth ) + 5 ) / 10;
/* Add days past before this year: */
ulDays +=
+( iYear * 365 ) /* Every normal year. */
+ ( iYear / 4 ) /* Plus a day for every leap year. */
- ( iYear / 100 ) /* Minus the centuries. */
+ ( iYear / 400 ) /* Except every fourth century. */
- ( DAYS_UNTIL_1970 ) /* Minus the days before 1-1-1970 */
+ ( DAYS_BEFORE_MARCH ); /* Because 2 months were subtracted. */
ulResult =
( ulDays * SECONDS_PER_DAY ) +
( pxTimeBuf->tm_hour * SECONDS_PER_HOUR ) +
( pxTimeBuf->tm_min * SECONDS_PER_MINUTE ) +
pxTimeBuf->tm_sec;
return ulResult;
}
#endif /* ffconfigTIME_SUPPORT */

View File

@ -0,0 +1,202 @@
/*
*FreeRTOS+FAT is an open source,
*thread aware and scalable FAT12/FAT16/FAT32 DOS/Windows compatible embedded FAT file system which was recently acquired by Real Time Engineers ltd.
*for use with and without the RTOS.
*FreeRTOS+FAT is already used in commercial products,
*and is the file system used in the FTP and HTTP server examples that are documented on the FreeRTOS+TCP pages.
*The standard C library style API includes a thread local errno value, and the lower level native API provides a rich set of detailed error codes.
*We are currently working hard on improving the embedded file systems documentation,
*adding additional scalability options, and updating the source code to ensure it conforms with our strict coding standards.
*We encourage you to download FreeRTOS+FAT to try the embedded FAT file system for yourself while we continue this work.
*Applications that use FreeRTOS+FAT must provide a FreeRTOSFATConfig.h header file in which the parameters described on this page can be defined:
***/
#ifndef FF_FATCONFIG_H
#define FF_FATCONFIG_H
#include <stdio.h>
#define portINLINE inline
#define FF_PRINTF printf
/*Must be set to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN,
depending on the endian of the architecture on which FreeRTOS is running.*/
//大小端
#define ffconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
/*Set to 1 to maintain a current working directory (CWD) for each task that accesses the file system, allowing relative paths to be used.
Set to 0 not to use a CWD, in which case full paths must be used for each file access.*/
//维护当前目录
#define ffconfigHAS_CWD 0
/*Set to an index within FreeRTOSs thread local storage array that is free for use by FreeRTOS+FAT.
FreeRTOS+FAT will use two consecutive indexes from this that set by ffconfigCWD_THREAD_LOCAL_INDEX.
The number of thread local storage pointers provided by FreeRTOS is set by configNUM_THREAD_LOCAL_STORAGE_POINTERS in FreeRTOSConfig.h.*/
//本地线程数组索引
#define ffconfigCWD_THREAD_LOCAL_INDEX 0
/*Set to 1 to include long file name support. Set to 0 to exclude long file name support.
If long file name support is excluded then only 8.3 file names can be used. Long file names will be recognised, but ignored.
Users should familiarise themselves with any patent issues that may potentially exist around the use of long file names in FAT file systems before enabling long file name support.*/
//长文件名
#define ffconfigLFN_SUPPORT 1
/*Only used when ffconfigLFN_SUPPORT is set to 1.
Set to 1 to include a files short name when listing a directory, i.e. when calling findfirst()/findnext().
The short name will be stored in the pcShortName field of FF_DIRENT.
Set to 0 to only include a files long name.*/
//短文件名
#define ffconfigINCLUDE_SHORT_NAME 0
/*Set to 1 to recognise and apply the case bits used by Windows XP+
when using short file names storing file names such as “readme.TXT” or “SETUP.exe” in a short-name entry.
This is the recommended setting for maximum compatibility.
Set to 0 to ignore the case bits.*/
#define ffconfigSHORTNAME_CASE 0
/*Only used when ffconfigLFN_SUPPORT is set to 1.
Set to 1 to use UTF-16 (wide-characters) for file and directory names.
Set to 0 to use either 8-bit ASCII or UTF-8 for file and directory names (see the ffconfigUNICODE_UTF8_SUPPORT).*/
#define ffconfigUNICODE_UTF16_SUPPORT 0
/*Only used when ffconfigLFN_SUPPORT is set to 1.
Set to 1 to use UTF-8 encoding for file and directory names.
Set to 0 to use either 8-bit ASCII or UTF-16 for file and directory names (see the ffconfig_UTF_16_SUPPORT setting).*/
#define ffconfigUNICODE_UTF8_SUPPORT 0
/*Set to 1 to include FAT12 support.
Set to 0 to exclude FAT12 support.
FAT16 and FAT32 are always enabled.*/
#define ffconfigFAT12_SUPPORT 0
/*When writing and reading data, i/o becomes less efficient if sizes other than 512 bytes are being used.
When set to 1 each file handle will allocate a 512-byte character buffer to facilitate “unaligned access”.*/
//当写入和读取数据时如果使用的大小不是512字节i/o的效率就会降低。当设置为1时每个文件句柄将分配一个512字节的字符缓冲区以促进“非对齐访问”。
#define ffconfigOPTIMISE_UNALIGNED_ACCESS 0
/*Input and output to a disk uses buffers that are only flushed at the following times:
When a new buffer is needed and no other buffers are available.
When opening a buffer in READ mode for a sector that has just been changed.
After creating, removing or closing a file or a directory.
Normally this is quick enough and it is efficient.
If ffconfigCACHE_WRITE_THROUGH is set to 1 then buffers will also be flushed each time a buffer is released which is less efficient but more secure.*/
//如果设置为1那么缓冲区也将在每次释放缓冲区时被刷新—这样效率较低但更安全。
#define ffconfigCACHE_WRITE_THROUGH 1
/*In most cases, the FAT table has two identical copies on the disk, allowing the second copy to be used in the case of a read error.
If Set to 1 to use both FATs this is less efficient but more secure.
Set to 0 to use only one FAT the second FAT will never be written to.*/
#define ffconfigWRITE_BOTH_FATS 1
/*Set to 1 to have the number of free clusters and the first free cluster to be written to the FS info sector each time one of those values changes.
Set to 0 not to store these values in the FS info sector, making booting slower, but making changes faster.*/
#define ffconfigWRITE_FREE_COUNT 1
/*Set to 1 to maintain file and directory time stamps for creation, modify and last access.
Set to 0 to exclude time stamps.
If time support is used, the following function must be supplied:
time_t FreeRTOS_time( time_t *pxTime );
FreeRTOS_time has the same semantics as the standard time() function.*/
#define ffconfigTIME_SUPPORT 0
/*Set to 1 if the media is removable (such as a memory card).
Set to 0 if the media is not removable.
When set to 1 all file handles will be “invalidated” if the media is extracted.
If set to 0 then file handles will not be invalidated.
In that case the user will have to confirm that the media is still present before every access.*/
//如果介质是可移动的(如存储卡)则设置为1。
#define ffconfigREMOVABLE_MEDIA 1
/*Set to 1 to determine the disks free space and the disks first free cluster when a disk is mounted.
Set to 0 to find these two values when they are first needed. Determining the values can take some time.*/
#define ffconfigMOUNT_FIND_FREE 1
/*Set to 1 to trust the contents of the ulLastFreeCluster and ulFreeClusterCount fields.
Set to 0 not to trust these fields.*/
#define ffconfigFSINFO_TRUSTED 1
/*Set to 1 to store recent paths in a cache,
enabling much faster access when the path is deep within a directory structure at the expense of additional RAM usage.
Set to 0 to not use a path cache.*/
#define ffconfigPATH_CACHE 1
/*Only used if ffconfigPATH_CACHE is 1.
Sets the maximum number of paths that can exist in the patch cache at any one time.*/
#define ffconfigPATH_CACHE_DEPTH 8
/*Set to 1 to calculate a HASH value for each existing short file name.
Use of HASH values can improve performance when working with large directories, or with files that have a similar name.
Set to 0 not to calculate a HASH value.*/
#define ffconfigHASH_CACHE 0
#define ffconfigHASH_CACHE_DEPTH 2
/*Only used if ffconfigHASH_CACHE is set to 1
Set to CRC8 or CRC16 to use 8-bit or 16-bit HASH values respectively.*/
#define ffconfigHASH_FUNCTION CRC16
/*Set to 1 to add a parameter to ff_mkdir() that allows an entire directory tree to be created in one go,
rather than having to create one directory in the tree at a time.
For example mkdir( “/etc/settings/network”, pdTRUE );.
Set to 0 to use the normal mkdir() semantics (without the additional parameter).*/
//可创建目录树
#define ffconfigMKDIR_RECURSIVE 1
/*Set to 1 for each call to fnReadBlocks and fnWriteBlocks to be performed with a semphore lock.
Set to 0 for each call to fnReadBlocks and fnWriteBlocks not to use an additional semaphore.*/
//#define ffconfigBLKDEV_USES_SEM 0
/*Set to a function that will be used for all dynamic memory allocations.
Setting to pvPortMalloc() will use the same memory allocator as FreeRTOS.
For example: #define ffconfigMALLOC( size ) pvPortMalloc( size )*/
#define ffconfigMALLOC( size ) pvPortMalloc( size )
/*Set to a function that matches the above allocator defined with ffconfigMALLOC.
Setting to vPortFree() will use the same memory free function as FreeRTOS.
For example: #define ffconfigFREE( ptr ) vPortFree( ptr )*/
#define ffconfigFREE( ptr ) vPortFree( ptr )
/*Set to 1 to calculate the free size and volume size as a 64-bit number.
Set to 0 to calculate these values as a 32-bit number.*/
#define ffconfig64_NUM_SUPPORT 1
/*Defines the maximum number of partitions (and also logical partitions) that can be recognised.*/
#define ffconfigMAX_PARTITIONS 4
/*Defines how many drives can be combined in total. Should be set to at least 2.*/
#define ffconfigMAX_FILE_SYS 4
/*In case the low-level driver returns an error FF_ERR_DRIVER_BUSY,
the library will pause for a number of ms, defined in ffconfigDRIVER_BUSY_SLEEP_MS before re-trying.*/
#define ffconfigDRIVER_BUSY_SLEEP_MS 20
/*Set to 1 to include the ff_fprintf() function in the build.
Set to 0 to exclude the ff_fprintf() function from the build.
ff_fprintf() is quite a heavy function because it allocates RAM and brings in a lot of string and variable argument handling code.
If ff_fprintf() is not being used then the code size can be reduced by setting ffconfigFPRINTF_SUPPORT to 0.*/
#define ffconfigFPRINTF_SUPPORT 1
/*ff_fprintf() will allocate a buffer of this size in which it will create its formatted string. The buffer will be freed before the function exits.*/
#define ffconfigFPRINTF_BUFFER_LENGTH 128
/*Set to 1 to inline some internal memory access functions.
Set to 0 not to use inline memory access functions.*/
#define ffconfigINLINE_MEMORY_ACCESS 0
/*Officially the only criteria to determine the FAT type (12, 16, or 32 bits) is the total number of clusters:
if( ulNumberOfClusters < 4085 ) : Volume is FAT12
if( ulNumberOfClusters < 65525 ) : Volume is FAT16
if( ulNumberOfClusters >= 65525 ) : Volume is FAT32
Not every formatted device follows the above rule.
Set to 1 to perform additional checks over and above inspecting the number of clusters on a disk to determine the FAT type.
Set to 0 to only look at the number of clusters on a disk to determine the FAT type.*/
#define ffconfigFAT_CHECK 1
/*Sets the maximum length for file names,
including the path. Note that the value of this define is directly related to the maximum stack use of the +FAT library.
In some APIs, a character buffer of size ffconfigMAX_FILENAME will be declared on stack.*/
//#define ffconfigMAX_FILENAME (49+1)
#define ffconfigMAX_FILENAME (79+1)
#define ffconfigMIN_CLUSTERS_FAT16 1024//2048
#endif

View File

@ -0,0 +1,463 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef FF_DEFAULTCONFIG_H
/* The error numbers defined in this file will be moved to the core FreeRTOS
* code in future versions of FreeRTOS - at which time the following header file
* will be removed. */
#include "FreeRTOS_errno_FAT.h"
#if !defined( ffconfigBYTE_ORDER )
/* Must be set to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN,
* depending on the endian of the architecture on which FreeRTOS is running. */
#error Invalid FreeRTOSFATConfig.h file: ffconfigBYTE_ORDER must be set to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN
#endif
#if ( ffconfigBYTE_ORDER != pdFREERTOS_LITTLE_ENDIAN ) && ( ffconfigBYTE_ORDER != pdFREERTOS_BIG_ENDIAN )
#error Invalid FreeRTOSFATConfig.h file: ffconfigBYTE_ORDER must be set to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN
#endif
#if ( pdFREERTOS_LITTLE_ENDIAN != 0 ) || ( pdFREERTOS_BIG_ENDIAN != 1 )
#error Invalid projdefs.h or FreeRTOS_errno_FAT.h file
#endif
#if !defined( ffconfigHAS_CWD )
/* Set to 1 to maintain a current working directory (CWD) for each task that
* accesses the file system, allowing relative paths to be used.
*
* Set to 0 not to use a CWD, in which case full paths must be used for each
* file access. */
#define ffconfigHAS_CWD 0
#if !defined( ffconfigCWD_THREAD_LOCAL_INDEX )
#error ffconfigCWD_THREAD_LOCAL_INDEX must be set to a free position within FreeRTOSs thread local storage pointer array for storage of a pointer to the CWD structure.
#endif
#endif
#if !defined( ffconfigLFN_SUPPORT )
/* Set to 1 to include long file name support. Set to 0 to exclude long
* file name support.
*
* If long file name support is excluded then only 8.3 file names can be used.
* Long file names will be recognised but ignored.
*
* Users should familiarise themselves with any patent issues that may
* potentially exist around the use of long file names in FAT file systems
* before enabling long file name support. */
#define ffconfigLFN_SUPPORT 0
#endif
#if !defined( ffconfigINCLUDE_SHORT_NAME )
/* Only used when ffconfigLFN_SUPPORT is set to 1.
*
* Set to 1 to include a file's short name when listing a directory, i.e. when
* calling findfirst()/findnext(). The short name will be stored in the
* 'pcShortName' field of FF_DirEnt_t.
*
* Set to 0 to only include a file's long name. */
#define ffconfigINCLUDE_SHORT_NAME 0
#endif
#if !defined( ffconfigSHORTNAME_CASE )
/* Set to 1 to recognise and apply the case bits used by Windows XP+ when
* using short file names - storing file names such as "readme.TXT" or
* "SETUP.exe" in a short-name entry. This is the recommended setting for
* maximum compatibility.
*
* Set to 0 to ignore the case bits. */
#define ffconfigSHORTNAME_CASE 0
#endif
#if !defined( ipconfigQUICK_SHORT_FILENAME_CREATION )
/* This method saves a lot of time when creating directories with
* many similar file names: when the short name version of a LFN already
* exists, try at most 3 entries with a tilde:
* README~1.TXT
* README~2.TXT
* README~3.TXT
* After that create entries with pseudo-random 4-digit hex digits:
* REA~E7BB.TXT
* REA~BA32.TXT
* REA~D394.TXT
*/
#define ipconfigQUICK_SHORT_FILENAME_CREATION 1
#endif
/* ASCII versus UNICODE, UTF-16 versus UTF-8 :
* FAT directories, when using Long File Names, always store file and directory
* names UTF-16 encoded.
* The user can select how these names must be represented internally:
* - ASCII (default)
* - UTF-8 (ffconfigUNICODE_UTF8_SUPPORT = 1)
* - UTF-16 (ffconfigUNICODE_UTF16_SUPPORT = 1)
*/
#if ( ffconfigUNICODE_UTF16_SUPPORT == 0 )
/* Only used when ffconfigLFN_SUPPORT is set to 1.
*
* Set to 1 to use UTF-16 (wide-characters) for file and directory names.
*
* Set to 0 to use either 8-bit ASCII or UTF-8 for file and directory names
* (see the ffconfigUNICODE_UTF8_SUPPORT). */
#define ffconfigUNICODE_UTF16_SUPPORT 0
#endif
#if !defined( ffconfigUNICODE_UTF8_SUPPORT )
/* Only used when ffconfigLFN_SUPPORT is set to 1.
*
* Set to 1 to use UTF-8 encoding for file and directory names.
*
* Set to 0 to use either 8-bit ASCII or UTF-16 for file and directory
* names (see the ffconfig_UTF_16_SUPPORT setting). */
#define ffconfigUNICODE_UTF8_SUPPORT 0
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
#error Can not use both UTF-16 and UTF-8
#endif
#if !defined( ffconfigFAT12_SUPPORT )
/* Set to 1 to include FAT12 support.
*
* Set to 0 to exclude FAT12 support.
*
* FAT16 and FAT32 are always enabled. */
#define ffconfigFAT12_SUPPORT 0
#endif
#if !defined( ffconfigOPTIMISE_UNALIGNED_ACCESS )
/* When writing and reading data, i/o becomes less efficient if sizes other
* than the sector size (usually 512 bytes) are being used. When set to 1, each file handle will
* allocate a one sector size character buffer to facilitate "unaligned access". */
#define ffconfigOPTIMISE_UNALIGNED_ACCESS 0
#endif
#if !defined( ffconfigCACHE_WRITE_THROUGH )
/* Input and output to a disk uses buffers that are only flushed at the
* following times:
*
* - When a new buffer is needed and no other buffers are available.
* - When opening a buffer in READ mode for a sector that has just been changed.
* - After creating, removing or closing a file or a directory.
*
* Normally this is quick enough and it is efficient. If
* ffconfigCACHE_WRITE_THROUGH is set to 1 then buffers will also be flushed each
* time a buffer is released - which is less efficient but more secure. */
#define ffconfigCACHE_WRITE_THROUGH 0
#endif
#if !defined( ffconfigWRITE_BOTH_FATS )
/* In most cases, the FAT table has two identical copies on the disk,
* allowing the second copy to be used in the case of a read error. If
*
* Set to 1 to use both FATs - this is less efficient but more secure.
*
* Set to 0 to use only one FAT - the second FAT will never be written to. */
#define ffconfigWRITE_BOTH_FATS 0
#endif
#if !defined( ffconfigWRITE_FREE_COUNT )
/* Set to 1 to have the number of free clusters and the first free cluster
* to be written to the FS info sector each time one of those values changes.
*
* Set to 0 not to store these values in the FS info sector, making booting
* slower, but making changes faster. */
#define ffconfigWRITE_FREE_COUNT 0
#endif
#if !defined( ffconfigTIME_SUPPORT )
/* Set to 1 to maintain file and directory time stamps for creation, modify
* and last access.
*
* Set to 0 to exclude time stamps.
*
* If time support is used, the following function must be supplied:
*
* time_t FreeRTOS_time( time_t *pxTime );
*
* FreeRTOS_time has the same semantics as the standard time() function. */
#define ffconfigTIME_SUPPORT 0
#endif
#if !defined( ffconfigREMOVABLE_MEDIA )
/* Set to 1 if the media is removable (such as a memory card).
*
* Set to 0 if the media is not removable.
*
* When set to 1 all file handles will be "invalidated" if the media is
* extracted. If set to 0 then file handles will not be invalidated.
* In that case the user will have to confirm that the media is still present
* before every access. */
#define ffconfigREMOVABLE_MEDIA 0
#endif
#if !defined( ffconfigMOUNT_FIND_FREE )
/* Set to 1 to determine the disk's free space and the disk's first free
* cluster when a disk is mounted.
*
* Set to 0 to find these two values when they are first needed. Determining
* the values can take some time. */
#define ffconfigMOUNT_FIND_FREE 0
#endif
#if !defined( ffconfigFSINFO_TRUSTED )
/* Set to 1 to 'trust' the contents of the 'ulLastFreeCluster' and
* ulFreeClusterCount fields.
*
* Set to 0 not to 'trust' these fields.*/
#define ffconfigFSINFO_TRUSTED 0
#endif
#if !defined( ffconfigFINDAPI_ALLOW_WILDCARDS )
/* For now must be set to 0. */
#define ffconfigFINDAPI_ALLOW_WILDCARDS 0
#endif
#if !defined( ffconfigWILDCARD_CASE_INSENSITIVE )
/* For now must be set to 0. */
#define ffconfigWILDCARD_CASE_INSENSITIVE 0
#endif
#if !defined( ffconfigPATH_CACHE )
/* Set to 1 to store recent paths in a cache, enabling much faster access
* when the path is deep within a directory structure at the expense of
* additional RAM usage.
*
* Set to 0 to not use a path cache. */
#define ffconfigPATH_CACHE 0
#endif
#if !defined( ffconfigPATH_CACHE_DEPTH )
/* Only used if ffconfigPATH_CACHE is 1.
*
* Sets the maximum number of paths that can exist in the patch cache at any
* one time. */
#define ffconfigPATH_CACHE_DEPTH 5
#endif
#if !defined( ffconfigHASH_CACHE )
/* Set to 1 to calculate a HASH value for each existing short file name.
* Use of HASH values can improve performance when working with large
* directories, or with files that have a similar name.
*
* Set to 0 not to calculate a HASH value. */
#define ffconfigHASH_CACHE 0
#endif
#if ( ffconfigHASH_CACHE != 0 )
#if !defined( ffconfigHASH_FUNCTION )
/* Only used if ffconfigHASH_CACHE is set to 1
*
* Set to CRC8 or CRC16 to use 8-bit or 16-bit HASH values respectively. */
#define ffconfigHASH_FUNCTION CRC16
#endif
#if ffconfigHASH_FUNCTION == CRC16
#define ffconfigHASH_TABLE_SIZE 8192
#elif ffconfigHASH_FUNCTION == CRC8
#define ffconfigHASH_TABLE_SIZE 32
#else
#error Invalid Hashing function selected. CRC16 or CRC8. See your FreeRTOSFATConfig.h.
#endif
#endif /* ffconfigHASH_CACHE != 0 */
#if !defined( ffconfigMKDIR_RECURSIVE )
/* Set to 1 to add a parameter to ff_mkdir() that allows an entire directory
* tree to be created in one go, rather than having to create one directory in
* the tree at a time. For example mkdir( "/etc/settings/network", pdTRUE );.
*
* Set to 0 to use the normal mkdir() semantics (without the additional
* parameter). */
#define ffconfigMKDIR_RECURSIVE 0
#endif
#if !defined( ffconfigMALLOC )
/* Set to a function that will be used for all dynamic memory allocations.
* Setting to pvPortMalloc() will use the same memory allocator as FreeRTOS. */
#define ffconfigMALLOC( size ) pvPortMalloc( size )
#endif
#if !defined( ffconfigFREE )
/* Set to a function that matches the above allocator defined with
* ffconfigMALLOC. Setting to vPortFree() will use the same memory free
* function as FreeRTOS. */
#define ffconfigFREE( ptr ) vPortFree( ptr )
#endif
#if !defined( ffconfig64_NUM_SUPPORT )
/* Set to 1 to calculate the free size and volume size as a 64-bit number.
*
* Set to 0 to calculate these values as a 32-bit number. */
#define ffconfig64_NUM_SUPPORT 0
#endif
#if !defined( ffconfigMAX_PARTITIONS )
/* Defines the maximum number of partitions (and also logical partitions)
* that can be recognised. */
#define ffconfigMAX_PARTITIONS 4
#endif
#if !defined( ffconfigMAX_FILE_SYS )
/* Defines how many drives can be combined in total. Should be set to at
* least 2. */
#define ffconfigMAX_FILE_SYS 4
#endif
#if !defined( ffconfigDRIVER_BUSY_SLEEP_MS )
/* In case the low-level driver returns an error 'FF_ERR_DRIVER_BUSY',
* the library will pause for a number of ms, defined in
* ffconfigDRIVER_BUSY_SLEEP_MS before re-trying. */
#define ffconfigDRIVER_BUSY_SLEEP_MS 20
#endif
#if !defined( ffconfigFPRINTF_SUPPORT )
/* Set to 1 to include the ff_fprintf() function.
*
* Set to 0 to exclude the ff_fprintf() function.
*
* ff_fprintf() is quite a heavy function because it allocates RAM and
* brings in a lot of string and variable argument handling code. If
* ff_fprintf() is not being used then the code size can be reduced by setting
* ffconfigFPRINTF_SUPPORT to 0. */
#define ffconfigFPRINTF_SUPPORT 0
#endif
#if !defined( ffconfigFPRINTF_BUFFER_LENGTH )
/* ff_fprintf() will allocate a buffer of this size in which it will create
* its formatted string. The buffer will be freed before the function
* exits. */
#define ffconfigFPRINTF_BUFFER_LENGTH 128
#endif
#if !defined( ffconfigDEBUG )
#define ffconfigDEBUG 0
#endif
#if !defined( ffconfigLONG_ERR_MSG )
#define ffconfigLONG_ERR_MSG 0
#endif
#if ( ffconfigDEBUG != 0 )
#if !defined( ffconfigHAS_FUNCTION_TAB )
#define ffconfigHAS_FUNCTION_TAB 1
#endif
#endif
#if !defined( ffconfigINLINE_MEMORY_ACCESS )
/* Set to 1 to inline some internal memory access functions.
*
* Set to 0 to not inline the memory access functions. */
#define ffconfigINLINE_MEMORY_ACCESS 0
#endif
#if !defined( ffconfigMIRROR_FATS_UMOUNT )
/*_RB_ not sure. */
#define ffconfigMIRROR_FATS_UMOUNT 0
#endif
#if !defined( ffconfigFAT_CHECK )
/* Officially the only criteria to determine the FAT type (12, 16, or 32
* bits) is the total number of clusters:
* if( ulNumberOfClusters < 4085 ) : Volume is FAT12
* if( ulNumberOfClusters < 65525 ) : Volume is FAT16
* if( ulNumberOfClusters >= 65525 ) : Volume is FAT32
* Not every formatted device follows the above rule.
*
* Set to 1 to perform additional checks over and above inspecting the
* number of clusters on a disk to determine the FAT type.
*
* Set to 0 to only look at the number of clusters on a disk to determine the
* FAT type. */
#define ffconfigFAT_CHECK 0
#endif
#if !defined( ffconfigMAX_FILENAME )
/* Sets the maximum length for file names, including the path.
* Note that the value of this define is directly related to the maximum stack
* use of the +FAT library. In some API's, a character buffer of size
* 'ffconfigMAX_FILENAME' will be declared on stack. */
#define ffconfigMAX_FILENAME 129
#endif
#if !defined( ffconfigUSE_DELTREE )
/* By default, do not include the recursive function ff_deltree() as
* recursion breaches the coding standard - USE WITH CARE. */
#define ffconfigUSE_DELTREE 0
#endif
#if !defined( ffconfigFILE_EXTEND_FLUSHES_BUFFERS )
/* When writing large files, the contents of the FAT entries will be flushed
* after every call to FF_Write(). This flushing can be inhibited, by defining
* ffconfigFILE_EXTEND_FLUSHES_BUFFERS as 0. */
#define ffconfigFILE_EXTEND_FLUSHES_BUFFERS 1
#endif
#if !defined( FF_PRINTF )
#define FF_PRINTF FF_PRINTF
static portINLINE void FF_PRINTF( const char * pcFormat,
... )
{
( void ) pcFormat;
}
#endif
#endif /* ifndef FF_DEFAULTCONFIG_H */

View File

@ -0,0 +1,87 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef FREERTOS_ERRNO_FAT
#define FREERTOS_ERRNO_FAT
/* The following definitions will be included in the core FreeRTOS code in
* future versions of FreeRTOS - hence the 'pd' (ProjDefs) prefix - at which time
* this file will be removed. */
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
* itself. */
/* For future compatibility (see comment above), check the definitions have not
* already been made. */
#ifndef pdFREERTOS_ERRNO_NONE
#define pdFREERTOS_ERRNO_NONE 0 /* No errors */
#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
* itself. */
#define pdFREERTOS_LITTLE_ENDIAN 0
#define pdFREERTOS_BIG_ENDIAN 1
#endif /* pdFREERTOS_ERRNO_NONE */
#endif /* FREERTOS_ERRNO_FAT */

View File

@ -0,0 +1,45 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_crc.h
* @ingroup CRC
*
**/
#ifndef _FF_CRC_H_
#define _FF_CRC_H_
uint8_t FF_GetCRC8( uint8_t * pbyData,
uint32_t stLength );
uint16_t FF_GetCRC16( uint8_t * pbyData,
uint32_t stLength );
uint32_t FF_GetCRC32( uint8_t * pbyData,
uint32_t stLength );
extern const uint32_t crc32_table[ 256 ];
#endif /* ifndef _FF_CRC_H_ */

View File

@ -0,0 +1,74 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_devices.h
**/
#ifndef FF_DEVICES_H
#define FF_DEVICES_H
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define FF_DEV_NO_DEV 0
#define FF_DEV_CHAR_DEV 1
#define FF_DEV_BLOCK_DEV 2
BaseType_t xCheckDevicePath( const char * pcPath );
int FF_Device_Seek( FF_FILE * pxStream,
long lOffset,
int iWhence );
BaseType_t FF_Device_Open( const char * pcPath,
FF_FILE * pxStream );
void FF_Device_Close( FF_FILE * pxStream );
size_t FF_Device_Read( void * pvBuf,
size_t lSize,
size_t lCount,
FF_FILE * pxStream );
size_t FF_Device_Write( const void * pvBuf,
size_t lSize,
size_t lCount,
FF_FILE * pxStream );
int FF_Device_GetDirEnt( const char * pcPath,
FF_DirEnt_t * pxDirEnt );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FF_DEVICES_H */

View File

@ -0,0 +1,274 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_dir.h
* @ingroup DIR
**/
#ifndef _FF_DIR_H_
#define _FF_DIR_H_
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
#define FIND_FLAG_SHORTNAME_SET 0x01u
#define FIND_FLAG_SHORTNAME_CHECKED 0x02u
#define FIND_FLAG_SHORTNAME_FOUND 0x04u
#define FIND_FLAG_FITS_SHORT 0x08u
#define FIND_FLAG_SIZE_OK 0x10u
#define FIND_FLAG_CREATE_FLAG 0x20u
#define FIND_FLAG_FITS_SHORT_OK ( FIND_FLAG_FITS_SHORT | FIND_FLAG_SIZE_OK )
typedef struct
{
uint32_t ulChainLength;
uint32_t ulDirCluster;
uint32_t ulCurrentClusterLCN;
uint32_t ulCurrentClusterNum;
FF_Buffer_t * pxBuffer;
} FF_FetchContext_t;
typedef struct
{
uint32_t ulFileSize;
uint32_t ulObjectCluster;
/* Book Keeping. */
uint32_t ulCurrentCluster;
uint32_t ulAddrCurrentCluster;
uint32_t ulDirCluster;
uint16_t usCurrentItem;
/* End Book Keeping. */
#if ( ffconfigTIME_SUPPORT != 0 )
FF_SystemTime_t xCreateTime; /* Date and Time Created. */
FF_SystemTime_t xModifiedTime; /* Date and Time Modified. */
FF_SystemTime_t xAccessedTime; /* Date of Last Access. */
#endif
#if ( ffconfigFINDAPI_ALLOW_WILDCARDS != 0 )
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_T_WCHAR pcWildCard[ ffconfigMAX_FILENAME ];
#else
char pcWildCard[ ffconfigMAX_FILENAME ];
#endif
BaseType_t xInvertWildCard;
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_T_WCHAR pcFileName[ ffconfigMAX_FILENAME ];
#else
char pcFileName[ ffconfigMAX_FILENAME ];
#endif
#if ( ffconfigLFN_SUPPORT != 0 ) && ( ffconfigINCLUDE_SHORT_NAME != 0 )
char pcShortName[ 13 ];
#endif
uint8_t ucAttrib;
#if ( ffconfigDEV_SUPPORT != 0 )
uint8_t ucIsDeviceDir;
#endif
FF_FetchContext_t xFetchContext;
} FF_DirEnt_t;
/*
* Some public API's, i.e. they're used but ff_stdio.c
*/
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_Error_t FF_FindFirst( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirent,
const FF_T_WCHAR * pcPath );
FF_Error_t FF_MkDir( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * pcPath );
#else
FF_Error_t FF_FindFirst( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirent,
const char * pcPath );
FF_Error_t FF_MkDir( FF_IOManager_t * pxIOManager,
const char * pcPath );
#endif /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
FF_Error_t FF_FindNext( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirent );
static portINLINE void FF_RewindFind( FF_DirEnt_t * pxDirent )
{
pxDirent->usCurrentItem = 0;
}
/*
* Some API's internal to the +FAT library.
*/
FF_Error_t FF_GetEntry( FF_IOManager_t * pxIOManager,
uint16_t usEntry,
uint32_t ulDirCluster,
FF_DirEnt_t * pxDirent );
FF_Error_t FF_PutEntry( FF_IOManager_t * pxIOManager,
uint16_t usEntry,
uint32_t ulDirCluster,
FF_DirEnt_t * pxDirent,
uint8_t * pucContents );
int8_t FF_FindEntry( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster,
int8_t * Name,
FF_DirEnt_t * pxDirent,
BaseType_t LFNs );
void FF_PopulateShortDirent( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirent,
const uint8_t * pucEntryBuffer );
FF_Error_t FF_PopulateLongDirent( FF_IOManager_t * pxIOManager,
FF_DirEnt_t * pxDirent,
uint16_t usEntry,
FF_FetchContext_t * pFetchContext );
FF_Error_t FF_InitEntryFetch( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster,
FF_FetchContext_t * pContext );
FF_Error_t FF_FetchEntryWithContext( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
FF_FetchContext_t * pContext,
uint8_t * pEntryBuffer );
FF_Error_t FF_PushEntryWithContext( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
FF_FetchContext_t * pContext,
uint8_t * pEntryBuffer );
FF_Error_t FF_CleanupEntryFetch( FF_IOManager_t * pxIOManager,
FF_FetchContext_t * pContext );
int8_t FF_PushEntry( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster,
uint16_t usEntry,
uint8_t * buffer,
void * pParam );
static portINLINE BaseType_t FF_isEndOfDir( const uint8_t * pucEntryBuffer )
{
return pucEntryBuffer[ 0 ] == ( uint8_t ) 0;
}
static portINLINE BaseType_t FF_isDeleted( const uint8_t * pucEntryBuffer )
{
return pucEntryBuffer[ 0 ] == ( uint8_t ) FF_FAT_DELETED;
}
struct _FF_FIND_PARAMS
{
uint32_t ulDirCluster; /* The beginning cluster of this directory. */
int32_t lFreeEntry; /* The first free entry big enough to add the file. */
uint32_t ulFlags; /* See FIND_FLAG_xxx defines above. */
char pcEntryBuffer[ 32 ]; /* LFN converted to short name. */
uint8_t ucCaseAttrib;
uint8_t ucFirstTilde;
};
typedef struct _FF_FIND_PARAMS FF_FindParams_t;
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
uint32_t FF_CreateFile( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams,
FF_T_WCHAR * FileName,
FF_DirEnt_t * pxDirent,
FF_Error_t * pError );
uint32_t FF_FindEntryInDir( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams,
const FF_T_WCHAR * name,
uint8_t pa_Attrib,
FF_DirEnt_t * pxDirent,
FF_Error_t * pError );
uint32_t FF_FindDir( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * pcPath,
uint16_t pathLen,
FF_Error_t * pError );
void FF_CreateShortName( FF_FindParams_t * pxFindParams,
const FF_T_WCHAR * pcLongName );
#else /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
uint32_t FF_CreateFile( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams,
char * FileName,
FF_DirEnt_t * pxDirent,
FF_Error_t * pError );
uint32_t FF_FindEntryInDir( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams,
const char * name,
uint8_t pa_Attrib,
FF_DirEnt_t * pxDirent,
FF_Error_t * pError );
uint32_t FF_FindDir( FF_IOManager_t * pxIOManager,
const char * pcPath,
uint16_t pathLen,
FF_Error_t * pError );
void FF_CreateShortName( FF_FindParams_t * pxFindParams,
const char * pcLongName );
#endif /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
int32_t FF_FindShortName( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams );
FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager,
FF_FindParams_t * findParams,
FF_DirEnt_t * pxDirent );
FF_Error_t FF_ExtendDirectory( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster );
FF_Error_t FF_RmLFNs( FF_IOManager_t * pxIOManager,
uint16_t usDirEntry,
FF_FetchContext_t * pContext );
#if ( ffconfigHASH_CACHE != 0 )
BaseType_t FF_CheckDirentHash( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster,
uint32_t ulHash );
BaseType_t FF_DirHashed( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster );
void FF_AddDirentHash( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster,
uint32_t ulHash );
FF_Error_t FF_HashDir( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster );
void FF_UnHashDir( FF_IOManager_t * pxIOManager,
uint32_t ulDirCluster );
#endif /* if ( ffconfigHASH_CACHE != 0 ) */
struct SBuffStats
{
unsigned sectorMatch;
unsigned sectorMiss;
unsigned bufCounts;
unsigned bufCalls;
};
extern struct SBuffStats buffStats;
#endif /* ifndef _FF_DIR_H_ */

View File

@ -0,0 +1,264 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef _FF_ERROR_H_
#define _FF_ERROR_H_
/**
* @file ff_error.h
* @ingroup ERROR
**/
/**
* Error codes are 32-bit numbers, and consist of three items:
* 1Bit 7Bits 8Bits 16Bits
* . ........ ........ ........ ........
* [ErrFlag][ModuleID][FunctionID][-- ERROR CODE --]
*
* Error Codes should always have the ErrFlag set, this is the reason why all module
* codes include it.
*
* When returning an error simply return the defined Error Code, OR'd with the function
* name (capitalised) in which the error has occurred.
*
* When receiving an Error code from another layer, do not modify the code, as this will
* prevent the error code from containing the origin of the error, simply pass it to the
* next layer.
*
* Some API's have been defined to provide, useful and meaningful Error messages to the
* the 'userspace' application layer.
*
**/
#define FF_MODULE_SHIFT 24
#define FF_FUNCTION_SHIFT 16
#define FF_GETERROR( x ) ( ( ( unsigned ) x ) & 0xFFFF )
#define FF_GETMODULE( x ) ( ( ( ( unsigned ) x ) >> FF_MODULE_SHIFT ) & 0x7F )
#define FF_GETFUNCTION( x ) ( ( ( ( unsigned ) x ) >> FF_FUNCTION_SHIFT ) & 0xFF )
#define FF_GETMOD_FUNC( x ) ( ( ( ( unsigned ) x ) >> FF_FUNCTION_SHIFT ) & 0xFFFF )
#define FF_ERRFLAG 0x80000000
#define FF_isERR( x ) ( ( ( x ) & FF_ERRFLAG ) != 0 )
/*----- FreeRTOS+FAT Module Identifiers */
#define FF_MODULE_IOMAN ( ( 1 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_DIR ( ( 2 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_FILE ( ( 3 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_FAT ( ( 4 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_CRC ( ( 5 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_FORMAT ( ( 6 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_MEMORY ( ( 7 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_STRING ( ( 8 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_LOCKING ( ( 9 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_TIME ( ( 10 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_DRIVER ( ( 11 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
#define FF_MODULE_STDIO ( ( 12 << FF_MODULE_SHIFT ) | FF_ERRFLAG )
/*----- FreeRTOS+FAT Function Identifiers (In Modular Order) */
/*----- FF_IOManager_t - The FreeRTOS+FAT I/O Manager. */
#define FF_CREATEIOMAN ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_DESTROYIOMAN ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_MOUNT ( ( 3 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_UNMOUNT ( ( 4 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_FLUSHCACHE ( ( 5 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_GETPARTITIONBLOCKSIZE ( ( 6 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_BLOCKREAD ( ( 7 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_BLOCKWRITE ( ( 8 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_DETERMINEFATTYPE ( ( 9 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_GETEFIPARTITIONENTRY ( ( 10 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_USERDRIVER ( ( 11 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_DECREASEFREECLUSTERS ( ( 12 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_INCREASEFREECLUSTERS ( ( 13 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_PARTITIONSEARCH ( ( 14 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
#define FF_PARSEEXTENDED ( ( 15 << FF_FUNCTION_SHIFT ) | FF_MODULE_IOMAN )
/*----- FreeRTOS+FAT Return codes for user Rd/Wr routines */
#define FF_ERR_DRIVER_NOMEDIUM ( FF_ERR_IOMAN_DRIVER_NOMEDIUM | FF_USERDRIVER | FF_MODULE_DRIVER )
#define FF_ERR_DRIVER_BUSY ( FF_ERR_IOMAN_DRIVER_BUSY | FF_USERDRIVER | FF_MODULE_DRIVER )
#define FF_ERR_DRIVER_FATAL_ERROR ( FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_USERDRIVER | FF_MODULE_DRIVER )
/*----- FF_DIR - The FreeRTOS+FAT directory handling routines. */
#define FF_FETCHENTRYWITHCONTEXT ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_PUSHENTRYWITHCONTEXT ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_GETENTRY ( ( 3 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDFIRST ( ( 4 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDNEXT ( ( 5 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_REWINDFIND ( ( 6 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDFREEDIRENT ( ( 7 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_PUTENTRY ( ( 8 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_CREATESHORTNAME ( ( 9 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_CREATELFNS ( ( 10 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_EXTENDDIRECTORY ( ( 11 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_MKDIR ( ( 12 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_TRAVERSE ( ( 13 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
#define FF_FINDDIR ( ( 14 << FF_FUNCTION_SHIFT ) | FF_MODULE_DIR )
/*----- FF_FILE - The FreeRTOS+FAT file handling routines. */
#define FF_GETMODEBITS ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_OPEN ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_ISDIREMPTY ( ( 3 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_RMDIR ( ( 4 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_RMFILE ( ( 5 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_MOVE ( ( 6 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_ISEOF ( ( 7 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_GETSEQUENTIALCLUSTERS ( ( 8 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_READCLUSTERS ( ( 9 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_EXTENDFILE ( ( 10 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_WRITECLUSTERS ( ( 11 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_READ ( ( 12 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_GETC ( ( 13 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_GETLINE ( ( 14 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_TELL ( ( 15 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_WRITE ( ( 16 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_PUTC ( ( 17 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_SEEK ( ( 18 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_INVALIDATE ( ( 19 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_CHECKVALID ( ( 20 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_CLOSE ( ( 21 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_SETTIME ( ( 22 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_BYTESLEFT ( ( 23 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_SETFILETIME ( ( 24 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_INITBUF ( ( 25 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
#define FF_SETEOF ( ( 26 << FF_FUNCTION_SHIFT ) | FF_MODULE_FILE )
/*----- FF_FAT - The FreeRTOS+FAT FAT handling routines. */
#define FF_GETFATENTRY ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_FAT )
#define FF_CLEARCLUSTER ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_FAT )
#define FF_PUTFATENTRY ( ( 3 << FF_FUNCTION_SHIFT ) | FF_MODULE_FAT )
#define FF_FINDFREECLUSTER ( ( 4 << FF_FUNCTION_SHIFT ) | FF_MODULE_FAT )
#define FF_COUNTFREECLUSTERS ( ( 5 << FF_FUNCTION_SHIFT ) | FF_MODULE_FAT )
/*----- FF_FORMAT - The FreeRTOS+FAT format routine */
#define FF_FORMATPARTITION ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_FORMAT )
/*----- FF_UNICODE - The FreeRTOS+FAT unicode routines. */
#define FF_UTF8CTOUTF16C ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_STRING )
#define FF_UTF16CTOUTF8C ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_STRING )
#define FF_UTF32CTOUTF16C ( ( 3 << FF_FUNCTION_SHIFT ) | FF_MODULE_STRING )
#define FF_UTF16CTOUTF32C ( ( 4 << FF_FUNCTION_SHIFT ) | FF_MODULE_STRING )
/*----- FF_STDIO - The stdio-interface to FreeRTOS+FAT. */
#define FF_CHMOD ( ( 1 << FF_FUNCTION_SHIFT ) | FF_MODULE_STDIO )
#define FF_STAT_FUNC ( ( 2 << FF_FUNCTION_SHIFT ) | FF_MODULE_STDIO )
/* FreeRTOS+FAT defines different Error-Code spaces for each module. This ensures
* that all error codes remain unique, and their meaning can be quickly identified.
*/
/* Global Error Codes */
#define FF_ERR_NONE 0 /* No Error */
/*#define FF_ERR_GENERIC 1*/ /* BAD NEVER USE THIS! -- Therefore commented out. */
#define FF_ERR_NULL_POINTER 2 /* Parameter was NULL. */
#define FF_ERR_NOT_ENOUGH_MEMORY 3 /* malloc() failed! - Could not allocate handle memory. */
#define FF_ERR_DEVICE_DRIVER_FAILED 4 /* The Block Device driver reported a FATAL error, cannot continue. */
/* User return codes for Rd/Wr functions: */
#define FF_ERR_IOMAN_DRIVER_NOMEDIUM 8
#define FF_ERR_IOMAN_DRIVER_BUSY 9
#define FF_ERR_IOMAN_DRIVER_FATAL_ERROR 10
/* IOMAN Error Codes */
#define FF_ERR_IOMAN_BAD_BLKSIZE 11 /* The provided blocksize was not a multiple of 512. */
#define FF_ERR_IOMAN_BAD_MEMSIZE 12 /* The memory size was not a multiple of the blocksize. */
#define FF_ERR_IOMAN_DEV_ALREADY_REGD 13 /* Device was already registered. Use FF_UnRegister() to re-use this IOMAN with another device. */
#define FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION 14 /* A mountable partition could not be found on the device. */
#define FF_ERR_IOMAN_INVALID_FORMAT 15
#define FF_ERR_IOMAN_INVALID_PARTITION_NUM 16 /* The partition number provided was out of range. */
#define FF_ERR_IOMAN_NOT_FAT_FORMATTED 17 /* The partition did not look like a FAT partition. */
#define FF_ERR_IOMAN_DEV_INVALID_BLKSIZE 18 /* IOMAN object BlkSize is not compatible with the blocksize of this device driver. */
#define FF_ERR_IOMAN_PARTITION_MOUNTED 19 /* Device is in use by an actively mounted partition. Unmount the partition first. */
#define FF_ERR_IOMAN_ACTIVE_HANDLES 20 /* The partition cannot be unmounted until all active file handles are closed. (There may also be active handles on the cache). */
#define FF_ERR_IOMAN_GPT_HEADER_CORRUPT 21 /* The GPT partition table appears to be corrupt, refusing to mount. */
#define FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE 22
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_READ 23
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE 24
/* File Error Codes 30 + */
#define FF_ERR_FILE_ALREADY_OPEN 30 /* File is in use. */
#define FF_ERR_FILE_NOT_FOUND 31 /* File was not found. */
#define FF_ERR_FILE_OBJECT_IS_A_DIR 32 /* Tried to FF_Open() a Directory. */
#define FF_ERR_FILE_IS_READ_ONLY 33 /* Tried to FF_Open() a file marked read only. */
#define FF_ERR_FILE_INVALID_PATH 34 /* The path of the file was not found. */
#define FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE 35
#define FF_ERR_FILE_NOT_OPENED_IN_READ_MODE 36
#define FF_ERR_FILE_EXTEND_FAILED 37 /* Could not extend the file. */
#define FF_ERR_FILE_DESTINATION_EXISTS 38
#define FF_ERR_FILE_SOURCE_NOT_FOUND 39
#define FF_ERR_FILE_DIR_NOT_FOUND 40
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT 41
#define FF_ERR_FILE_BAD_HANDLE 42 /* A file handle was invalid */
#define FF_ERR_FILE_MEDIA_REMOVED 43 /* File handle got invalid because media was removed */
#define FF_ERR_FILE_READ_ZERO 44 /* Used internally. */
#define FF_ERR_FILE_SEEK_INVALID_ORIGIN 45 /* Seeking beyond end of file. */
#define FF_ERR_FILE_SEEK_INVALID_POSITION 46 /* Bad value for the 'whence' parameter. */
/* Directory Error Codes 50 + */
#define FF_ERR_DIR_OBJECT_EXISTS 50 /* A file or folder of the same name already exists in the current directory. */
#define FF_ERR_DIR_DIRECTORY_FULL 51 /* No more items could be added to the directory. */
#define FF_ERR_DIR_END_OF_DIR 52 /*/ */
#define FF_ERR_DIR_NOT_EMPTY 53 /* Cannot delete a directory that contains files or folders. */
#define FF_ERR_DIR_INVALID_PATH 54 /* Could not find the directory specified by the path. */
#define FF_ERR_DIR_INVALID_PARAMETER 55 /* Could not find the directory specified by the path. */
#define FF_ERR_DIR_CANT_EXTEND_ROOT_DIR 56 /* Can't extend the root dir. */
#define FF_ERR_DIR_EXTEND_FAILED 57 /* Not enough space to extend the directory. */
#define FF_ERR_DIR_NAME_TOO_LONG 58 /* Name exceeds the number of allowed characters for a filename. */
/* Fat Error Codes 70 + */
#define FF_ERR_FAT_NO_FREE_CLUSTERS 70 /* No more free space is available on the disk. */
/* UNICODE Error Codes 100 + */
#define FF_ERR_UNICODE_INVALID_CODE 100 /* An invalid Unicode character was provided! */
#define FF_ERR_UNICODE_DEST_TOO_SMALL 101 /* Not enough space in the UTF-16 buffer to encode the entire sequence as UTF-16. */
#define FF_ERR_UNICODE_INVALID_SEQUENCE 102 /* An invalid UTF-16 sequence was encountered. */
#define FF_ERR_UNICODE_CONVERSION_EXCEEDED 103 /* Filename exceeds MAX long-filename length when converted to UTF-16. */
typedef int32_t FF_Error_t;
#if ( ffconfigDEBUG != 0 )
const char * FF_GetErrMessage( FF_Error_t iErrorCode );
const char * FF_GetErrModule( FF_Error_t iErrorCode );
const char * FF_GetErrFunction( FF_Error_t iErrorCode );
const char * FF_GetErrDescription( FF_Error_t iErrorCode,
char * pcBuffer,
int iMaxLength ); /* Get the complete description */
#else /* ffconfigDEBUG */
#define FF_GetErrMessage( X ) "" /* A special MACRO in case FF_GetErrMessage() isn't gated with ffconfigDEBUG */
#define FF_GetErrModule( X ) ""
#define FF_GetErrFunction( X ) ""
static portINLINE const char * FF_GetErrDescription( FF_Error_t iErrorCode,
char * pcBuffer,
int iMaxLength )
{
( void ) iErrorCode;
( void ) iMaxLength;
strcpy( pcBuffer, "unknown" );
return pcBuffer;
}
#endif /* Function call is safely replaced with a NULL string. */
#endif /* INCLUDE GUARD END */

View File

@ -0,0 +1,168 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_fat.h
* @ingroup FAT
**/
#ifndef _FF_FAT_H_
#define _FF_FAT_H_
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
/*---------- ERROR CODES */
/*---------- PROTOTYPES */
/* HT statistics Will be taken away after testing: */
#if ( ffconfigFAT_USES_STAT != 0 )
struct SFatStat
{
unsigned initCount;
unsigned clearCount;
unsigned getCount[ 2 ]; /* Index 0 for READ counts, index 1 for WRITE counts. */
unsigned reuseCount[ 2 ];
unsigned missCount[ 2 ];
};
extern struct SFatStat fatStat;
#endif /* if ( ffconfigFAT_USES_STAT != 0 ) */
#if ( ffconfigWRITE_BOTH_FATS != 0 )
#define ffconfigBUF_STORE_COUNT 2
#else
#define ffconfigBUF_STORE_COUNT 1
#endif
typedef struct _FatBuffers
{
FF_Buffer_t * pxBuffers[ ffconfigBUF_STORE_COUNT ];
uint8_t ucMode; /* FF_MODE_READ or WRITE. */
} FF_FATBuffers_t;
uint32_t FF_getClusterPosition( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
uint32_t ulEntrySize );
uint32_t FF_getClusterChainNumber( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
uint32_t ulEntrySize );
uint32_t FF_getMajorBlockNumber( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
uint32_t ulEntrySize );
uint32_t FF_getMinorBlockNumber( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
uint32_t ulEntrySize );
uint32_t FF_getMinorBlockEntry( FF_IOManager_t * pxIOManager,
uint32_t ulEntry,
uint32_t ulEntrySize );
/* A partition may define a block size larger than 512 bytes (at offset 0x0B of the PBR).
* This function translates a block address to an address based on 'pxIOManager->usBlkSize',
* which is usually 512 bytes.
*/
static portINLINE uint32_t FF_getRealLBA( FF_IOManager_t * pxIOManager,
uint32_t LBA )
{
return LBA * pxIOManager->xPartition.ucBlkFactor;
}
uint32_t FF_Cluster2LBA( FF_IOManager_t * pxIOManager,
uint32_t ulCluster );
uint32_t FF_LBA2Cluster( FF_IOManager_t * pxIOManager,
uint32_t ulAddress );
uint32_t FF_getFATEntry( FF_IOManager_t * pxIOManager,
uint32_t ulCluster,
FF_Error_t * pxError,
FF_FATBuffers_t * pxFATBuffers );
FF_Error_t FF_putFATEntry( FF_IOManager_t * pxIOManager,
uint32_t ulCluster,
uint32_t ulValue,
FF_FATBuffers_t * pxFATBuffers );
BaseType_t FF_isEndOfChain( FF_IOManager_t * pxIOManager,
uint32_t ulFatEntry );
uint32_t FF_FindFreeCluster( FF_IOManager_t * pxIOManager,
FF_Error_t * pxError,
BaseType_t aDoClaim );
uint32_t FF_ExtendClusterChain( FF_IOManager_t * pxIOManager,
uint32_t ulStartCluster,
uint32_t ulCount );
FF_Error_t FF_UnlinkClusterChain( FF_IOManager_t * pxIOManager,
uint32_t ulStartCluster,
BaseType_t xDoTruncate );
uint32_t FF_TraverseFAT( FF_IOManager_t * pxIOManager,
uint32_t ulStart,
uint32_t ulCount,
FF_Error_t * pxError );
uint32_t FF_CreateClusterChain( FF_IOManager_t * pxIOManager,
FF_Error_t * pxError );
uint32_t FF_GetChainLength( FF_IOManager_t * pxIOManager,
uint32_t pa_nStartCluster,
uint32_t * piEndOfChain,
FF_Error_t * pxError );
uint32_t FF_FindEndOfChain( FF_IOManager_t * pxIOManager,
uint32_t Start,
FF_Error_t * pxError );
FF_Error_t FF_ClearCluster( FF_IOManager_t * pxIOManager,
uint32_t ulCluster );
#if ( ffconfig64_NUM_SUPPORT != 0 )
uint64_t FF_GetFreeSize( FF_IOManager_t * pxIOManager,
FF_Error_t * pxError );
#else
uint32_t FF_GetFreeSize( FF_IOManager_t * pxIOManager,
FF_Error_t * pxError );
#endif
/* WARNING: If this prototype changes, it must be updated in ff_ioman.c also! */
uint32_t FF_CountFreeClusters( FF_IOManager_t * pxIOManager,
FF_Error_t * pxError );
FF_Error_t FF_ReleaseFATBuffers( FF_IOManager_t * pxIOManager,
FF_FATBuffers_t * pxFATBuffers );
static portINLINE void FF_InitFATBuffers( FF_FATBuffers_t * pxFATBuffers,
uint8_t ucMode )
{
pxFATBuffers->pxBuffers[ 0 ] = NULL;
#if ffconfigBUF_STORE_COUNT > 1
pxFATBuffers->pxBuffers[ 1 ] = NULL;
#endif
#if ffconfigBUF_STORE_COUNT > 2
#error Please check this code, maybe it is time to use memset
#endif
pxFATBuffers->ucMode = ucMode; /* FF_MODE_READ/WRITE */
#if ffconfigFAT_USES_STAT
{
fatStat.initCount++;
}
#endif
}
#endif /* ifndef _FF_FAT_H_ */

View File

@ -0,0 +1,108 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef _FF_FATDEF_H_
#define _FF_FATDEF_H_
/*
* This file defines offsets to various data for the FAT specification.
*/
/* MBR / PBR Offsets. */
#define FF_FAT_BYTES_PER_SECTOR 0x00B
#define FF_FAT_SECTORS_PER_CLUS 0x00D
#define FF_FAT_RESERVED_SECTORS 0x00E
#define FF_FAT_NUMBER_OF_FATS 0x010
#define FF_FAT_ROOT_ENTRY_COUNT 0x011
#define FF_FAT_16_TOTAL_SECTORS 0x013
#define FF_FAT_MEDIA_TYPE 0x015
#define FF_FAT_32_TOTAL_SECTORS 0x020
#define FF_FAT_16_SECTORS_PER_FAT 0x016
#define FF_FAT_32_SECTORS_PER_FAT 0x024
#define FF_FAT_ROOT_DIR_CLUSTER 0x02C
#define FF_FAT_EXT_BOOT_SIGNATURE 0x042
#define FF_FAT_16_VOL_LABEL 0x02B
#define FF_FAT_32_VOL_LABEL 0x047
#define FF_FAT_PTBL 0x1BE
#define FF_FAT_PTBL_LBA 0x008
#define FF_FAT_PTBL_SECT_COUNT 0x00C
#define FF_FAT_PTBL_ACTIVE 0x000
#define FF_FAT_PTBL_ID 0x004
#define FF_DOS_EXT_PART 0x05
#define FF_LINUX_EXT_PART 0x85
#define FF_WIN98_EXT_PART 0x0f
#define FF_FAT_MBR_SIGNATURE 0x1FE
#define FF_FAT_DELETED 0xE5
/* Directory Entry Offsets. */
#define FF_FAT_DIRENT_SHORTNAME 0x000
#define FF_FAT_DIRENT_ATTRIB 0x00B
#define FF_FAT_DIRENT_CREATE_TIME 0x00E /* Creation Time. */
#define FF_FAT_DIRENT_CREATE_DATE 0x010 /* Creation Date. */
#define FF_FAT_DIRENT_LASTACC_DATE 0x012 /* Date of Last Access. */
#define FF_FAT_DIRENT_CLUS_HIGH 0x014
#define FF_FAT_DIRENT_LASTMOD_TIME 0x016 /* Time of Last modification. */
#define FF_FAT_DIRENT_LASTMOD_DATE 0x018 /* Date of Last modification. */
#define FF_FAT_DIRENT_CLUS_LOW 0x01A
#define FF_FAT_DIRENT_FILESIZE 0x01C
#define FF_FAT_LFN_ORD 0x000
#define FF_FAT_LFN_NAME_1 0x001
#define FF_FAT_LFN_CHECKSUM 0x00D
#define FF_FAT_LFN_NAME_2 0x00E
#define FF_FAT_LFN_NAME_3 0x01C
/* Dirent Attributes. */
#define FF_FAT_ATTR_READONLY 0x01
#define FF_FAT_ATTR_HIDDEN 0x02
#define FF_FAT_ATTR_SYSTEM 0x04
#define FF_FAT_ATTR_VOLID 0x08
#define FF_FAT_ATTR_DIR 0x10
#define FF_FAT_ATTR_ARCHIVE 0x20
#define FF_FAT_ATTR_LFN 0x0F
/**
* -- Hein_Tibosch additions for mixed case in shortnames --
*
* Specifically, bit 4 means lowercase extension and bit 3 lowercase basename,
* which allows for combinations such as "example.TXT" or "HELLO.txt" but not "Mixed.txt"
*/
#define FF_FAT_CASE_OFFS 0x0C /* After NT/XP : 2 case bits. */
#define FF_FAT_CASE_ATTR_BASE 0x08
#define FF_FAT_CASE_ATTR_EXT 0x10
#if ( ffconfigLFN_SUPPORT != 0 ) && ( ffconfigINCLUDE_SHORT_NAME != 0 )
#define FF_FAT_ATTR_IS_LFN 0x40 /* artificial attribute, for debugging only. */
#endif
#endif /* ifndef _FF_FATDEF_H_ */

View File

@ -0,0 +1,204 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_file.h
* @ingroup FILEIO
**/
#ifndef _FF_FILE_H_
#define _FF_FILE_H_
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
#define FF_SEEK_SET 0
#define FF_SEEK_CUR 1
#define FF_SEEK_END 2
#if ( ffconfigOPTIMISE_UNALIGNED_ACCESS != 0 )
#define FF_BUFSTATE_INVALID 0x00 /* Data in file handle buffer is invalid. */
#define FF_BUFSTATE_VALID 0x01 /* Valid data in pBuf (Something has been read into it). */
#define FF_BUFSTATE_WRITTEN 0x02 /* Data was written into pBuf, this must be saved when leaving sector. */
#endif
#if ( ffconfigDEV_SUPPORT != 0 )
struct xDEV_NODE
{
uint8_t
ucIsDevice;
};
#endif
typedef struct _FF_FILE
{
FF_IOManager_t * pxIOManager; /* Ioman Pointer! */
uint32_t ulFileSize; /* File's Size. */
uint32_t ulObjectCluster; /* File's Start Cluster. */
uint32_t ulChainLength; /* Total Length of the File's cluster chain. */
uint32_t ulCurrentCluster; /* Prevents FAT Thrashing. */
uint32_t ulAddrCurrentCluster; /* Address of the current cluster. */
uint32_t ulEndOfChain; /* Address of the last cluster in the chain. */
uint32_t ulFilePointer; /* Current Position Pointer. */
uint32_t ulDirCluster; /* Cluster Number that the Dirent is in. */
uint32_t ulValidFlags; /* Handle validation flags. */
#if ( ffconfigOPTIMISE_UNALIGNED_ACCESS != 0 )
uint8_t * pucBuffer; /* A buffer for providing fast unaligned access. */
uint8_t ucState; /* State information about the buffer. */
#endif
uint8_t ucMode; /* Mode that File Was opened in. */
uint16_t usDirEntry; /* Dirent Entry Number describing this file. */
#if ( ffconfigDEV_SUPPORT != 0 )
struct SFileCache * pxDevNode;
#endif
struct _FF_FILE * pxNext; /* Pointer to the next file object in the linked list. */
} FF_FILE;
#define FF_VALID_FLAG_INVALID 0x00000001
#define FF_VALID_FLAG_DELETED 0x00000002
/*---------- PROTOTYPES */
/* PUBLIC (Interfaces): */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_FILE * FF_Open( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * path,
uint8_t Mode,
FF_Error_t * pError );
BaseType_t FF_isDirEmpty( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * Path );
FF_Error_t FF_RmFile( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * path );
FF_Error_t FF_RmDir( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * path );
FF_Error_t FF_Move( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * szSourceFile,
const FF_T_WCHAR * szDestinationFile,
BaseType_t bDeleteIfExists );
#else /* ffconfigUNICODE_UTF16_SUPPORT */
FF_FILE * FF_Open( FF_IOManager_t * pxIOManager,
const char * path,
uint8_t Mode,
FF_Error_t * pError );
BaseType_t FF_isDirEmpty( FF_IOManager_t * pxIOManager,
const char * Path );
FF_Error_t FF_RmFile( FF_IOManager_t * pxIOManager,
const char * path );
FF_Error_t FF_RmDir( FF_IOManager_t * pxIOManager,
const char * path );
FF_Error_t FF_Move( FF_IOManager_t * pxIOManager,
const char * szSourceFile,
const char * szDestinationFile,
BaseType_t bDeleteIfExists );
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
#if ( ffconfigTIME_SUPPORT != 0 )
enum
{
ETimeCreate = 1,
ETimeMod = 2,
ETimeAccess = 4,
ETimeAll = 7
};
FF_Error_t FF_SetFileTime( FF_FILE * pFile,
FF_SystemTime_t * pxTime,
UBaseType_t uxWhat );
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_Error_t FF_SetTime( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * path,
FF_SystemTime_t * pxTime,
UBaseType_t uxWhat );
#else
FF_Error_t FF_SetTime( FF_IOManager_t * pxIOManager,
const char * path,
FF_SystemTime_t * pxTime,
UBaseType_t uxWhat );
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
#endif /* ffconfigTIME_SUPPORT */
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_Error_t FF_SetPerm( FF_IOManager_t * pxIOManager,
const FF_T_WCHAR * path,
UBaseType_t aPerm );
#else
FF_Error_t FF_SetPerm( FF_IOManager_t * pxIOManager,
const char * path,
UBaseType_t aPerm );
#endif
FF_Error_t FF_SetEof( FF_FILE * pFile );
FF_Error_t FF_Close( FF_FILE * pFile );
int32_t FF_GetC( FF_FILE * pFile );
int32_t FF_GetLine( FF_FILE * pFile,
char * szLine,
uint32_t ulLimit );
int32_t FF_Read( FF_FILE * pFile,
uint32_t ElementSize,
uint32_t Count,
uint8_t * buffer );
int32_t FF_Write( FF_FILE * pFile,
uint32_t ElementSize,
uint32_t Count,
uint8_t * buffer );
BaseType_t FF_isEOF( FF_FILE * pFile );
int32_t FF_BytesLeft( FF_FILE * pFile ); /* Returns # of bytes left to read. */
/* FF_FileSize is an earlier version of FF_GetFileSize(). For files
* equal to or larger than 2GB, the return value is negative.
* Function is deprecated. Please use FF_GetFileSize(). */
int32_t FF_FileSize( FF_FILE * pFile ); /* Returns # of bytes in a file. */
/* Use the following function in case files may get larger than 2 GB.
* Writes the size of a file to the parameter.
* Returns 0 or error code. */
FF_Error_t FF_GetFileSize( FF_FILE * pFile,
uint32_t * pulSize );
FF_Error_t FF_Seek( FF_FILE * pFile,
int32_t Offset,
BaseType_t xOrigin );
int32_t FF_PutC( FF_FILE * pFile,
uint8_t Value );
static portINLINE uint32_t FF_Tell( FF_FILE * pFile )
{
return pFile ? pFile->ulFilePointer : 0;
}
uint8_t FF_GetModeBits( const char * Mode );
FF_Error_t FF_CheckValid( FF_FILE * pFile ); /* Check if pFile is a valid FF_FILE pointer. */
#if ( ffconfigREMOVABLE_MEDIA != 0 )
int32_t FF_Invalidate( FF_IOManager_t * pxIOManager ); /* Invalidate all handles belonging to pxIOManager. */
#endif
/* Private : */
#endif /* ifndef _FF_FILE_H_ */

View File

@ -0,0 +1,87 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_format.c
* @ingroup FORMAT
*
**/
#ifndef _FF_FORMAT_H_
#define _FF_FORMAT_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
/*---------- PROTOTYPES */
/* PUBLIC (Interfaces): */
typedef enum _FF_SizeType
{
eSizeIsQuota, /* Assign a quotum (sum of xSizes is free, all disk space will be allocated) */
eSizeIsPercent, /* Assign a percentage of the available space (sum of xSizes must be <= 100) */
eSizeIsSectors, /* Assign fixed number of sectors (sum of xSizes must be < ulSectorCount) */
} eSizeType_t;
typedef struct _FF_PartitionParameters
{
uint32_t ulSectorCount; /* Total number of sectors on the disk, including hidden/reserved */
/* Must be obtained from the block driver */
uint32_t ulHiddenSectors; /* Keep at least these initial sectors free */
uint32_t ulInterSpace; /* Number of sectors to keep free between partitions (when 0 -> 2048) */
BaseType_t xSizes[ ffconfigMAX_PARTITIONS ]; /* E.g. 80, 20, 0, 0 (see eSizeType) */
BaseType_t xPrimaryCount; /* The number of partitions that must be "primary" */
eSizeType_t eSizeType;
} FF_PartitionParameters_t;
FF_Error_t FF_Partition( FF_Disk_t * pxDisk,
FF_PartitionParameters_t * pParams );
FF_Error_t FF_Format( FF_Disk_t * pxDisk,
BaseType_t xPartitionNumber,
BaseType_t xPreferFAT16,
BaseType_t xSmallClusters );
FF_Error_t FF_FormatDisk( FF_Disk_t * pxDisk,
BaseType_t xPartitionNumber,
BaseType_t xPreferFAT16,
BaseType_t xSmallClusters,
const char * pcVolumeName );
/* Private : */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef _FF_FORMAT_H_ */

View File

@ -0,0 +1,62 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef PLUS_FAT_H
#define PLUS_FAT_H
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "FreeRTOSFATConfig.h"
#include "FreeRTOSFATConfigDefaults.h"
#include "ff_error.h"
#include "ff_string.h"
#include "ff_ioman.h"
#include "ff_fat.h"
#include "ff_fatdef.h"
#include "ff_memory.h"
#include "ff_time.h"
#include "ff_crc.h"
#include "ff_file.h"
#include "ff_dir.h"
#include "ff_format.h"
#include "ff_locking.h"
/* See if any older defines with a prefix "FF_" are still defined: */
#include "ff_old_config_defines.h"
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef PLUS_FAT_H */

View File

@ -0,0 +1,414 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_ioman.h
* @ingroup IOMAN
**/
#ifndef _FF_IOMAN_H_
#define _FF_IOMAN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h> /* Use of malloc() */
#ifndef PLUS_FAT_H
#error this header will be included from "ff_headers.h"
#endif
#define FF_T_FAT12 0x0A
#define FF_T_FAT16 0x0B
#define FF_T_FAT32 0x0C
#define FF_MODE_READ 0x01 /* Buffer / FILE Mode for Read Access. */
#define FF_MODE_WRITE 0x02 /* Buffer / FILE Mode for Write Access. */
#define FF_MODE_APPEND 0x04 /* FILE Mode Append Access. */
#define FF_MODE_CREATE 0x08 /* FILE Mode Create file if not existing. */
#define FF_MODE_TRUNCATE 0x10 /* FILE Mode Truncate an Existing file. */
#define FF_MODE_VIRGIN 0x40 /* Buffer mode: do not fetch content from disk. Used for write-only buffers. */
#define FF_MODE_DIR 0x80 /* Special Mode to open a Dir. (Internal use ONLY!) */
#define FF_MODE_RD_WR ( FF_MODE_READ | FF_MODE_WRITE ) /* Just for bit filtering. */
/* The buffer write-only mode saves a fetch from disk.
* The write-only mode is used when a buffer is needed just
* for clearing sectors. */
#define FF_MODE_WR_ONLY ( FF_MODE_VIRGIN | FF_MODE_WRITE ) /* Buffer for Write-only Access (Internal use ONLY!) */
#define FF_BUF_MAX_HANDLES 0xFFFF /* Maximum number handles sharing a buffer. (16 bit integer, we don't want to overflow it!) */
#define FF_MAX_ENTRIES_PER_DIRECTORY 0xFFFF
#define FF_SIZEOF_DIRECTORY_ENTRY 32
#ifndef pdTRUE_SIGNED
/* Temporary solution: eventually the defines below will appear
* in 'Source\include\projdefs.h' */
#define pdTRUE_SIGNED pdTRUE
#define pdFALSE_SIGNED pdFALSE
#define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1u )
#define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0u )
#endif
/**
* I/O Driver Definitions
* Provide access to any Block Device via the following interfaces.
* Returns the number of blocks actually read or written.
**/
/**
* A special information structure for the FreeRTOS+FAT mass storage device
* driver model.
**/
typedef struct
{
uint16_t BlkSize;
uint32_t TotalBlocks;
} FF_DeviceInfo_t;
#if ( ffconfigHASH_CACHE != 0 )
#define FF_HASH_TABLE_ENTRY_COUNT ( ( ffconfigHASH_TABLE_SIZE + 3 ) / 4 )
struct xHASH_TABLE
{
uint32_t ulDirCluster; /* The Starting Cluster of the dir that the hash represents. */
uint32_t ulNumHandles; /* Number of active Handles using this hash table. */
uint32_t ulMisses; /* Number of times this Hash Table was missed, (i.e. how redundant it is). */
uint32_t ulBitTable[ FF_HASH_TABLE_ENTRY_COUNT ];
};
typedef struct xHASH_TABLE FF_HashTable_t;
void FF_ClearHash( FF_HashTable_t * pxHash,
uint32_t ulHash );
void FF_SetHash( FF_HashTable_t * pxHash,
uint32_t ulHash );
BaseType_t FF_isHashSet( FF_HashTable_t * pxHash,
uint32_t ulHash );
#endif /* ffconfigHASH_CACHE */
/* A forward declaration for the I/O manager, to be used in 'struct xFFDisk'. */
struct _FF_IOMAN;
struct xFFDisk;
typedef void ( * FF_FlushApplicationHook )( struct xFFDisk * pxDisk );
/*
* Some low-level drivers also need to flush data to a device.
* Use an Application hook that will be called every time when
* FF_FlushCache() is called. The semaphore will still be taken
* to avoid unwanted reentrancy.
* For example:
*
* void FTL_FlushData( struct xFFDisk *pxDisk )
* {
* // You may or may not inspect 'pxDisk'
* FTL_FlushTableCache();
* }
*
* Make sure you bind the function to the disc object, right after creation:
*
* pxDisk->fnFlushApplicationHook = FTL_FlushData;
*/
/* Structure that contains fields common to all media drivers, and can be
* extended to contain additional fields to tailor it for use with a specific media
* type. */
struct xFFDisk
{
struct
{
/* Flags that can optionally be used by the media driver to ensure the
* disk has been initialised, registered and mounted before it is accessed. */
uint32_t bIsInitialised : 1;
uint32_t bIsMounted : 1;
uint32_t spare0 : 5;
/* The partition number on the media described by this structure. */
uint32_t bPartitionNumber : 8;
uint32_t spare1 : 16;
}
xStatus;
/* Provided to allow this structure to be extended to include additional
* attributes that are specific to a media type. */
void * pvTag;
/* Points to input and output manager used by the disk described by this
* structure. */
struct _FF_IOMAN * pxIOManager;
/* The number of sectors on the disk. */
uint32_t ulNumberOfSectors;
/* See comments here above. */
FF_FlushApplicationHook fnFlushApplicationHook;
/* Field that can optionally be set to a signature that is unique to the
* media. Read and write functions can check the ulSignature field to validate
* the media type before they attempt to access the pvTag field, or perform any
* read and write operations. */
uint32_t ulSignature;
};
typedef struct xFFDisk FF_Disk_t;
typedef int32_t ( * FF_WriteBlocks_t ) ( uint8_t * pucBuffer,
uint32_t ulSectorAddress,
uint32_t ulCount,
FF_Disk_t * pxDisk );
typedef int32_t ( * FF_ReadBlocks_t ) ( uint8_t * pucBuffer,
uint32_t ulSectorAddress,
uint32_t ulCount,
FF_Disk_t * pxDisk );
/**
* @public
* @brief Describes the block device driver interface to FreeRTOS+FAT.
**/
typedef struct
{
FF_WriteBlocks_t fnpWriteBlocks; /* Function Pointer, to write a block(s) from a block device. */
FF_ReadBlocks_t fnpReadBlocks; /* Function Pointer, to read a block(s) from a block device. */
FF_Disk_t * pxDisk; /* Earlier called 'pParam': pointer to some parameters e.g. for a Low-Level Driver Handle. */
} FF_BlockDevice_t;
/**
* @private
* @brief FreeRTOS+FAT handles memory with buffers, described as below.
* @note This may change throughout development.
**/
typedef struct
{
uint32_t ulSector; /* The LBA of the Cached sector. */
uint32_t ulLRU; /* For the Least Recently Used algorithm. */
uint8_t * pucBuffer; /* Pointer to the cache block. */
uint32_t ucMode : 8, /* Read or Write mode. */
bModified : 1, /* If the sector was modified since read. */
bValid : 1; /* Initially FALSE. */
uint16_t usNumHandles; /* Number of objects using this buffer. */
uint16_t usPersistance; /* For the persistance algorithm. */
} FF_Buffer_t;
typedef struct
{
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
FF_T_WCHAR pcPath[ ffconfigMAX_FILENAME ];
#else
char pcPath[ ffconfigMAX_FILENAME ];
#endif
uint32_t ulDirCluster;
} FF_PathCache_t;
/**
* @private
* @brief FreeRTOS+FAT identifies a partition with the following data.
* @note This may shrink as development and optimisation goes on.
**/
typedef struct
{
uint32_t ulBeginLBA; /* LBA start address of the partition. */
uint32_t ulFATBeginLBA; /* LBA of the FAT tables. */
uint32_t ulSectorsPerFAT; /* Number of sectors per Fat. */
uint32_t ulTotalSectors;
uint32_t ulDataSectors;
#if ( ffconfigWRITE_FREE_COUNT != 0 )
uint32_t ulFSInfoLBA; /* LBA of the FSINFO sector. */
#endif
uint32_t ulRootDirSectors;
uint32_t ulFirstDataSector;
uint32_t ulClusterBeginLBA; /* LBA of first cluster. */
uint32_t ulNumClusters; /* Number of clusters. */
uint32_t ulRootDirCluster; /* Cluster number of the root directory entry. */
uint32_t ulLastFreeCluster;
uint32_t ulFreeClusterCount; /* Records free space on mount. */
uint32_t ulSectorsPerCluster; /* Number of sectors per Cluster. */
char pcVolumeLabel[ 12 ]; /* Volume Label of the partition. */
uint16_t usBlkSize; /* Size of a Sector Block in bytes. */
uint16_t usReservedSectors;
uint8_t ucType; /* Partition Type Identifier. */
uint8_t ucBlkFactor; /* Scale Factor for block sizes above 512! */
uint8_t ucNumFATS; /* Number of FAT tables. */
uint8_t ucPartitionMounted; /* pdTRUE if the partition is mounted, otherwise pdFALSE. */
#if ( ffconfigPATH_CACHE != 0 )
FF_PathCache_t pxPathCache[ ffconfigPATH_CACHE_DEPTH ];
uint32_t ulPCIndex;
#endif
} FF_Partition_t;
/**
* @public
* @brief FF_IOManager_t Object description.
*
* FreeRTOS+FAT functions around an object like this.
**/
#define FF_FAT_LOCK 0x01 /* Lock bit mask for FAT table locking. */
#define FF_DIR_LOCK 0x02 /* Lock bit mask for DIR modification locking. */
#define FF_BUF_LOCK 0x04 /* Lock bit mask for buffers. */
/**
* @public
* @brief FF_IOManager_t Object. A developer should not touch these values.
*
**/
typedef struct _FF_IOMAN
{
FF_BlockDevice_t xBlkDevice; /* Pointer to a Block device description. */
FF_Partition_t xPartition; /* A partition description. */
FF_Buffer_t * pxBuffers; /* Pointer to an array of buffer descriptors. */
void * pvSemaphore; /* Pointer to a Semaphore object. (For buffer description modifications only!). */
void * FirstFile; /* Pointer to the first File object. */
void * xEventGroup; /* An event group, used for locking FAT, DIR and Buffers. Replaces ucLocks. */
uint8_t * pucCacheMem; /* Pointer to a block of memory for the cache. */
uint16_t usSectorSize; /* The sector size that IOMAN is configured to. */
uint16_t usCacheSize; /* Size of the cache in number of Sectors. */
uint8_t ucPreventFlush; /* Flushing to disk only allowed when 0. */
uint8_t ucFlags; /* Bit-Mask: identifying allocated pointers and other flags */
#if ( ffconfigHASH_CACHE != 0 )
FF_HashTable_t xHashCache[ ffconfigHASH_CACHE_DEPTH ];
#endif
void * pvFATLockHandle;
} FF_IOManager_t;
/* Bit values for 'FF_IOManager_t::ucFlags': */
/* Memory Allocation testing and other flags. */
#define FF_IOMAN_ALLOC_BUFDESCR 0x01 /* Flags the pxBuffers pointer is allocated. */
#define FF_IOMAN_ALLOC_BUFFERS 0x02 /* Flags the pucCacheMem pointer is allocated. */
#define FF_IOMAN_BLOCK_DEVICE_IS_REENTRANT 0x10 /* When true, ffRead/ffWrite are not protected by a semaphore. */
#if ( ffconfigREMOVABLE_MEDIA != 0 )
#define FF_IOMAN_DEVICE_IS_EXTRACTED 0x20
#endif /* ffconfigREMOVABLE_MEDIA */
typedef struct xFF_CREATION_PARAMETERS
{
uint8_t * pucCacheMemory; /* User provided memory, or use NULL to malloc the cache memory. */
uint32_t ulMemorySize; /* Size of the cache memory, must be a multiple of 'ulSectorSize'. */
BaseType_t ulSectorSize; /* Sector size, unit for reading/writing to the disk, normally 512 bytes. */
FF_WriteBlocks_t fnWriteBlocks; /* A function to write sectors to the device. */
FF_ReadBlocks_t fnReadBlocks; /* A function to read sectors from the device. */
FF_Disk_t * pxDisk; /* Some properties of the disk driver. */
void * pvSemaphore; /* Pointer to a Semaphore object. */
BaseType_t xBlockDeviceIsReentrant; /* Make non-zero if ffRead/ffWrite are re-entrant. */
} FF_CreationParameters_t;
/*---------- PROTOTYPES (in order of appearance). */
/* PUBLIC (Interfaces): */
FF_IOManager_t * FF_CreateIOManger( FF_CreationParameters_t * pxParameters,
FF_Error_t * pError );
FF_Error_t FF_DeleteIOManager( FF_IOManager_t * pxIOManager );
FF_Error_t FF_Mount( FF_Disk_t * pxDisk,
BaseType_t xPartitionNumber );
FF_Error_t FF_Unmount( FF_Disk_t * pxDisk );
FF_Error_t FF_FlushCache( FF_IOManager_t * pxIOManager );
static portINLINE BaseType_t FF_Mounted( FF_IOManager_t * pxIOManager )
{
return pxIOManager && pxIOManager->xPartition.ucPartitionMounted;
}
int32_t FF_GetPartitionBlockSize( FF_IOManager_t * pxIOManager );
#if ( ffconfig64_NUM_SUPPORT != 0 )
uint64_t FF_GetVolumeSize( FF_IOManager_t * pxIOManager );
#else
uint32_t FF_GetVolumeSize( FF_IOManager_t * pxIOManager );
#endif
/* PUBLIC (To FreeRTOS+FAT Only): */
int32_t FF_BlockRead( FF_IOManager_t * pxIOManager,
uint32_t ulSectorLBA,
uint32_t ulNumSectors,
void * pBuffer,
BaseType_t aSemLocked );
int32_t FF_BlockWrite( FF_IOManager_t * pxIOManager,
uint32_t ulSectorLBA,
uint32_t ulNumSectors,
void * pBuffer,
BaseType_t aSemLocked );
FF_Error_t FF_IncreaseFreeClusters( FF_IOManager_t * pxIOManager,
uint32_t Count );
FF_Error_t FF_DecreaseFreeClusters( FF_IOManager_t * pxIOManager,
uint32_t Count );
FF_Buffer_t * FF_GetBuffer( FF_IOManager_t * pxIOManager,
uint32_t ulSector,
uint8_t Mode );
FF_Error_t FF_ReleaseBuffer( FF_IOManager_t * pxIOManager,
FF_Buffer_t * pBuffer );
/* 'Internal' to FreeRTOS+FAT. */
typedef struct _SPart
{
uint32_t ulStartLBA; /* FF_FAT_PTBL_LBA */
uint32_t ulSectorCount; /* FF_FAT_PTBL_SECT_COUNT */
uint32_t
ucActive : 8, /* FF_FAT_PTBL_ACTIVE */
ucPartitionID : 8, /* FF_FAT_PTBL_ID */
bIsExtended : 1;
} FF_Part_t;
typedef struct _SPartFound
{
int iCount;
FF_Part_t pxPartitions[ ffconfigMAX_PARTITIONS ];
} FF_SPartFound_t;
/* This function will parse the 4 entries in a partition table: */
void FF_ReadParts( uint8_t * pucBuffer,
FF_Part_t * pxParts );
/* FF_PartitionCount() has now been replaced by FF_PartitionSearch()
* It will enumerate all valid partitions found
* If sector-0 happens to be a valid MBR, 1 partition will be returned
*/
FF_Error_t FF_PartitionSearch( FF_IOManager_t * pxIOManager,
FF_SPartFound_t * pPartsFound );
/* HT : for debugging only. */
BaseType_t xIsFatSector( FF_IOManager_t * pxIOManager,
uint32_t ulSectorNr );
BaseType_t xNeedLogging( FF_IOManager_t * pxIOManager );
BaseType_t xIsRootDirSector( FF_IOManager_t * pxIOManager,
uint32_t ulSectorNr );
const char * pcSectorType( FF_IOManager_t * pxIOManager,
uint32_t ulSectorNr );
/* Needed to make this public/private to be used in FF_Partition/FF_Format. */
void FF_IOMAN_InitBufferDescriptors( FF_IOManager_t * pxIOManager );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ifndef _FF_IOMAN_H_ */

View File

@ -0,0 +1,94 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_locking.h
* @ingroup LOCKING
**/
#ifndef _FF_LOCKING_H_
#define _FF_LOCKING_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
/*---------- PROTOTYPES (in order of appearance). */
/* PUBLIC: */
/* PRIVATE: */
void FF_PendSemaphore( void * pSemaphore );
BaseType_t FF_TrySemaphore( void * pSemaphore,
uint32_t TimeMs );
void FF_ReleaseSemaphore( void * pSemaphore );
void FF_Sleep( uint32_t TimeMs );
/* Create an event group and bind it to an I/O manager. */
BaseType_t FF_CreateEvents( FF_IOManager_t * pxIOManager );
/* Delete an event group. */
void FF_DeleteEvents( FF_IOManager_t * pxIOManager );
/* Get a lock on all DIR operations for a given I/O manager. */
void FF_LockDirectory( FF_IOManager_t * pxIOManager );
/* Release the lock on all DIR operations. */
void FF_UnlockDirectory( FF_IOManager_t * pxIOManager );
/* Get a lock on all FAT operations for a given I/O manager. */
void FF_LockFAT( FF_IOManager_t * pxIOManager );
/* Release the lock on all FAT operations. */
void FF_UnlockFAT( FF_IOManager_t * pxIOManager );
/* Called from FF_GetBuffer() as long as no buffer is available. */
BaseType_t FF_BufferWait( FF_IOManager_t * pxIOManager,
uint32_t xWaitMS );
/* Called from FF_ReleaseBuffer(). */
void FF_BufferProceed( FF_IOManager_t * pxIOManager );
/* Check if the current task already has locked the FAT. */
int FF_Has_Lock( FF_IOManager_t * pxIOManager,
uint32_t aBits );
/*
* Throw a configASSERT() in case the FAT has not been locked
* by this task.
*/
/* _HT_ This function is only necessary while testing. */
void FF_Assert_Lock( FF_IOManager_t * pxIOManager,
uint32_t aBits );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _FF_LOCKING_H_ */

View File

@ -0,0 +1,187 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_memory.h
* @ingroup MEMORY
**/
#ifndef _FF_MEMORY_H_
#define _FF_MEMORY_H_
/*
* When sector data is written or analysed, some values might be stored unaligned.
* The routines below treat all values as little arrays of either 2 or 4 bytes.
* Also on big endian platforms, the order of bytes will be swapped.
*/
/*---------- PROTOTYPES */
#if ( ffconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
/*
* FAT is little endian.
* On a little endian CPU, bytes will be copied to the structures below 1-to-1 :
*/
typedef struct
{
uint8_t u8_0; /* the first byte */
uint8_t u8_1; /* the second byte */
} FF_TShort_t;
typedef struct
{
uint8_t u8_0;
uint8_t u8_1;
uint8_t u8_2;
uint8_t u8_3;
} FF_TLong_t;
#elif ( ffconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
/*
* On a big endian CPU, all bytes will be swapped, either 2 or 4 bytes:
*/
typedef struct
{
uint8_t u8_1; /* the second byte */
uint8_t u8_0; /* the first byte */
} FF_TShort_t;
typedef struct
{
uint8_t u8_3;
uint8_t u8_2;
uint8_t u8_1;
uint8_t u8_0;
} FF_TLong_t;
#else /* if ( ffconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) */
#error Little or Big Endian? - Please set ffconfigBYTE_ORDER to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN 1 in FreeRTOSFATConfig.h
#endif /* if ( ffconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) */
/*! 16-bit union. */
typedef union
{
uint16_t u16;
FF_TShort_t bytes;
} FF_T_UN16;
/*! 32-bit union. */
typedef union
{
uint32_t u32;
FF_TLong_t bytes;
} FF_T_UN32;
/* HT inlined these functions:
*/
#if ( ffconfigINLINE_MEMORY_ACCESS != 0 )
static portINLINE uint8_t FF_getChar( const uint8_t * pBuffer,
uint32_t aOffset )
{
return ( uint8_t ) ( pBuffer[ aOffset ] );
}
static portINLINE uint16_t FF_getShort( const uint8_t * pBuffer,
uint32_t aOffset )
{
FF_T_UN16 u16;
pBuffer += aOffset;
u16.bytes.u8_1 = pBuffer[ 1 ];
u16.bytes.u8_0 = pBuffer[ 0 ];
return u16.u16;
}
static portINLINE uint32_t FF_getLong( const uint8_t * pBuffer,
uint32_t aOffset )
{
FF_T_UN32 u32;
pBuffer += aOffset;
u32.bytes.u8_3 = pBuffer[ 3 ];
u32.bytes.u8_2 = pBuffer[ 2 ];
u32.bytes.u8_1 = pBuffer[ 1 ];
u32.bytes.u8_0 = pBuffer[ 0 ];
return u32.u32;
}
static portINLINE void FF_putChar( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
pBuffer[ aOffset ] = ( uint8_t ) Value;
}
static portINLINE void FF_putShort( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
FF_T_UN16 u16;
u16.u16 = ( uint16_t ) Value;
pBuffer += aOffset;
pBuffer[ 0 ] = u16.bytes.u8_0;
pBuffer[ 1 ] = u16.bytes.u8_1;
}
static portINLINE void FF_putLong( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value )
{
FF_T_UN32 u32;
u32.u32 = Value;
pBuffer += aOffset;
pBuffer[ 0 ] = u32.bytes.u8_0;
pBuffer[ 1 ] = u32.bytes.u8_1;
pBuffer[ 2 ] = u32.bytes.u8_2;
pBuffer[ 3 ] = u32.bytes.u8_3;
}
#else /* ffconfigINLINE_MEMORY_ACCESS */
uint8_t FF_getChar( const uint8_t * pBuffer,
uint32_t aOffset );
uint16_t FF_getShort( const uint8_t * pBuffer,
uint32_t aOffset );
uint32_t FF_getLong( const uint8_t * pBuffer,
uint32_t aOffset );
void FF_putChar( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value );
void FF_putShort( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value );
void FF_putLong( uint8_t * pBuffer,
uint32_t aOffset,
uint32_t Value );
#endif /* ffconfigINLINE_MEMORY_ACCESS */
#endif /* _FF_MEMORY_H_ */

View File

@ -0,0 +1,256 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* As of 15/3/2015 all +FAT configuration items changed their prefix,
* e.g. FF_LITTLE_ENDIAN has become ffconfigLITTLE_ENDIAN
* This tempoary header file checks for the presence old configuration items
* and issue a compiler error if any is defined.
*/
#ifdef FF_LITTLE_ENDIAN
#error FF_LITTLE_ENDIAN was dropped and replaced with 'ffconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN'
#endif
#ifdef FF_BIG_ENDIAN
#error FF_BIG_ENDIAN was dropped and replaced with 'ffconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN'
#endif
#ifdef ffconfigLITTLE_ENDIAN
#error ffconfigLITTLE_ENDIAN was dropped.
#endif
#ifdef ffconfigBIG_ENDIAN
#error ffconfigBIG_ENDIAN was dropped.
#endif
#ifdef FF_HAS_CWD
#error FF_HAS_CWD still defined. Please use ffconfig prefix.
#endif
#if !defined( pdFREERTOS_LITTLE_ENDIAN ) || !defined( pdFREERTOS_BIG_ENDIAN )
#error Missing defines from FreeRTOS
#endif
#ifdef FF_LFN_SUPPORT
#error FF_LFN_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_INCLUDE_SHORT_NAME
#error FF_INCLUDE_SHORT_NAME still defined. Please use ffconfig prefix.
#endif
#ifdef FF_SHORTNAME_CASE
#error FF_SHORTNAME_CASE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_UNICODE_UTF16_SUPPORT
#error FF_UNICODE_UTF16_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_UNICODE_UTF8_SUPPORT
#error FF_UNICODE_UTF8_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FAT12_SUPPORT
#error FF_FAT12_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_OPTIMISE_UNALIGNED_ACCESS
#error FF_OPTIMISE_UNALIGNED_ACCESS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_CACHE_WRITE_THROUGH
#error FF_CACHE_WRITE_THROUGH still defined. Please use ffconfig prefix.
#endif
#ifdef FF_WRITE_BOTH_FATS
#error FF_WRITE_BOTH_FATS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_WRITE_FREE_COUNT
#error FF_WRITE_FREE_COUNT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_TIME_SUPPORT
#error FF_TIME_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_REMOVABLE_MEDIA
#error FF_REMOVABLE_MEDIA still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MOUNT_FIND_FREE
#error FF_MOUNT_FIND_FREE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
#error FF_FINDAPI_ALLOW_WILDCARDS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_WILDCARD_CASE_INSENSITIVE
#error FF_WILDCARD_CASE_INSENSITIVE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_PATH_CACHE
#error FF_PATH_CACHE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_PATH_CACHE_DEPTH
#error FF_PATH_CACHE_DEPTH still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_CACHE
#error FF_HASH_CACHE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_FUNCTION
#error FF_HASH_FUNCTION still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_TABLE_SIZE
#error FF_HASH_TABLE_SIZE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_TABLE_SIZE
#error FF_HASH_TABLE_SIZE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MKDIR_RECURSIVE
#error FF_MKDIR_RECURSIVE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_BLKDEV_USES_SEM
#error FF_BLKDEV_USES_SEM is not used any more
#endif
#ifdef ffconfigBLKDEV_USES_SEM
#error ffconfigBLKDEV_USES_SEM is not used any more
#endif
#ifdef FF_MALLOC
#error FF_MALLOC still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FREE
#error FF_FREE still defined. Please use ffconfig prefix.
#endif
#ifdef FF_64_NUM_SUPPORT
#error FF_64_NUM_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MAX_PARTITIONS
#error FF_MAX_PARTITIONS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MAX_FILE_SYS
#error FF_MAX_FILE_SYS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_DRIVER_BUSY_SLEEP_MS
#error FF_DRIVER_BUSY_SLEEP_MS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FPRINTF_SUPPORT
#error FF_FPRINTF_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FPRINTF_BUFFER_LENGTH
#error FF_FPRINTF_BUFFER_LENGTH still defined. Please use ffconfig prefix.
#endif
#ifdef FF_DEBUG
#error FF_DEBUG still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HAS_FUNCTION_TAB
#error FF_HAS_FUNCTION_TAB still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FAT_CHECK
#error FF_FAT_CHECK still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MAX_FILENAME
#error FF_MAX_FILENAME still defined. Please use ffconfig prefix.
#endif
#ifdef FF_PRINTFFF_PRINTF
#error FF_PRINTFFF_PRINTF still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FAT_USES_STAT
#error FF_FAT_USES_STAT still defined. Please use ffconfig prefix.
#endif
#ifdef BUF_STORE_COUNT
#error BUF_STORE_COUNT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_USE_NOTIFY
#error FF_USE_NOTIFY still defined. Please use ffconfig prefix.
#endif
#ifdef FF_DEV_SUPPORT
#error FF_DEV_SUPPORT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_FSINFO_TRUSTED
#error FF_FSINFO_TRUSTED still defined. Please use ffconfig prefix.
#endif
#ifdef FF_LONG_ERR_MSG
#error FF_LONG_ERR_MSG still defined. Please use ffconfig prefix.
#endif
#ifdef FF_INLINE_MEMORY_ACCESS
#error FF_INLINE_MEMORY_ACCESS still defined. Please use ffconfig prefix.
#endif
#ifdef FF_MIRROR_FATS_UMOUNT
#error FF_MIRROR_FATS_UMOUNT still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_CACHE_DEPTH
#error FF_HASH_CACHE_DEPTH still defined. Please use ffconfig prefix.
#endif
#ifdef FF_HASH_TABLE_SUPPORT
#error FF_HASH_TABLE_SUPPORT was dropped
#endif
#ifdef FF_INLINE_BLOCK_CALCULATIONS
#error FF_INLINE_BLOCK_CALCULATIONS was dropped
#endif
#ifdef FF_CWD_THREAD_LOCAL_INDEX
#error FF_CWD_THREAD_LOCAL_INDEX is now called ffconfigCWD_THREAD_LOCAL_INDEX
#endif
#ifdef FF_DEV_PATH
#error FF_DEV_PATH was dropped
#endif

View File

@ -0,0 +1,383 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* ff_stdio.h
*
* An front-end which make +FAT look like the well-known stdio-functions
*/
#ifndef FF_STDIO_H
#define FF_STDIO_H
#if defined( __WIN32__ )
#include <dir.h>
#endif
/* Standard includes. */
#include <stdio.h>
#include <stdarg.h>
/* FreeRTOS+FAT includes. */
#include "ff_headers.h"
#include "ff_sys.h"
#if ( ffconfigDEV_SUPPORT != 0 )
#include "ff_devices.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Error return from some functions. */
#define FF_EOF ( -1 )
/* Bits used in the FF_Stat_t structure. */
#define FF_IFDIR 0040000u /* directory */
#define FF_IFCHR 0020000u /* character special */
#define FF_IFBLK 0060000u /* block special */
#define FF_IFREG 0100000u /* regular */
/* Bits used in the FF_FindData_t structure. */
#define FF_FA_NORMAL 0x00
#define FF_FA_RDONLY 0x01
#define FF_FA_HIDDEN 0x02
#define FF_FA_SYSTEM 0x04
#define FF_FA_LABEL 0x08
#define FF_FA_DIREC 0x10
#define FF_FA_ARCH 0x20
/* FreeRTOS+FAT uses three thread local buffers. The first stores errno, the
* second a pointer to the CWD structure (if one is used), and the third the more
* descriptive error code. */
#define stdioERRNO_THREAD_LOCAL_OFFSET ( ffconfigCWD_THREAD_LOCAL_INDEX + 0 )
#define stdioCWD_THREAD_LOCAL_OFFSET ( ffconfigCWD_THREAD_LOCAL_INDEX + 1 )
#define stdioFF_ERROR_THREAD_LOCAL_OFFSET ( ffconfigCWD_THREAD_LOCAL_INDEX + 2 )
/* Structure used with ff_stat(). */
typedef struct FF_STAT
{
uint32_t st_ino; /* First data cluster number. */
uint32_t st_size; /* Size of the object in number of bytes. */
uint16_t st_dev; /* The device on which the file can be found (see ff_sys.c) */
uint16_t st_mode; /* The mode (attribute bits) of this file or directory. */
#if ( ffconfigTIME_SUPPORT == 1 )
uint32_t st_atime;
uint32_t st_mtime;
uint32_t st_ctime;
#endif /* ffconfigTIME_SUPPORT */
} FF_Stat_t;
/* Structure used with ff_findfirst(), ff_findnext(), etc. */
typedef struct
{
/* private */
UBaseType_t
#if ( ffconfigDEV_SUPPORT != 0 )
bIsDeviceDir : 1,
#endif
bEntryPOwner : 1;
struct FF_DIR_HANDLER xDirectoryHandler;
FF_DirEnt_t xDirectoryEntry;
/* Public fields included so FF_DirEnt_t does not need to be public. */
const char * pcFileName;
uint32_t ulFileSize;
uint8_t ucAttributes;
} FF_FindData_t;
/*-----------------------------------------------------------
* Get and set the task's file system errno
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
/*
* int FF_GetErrno( void );
* void FF_SetErrno( int ff_errno );
*
* _RB_ comments are incorrect and index should use the stdioERRNO_THREAD_LOCAL_OFFSET offset.
*/
/* The errno is stored in a thread local buffer. */
static portINLINE void stdioSET_ERRNO( int iErrno )
{
vTaskSetThreadLocalStoragePointer( NULL, ffconfigCWD_THREAD_LOCAL_INDEX, ( void * ) ( iErrno ) );
}
static portINLINE int stdioGET_ERRNO( void )
{
void * pvResult;
pvResult = pvTaskGetThreadLocalStoragePointer( ( TaskHandle_t ) NULL, ffconfigCWD_THREAD_LOCAL_INDEX );
return ( int ) pvResult;
}
#if ( ( configNUM_THREAD_LOCAL_STORAGE_POINTERS - ffconfigCWD_THREAD_LOCAL_INDEX ) < 3 )
#error Please define space for 3 entries
#endif
/*
* Store the FreeRTOS+FAT error code, which provides more detail than errno.
*/
static portINLINE void stdioSET_FF_ERROR( FF_Error_t iFF_ERROR )
{
vTaskSetThreadLocalStoragePointer( NULL, stdioFF_ERROR_THREAD_LOCAL_OFFSET, ( void * ) ( iFF_ERROR ) );
}
/*
* Read back the FreeRTOS+FAT error code, which provides more detail than
* errno.
*/
static portINLINE FF_Error_t stdioGET_FF_ERROR( void )
{
void * pvResult;
pvResult = pvTaskGetThreadLocalStoragePointer( NULL, stdioFF_ERROR_THREAD_LOCAL_OFFSET );
return ( FF_Error_t ) pvResult;
}
/*-----------------------------------------------------------
* Open and close a file
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
FF_FILE * ff_fopen( const char * pcFile,
const char * pcMode );
int ff_fclose( FF_FILE * pxStream );
/*-----------------------------------------------------------
* Seek and tell
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_fseek( FF_FILE * pxStream,
long lOffset,
int iWhence );
void ff_rewind( FF_FILE * pxStream );
long ff_ftell( FF_FILE * pxStream );
int ff_feof( FF_FILE * pxStream );
/*-----------------------------------------------------------
* Read and write
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
size_t ff_fread( void * pvBuffer,
size_t xSize,
size_t xItems,
FF_FILE * pxStream );
size_t ff_fwrite( const void * pvBuffer,
size_t xSize,
size_t xItems,
FF_FILE * pxStream );
/* Whenever possible, use ellipsis parameter type checking.
* _RB_ Compiler specifics need to be moved to the compiler specific header files. */
#if defined( __GNUC__ )
/* The GNU-C compiler will check if the parameters are correct. */
int ff_fprintf( FF_FILE * pxStream,
const char * pcFormat,
... )
__attribute__( ( format( __printf__, 2, 3 ) ) );
#else
int ff_fprintf( FF_FILE * pxStream,
const char * pcFormat,
... );
#endif
int ff_fgetc( FF_FILE * pxStream );
int ff_fputc( int iChar,
FF_FILE * pxStream );
char * ff_fgets( char * pcBuffer,
size_t xCount,
FF_FILE * pxStream );
/*-----------------------------------------------------------
* Change length of file (truncate)
* File should have been opened in "w" or "a" mode
* The actual length of the file will be made equal to the current writing
* position
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_seteof( FF_FILE * pxStream );
/*-----------------------------------------------------------
* Open a file in append/update mode, truncate its length to a given value,
* or write zero's up until the required length, and return a handle to the open
* file. If NULL is returned, ff_errno contains an error code.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
FF_FILE * ff_truncate( const char * pcFileName,
long lTruncateSize );
/*-----------------------------------------------------------
* Flush to disk
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_fflush( FF_FILE * pxStream );
/*-----------------------------------------------------------
* Create directory, remove and rename files
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
#if ( ffconfigMKDIR_RECURSIVE == 0 )
int ff_mkdir( const char * pcPath );
#else
/* If the parameter bRecursive is non-zero, the entire path will be checked
* and if necessary, created. */
int ff_mkdir( const char * pcPath,
int bRecursive );
#endif
/*-----------------------------------------------------------
* Create path specified by the pcPath parameter.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_mkpath( const char * pcPath );
/*-----------------------------------------------------------
* Remove the directory specified by the pcDirectory parameter.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_rmdir( const char * pcDirectory );
/*-----------------------------------------------------------
* Delete a directory and, recursively, all of its contents.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
#if ( ffconfigUSE_DELTREE != 0 )
/* By default, this function will not be compiled. The function will
* recursively call itself, which is against the FreeRTOS coding standards, so
* IT MUST BE USED WITH CARE.
*
* The cost of each recursion will be roughly:
* Stack : 48 (12 stack words)
* Heap : 112 + ffconfigMAX_FILENAME
* These numbers may change depending on CPU and compiler. */
int ff_deltree( const char * pcPath );
#endif
/*-----------------------------------------------------------
* Remove/delete a file.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_remove( const char * pcPath );
/*-----------------------------------------------------------
* Move a file, also cross-directory but not across a file system.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_rename( const char * pcOldName,
const char * pcNewName,
int bDeleteIfExists );
/*-----------------------------------------------------------
* Get the status of a file.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
int ff_stat( const char * pcFileName,
FF_Stat_t * pxStatBuffer );
/* _HT_ Keep this for a while, until the new ff_stat() is wel tested */
int ff_old_stat( const char * pcName,
FF_Stat_t * pxStatBuffer );
/*-----------------------------------------------------------
* Get the length of a file in bytes.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
size_t ff_filelength( FF_FILE * pxFile );
/*-----------------------------------------------------------
* Working directory and iterating through directories.
* The most up to date API documentation is currently provided on the following URL:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/Standard_File_System_API.html
*-----------------------------------------------------------*/
#if ffconfigHAS_CWD
int ff_chdir( const char * pcDirectoryName );
char * ff_getcwd( char * pcBuffer,
size_t xBufferLength );
#endif
int ff_findfirst( const char * pcDirectory,
FF_FindData_t * pxFindData );
int ff_findnext( FF_FindData_t * pxFindData );
int ff_isdirempty( const char * pcPath );
/* _RB_ What to do regarding documentation for the definitions below here. */
#if ( ffconfig64_NUM_SUPPORT != 0 )
int64_t ff_diskfree( const char * pcPath,
uint32_t * pxSectorCount );
#else
int32_t ff_diskfree( const char * pcPath,
uint32_t * pxSectorCount );
#endif
int ff_finddir( const char * pcPath );
#if ( ffconfigHAS_CWD == 1 )
/* Obtain the CWD used by the current task. */
void ff_free_CWD_space( void );
#endif
typedef enum _EFileAction
{
eFileCreate,
eFileRemove,
eFileChange,
eFileIsDir = 0x80,
} eFileAction_t;
void callFileEvents( const char * apPath,
eFileAction_t aAction );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FF_STDIO_H */

View File

@ -0,0 +1,139 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_string.c
* @ingroup STRING
*
* @defgroup STRING FreeRTOS+FAT String Library
* @brief Portable String Library for FreeRTOS+FAT
*
*
**/
#ifndef _FF_STRING_H_
#define _FF_STRING_H_
#include "FreeRTOSFATConfig.h"
#include <string.h>
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
#include <wchar.h>
typedef wchar_t FF_T_WCHAR; /*/< Unicode UTF-16 Character type, for FreeRTOS+FAT when UNICODE is enabled. */
#endif
#if defined( _MSC_VER ) && ( _MSC_VER <= 1600 )
#define FF_stricmp _stricmp
#else
#define FF_stricmp strcasecmp
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
void FF_tolower( FF_T_WCHAR * string,
uint32_t strLen );
void FF_toupper( FF_T_WCHAR * string,
uint32_t strLen );
BaseType_t FF_strmatch( const FF_T_WCHAR * str1,
const FF_T_WCHAR * str2,
BaseType_t len );
FF_T_WCHAR * FF_strtok( const FF_T_WCHAR * string,
FF_T_WCHAR * token,
uint16_t * tokenNumber,
BaseType_t * last,
BaseType_t xLength );
BaseType_t FF_wildcompare( const FF_T_WCHAR * pcWildCard,
const FF_T_WCHAR * pszString );
/* ASCII to UTF16 and UTF16 to ASCII routines. -- These are lossy routines, and are only for converting ASCII to UTF-16 */
/* and the equivalent back to ASCII. Do not use them for international text. */
void FF_cstrtowcs( FF_T_WCHAR * wcsDest,
const char * szpSource );
void FF_wcstocstr( char * szpDest,
const FF_T_WCHAR * wcsSource );
void FF_cstrntowcs( FF_T_WCHAR * wcsDest,
const char * szpSource,
uint32_t len );
void FF_wcsntocstr( char * szpDest,
const FF_T_WCHAR * wcsSource,
uint32_t len );
#else /* if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) */
void FF_tolower( char * string,
uint32_t strLen );
void FF_toupper( char * string,
uint32_t strLen );
BaseType_t FF_strmatch( const char * str1,
const char * str2,
BaseType_t len );
char * FF_strtok( const char * string,
char * token,
uint16_t * tokenNumber,
BaseType_t * last,
BaseType_t xLength );
BaseType_t FF_wildcompare( const char * pcWildCard,
const char * pszString );
#endif /* ffconfigUNICODE_UTF16_SUPPORT */
/* UTF8 / UTF16 Transformation Functions. */
#if ( ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF ) ) || ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
UBaseType_t FF_GetUtf16SequenceLen( uint16_t usLeadChar );
#endif
#if ( ffconfigUNICODE_UTF8_SUPPORT != 0 )
int32_t FF_Utf8ctoUtf16c( uint16_t * utf16Dest,
const uint8_t * utf8Source,
uint32_t ulSize );
int32_t FF_Utf16ctoUtf8c( uint8_t * utf8Dest,
const uint16_t * utf16Source,
uint32_t ulSize );
#endif /* ffconfigUNICODE_UTF8_SUPPORT */
/* UTF16 / UTF32 Transformation Functions. */
#if ( ffconfigNOT_USED_FOR_NOW != 0 )
int32_t FF_Utf16ctoUtf32c( uint32_t * utf32Dest,
const uint16_t * utf16Source );
#endif
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 ) && ( WCHAR_MAX > 0xFFFF )
int32_t FF_Utf32ctoUtf16c( uint16_t * utf16Dest,
uint32_t utf32char,
uint32_t ulSize );
#endif
/* String transformations. */
int32_t FF_Utf32stoUtf8s( uint8_t * Utf8String,
uint32_t * Utf32String );
#if ( ffconfigUNICODE_UTF16_SUPPORT != 0 )
#define STRNCPY( target, src, maxlen ) wcsncpy( ( target ), ( src ), ( maxlen ) )
#define STRLEN( string ) wcslen( ( string ) )
#else
#define STRNCPY( target, src, maxlen ) strncpy( ( target ), ( src ), ( maxlen ) );
#define STRLEN( string ) strlen( ( string ) )
#endif
#endif /* ifndef _FF_STRING_H_ */

View File

@ -0,0 +1,133 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/*
* ff_sys.h
*
* This module allow to map several separate file-sub-systems into a root directory
*
* For instance, a system with 3 sub sytems:
*
* /flash : NAND flash driver
* /ram : RAM-disk driver
* / : SD-card driver
*
* In this example, the SD-card driver handles ALL files and directories which
* do not match /flash/ * or /ram/ *
*
* Now for instance a file call "/flash/etc/network.ini"
* will be stored as "/etc/network.ini" on the NAND drive
*
* This module along with ff_stdio.c make translations between absolute
* and relative paths
*/
#ifndef FF_SYS_H
#define FF_SYS_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct FILE_SUB_SYSTEM
{
char pcPath[ 16 ];
BaseType_t xPathlen;
FF_IOManager_t * pxManager;
} FF_SubSystem_t;
typedef struct FF_DIR_HANDLER
{
union
{
struct
{
unsigned
bEndOfDir : 1,
bFirstCalled : 1,
bIsValid : 1,
bAddDotEntries : 2;
} bits;
unsigned uFlags;
} u;
/*
* path will contain the relative path. It will be used when calling +FAT functions
* like FF_FindFirst() / FF_FindNext()
* For instance, for "/flash/etc" path will become "/etc"
*/
const char * pcPath;
FF_IOManager_t * pxManager; /* Will point to handler of this partition. */
BaseType_t xFSIndex; /* The index of this entry, where 0 always means: the root system. */
} FF_DirHandler_t;
/*
* Initialise (clear) the file system table
* This will also called by FF_FS_Add()
*/
void FF_FS_Init( void );
/*
* Add a file system
* The path must be absolute, e.g. start with a slash
* The second argument is the FF_Disk_t structure that is handling the driver
*/
int FF_FS_Add( const char * pcPath,
FF_Disk_t * pxDisk );
/*
* Remove a file system
* which ws earlier added by ff_fs_ad()
*/
void FF_FS_Remove( const char * pcPath );
/*
* Internally used by ff_stdio:
* The ff_dir_handler helps to iterate through a mounte directory
*
* FF_FS_Find() will find a ff_dir_handler for a given path
*/
int FF_FS_Find( const char * pcPath,
FF_DirHandler_t * pxHandler );
/*
* For internal use:
* Get the file system information, based on an index
*/
int FF_FS_Get( int iIndex,
FF_SubSystem_t * pxSystem );
/*
* Returns the number of registered
* file systems
*/
int FF_FS_Count( void );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FF_SYS_H */

View File

@ -0,0 +1,86 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/**
* @file ff_time.h
* @ingroup TIME
*
* Provides a means for receiving the time on any platform.
**/
#ifndef _FF_TIME_H_
#define _FF_TIME_H_
#include <time.h>
#include "FreeRTOSFATConfig.h"
/* _HT_
* The following declarations and functions may be moved to a common directory?
*/
typedef struct xTIME_STRUCT
{
int tm_sec; /* Seconds */
int tm_min; /* Minutes */
int tm_hour; /* Hour (0--23) */
int tm_mday; /* Day of month (1--31) */
int tm_mon; /* Month (0--11) */
int tm_year; /* Year (calendar year minus 1900) */
int tm_wday; /* Weekday (0--6; Sunday = 0) */
int tm_yday; /* Day of year (0--365) */
int tm_isdst; /* 0 if daylight savings time is not in effect) */
} FF_TimeStruct_t;
/* Equivalent of time() : returns the number of seconds after 1-1-1970. */
time_t FreeRTOS_time( time_t * pxTime );
/* Equivalent of mktime() : calculates the number of seconds after 1-1-1970. */
time_t FreeRTOS_mktime( const FF_TimeStruct_t * pxTimeBuf );
/* Equivalent of gmtime_r() : Fills a 'struct tm'. */
FF_TimeStruct_t * FreeRTOS_gmtime_r( const time_t * pxTime,
FF_TimeStruct_t * pxTimeBuf );
/**
* @public
* @brief A TIME and DATE object for FreeRTOS+FAT. A FreeRTOS+FAT time driver must populate these values.
*
**/
typedef struct
{
uint16_t Year; /* Year (e.g. 2009). */
uint16_t Month; /* Month (e.g. 1 = Jan, 12 = Dec). */
uint16_t Day; /* Day (1 - 31). */
uint16_t Hour; /* Hour (0 - 23). */
uint16_t Minute; /* Min (0 - 59). */
uint16_t Second; /* Second (0 - 59). */
} FF_SystemTime_t;
/*---------- PROTOTYPES */
int32_t FF_GetSystemTime( FF_SystemTime_t * pxTime );
#endif /* ifndef _FF_TIME_H_ */

View File

@ -0,0 +1,449 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "portmacro.h"
/* FreeRTOS+FAT includes. */
#include "ff_headers.h"
#include "ff_ramdisk.h"
#include "ff_sys.h"
#define ramHIDDEN_SECTOR_COUNT 8
#define ramPRIMARY_PARTITIONS 1
#define ramHUNDRED_64_BIT 100ULL
#define ramSECTOR_SIZE 512UL
#define ramPARTITION_NUMBER 0 /* Only a single partition is used. */
#define ramBYTES_PER_KB ( 1024ull )
#define ramSECTORS_PER_KB ( ramBYTES_PER_KB / 512ull )
/* Used as a magic number to indicate that an FF_Disk_t structure is a RAM
* disk. */
#define ramSIGNATURE 0x41404342
/*-----------------------------------------------------------*/
/*
* The function that writes to the media - as this is implementing a RAM disk
* the media is just a RAM buffer.
*/
static int32_t prvWriteRAM( uint8_t * pucBuffer,
uint32_t ulSectorNumber,
uint32_t ulSectorCount,
FF_Disk_t * pxDisk );
/*
* The function that reads from the media - as this is implementing a RAM disk
* the media is just a RAM buffer.
*/
static int32_t prvReadRAM( uint8_t * pucBuffer,
uint32_t ulSectorNumber,
uint32_t ulSectorCount,
FF_Disk_t * pxDisk );
#ifndef RAMDISK_ALREADY_PARTITIONED
/*
* This is the driver for a RAM disk. Unlike most media types, RAM disks are
* volatile so are created anew each time the system is booted. As the disk is
* new and just created, it must also be partitioned and formatted.
*/
static FF_Error_t prvPartitionAndFormatDisk( FF_Disk_t * pxDisk );
#endif
/*-----------------------------------------------------------*/
/* This is the prototype of the function used to initialise the RAM disk driver.
* Other media drivers do not have to have the same prototype.
*
* In this example:
+ pcName is the name to give the disk within FreeRTOS+FAT's virtual file system.
+ pucDataBuffer is the start of the RAM to use as the disk.
+ ulSectorCount is effectively the size of the disk, each sector is 512 bytes.
+ xIOManagerCacheSize is the size of the IO manager's cache, which must be a
+ multiple of the sector size, and at least twice as big as the sector size.
*/
FF_Disk_t * FF_RAMDiskInit( char * pcName,
uint8_t * pucDataBuffer,
uint32_t ulSectorCount,
size_t xIOManagerCacheSize )
{
FF_Error_t xError;
FF_Disk_t * pxDisk = NULL;
FF_CreationParameters_t xParameters;
/* Check the validity of the xIOManagerCacheSize parameter. */
configASSERT( ( xIOManagerCacheSize % ramSECTOR_SIZE ) == 0 );
configASSERT( ( xIOManagerCacheSize >= ( 2 * ramSECTOR_SIZE ) ) );
/* Attempt to allocated the FF_Disk_t structure. */
pxDisk = ( FF_Disk_t * ) pvPortMalloc( sizeof( FF_Disk_t ) );
if( pxDisk != NULL )
{
/* Start with every member of the structure set to zero. */
memset( pxDisk, '\0', sizeof( FF_Disk_t ) );
/* Clear the entire space. */
#ifndef RAMDISK_ALREADY_PARTITIONED
memset( pucDataBuffer, '\0', ulSectorCount * ramSECTOR_SIZE );
#endif
/* The pvTag member of the FF_Disk_t structure allows the structure to be
* extended to also include media specific parameters. The only media
* specific data that needs to be stored in the FF_Disk_t structure for a
* RAM disk is the location of the RAM buffer itself - so this is stored
* directly in the FF_Disk_t's pvTag member. */
pxDisk->pvTag = ( void * ) pucDataBuffer;
/* The signature is used by the disk read and disk write functions to
* ensure the disk being accessed is a RAM disk. */
pxDisk->ulSignature = ramSIGNATURE;
/* The number of sectors is recorded for bounds checking in the read and
* write functions. */
pxDisk->ulNumberOfSectors = ulSectorCount;
/* Create the IO manager that will be used to control the RAM disk. */
memset( &xParameters, '\0', sizeof( xParameters ) );
xParameters.pucCacheMemory = NULL;
xParameters.ulMemorySize = xIOManagerCacheSize;
xParameters.ulSectorSize = ramSECTOR_SIZE;
xParameters.fnWriteBlocks = prvWriteRAM;
xParameters.fnReadBlocks = prvReadRAM;
xParameters.pxDisk = pxDisk;
/* Driver is reentrant so xBlockDeviceIsReentrant can be set to pdTRUE.
* In this case the semaphore is only used to protect FAT data
* structures. */
xParameters.pvSemaphore = ( void * ) xSemaphoreCreateRecursiveMutex();
xParameters.xBlockDeviceIsReentrant = pdFALSE;
pxDisk->pxIOManager = FF_CreateIOManger( &xParameters, &xError );
if( ( pxDisk->pxIOManager != NULL ) && ( FF_isERR( xError ) == pdFALSE ) )
{
/* Record that the RAM disk has been initialised. */
pxDisk->xStatus.bIsInitialised = pdTRUE;
#ifdef RAMDISK_ALREADY_PARTITIONED
xError = FF_ERR_NONE;
#else
/* Create a partition on the RAM disk. NOTE! The disk is only
* being partitioned here because it is a new RAM disk. It is
* known that the disk has not been used before, and cannot already
* contain any partitions. Most media drivers will not perform
* this step because the media will have already been partitioned. */
xError = prvPartitionAndFormatDisk( pxDisk );
#endif
if( FF_isERR( xError ) == pdFALSE )
{
/* Record the partition number the FF_Disk_t structure is, then
* mount the partition. */
pxDisk->xStatus.bPartitionNumber = ramPARTITION_NUMBER;
/* Mount the partition. */
xError = FF_Mount( pxDisk, ramPARTITION_NUMBER );
FF_PRINTF( "FF_RAMDiskInit: FF_Mount: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
}
if( FF_isERR( xError ) == pdFALSE )
{
/* The partition mounted successfully, add it to the virtual
* file system - where it will appear as a directory off the file
* system's root directory. */
FF_FS_Add( pcName, pxDisk );
}
}
else
{
FF_PRINTF( "FF_RAMDiskInit: FF_CreateIOManger: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
/* The disk structure was allocated, but the disk's IO manager could
* not be allocated, so free the disk again. */
FF_RAMDiskDelete( pxDisk );
pxDisk = NULL;
}
}
else
{
FF_PRINTF( "FF_RAMDiskInit: Malloc failed\n" );
}
return pxDisk;
}
/*-----------------------------------------------------------*/
BaseType_t FF_RAMDiskDelete( FF_Disk_t * pxDisk )
{
if( pxDisk != NULL )
{
pxDisk->ulSignature = 0;
pxDisk->xStatus.bIsInitialised = 0;
if( pxDisk->pxIOManager != NULL )
{
FF_DeleteIOManager( pxDisk->pxIOManager );
}
vPortFree( pxDisk );
}
return pdPASS;
}
/*-----------------------------------------------------------*/
static int32_t prvReadRAM( uint8_t * pucDestination,
uint32_t ulSectorNumber,
uint32_t ulSectorCount,
FF_Disk_t * pxDisk )
{
int32_t lReturn;
uint8_t * pucSource;
if( pxDisk != NULL )
{
if( pxDisk->ulSignature != ramSIGNATURE )
{
/* The disk structure is not valid because it doesn't contain a
* magic number written to the disk when it was created. */
lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
}
else if( pxDisk->xStatus.bIsInitialised == pdFALSE )
{
/* The disk has not been initialised. */
lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
}
else if( ulSectorNumber >= pxDisk->ulNumberOfSectors )
{
/* The start sector is not within the bounds of the disk. */
lReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
else if( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) < ulSectorCount )
{
/* The end sector is not within the bounds of the disk. */
lReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
else
{
/* Obtain the pointer to the RAM buffer being used as the disk. */
pucSource = ( uint8_t * ) pxDisk->pvTag;
/* Move to the start of the sector being read. */
pucSource += ( ramSECTOR_SIZE * ulSectorNumber );
/* Copy the data from the disk. As this is a RAM disk this can be
* done using memcpy(). */
memcpy( ( void * ) pucDestination,
( void * ) pucSource,
( size_t ) ( ulSectorCount * ramSECTOR_SIZE ) );
lReturn = FF_ERR_NONE;
}
}
else
{
lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
}
return lReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvWriteRAM( uint8_t * pucSource,
uint32_t ulSectorNumber,
uint32_t ulSectorCount,
FF_Disk_t * pxDisk )
{
int32_t lReturn = FF_ERR_NONE;
uint8_t * pucDestination;
if( pxDisk != NULL )
{
if( pxDisk->ulSignature != ramSIGNATURE )
{
/* The disk structure is not valid because it doesn't contain a
* magic number written to the disk when it was created. */
lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
}
else if( pxDisk->xStatus.bIsInitialised == pdFALSE )
{
/* The disk has not been initialised. */
lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
}
else if( ulSectorNumber >= pxDisk->ulNumberOfSectors )
{
/* The start sector is not within the bounds of the disk. */
lReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
else if( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) < ulSectorCount )
{
/* The end sector is not within the bounds of the disk. */
lReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
else
{
/* Obtain the location of the RAM being used as the disk. */
pucDestination = ( uint8_t * ) pxDisk->pvTag;
/* Move to the sector being written to. */
pucDestination += ( ramSECTOR_SIZE * ulSectorNumber );
/* Write to the disk. As this is a RAM disk the write can use a
* memcpy(). */
memcpy( ( void * ) pucDestination,
( void * ) pucSource,
( size_t ) ulSectorCount * ( size_t ) ramSECTOR_SIZE );
lReturn = FF_ERR_NONE;
}
}
else
{
lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
}
return lReturn;
}
/*-----------------------------------------------------------*/
#ifndef RAMDISK_ALREADY_PARTITIONED
static FF_Error_t prvPartitionAndFormatDisk( FF_Disk_t * pxDisk )
{
FF_PartitionParameters_t xPartition;
FF_Error_t xError;
/* Create a single partition that fills all available space on the disk. */
memset( &xPartition, '\0', sizeof( xPartition ) );
xPartition.ulSectorCount = pxDisk->ulNumberOfSectors;
xPartition.ulHiddenSectors = ramHIDDEN_SECTOR_COUNT;
xPartition.xPrimaryCount = ramPRIMARY_PARTITIONS;
xPartition.eSizeType = eSizeIsQuota;
/* Partition the disk */
xError = FF_Partition( pxDisk, &xPartition );
FF_PRINTF( "FF_Partition: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
if( FF_isERR( xError ) == pdFALSE )
{
/* Format the partition. */
xError = FF_Format( pxDisk, ramPARTITION_NUMBER, pdTRUE, pdTRUE );
FF_PRINTF( "FF_RAMDiskInit: FF_Format: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
}
return xError;
}
/*-----------------------------------------------------------*/
#endif
BaseType_t FF_RAMDiskShowPartition( FF_Disk_t * pxDisk )
{
FF_Error_t xError;
uint64_t ullFreeSectors;
uint32_t ulTotalSizeKB, ulFreeSizeKB;
int iPercentageFree;
FF_IOManager_t * pxIOManager;
const char * pcTypeName = "unknown type";
BaseType_t xReturn = pdPASS;
if( pxDisk == NULL )
{
xReturn = pdFAIL;
}
else
{
pxIOManager = pxDisk->pxIOManager;
FF_PRINTF( "Reading FAT and calculating Free Space\n" );
switch( pxIOManager->xPartition.ucType )
{
case FF_T_FAT12:
pcTypeName = "FAT12";
break;
case FF_T_FAT16:
pcTypeName = "FAT16";
break;
case FF_T_FAT32:
pcTypeName = "FAT32";
break;
default:
pcTypeName = "UNKOWN";
break;
}
FF_GetFreeSize( pxIOManager, &xError );
ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
if( pxIOManager->xPartition.ulDataSectors == ( uint32_t ) 0 )
{
iPercentageFree = 0;
}
else
{
iPercentageFree = ( int ) ( ( ramHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2 ) /
( ( uint64_t ) pxIOManager->xPartition.ulDataSectors ) );
}
ulTotalSizeKB = pxIOManager->xPartition.ulDataSectors / ramSECTORS_PER_KB;
ulFreeSizeKB = ( uint32_t ) ( ullFreeSectors / ramSECTORS_PER_KB );
/* It is better not to use the 64-bit format such as %Lu because it
* might not be implemented. */
FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber );
FF_PRINTF( "Type %8u (%s)\n", pxIOManager->xPartition.ucType, pcTypeName );
FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel );
FF_PRINTF( "TotalSectors %8lu\n", pxIOManager->xPartition.ulTotalSectors );
FF_PRINTF( "SecsPerCluster %8lu\n", pxIOManager->xPartition.ulSectorsPerCluster );
FF_PRINTF( "Size %8lu KB\n", ulTotalSizeKB );
FF_PRINTF( "FreeSize %8lu KB ( %d perc free )\n", ulFreeSizeKB, iPercentageFree );
}
return xReturn;
}
/*-----------------------------------------------------------*/
void FF_RAMDiskFlush( FF_Disk_t * pxDisk )
{
if( ( pxDisk != NULL ) && ( pxDisk->xStatus.bIsInitialised != 0 ) && ( pxDisk->pxIOManager != NULL ) )
{
FF_FlushCache( pxDisk->pxIOManager );
}
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,55 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef __RAMDISK_H__
#define __RAMDISK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_headers.h"
//#define RAMDISK_ALREADY_PARTITIONED
/* Create a RAM disk, supplying enough memory to hold N sectors of 512 bytes each */
FF_Disk_t * FF_RAMDiskInit( char * pcName,
uint8_t * pucDataBuffer,
uint32_t ulSectorCount,
size_t xIOManagerCacheSize );
/* Release all resources */
BaseType_t FF_RAMDiskDelete( FF_Disk_t * pxDisk );
/* Show some partition information */
BaseType_t FF_RAMDiskShowPartition( FF_Disk_t * pxDisk );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __RAMDISK_H__ */

View File

@ -0,0 +1,80 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef __SDDISK_H__
#define __SDDISK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_headers.h"
/* Return non-zero if the SD-card is present.
* The parameter 'pxDisk' may be null, unless device locking is necessary. */
BaseType_t FF_SDDiskDetect( FF_Disk_t * pxDisk );
/* Create a RAM disk, supplying enough memory to hold N sectors of 512 bytes each */
FF_Disk_t * FF_SDDiskInit( const char * pcName );
BaseType_t FF_SDDiskReinit( FF_Disk_t * pxDisk );
/* Unmount the volume */
BaseType_t FF_SDDiskUnmount( FF_Disk_t * pDisk );
/* Mount the volume */
BaseType_t FF_SDDiskMount( FF_Disk_t * pDisk );
/* Release all resources */
BaseType_t FF_SDDiskDelete( FF_Disk_t * pDisk );
/* Show some partition information */
BaseType_t FF_SDDiskShowPartition( FF_Disk_t * pDisk );
/* Flush changes from the driver's buf to disk */
void FF_SDDiskFlush( FF_Disk_t * pDisk );
/* Format a given partition on an SD-card. */
BaseType_t FF_SDDiskFormat( FF_Disk_t * pxDisk,
BaseType_t aPart );
/* Format a given partition by name on an SD-card. */
BaseType_t FF_SDDiskFormatRemount( FF_Disk_t * pxDisk,
const char *pcName );
/* Return non-zero if an SD-card is detected in a given slot. */
BaseType_t FF_SDDiskInserted( BaseType_t xDriveNr );
/* _RB_ Temporary function - ideally the application would not need the IO
* manageer structure, just a handle to a disk. */
FF_IOManager_t * sddisk_ioman( FF_Disk_t * pxDisk );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __SDDISK_H__ */

View File

@ -0,0 +1,73 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef __SFDISK_H__
#define __SFDISK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_headers.h"
/* Return non-zero if the spi-flash is present.
* The parameter 'pxDisk' may be null, unless device locking is necessary. */
BaseType_t FF_SFDiskDetect( FF_Disk_t * pxDisk );
/* Create a RAM disk, supplying enough memory to hold N sectors of 512 bytes each */
FF_Disk_t * FF_SFDiskInit( const char * pcName );
BaseType_t FF_SFDiskReinit( FF_Disk_t * pxDisk );
/* Unmount the volume */
BaseType_t FF_SFDiskUnmount( FF_Disk_t * pDisk );
/* Mount the volume */
BaseType_t FF_SFDiskMount( FF_Disk_t * pDisk );
/* Release all resources */
BaseType_t FF_SFDiskDelete( FF_Disk_t * pDisk );
/* Show some partition information */
BaseType_t FF_SFDiskShowPartition( FF_Disk_t * pDisk );
/* Flush changes from the driver's buf to disk */
void FF_SFDiskFlush( FF_Disk_t * pDisk );
/* Format a given partition on an spi-flash. */
BaseType_t FF_SFDiskFormat( FF_Disk_t * pxDisk,
BaseType_t aPart );
/* Return non-zero if an spi-flash is detected in a given slot. */
BaseType_t FF_SFDiskInserted( BaseType_t xDriveNr );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __SFDISK_H__ */

View File

@ -0,0 +1,77 @@
/*
* FreeRTOS+FAT V2.3.3
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef __USBDISK_H__
#define __USBDISK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_headers.h"
/* Return non-zero if the SD-card is present.
* The parameter 'pxDisk' may be null, unless device locking is necessary. */
BaseType_t FF_USBDiskDetect( FF_Disk_t * pxDisk );
/* Create a RAM disk, supplying enough memory to hold N sectors of 512 bytes each */
FF_Disk_t * FF_USBDiskInit( const char * pcName );
BaseType_t FF_USBDiskReinit( FF_Disk_t * pxDisk );
/* Unmount the volume */
BaseType_t FF_USBDiskUnmount( FF_Disk_t * pDisk );
/* Mount the volume */
BaseType_t FF_USBDiskMount( FF_Disk_t * pDisk );
/* Release all resources */
BaseType_t FF_USBDiskDelete( FF_Disk_t * pDisk );
/* Show some partition information */
BaseType_t FF_USBDiskShowPartition( FF_Disk_t * pDisk );
/* Flush changes from the driver's buf to disk */
void FF_USBDiskFlush( FF_Disk_t * pDisk );
/* Format a given partition on an SD-card. */
BaseType_t FF_USBDiskFormat( FF_Disk_t * pxDisk,
BaseType_t aPart );
/* Return non-zero if an SD-card is detected in a given slot. */
BaseType_t FF_USBDiskInserted( BaseType_t xDriveNr );
/* _RB_ Temporary function - ideally the application would not need the IO
* manageer structure, just a handle to a disk. */
FF_IOManager_t * usbdisk_ioman( FF_Disk_t * pxDisk );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __USBDISK_H__ */

View File

@ -0,0 +1,710 @@
/*
* FreeRTOS+FAT build 191128 - Note: FreeRTOS+FAT is still in the lab!
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Authors include James Walmsley, Hein Tibosch and Richard Barry
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
*
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/* LPC18xx includes. */
#include "chip.h"
#include "board.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "portmacro.h"
/* FreeRTOS+FAT includes. */
#include "ff_sddisk.h"
#include "ff_sys.h"
#include "mmcsd_core.h"
/* Misc definitions. */
#define sdSIGNATURE 0x41404342UL
#define sdHUNDRED_64_BIT ( 100ull )
#define sdBYTES_PER_MB ( 1024ull * 1024ull )
#define sdSECTORS_PER_MB ( sdBYTES_PER_MB / 512ull )
#define sdIOMAN_MEM_SIZE 4096
#define sdAligned( pvAddress ) ( ( ( ( size_t ) ( pvAddress ) ) & ( sizeof( size_t ) - 1 ) ) == 0 )
/*-----------------------------------------------------------*/
/*_RB_ Functions require comment blocks. */
static int32_t prvSDMMC_Init( void );
static int32_t prvFFRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
static int32_t prvFFWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
/*-----------------------------------------------------------*/
/*_RB_ Variables require a comment block where appropriate. */
static struct mmcsd_card *xCardInfo;
static BaseType_t xSDCardStatus;
static SemaphoreHandle_t xPlusFATMutex;
/*-----------------------------------------------------------*/
static int32_t prvFFRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
/*_RB_ Many of the comments in this file apply to other functions in the file. */
if( ( pxDisk != NULL ) &&
( xSDCardStatus == pdPASS ) &&
( pxDisk->ulSignature == sdSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
#if DEVICE_TYPE_SELECT == EMMC_FLASH
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber + OTA_MEDIA_OFFSET / 512, pucBuffer, ulSectorCount, 0 );
#else
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber, pucBuffer, ulSectorCount, 0 );
#endif
/*_RB_ I'm guessing 512 is a sector size, but that needs to be clear.
Is it defined in a header somewhere? If so we can do a search and
replace in files on it as it seems to be used everywhere. */
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
/*_RB_ Signed number used to return bitmap (again below). */
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised != 0 )
{
FF_PRINTF( "prvFFRead: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvFFWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
if( ( pxDisk != NULL ) &&
( xSDCardStatus == pdPASS ) &&
( pxDisk->ulSignature == sdSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
#if DEVICE_TYPE_SELECT == EMMC_FLASH
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber + OTA_MEDIA_OFFSET / 512, pucBuffer, ulSectorCount, 1 );
#else
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber, pucBuffer, ulSectorCount, 1 );
#endif
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised )
{
FF_PRINTF( "prvFFWrite: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
void FF_SDDiskFlush( FF_Disk_t *pxDisk )
{
if( ( pxDisk != NULL ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( pxDisk->pxIOManager != NULL ) )
{
FF_FlushCache( pxDisk->pxIOManager );
}
}
/*-----------------------------------------------------------*/
#if DEVICE_TYPE_SELECT == EMMC_FLASH
#define emmcSECTOR_SIZE 512
#define emmcHIDDEN_SECTOR_COUNT 8
#define emmcPRIMARY_PARTITIONS 1
#define emmcPARTITION_NUMBER 0 /* Only a single partition is used. */
static FF_Error_t PartitionAndFormatEmmcDisk( FF_Disk_t * pxDisk )
{
FF_PartitionParameters_t xPartition;
FF_Error_t xError;
/* Create a single partition that fills all available space on the disk. */
memset( &xPartition, '\0', sizeof( xPartition ) );
xPartition.ulSectorCount = OTA_MEDIA_SIZE / emmcSECTOR_SIZE;
xPartition.ulHiddenSectors = emmcHIDDEN_SECTOR_COUNT;
xPartition.xPrimaryCount = emmcPRIMARY_PARTITIONS;
xPartition.eSizeType = eSizeIsQuota;
/* Partition the disk */
xError = FF_Partition( pxDisk, &xPartition );
FF_PRINTF( "FF_Partition: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
if( FF_isERR( xError ) == pdFALSE )
{
/* Format the partition. */
xError = FF_Format( pxDisk, emmcPARTITION_NUMBER, pdFALSE, pdFALSE );
FF_PRINTF( "FF_Format: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
if ( FF_isERR( xError ) == pdFALSE )
{
xError = FF_Mount( pxDisk, 0 );
FF_PRINTF( "FF_Mount: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
FF_SDDiskShowPartition( pxDisk );
}
}
return xError;
}
#endif
/* Initialise the SDIO driver and mount an SD card */
FF_Disk_t *FF_SDDiskInit( const char *pcName )
{
FF_Error_t xFFError;
BaseType_t xPartitionNumber = 0;
FF_CreationParameters_t xParameters;
FF_Disk_t * pxDisk;
xSDCardStatus = prvSDMMC_Init();
if( xSDCardStatus == pdPASS )
{
pxDisk = ( FF_Disk_t * ) pvPortMalloc( sizeof( *pxDisk ) );
if( pxDisk != NULL )
{
/* Initialise the created disk structure. */
memset( pxDisk, '\0', sizeof( *pxDisk ) );
if( xPlusFATMutex == NULL)
{
xPlusFATMutex = xSemaphoreCreateRecursiveMutex();
}
pxDisk->ulNumberOfSectors = xCardInfo->card_blknr;
pxDisk->ulSignature = sdSIGNATURE;
if( xPlusFATMutex != NULL)
{
memset( &xParameters, '\0', sizeof( xParameters ) );
xParameters.ulMemorySize = sdIOMAN_MEM_SIZE;
xParameters.ulSectorSize = 512;
xParameters.fnWriteBlocks = prvFFWrite;
xParameters.fnReadBlocks = prvFFRead;
xParameters.pxDisk = pxDisk;
/* prvFFRead()/prvFFWrite() are not re-entrant and must be
protected with the use of a semaphore. */
xParameters.xBlockDeviceIsReentrant = pdFALSE;
/* The semaphore will be used to protect critical sections in
the +FAT driver, and also to avoid concurrent calls to
prvFFRead()/prvFFWrite() from different tasks. */
xParameters.pvSemaphore = ( void * ) xPlusFATMutex;
pxDisk->pxIOManager = FF_CreateIOManger( &xParameters, &xFFError );
if( pxDisk->pxIOManager == NULL )
{
FF_PRINTF( "FF_SDDiskInit: FF_CreateIOManger: %s\n", ( const char * ) FF_GetErrMessage( xFFError ) );
FF_SDDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
pxDisk->xStatus.bIsInitialised = pdTRUE;
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
if( FF_SDDiskMount( pxDisk ) == 0 )
{
#if DEVICE_TYPE_SELECT == EMMC_FLASH
if ( PartitionAndFormatEmmcDisk(pxDisk) != FF_ERR_NONE )
{
FF_PRINTF( "FF_SDDiskInit: Mounted SD-card/emmc fail.\n");
FF_SDDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_SDDiskInit: Mount SD-card/emmc as root \"%s\"\n", pcName );
}
#else
FF_PRINTF( "FF_SDDiskInit: Mounted SD-card/emmc fail.\n");
FF_SDDiskDelete( pxDisk );
pxDisk = NULL;
#endif
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_SDDiskInit: Mounted SD-card as root \"%s\"\n", pcName );
}
} /* if( pxDisk->pxIOManager != NULL ) */
} /* if( xPlusFATMutex != NULL) */
} /* if( pxDisk != NULL ) */
else
{
FF_PRINTF( "FF_SDDiskInit: Malloc failed\n" );
}
} /* if( xSDCardStatus == pdPASS ) */
else
{
FF_PRINTF( "FF_SDDiskInit: prvSDMMC_Init failed\n" );
pxDisk = NULL;
}
return pxDisk;
}
/*-----------------------------------------------------------*/
BaseType_t FF_SDDiskFormat( FF_Disk_t *pxDisk, BaseType_t xPartitionNumber )
{
FF_Error_t xError;
BaseType_t xReturn = pdFAIL;
xError = FF_Unmount( pxDisk );
if( FF_isERR( xError ) != pdFALSE )
{
FF_PRINTF( "FF_SDDiskFormat: unmount fails: %08x\n", ( unsigned ) xError );
}
else
{
/* Format the drive - try FAT32 with large clusters. */
xError = FF_Format( pxDisk, xPartitionNumber, pdFALSE, pdFALSE);
if( FF_isERR( xError ) )
{
FF_PRINTF( "FF_SDDiskFormat: %s\n", (const char*)FF_GetErrMessage( xError ) );
}
else
{
FF_PRINTF( "FF_SDDiskFormat: OK, now remounting\n" );
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
xError = FF_SDDiskMount( pxDisk );
FF_PRINTF( "FF_SDDiskFormat: rc %08x\n", ( unsigned )xError );
if( FF_isERR( xError ) == pdFALSE )
{
xReturn = pdPASS;
}
}
}
return xReturn;
}
BaseType_t FF_SDDiskFormatRemount( FF_Disk_t *pxDisk, const char *pcName )
{
FF_Error_t xError;
BaseType_t xReturn = pdFAIL;
xError = FF_Unmount( pxDisk );
if( FF_isERR( xError ) != pdFALSE )
{
FF_PRINTF( "FF_SDDiskFormat: unmount fails: %08x\n", ( unsigned ) xError );
}
else
{
#if DEVICE_TYPE_SELECT == EMMC_FLASH
if ( PartitionAndFormatEmmcDisk(pxDisk) != FF_ERR_NONE )
{
FF_PRINTF( "FF_SDDiskFormatRemount: PartitionAndFormatEmmcDisk fail.\n");
FF_SDDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_SDDiskFormatRemount: Mount SD-card/emmc as root \"%s\"\n", pcName );
}
#else
FF_PRINTF( "FF_SDDiskInit: Mounted SD-card/emmc fail.\n");
FF_SDDiskDelete( pxDisk );
pxDisk = NULL;
#endif
}
return xReturn;
}
/*-----------------------------------------------------------*/
/* Get a pointer to IOMAN, which can be used for all FreeRTOS+FAT functions */
BaseType_t FF_SDDiskMount( FF_Disk_t *pxDisk )
{
FF_Error_t xFFError;
BaseType_t xReturn;
/* Mount the partition */
xFFError = FF_Mount( pxDisk, pxDisk->xStatus.bPartitionNumber );
if( FF_isERR( xFFError ) )
{
FF_PRINTF( "FF_SDDiskMount: %08lX\n", xFFError );
xReturn = pdFAIL;
}
else
{
pxDisk->xStatus.bIsMounted = pdTRUE;
FF_PRINTF( "****** FreeRTOS+FAT initialized %lu sectors\n", pxDisk->pxIOManager->xPartition.ulTotalSectors );
FF_SDDiskShowPartition( pxDisk );
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
FF_IOManager_t *sddisk_ioman( FF_Disk_t *pxDisk )
{
FF_IOManager_t *pxReturn;
if( ( pxDisk != NULL ) && ( pxDisk->xStatus.bIsInitialised != pdFALSE ) )
{
pxReturn = pxDisk->pxIOManager;
}
else
{
pxReturn = NULL;
}
return pxReturn;
}
/*-----------------------------------------------------------*/
/* Release all resources */
BaseType_t FF_SDDiskDelete( FF_Disk_t *pxDisk )
{
if( pxDisk != NULL )
{
pxDisk->ulSignature = 0;
pxDisk->xStatus.bIsInitialised = 0;
if( pxDisk->pxIOManager != NULL )
{
if( FF_Mounted( pxDisk->pxIOManager ) != pdFALSE )
{
FF_Unmount( pxDisk );
}
FF_DeleteIOManager( pxDisk->pxIOManager );
}
vPortFree( pxDisk );
}
return 1;
}
/*-----------------------------------------------------------*/
BaseType_t FF_SDDiskShowPartition( FF_Disk_t *pxDisk )
{
FF_Error_t xError;
uint64_t ullFreeSectors;
uint32_t ulTotalSizeMB, ulFreeSizeMB;
int iPercentageFree;
FF_IOManager_t *pxIOManager;
const char *pcTypeName = "unknown type";
BaseType_t xReturn = pdPASS;
if( pxDisk == NULL )
{
xReturn = pdFAIL;
}
else
{
pxIOManager = pxDisk->pxIOManager;
FF_PRINTF( "Reading FAT and calculating Free Space\n" );
switch( pxIOManager->xPartition.ucType )
{
case FF_T_FAT12:
pcTypeName = "FAT12";
break;
case FF_T_FAT16:
pcTypeName = "FAT16";
break;
case FF_T_FAT32:
pcTypeName = "FAT32";
break;
default:
pcTypeName = "UNKOWN";
break;
}
FF_GetFreeSize( pxIOManager, &xError );
ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
iPercentageFree = ( int ) ( ( sdHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2 ) /
( ( uint64_t )pxIOManager->xPartition.ulDataSectors ) );
ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / sdSECTORS_PER_MB;
ulFreeSizeMB = ( uint32_t ) ( ullFreeSectors / sdSECTORS_PER_MB );
/* It is better not to use the 64-bit format such as %Lu because it
might not be implemented. */
FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber );
FF_PRINTF( "Type %8u (%s)\n", pxIOManager->xPartition.ucType, pcTypeName );
FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel );
FF_PRINTF( "TotalSectors %8lu\n", pxIOManager->xPartition.ulTotalSectors );
FF_PRINTF( "SecsPerCluster %8lu\n", pxIOManager->xPartition.ulSectorsPerCluster );
FF_PRINTF( "Size %8lu MB\n", ulTotalSizeMB );
FF_PRINTF( "FreeSize %8lu MB ( %d perc free )\n", ulFreeSizeMB, iPercentageFree );
}
return xReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvSDMMC_Init( void )
{
if (!xCardInfo) {
xCardInfo = mmcsd_get_sdmmc_card_info();
if (!xCardInfo)
return pdFAIL;
}
mmcsd_set_blksize(xCardInfo);
return pdPASS;
}
/*-----------------------------------------------------------*/
#if DEVICE_TYPE_SELECT == EMMC_FLASH
static uint32_t cached_sector = 0xffffffff;
static uint8_t cached_data[emmcSECTOR_SIZE];
int32_t phyRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount)
{
int32_t iReturn;
/*_RB_ Many of the comments in this file apply to other functions in the file. */
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber, pucBuffer, ulSectorCount, 0 );
/*_RB_ I'm guessing 512 is a sector size, but that needs to be clear.
Is it defined in a header somewhere? If so we can do a search and
replace in files on it as it seems to be used everywhere. */
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
/*_RB_ Signed number used to return bitmap (again below). */
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
int32_t phyWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount)
{
int32_t iReturn;
xSDCardStatus = prvSDMMC_Init();
iReturn = mmcsd_req_blk( xCardInfo, ulSectorNumber, pucBuffer, ulSectorCount, 1 );
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
return iReturn;
}
#define EMMC_RW_MAX_SIZE 0x100000
static int raw_emmc_read(uint32_t offset, size_t size, uint8_t *data)
{
unsigned int blkcnt = 0;
unsigned int blkstart = 0;
unsigned char *ptembuf = NULL;
unsigned int inoffset = 0;
unsigned int readsize = 0;
int ret = 0;
xSDCardStatus = prvSDMMC_Init();
blkstart = offset / emmcSECTOR_SIZE;
inoffset = offset - blkstart * emmcSECTOR_SIZE;
readsize = size + inoffset;
blkcnt = (readsize + emmcSECTOR_SIZE - 1) / emmcSECTOR_SIZE;
ptembuf = (uint8_t *)pvPortMalloc(blkcnt * emmcSECTOR_SIZE);
if(!ptembuf)
printf("malloc Error!!1\n");
ret = phyRead(ptembuf, blkstart, blkcnt);
memcpy(data, ptembuf + inoffset, size);
if(ptembuf) {
free(ptembuf);
ptembuf = NULL;
}
return ret;
}
static int raw_emmc_write(uint32_t offset, size_t size, uint8_t *data)
{
unsigned int blkcnt = 0;
unsigned int blkstart = 0, blkend = 0;
unsigned char *ptembuf = NULL;
unsigned int inoffset = 0;
unsigned int endoffset = 0;
unsigned int wsize = 0;
int ret = 0;
xSDCardStatus = prvSDMMC_Init();
blkstart = offset / emmcSECTOR_SIZE;
inoffset = offset % emmcSECTOR_SIZE;
wsize = size + inoffset;
blkcnt = (wsize + emmcSECTOR_SIZE - 1) / emmcSECTOR_SIZE;
blkend = blkstart + blkcnt - 1;
endoffset = wsize % emmcSECTOR_SIZE;
ptembuf = (uint8_t *)pvPortMalloc(blkcnt * emmcSECTOR_SIZE);
if(ptembuf) {
if (inoffset) {
if (blkstart != cached_sector) {
phyRead(cached_data, blkstart, 1);
cached_sector = blkstart;
}
memcpy(ptembuf, cached_data, inoffset);
}
if (data)
memcpy(ptembuf + inoffset, data, size);
else
memset(ptembuf + inoffset, 0xff, size);
if (cached_sector == blkstart) {
if (size > emmcSECTOR_SIZE - inoffset)
memcpy(cached_data + inoffset, ptembuf + inoffset, emmcSECTOR_SIZE - inoffset);
else
memcpy(cached_data + inoffset, ptembuf + inoffset, size);
}
if (endoffset) {
if (blkend != cached_sector) {
phyRead(cached_data, blkend, 1);
cached_sector = blkend;
}
memcpy(ptembuf + wsize, cached_data + endoffset, emmcSECTOR_SIZE - endoffset);
memcpy(cached_data, ptembuf + wsize - endoffset, endoffset);
}
ret = phyWrite(ptembuf,blkstart,blkcnt);
if(ptembuf) {
free(ptembuf);
ptembuf = NULL;
}
} else
printf("emmc_write malloc Error!!1\n");
return ret;
}
int emmc_read(uint32_t offset, size_t size, uint8_t *data)
{
int32_t leftsize = size;
int32_t off = offset;
uint8_t *buf = data;
uint32_t rsize;
int ret;
while (leftsize > 0) {
rsize = leftsize > EMMC_RW_MAX_SIZE ? EMMC_RW_MAX_SIZE : leftsize;
ret = raw_emmc_read(off, rsize, buf);
if (ret)
return ret;
leftsize -= rsize;
off += rsize;
buf += rsize;
}
return 0;
}
int emmc_write(uint32_t offset, size_t size, uint8_t *data)
{
int32_t leftsize = size;
int32_t off = offset;
uint8_t *buf = data;
uint32_t wsize;
int ret;
while (leftsize > 0) {
wsize = leftsize > EMMC_RW_MAX_SIZE ? EMMC_RW_MAX_SIZE : leftsize;
ret = raw_emmc_write(off, wsize, buf);
if (ret)
return ret;
leftsize -= wsize;
off += wsize;
if (buf)
buf += wsize;
}
return 0;
}
#endif

View File

@ -0,0 +1,451 @@
/*
* FreeRTOS+FAT build 191128 - Note: FreeRTOS+FAT is still in the lab!
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Authors include James Walmsley, Hein Tibosch and Richard Barry
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
*
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/* LPC18xx includes. */
#include "chip.h"
#include "board.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "portmacro.h"
/* FreeRTOS+FAT includes. */
#include "ff_sfdisk.h"
#include "ff_sys.h"
#include "sfud.h"
/* Misc definitions. */
#define sfSIGNATURE 0x41404342UL
#define sfHUNDRED_64_BIT ( 100ull )
#define sfBYTES_PER_MB ( 1024ull * 1024ull )
#define sfSECTOR_SIZE ( 4096ull )
#define sfSECTORS_PER_MB ( sfBYTES_PER_MB / sfSECTOR_SIZE )
#define sfIOMAN_MEM_SIZE 16384
#define sfDISK_MEDIA_OFFSET OTA_MEDIA_OFFSET
#define sfAligned( pvAddress ) ( ( ( ( size_t ) ( pvAddress ) ) & ( sizeof( size_t ) - 1 ) ) == 0 )
/*-----------------------------------------------------------*/
/*_RB_ Functions require comment blocks. */
static int32_t prvFFRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
static int32_t prvFFWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
/*-----------------------------------------------------------*/
/*_RB_ Variables require a comment block where appropriate. */
static sfud_flash *sflash;
static SemaphoreHandle_t xPlusFATMutex;
/*-----------------------------------------------------------*/
static int32_t prvFFRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
/*_RB_ Many of the comments in this file apply to other functions in the file. */
if( ( pxDisk != NULL ) &&
( sflash != NULL ) &&
( pxDisk->ulSignature == sfSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
iReturn = sfud_read(sflash, sfDISK_MEDIA_OFFSET + ulSectorNumber * sfSECTOR_SIZE,
ulSectorCount * sfSECTOR_SIZE, pucBuffer);
/*_RB_ I'm guessing 4096 is a sector size, but that needs to be clear.
Is it defined in a header somewhere? If so we can do a search and
replace in files on it as it seems to be used everywhere. */
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
/*_RB_ Signed number used to return bitmap (again below). */
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised != 0 )
{
FF_PRINTF( "prvFFRead: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvFFWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
if( ( pxDisk != NULL ) &&
( sflash != NULL ) &&
( pxDisk->ulSignature == sfSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
iReturn = sfud_erase_write(sflash, sfDISK_MEDIA_OFFSET + ulSectorNumber * sfSECTOR_SIZE,
ulSectorCount * sfSECTOR_SIZE, pucBuffer);
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised )
{
FF_PRINTF( "prvFFWrite: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
void FF_SFDiskFlush( FF_Disk_t *pxDisk )
{
if( ( pxDisk != NULL ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( pxDisk->pxIOManager != NULL ) )
{
FF_FlushCache( pxDisk->pxIOManager );
}
}
/*-----------------------------------------------------------*/
#define sfHIDDEN_SECTOR_COUNT 8
#define sfPRIMARY_PARTITIONS 1
#define sfPARTITION_NUMBER 0 /* Only a single partition is used. */
static FF_Error_t PartitionAndFormatSFDisk( FF_Disk_t * pxDisk )
{
FF_PartitionParameters_t xPartition;
FF_Error_t xError;
/* Create a single partition that fills all available space on the disk. */
memset( &xPartition, '\0', sizeof( xPartition ) );
xPartition.ulSectorCount = OTA_MEDIA_SIZE / sfSECTOR_SIZE;
xPartition.ulHiddenSectors = sfHIDDEN_SECTOR_COUNT;
xPartition.xPrimaryCount = sfPRIMARY_PARTITIONS;
xPartition.eSizeType = eSizeIsQuota;
/* Partition the disk */
xError = FF_Partition( pxDisk, &xPartition );
FF_PRINTF( "FF_Partition: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
if( FF_isERR( xError ) == pdFALSE )
{
/* Format the partition. */
xError = FF_Format( pxDisk, sfPARTITION_NUMBER, pdFALSE, pdFALSE );
FF_PRINTF( "FF_Format: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
if ( FF_isERR( xError ) == pdFALSE )
{
xError = FF_Mount( pxDisk, 0 );
FF_PRINTF( "FF_Mount: %s\n", ( const char * ) FF_GetErrMessage( xError ) );
FF_SFDiskShowPartition( pxDisk );
}
}
return xError;
}
/* mount an spi-flash partition */
FF_Disk_t *FF_SFDiskInit( const char *pcName )
{
FF_Error_t xFFError;
BaseType_t xPartitionNumber = 0;
FF_CreationParameters_t xParameters;
FF_Disk_t * pxDisk;
sflash = sfud_get_device(0);
if( sflash != NULL )
{
pxDisk = ( FF_Disk_t * ) pvPortMalloc( sizeof( *pxDisk ) );
if( pxDisk != NULL )
{
/* Initialise the created disk structure. */
memset( pxDisk, '\0', sizeof( *pxDisk ) );
if( xPlusFATMutex == NULL)
{
xPlusFATMutex = xSemaphoreCreateRecursiveMutex();
}
//pxDisk->ulNumberOfSectors = sflash->chip.capacity / sfSECTOR_SIZE;
pxDisk->ulNumberOfSectors = OTA_MEDIA_SIZE / sfSECTOR_SIZE;
pxDisk->ulSignature = sfSIGNATURE;
if( xPlusFATMutex != NULL)
{
memset( &xParameters, '\0', sizeof( xParameters ) );
xParameters.ulMemorySize = sfIOMAN_MEM_SIZE;
xParameters.ulSectorSize = sfSECTOR_SIZE;
xParameters.fnWriteBlocks = prvFFWrite;
xParameters.fnReadBlocks = prvFFRead;
xParameters.pxDisk = pxDisk;
/* prvFFRead()/prvFFWrite() are not re-entrant and must be
protected with the use of a semaphore. */
xParameters.xBlockDeviceIsReentrant = pdFALSE;
/* The semaphore will be used to protect critical sections in
the +FAT driver, and also to avoid concurrent calls to
prvFFRead()/prvFFWrite() from different tasks. */
xParameters.pvSemaphore = ( void * ) xPlusFATMutex;
pxDisk->pxIOManager = FF_CreateIOManger( &xParameters, &xFFError );
if( pxDisk->pxIOManager == NULL )
{
FF_PRINTF( "FF_SFDiskInit: FF_CreateIOManger: %s\n", ( const char * ) FF_GetErrMessage( xFFError ) );
FF_SFDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
pxDisk->xStatus.bIsInitialised = pdTRUE;
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
if( FF_SFDiskMount( pxDisk ) == 0 )
{
if ( PartitionAndFormatSFDisk(pxDisk) != FF_ERR_NONE )
{
FF_PRINTF( "FF_SFDiskInit: Mount spi-flash fail.\n");
FF_SFDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_SFDiskInit: Mounted spi-flash as root \"%s\"\n", pcName );
}
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_SFDiskInit: Mounted spi-flash as root \"%s\"\n", pcName );
}
} /* if( pxDisk->pxIOManager != NULL ) */
} /* if( xPlusFATMutex != NULL) */
} /* if( pxDisk != NULL ) */
else
{
FF_PRINTF( "FF_SFDiskInit: Malloc failed\n" );
}
} /* if( sflash != NULL ) */
else
{
FF_PRINTF( "FF_SFDiskInit: sfud_get_device failed\n" );
pxDisk = NULL;
}
return pxDisk;
}
/*-----------------------------------------------------------*/
BaseType_t FF_SFDiskFormat( FF_Disk_t *pxDisk, BaseType_t xPartitionNumber )
{
FF_Error_t xError;
BaseType_t xReturn = pdFAIL;
xError = FF_Unmount( pxDisk );
if( FF_isERR( xError ) != pdFALSE )
{
FF_PRINTF( "FF_SFDiskFormat: unmount fails: %08x\n", ( unsigned ) xError );
}
else
{
/* Format the drive - try FAT32 with large clusters. */
xError = FF_Format( pxDisk, xPartitionNumber, pdFALSE, pdFALSE);
if( FF_isERR( xError ) )
{
FF_PRINTF( "FF_SFDiskFormat: %s\n", (const char*)FF_GetErrMessage( xError ) );
}
else
{
FF_PRINTF( "FF_SFDiskFormat: OK, now remounting\n" );
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
xError = FF_SFDiskMount( pxDisk );
FF_PRINTF( "FF_SFDiskFormat: rc %08x\n", ( unsigned )xError );
if( FF_isERR( xError ) == pdFALSE )
{
xReturn = pdPASS;
}
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
/* Get a pointer to IOMAN, which can be used for all FreeRTOS+FAT functions */
BaseType_t FF_SFDiskMount( FF_Disk_t *pxDisk )
{
FF_Error_t xFFError;
BaseType_t xReturn;
/* Mount the partition */
xFFError = FF_Mount( pxDisk, pxDisk->xStatus.bPartitionNumber );
if( FF_isERR( xFFError ) )
{
FF_PRINTF( "FF_SFDiskMount: %08lX\n", xFFError );
xReturn = pdFAIL;
}
else
{
pxDisk->xStatus.bIsMounted = pdTRUE;
FF_PRINTF( "****** FreeRTOS+FAT initialized %lu sectors\n", pxDisk->pxIOManager->xPartition.ulTotalSectors );
FF_SFDiskShowPartition( pxDisk );
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
/* Release all resources */
BaseType_t FF_SFDiskDelete( FF_Disk_t *pxDisk )
{
if( pxDisk != NULL )
{
pxDisk->ulSignature = 0;
pxDisk->xStatus.bIsInitialised = 0;
if( pxDisk->pxIOManager != NULL )
{
if( FF_Mounted( pxDisk->pxIOManager ) != pdFALSE )
{
FF_Unmount( pxDisk );
}
FF_DeleteIOManager( pxDisk->pxIOManager );
}
vPortFree( pxDisk );
}
return 1;
}
/*-----------------------------------------------------------*/
BaseType_t FF_SFDiskShowPartition( FF_Disk_t *pxDisk )
{
FF_Error_t xError;
uint64_t ullFreeSectors;
uint32_t ulTotalSizeMB, ulFreeSizeMB;
int iPercentageFree;
FF_IOManager_t *pxIOManager;
const char *pcTypeName = "unknown type";
BaseType_t xReturn = pdPASS;
if( pxDisk == NULL )
{
xReturn = pdFAIL;
}
else
{
pxIOManager = pxDisk->pxIOManager;
FF_PRINTF( "Reading FAT and calculating Free Space\n" );
switch( pxIOManager->xPartition.ucType )
{
case FF_T_FAT12:
pcTypeName = "FAT12";
break;
case FF_T_FAT16:
pcTypeName = "FAT16";
break;
case FF_T_FAT32:
pcTypeName = "FAT32";
break;
default:
pcTypeName = "UNKOWN";
break;
}
FF_GetFreeSize( pxIOManager, &xError );
ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
iPercentageFree = ( int ) ( ( sfHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2 ) /
( ( uint64_t )pxIOManager->xPartition.ulDataSectors ) );
ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / sfSECTORS_PER_MB;
ulFreeSizeMB = ( uint32_t ) ( ullFreeSectors / sfSECTORS_PER_MB );
/* It is better not to use the 64-bit format such as %Lu because it
might not be implemented. */
FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber );
FF_PRINTF( "Type %8u (%s)\n", pxIOManager->xPartition.ucType, pcTypeName );
FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel );
FF_PRINTF( "TotalSectors %8lu\n", pxIOManager->xPartition.ulTotalSectors );
FF_PRINTF( "SecsPerCluster %8lu\n", pxIOManager->xPartition.ulSectorsPerCluster );
FF_PRINTF( "Size %8lu MB\n", ulTotalSizeMB );
FF_PRINTF( "FreeSize %8lu MB ( %d perc free )\n", ulFreeSizeMB, iPercentageFree );
}
return xReturn;
}
/*-----------------------------------------------------------*/

View File

@ -0,0 +1,424 @@
/*
* FreeRTOS+FAT build 191128 - Note: FreeRTOS+FAT is still in the lab!
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Authors include James Walmsley, Hein Tibosch and Richard Barry
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
*
*/
/* Standard includes. */
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/* LPC18xx includes. */
#include "chip.h"
#include "board.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "portmacro.h"
/* FreeRTOS+FAT includes. */
#include "ff_usbdisk.h"
#include "usb_massstorage.h"
#include "ff_sys.h"
/* Misc definitions. */
#define usbSIGNATURE 0x41404342UL
#define usbHUNDRED_64_BIT ( 100ull )
#define usbBYTES_PER_MB ( 1024ull * 1024ull )
#define usbSECTORS_PER_MB ( usbBYTES_PER_MB / 512ull )
#define usbIOMAN_MEM_SIZE 4096
#define usbAligned( pvAddress ) ( ( ( ( size_t ) ( pvAddress ) ) & ( sizeof( size_t ) - 1 ) ) == 0 )
/*-----------------------------------------------------------*/
/*_RB_ Functions require comment blocks. */
static int32_t prvUSBDisk_Init( void );
static int32_t prvFFUSBDiskRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
static int32_t prvFFUSBDiskWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk );
/*-----------------------------------------------------------*/
/*_RB_ Variables require a comment block where appropriate. */
static struct blk_desc *xUSBInfo;
static BaseType_t xUSBDiskStatus;
static SemaphoreHandle_t xPlusFATMutex;
/*-----------------------------------------------------------*/
static int32_t prvFFUSBDiskRead( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
/*_RB_ Many of the comments in this file apply to other functions in the file. */
if( ( pxDisk != NULL ) && NULL != xUSBInfo->block_read &&
( xUSBDiskStatus == pdPASS ) &&
( pxDisk->ulSignature == usbSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
iReturn = xUSBInfo->block_read(xUSBInfo, ulSectorNumber, ulSectorCount, (void *)pucBuffer);
/*_RB_ I'm guessing 512 is a sector size, but that needs to be clear.
Is it defined in a header somewhere? If so we can do a search and
replace in files on it as it seems to be used everywhere. */
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
/*_RB_ Signed number used to return bitmap (again below). */
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised != 0 )
{
FF_PRINTF( "prvFFRead: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvFFUSBDiskWrite( uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk )
{
int32_t iReturn;
if( ( pxDisk != NULL ) && NULL != xUSBInfo->block_write &&
( xUSBDiskStatus == pdPASS ) &&
( pxDisk->ulSignature == usbSIGNATURE ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( ulSectorNumber < pxDisk->ulNumberOfSectors ) &&
( ( pxDisk->ulNumberOfSectors - ulSectorNumber ) >= ulSectorCount ) )
{
iReturn = xUSBInfo->block_write(xUSBInfo, ulSectorNumber, ulSectorCount, (const void *)pucBuffer);
if( iReturn == 0 ) /*_RB_ Signed/unsigned mismatch (twice!) */
{
iReturn = FF_ERR_NONE;
}
else
{
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
}
else
{
memset( ( void * ) pucBuffer, '\0', ulSectorCount * 512 );
if( pxDisk->xStatus.bIsInitialised )
{
FF_PRINTF( "prvFFWrite: warning: %lu + %lu > %lu\n", ulSectorNumber, ulSectorCount, pxDisk->ulNumberOfSectors );
}
iReturn = ( FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG );
}
return iReturn;
}
/*-----------------------------------------------------------*/
void FF_USBDiskFlush( FF_Disk_t *pxDisk )
{
if( ( pxDisk != NULL ) &&
( pxDisk->xStatus.bIsInitialised != pdFALSE ) &&
( pxDisk->pxIOManager != NULL ) )
{
FF_FlushCache( pxDisk->pxIOManager );
}
}
/*-----------------------------------------------------------*/
/* Initialise the USB driver and mount an Udisk */
FF_Disk_t *FF_USBDiskInit( const char *pcName )
{
FF_Error_t xFFError;
BaseType_t xPartitionNumber = 0;
FF_CreationParameters_t xParameters;
FF_Disk_t * pxDisk;
xUSBDiskStatus = prvUSBDisk_Init();
if( xUSBDiskStatus == pdPASS )
{
pxDisk = ( FF_Disk_t * ) pvPortMalloc( sizeof( *pxDisk ) );
if( pxDisk != NULL )
{
/* Initialise the created disk structure. */
memset( pxDisk, '\0', sizeof( *pxDisk ) );
if( xPlusFATMutex == NULL)
{
xPlusFATMutex = xSemaphoreCreateRecursiveMutex();
}
pxDisk->ulNumberOfSectors = xUSBInfo->lba;
pxDisk->ulSignature = usbSIGNATURE;
if( xPlusFATMutex != NULL)
{
memset( &xParameters, '\0', sizeof( xParameters ) );
xParameters.ulMemorySize = usbIOMAN_MEM_SIZE;
xParameters.ulSectorSize = 512;
xParameters.fnWriteBlocks = prvFFUSBDiskWrite;
xParameters.fnReadBlocks = prvFFUSBDiskRead;
xParameters.pxDisk = pxDisk;
/* prvFFRead()/prvFFWrite() are not re-entrant and must be
protected with the use of a semaphore. */
xParameters.xBlockDeviceIsReentrant = pdFALSE;
/* The semaphore will be used to protect critical sections in
the +FAT driver, and also to avoid concurrent calls to
prvFFRead()/prvFFWrite() from different tasks. */
xParameters.pvSemaphore = ( void * ) xPlusFATMutex;
pxDisk->pxIOManager = FF_CreateIOManger( &xParameters, &xFFError );
if( pxDisk->pxIOManager == NULL )
{
FF_PRINTF( "FF_USBDiskInit: FF_CreateIOManger: %s\n", ( const char * ) FF_GetErrMessage( xFFError ) );
FF_USBDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
pxDisk->xStatus.bIsInitialised = pdTRUE;
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
if( FF_USBDiskMount( pxDisk ) == 0 )
{
FF_USBDiskDelete( pxDisk );
pxDisk = NULL;
}
else
{
if( pcName == NULL )
{
pcName = "/";
}
FF_FS_Add( pcName, pxDisk );
FF_PRINTF( "FF_USBDiskInit: Mounted Udisk as root \"%s\"\n", pcName );
FF_USBDiskShowPartition( pxDisk );
}
} /* if( pxDisk->pxIOManager != NULL ) */
} /* if( xPlusFATMutex != NULL) */
} /* if( pxDisk != NULL ) */
else
{
FF_PRINTF( "FF_USBDiskInit: Malloc failed\n" );
}
} /* if( xUSBDiskStatus == pdPASS ) */
else
{
FF_PRINTF( "FF_USBDiskInit: prvUSBDisk_Init failed\n" );
pxDisk = NULL;
}
return pxDisk;
}
/*-----------------------------------------------------------*/
BaseType_t FF_USBDiskFormat( FF_Disk_t *pxDisk, BaseType_t xPartitionNumber )
{
FF_Error_t xError;
BaseType_t xReturn = pdFAIL;
xError = FF_Unmount( pxDisk );
if( FF_isERR( xError ) != pdFALSE )
{
FF_PRINTF( "FF_USBDiskFormat: unmount fails: %08x\n", ( unsigned ) xError );
}
else
{
/* Format the drive - try FAT32 with large clusters. */
xError = FF_Format( pxDisk, xPartitionNumber, pdFALSE, pdFALSE);
if( FF_isERR( xError ) )
{
FF_PRINTF( "FF_USBDiskFormat: %s\n", (const char*)FF_GetErrMessage( xError ) );
}
else
{
FF_PRINTF( "FF_USBDiskFormat: OK, now remounting\n" );
pxDisk->xStatus.bPartitionNumber = xPartitionNumber;
xError = FF_USBDiskMount( pxDisk );
FF_PRINTF( "FF_USBDiskFormat: rc %08x\n", ( unsigned )xError );
if( FF_isERR( xError ) == pdFALSE )
{
xReturn = pdPASS;
}
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
/* Get a pointer to IOMAN, which can be used for all FreeRTOS+FAT functions */
BaseType_t FF_USBDiskMount( FF_Disk_t *pxDisk )
{
FF_Error_t xFFError;
BaseType_t xReturn;
/* Mount the partition */
xFFError = FF_Mount( pxDisk, pxDisk->xStatus.bPartitionNumber );
if( FF_isERR( xFFError ) )
{
FF_PRINTF( "FF_USBDiskMount: %08lX\n", xFFError );
xReturn = pdFAIL;
}
else
{
pxDisk->xStatus.bIsMounted = pdTRUE;
FF_PRINTF( "****** FreeRTOS+FAT initialized %lu sectors\n", pxDisk->pxIOManager->xPartition.ulTotalSectors );
FF_USBDiskShowPartition( pxDisk );
xReturn = pdPASS;
}
return xReturn;
}
/*-----------------------------------------------------------*/
FF_IOManager_t *usbdisk_ioman( FF_Disk_t *pxDisk )
{
FF_IOManager_t *pxReturn;
if( ( pxDisk != NULL ) && ( pxDisk->xStatus.bIsInitialised != pdFALSE ) )
{
pxReturn = pxDisk->pxIOManager;
}
else
{
pxReturn = NULL;
}
return pxReturn;
}
/*-----------------------------------------------------------*/
/* Release all resources */
BaseType_t FF_USBDiskDelete( FF_Disk_t *pxDisk )
{
if( pxDisk != NULL )
{
pxDisk->ulSignature = 0;
pxDisk->xStatus.bIsInitialised = 0;
if( pxDisk->pxIOManager != NULL )
{
if( FF_Mounted( pxDisk->pxIOManager ) != pdFALSE )
{
FF_Unmount( pxDisk );
}
FF_DeleteIOManager( pxDisk->pxIOManager );
}
vPortFree( pxDisk );
}
return 1;
}
/*-----------------------------------------------------------*/
BaseType_t FF_USBDiskShowPartition( FF_Disk_t *pxDisk )
{
FF_Error_t xError;
uint64_t ullFreeSectors;
uint32_t ulTotalSizeMB, ulFreeSizeMB;
int iPercentageFree;
FF_IOManager_t *pxIOManager;
const char *pcTypeName = "unknown type";
BaseType_t xReturn = pdPASS;
if( pxDisk == NULL )
{
xReturn = pdFAIL;
}
else
{
pxIOManager = pxDisk->pxIOManager;
FF_PRINTF( "Reading FAT and calculating Free Space\n" );
switch( pxIOManager->xPartition.ucType )
{
case FF_T_FAT12:
pcTypeName = "FAT12";
break;
case FF_T_FAT16:
pcTypeName = "FAT16";
break;
case FF_T_FAT32:
pcTypeName = "FAT32";
break;
default:
pcTypeName = "UNKOWN";
break;
}
FF_GetFreeSize( pxIOManager, &xError );
ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
iPercentageFree = ( int ) ( ( usbHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2 ) /
( ( uint64_t )pxIOManager->xPartition.ulDataSectors ) );
ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / usbSECTORS_PER_MB;
ulFreeSizeMB = ( uint32_t ) ( ullFreeSectors / usbSECTORS_PER_MB );
/* It is better not to use the 64-bit format such as %Lu because it
might not be implemented. */
FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber );
FF_PRINTF( "Type %8u (%s)\n", pxIOManager->xPartition.ucType, pcTypeName );
FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel );
FF_PRINTF( "TotalSectors %8lu\n", pxIOManager->xPartition.ulTotalSectors );
FF_PRINTF( "SecsPerCluster %8lu\n", pxIOManager->xPartition.ulSectorsPerCluster );
FF_PRINTF( "Size %8lu MB\n", ulTotalSizeMB );
FF_PRINTF( "FreeSize %8lu MB ( %d perc free )\n", ulFreeSizeMB, iPercentageFree );
}
return xReturn;
}
/*-----------------------------------------------------------*/
static int32_t prvUSBDisk_Init( void )
{
xUSBInfo = &usb_dev_desc[0];//use the first device
return pdPASS;
}
/*-----------------------------------------------------------*/