Add FAT SL code and demo project.
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h
new file mode 100644
index 0000000..04793be
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h
@@ -0,0 +1,171 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions, 

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High 

+    Integrity Systems, who sell the code with commercial support, 

+    indemnification and middleware, under the OpenRTOS brand.

+    

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety 

+    engineered and independently SIL3 certified version for use in safety and 

+    mission critical applications that require provable dependability.

+*/

+

+#ifndef FREERTOS_CONFIG_H

+#define FREERTOS_CONFIG_H

+

+/*-----------------------------------------------------------

+ * Application specific definitions.

+ *

+ * These definitions should be adjusted for your particular hardware and

+ * application requirements.

+ *

+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE

+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.

+ * http://www.freertos.org/a00110.html

+ *

+ * The bottom of this file contains some constants specific to running the UDP

+ * stack in this demo.  Constants specific to FreeRTOS+UDP itself (rather than

+ * the demo) are contained in FreeRTOSIPConfig.h.

+ *----------------------------------------------------------*/

+

+#define configUSE_PREEMPTION			1

+#define configMAX_PRIORITIES			( ( unsigned portBASE_TYPE ) 7 )

+#define configTICK_RATE_HZ				( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */

+#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */

+#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 32U * 1024U ) )

+#define configMAX_TASK_NAME_LEN			( 7 )

+#define configUSE_TRACE_FACILITY		1

+#define configUSE_16_BIT_TICKS			0

+#define configIDLE_SHOULD_YIELD			1

+#define configUSE_CO_ROUTINES 			0

+#define configUSE_MUTEXES				1

+#define configUSE_RECURSIVE_MUTEXES		1

+#define configQUEUE_REGISTRY_SIZE		0

+#define configUSE_APPLICATION_TASK_TAG	0

+#define configUSE_COUNTING_SEMAPHORES	1

+#define configUSE_ALTERNATIVE_API		0

+

+/* Hook function related definitions. */

+#define configUSE_TICK_HOOK				0

+#define configUSE_IDLE_HOOK				1

+#define configUSE_MALLOC_FAILED_HOOK	1

+#define configCHECK_FOR_STACK_OVERFLOW	0 /* Not applicable to the Win32 port. */

+

+/* Software timer related definitions. */

+#define configUSE_TIMERS				1

+#define configTIMER_TASK_PRIORITY		( configMAX_PRIORITIES - 1 )

+#define configTIMER_QUEUE_LENGTH		5

+#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )

+

+/* Run time stats gathering definitions. */

+unsigned long ulGetRunTimeCounterValue( void );

+void vConfigureTimerForRunTimeStats( void );

+#define configGENERATE_RUN_TIME_STATS	1

+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()

+#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()

+

+/* Co-routine definitions. */

+#define configUSE_CO_ROUTINES 			0

+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

+

+/* Set the following definitions to 1 to include the API function, or zero

+to exclude the API function. */

+#define INCLUDE_vTaskPrioritySet			1

+#define INCLUDE_uxTaskPriorityGet			1

+#define INCLUDE_vTaskDelete					1

+#define INCLUDE_vTaskCleanUpResources		0

+#define INCLUDE_vTaskSuspend				1

+#define INCLUDE_vTaskDelayUntil				1

+#define INCLUDE_vTaskDelay					1

+#define INCLUDE_uxTaskGetStackHighWaterMark	1

+#define INCLUDE_xTaskGetSchedulerState		1

+#define INCLUDE_xTimerGetTimerTaskHandle	0

+#define INCLUDE_xTaskGetIdleTaskHandle		0

+#define INCLUDE_xQueueGetMutexHolder		1

+

+/* Assert call defined for debug builds. */

+#ifdef _DEBUG

+	extern void vAssertCalled( const char *pcFile, unsigned long ulLine );

+	#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )

+#endif /* _DEBUG */

+

+

+

+/* Application specific definitions follow. **********************************/

+

+/* The UDP port to use for incoming command inputs.  The outgoing port is

+set to ( configUDP_CLI_PORT_NUMBER + 1 ). */

+#define configUDP_CLI_PORT_NUMBER	5001

+

+/* The size of the global output buffer that is available for use when there

+are multiple command interpreters running at once (for example, one on a UART

+and one on TCP/IP).  This is done to prevent an output buffer being defined by

+each implementation - which would waste RAM.  In this case, there is only one

+command interpreter running, and it has its own local output buffer, so the

+global buffer is just set to be one byte long as it is not used and should not

+take up unnecessary RAM. */

+#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1

+

+#endif /* FREERTOS_CONFIG_H */

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h
new file mode 100644
index 0000000..373d780
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h
@@ -0,0 +1,67 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers

+ * Ltd. by HCC Embedded for use with FreeRTOS.  It is not, in itself, part of

+ * the FreeRTOS kernel.  FreeRTOS+FAT SL is licensed separately from FreeRTOS,

+ * and uses a different license to FreeRTOS.  FreeRTOS+FAT SL uses a dual

+ * license model, information on which is provided below:

+ *

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified and distributed

+ * without charge provided the user adheres to version two of the GNU General

+ * Public license (GPL) and does not remove the copyright notice or this text.

+ * The GPL V2 text is available on the gnu.org web site, and on the following

+ * URL: http://www.FreeRTOS.org/gpl-2.0.txt

+ *

+ * - Commercial licensing -

+ * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into

+ * proprietary software for redistribution in any form must first obtain a

+ * commercial license - and in-so-doing support the maintenance, support and

+ * further development of the FreeRTOS+FAT SL product.  Commercial licenses can

+ * be obtained from http://shop.freertos.org and do not require any source files

+ * to be changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _CONFIG_FAT_SL_H

+#define _CONFIG_FAT_SL_H

+

+#include "../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#include "../api/api_mdriver.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+/**************************************************************************

+**

+**  FAT SL user settings

+**

+**************************************************************************/

+#define F_SECTOR_SIZE           512u  /* Disk sector size. */

+#define F_FS_THREAD_AWARE       1     /* Set to one if the file system will be access from more than one task. */

+#define F_MAXPATH               64    /* Maximum length a file name (including its full path) can be. */

+#define F_MAX_LOCK_WAIT_TICKS   20    /* The maximum number of RTOS ticks to wait when attempting to obtain a lock on the file system when F_FS_THREAD_AWARE is set to 1. */

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* _CONFIG_FAT_SL_H */

+

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h
new file mode 100644
index 0000000..1c3ce96
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h
@@ -0,0 +1,52 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers

+ * Ltd. by HCC Embedded for use with FreeRTOS.  It is not, in itself, part of

+ * the FreeRTOS kernel.  FreeRTOS+FAT SL is licensed separately from FreeRTOS,

+ * and uses a different license to FreeRTOS.  FreeRTOS+FAT SL uses a dual

+ * license model, information on which is provided below:

+ *

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified and distributed

+ * without charge provided the user adheres to version two of the GNU General

+ * Public license (GPL) and does not remove the copyright notice or this text.

+ * The GPL V2 text is available on the gnu.org web site, and on the following

+ * URL: http://www.FreeRTOS.org/gpl-2.0.txt

+ *

+ * - Commercial licensing -

+ * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into

+ * proprietary software for redistribution in any form must first obtain a

+ * commercial license - and in-so-doing support the maintenance, support and

+ * further development of the FreeRTOS+FAT SL product.  Commercial licenses can

+ * be obtained from http://shop.freertos.org and do not require any source files

+ * to be changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _CONFIG_MDRIVER_RAM_H_

+#define _CONFIG_MDRIVER_RAM_H_

+

+#include "../version/ver_mdriver_ram.h"

+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2

+ #error Incompatible MDRIVER_RAM version number!

+#endif

+

+#define MDRIVER_RAM_SECTOR_SIZE   512       /* Sector size */

+

+#define MDRIVER_RAM_VOLUME0_SIZE  (128 * 1024) /* defintion for size of ramdrive0 */

+

+#define MDRIVER_MEM_LONG_ACCESS   1         /* set this value to 1 if 32bit access available */

+

+#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */

+

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c
new file mode 100644
index 0000000..0e36e7a
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c
@@ -0,0 +1,618 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High

+    Integrity Systems, who sell the code with commercial support,

+    indemnification and middleware, under the OpenRTOS brand.

+

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety

+    engineered and independently SIL3 certified version for use in safety and

+    mission critical applications that require provable dependability.

+*/

+

+/* FreeRTOS includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+

+/* Standard includes. */

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+

+/* FreeRTOS+CLI includes. */

+#include "FreeRTOS_CLI.h"

+

+/* File system includes. */

+#include "fat_sl.h"

+#include "api_mdriver_ram.h"

+#include "test.h"

+

+#ifdef _WINDOWS_

+	#define snprintf _snprintf

+#endif

+

+#define cliNEW_LINE		"\r\n"

+

+/*******************************************************************************

+ * See the URL in the comments within main.c for the location of the online

+ * documentation.

+ ******************************************************************************/

+

+/*

+ * Print out information on a single file.

+ */

+static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct );

+

+/*

+ * Copies an existing file into a newly created file.

+ */

+static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,

+							int32_t lSourceFileLength,

+							int8_t *pcDestinationFile,

+							int8_t *pxWriteBuffer,

+							size_t xWriteBufferLen );

+

+/*

+ * Implements the DIR command.

+ */

+static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the CD command.

+ */

+static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the DEL command.

+ */

+static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the TYPE command.

+ */

+static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the COPY command.

+ */

+static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the TEST command.

+ */

+static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/* Structure that defines the DIR command line command, which lists all the

+files in the current directory. */

+static const CLI_Command_Definition_t xDIR =

+{

+	( const int8_t * const ) "dir", /* The command string to type. */

+	( const int8_t * const ) "\r\ndir:\r\n Lists the files in the current directory\r\n",

+	prvDIRCommand, /* The function to run. */

+	0 /* No parameters are expected. */

+};

+

+/* Structure that defines the CD command line command, which changes the

+working directory. */

+static const CLI_Command_Definition_t xCD =

+{

+	( const int8_t * const ) "cd", /* The command string to type. */

+	( const int8_t * const ) "\r\ncd <dir name>:\r\n Changes the working directory\r\n",

+	prvCDCommand, /* The function to run. */

+	1 /* One parameter is expected. */

+};

+

+/* Structure that defines the TYPE command line command, which prints the

+contents of a file to the console. */

+static const CLI_Command_Definition_t xTYPE =

+{

+	( const int8_t * const ) "type", /* The command string to type. */

+	( const int8_t * const ) "\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",

+	prvTYPECommand, /* The function to run. */

+	1 /* One parameter is expected. */

+};

+

+/* Structure that defines the DEL command line command, which deletes a file. */

+static const CLI_Command_Definition_t xDEL =

+{

+	( const int8_t * const ) "del", /* The command string to type. */

+	( const int8_t * const ) "\r\ndel <filename>:\r\n deletes a file or directory\r\n",

+	prvDELCommand, /* The function to run. */

+	1 /* One parameter is expected. */

+};

+

+/* Structure that defines the COPY command line command, which deletes a file. */

+static const CLI_Command_Definition_t xCOPY =

+{

+	( const int8_t * const ) "copy", /* The command string to type. */

+	( const int8_t * const ) "\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",

+	prvCOPYCommand, /* The function to run. */

+	2 /* Two parameters are expected. */

+};

+

+/* Structure that defines the TEST command line command, which executes some

+file system driver tests. */

+static const CLI_Command_Definition_t xTEST_FS =

+{

+	( const int8_t * const ) "testfs", /* The command string to type. */

+	( const int8_t * const ) "\r\ntest_fs:\r\n Executes some file system test.  ALL FILES WILL BE DELETED!!!\r\n",

+	prvTESTFSCommand, /* The function to run. */

+	0 /* No parameters are expected. */

+};

+

+/*-----------------------------------------------------------*/

+

+void vRegisterFileSystemCLICommands( void )

+{

+	/* Register all the command line commands defined immediately above. */

+	FreeRTOS_CLIRegisterCommand( &xDIR );

+	FreeRTOS_CLIRegisterCommand( &xCD );

+	FreeRTOS_CLIRegisterCommand( &xTYPE );

+	FreeRTOS_CLIRegisterCommand( &xDEL );

+	FreeRTOS_CLIRegisterCommand( &xCOPY );

+	FreeRTOS_CLIRegisterCommand( &xTEST_FS );

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcParameter;

+portBASE_TYPE xParameterStringLength, xReturn = pdTRUE;

+static F_FILE *pxFile = NULL;

+int iChar;

+size_t xByte;

+size_t xColumns = 50U;

+

+	/* Ensure there is always a null terminator after each character written. */

+	memset( pcWriteBuffer, 0x00, xWriteBufferLen );

+

+	/* Ensure the buffer leaves space for the \r\n. */

+	configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );

+	xWriteBufferLen -= strlen( cliNEW_LINE );

+

+	if( xWriteBufferLen < xColumns )

+	{

+		/* Ensure the loop that uses xColumns as an end condition does not

+		write off the end of the buffer. */

+		xColumns = xWriteBufferLen;

+	}

+

+	if( pxFile == NULL )

+	{

+		/* The file has not been opened yet.  Find the file name. */

+		pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+									(

+										pcCommandString,		/* The command string itself. */

+										1,						/* Return the first parameter. */

+										&xParameterStringLength	/* Store the parameter string length. */

+									);

+

+		/* Sanity check something was returned. */

+		configASSERT( pcParameter );

+

+		/* Attempt to open the requested file. */

+		pxFile = f_open( ( const char * ) pcParameter, "r" );

+	}

+

+	if( pxFile != NULL )

+	{

+		/* Read the next chunk of data from the file. */

+		for( xByte = 0; xByte < xColumns; xByte++ )

+		{

+			iChar = f_getc( pxFile );

+

+			if( iChar == -1 )

+			{

+				/* No more characters to return. */

+				f_close( pxFile );

+				pxFile = NULL;

+				break;

+			}

+			else

+			{

+				pcWriteBuffer[ xByte ] = ( int8_t ) iChar;

+			}

+		}

+	}

+

+	if( pxFile == NULL )

+	{

+		/* Either the file was not opened, or all the data from the file has

+		been returned and the file is now closed. */

+		xReturn = pdFALSE;

+	}

+

+	strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );

+

+	return xReturn;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcParameter;

+portBASE_TYPE xParameterStringLength;

+unsigned char ucReturned;

+size_t xStringLength;

+

+	/* Obtain the parameter string. */

+	pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+								(

+									pcCommandString,		/* The command string itself. */

+									1,						/* Return the first parameter. */

+									&xParameterStringLength	/* Store the parameter string length. */

+								);

+

+	/* Sanity check something was returned. */

+	configASSERT( pcParameter );

+

+	/* Attempt to move to the requested directory. */

+	ucReturned = f_chdir( ( char * ) pcParameter );

+

+	if( ucReturned == F_NO_ERROR )

+	{

+		sprintf( ( char * ) pcWriteBuffer, "In: " );

+		xStringLength = strlen( ( const char * ) pcWriteBuffer );

+		f_getcwd( ( char * ) &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) );

+	}

+	else

+	{

+		sprintf( ( char * ) pcWriteBuffer, "Error" );

+	}

+

+	strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );

+

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+static F_FIND *pxFindStruct = NULL;

+unsigned char ucReturned;

+portBASE_TYPE xReturn = pdFALSE;

+

+	/* This assumes pcWriteBuffer is long enough. */

+	( void ) pcCommandString;

+

+	/* Ensure the buffer leaves space for the \r\n. */

+	configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );

+	xWriteBufferLen -= strlen( cliNEW_LINE );

+

+	if( pxFindStruct == NULL )

+	{

+		/* This is the first time this function has been executed since the Dir

+		command was run.  Create the find structure. */

+		pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) );

+

+		if( pxFindStruct != NULL )

+		{

+			ucReturned = f_findfirst( "*.*", pxFindStruct );

+

+			if( ucReturned == F_NO_ERROR )

+			{

+				prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );

+				xReturn = pdPASS;

+			}

+			else

+			{

+				snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." );

+			}

+		}

+		else

+		{

+			snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." );

+		}

+	}

+	else

+	{

+		/* The find struct has already been created.  Find the next file in

+		the directory. */

+		ucReturned = f_findnext( pxFindStruct );

+

+		if( ucReturned == F_NO_ERROR )

+		{

+			prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );

+			xReturn = pdPASS;

+		}

+		else

+		{

+			/* There are no more files.  Free the find structure. */

+			vPortFree( pxFindStruct );

+			pxFindStruct = NULL;

+

+			/* No string to return. */

+			pcWriteBuffer[ 0 ] = 0x00;

+		}

+	}

+

+	strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );

+

+	return xReturn;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcParameter;

+portBASE_TYPE xParameterStringLength;

+unsigned char ucReturned;

+

+	/* This function assumes xWriteBufferLen is large enough! */

+	( void ) xWriteBufferLen;

+

+	/* Obtain the parameter string. */

+	pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+								(

+									pcCommandString,		/* The command string itself. */

+									1,						/* Return the first parameter. */

+									&xParameterStringLength	/* Store the parameter string length. */

+								);

+

+	/* Sanity check something was returned. */

+	configASSERT( pcParameter );

+

+	/* Attempt to delete the file. */

+	ucReturned = f_delete( ( const char * ) pcParameter );

+

+	if( ucReturned == F_NO_ERROR )

+	{

+		sprintf( ( char * ) pcWriteBuffer, "%s was deleted", pcParameter );

+	}

+	else

+	{

+		sprintf( ( char * ) pcWriteBuffer, "Error" );

+	}

+

+	strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );

+

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+unsigned portBASE_TYPE uxOriginalPriority;

+

+	/* Avoid compiler warnings. */

+	( void ) xWriteBufferLen;

+	( void ) pcCommandString;

+

+	/* Limitations in the interaction with the Windows TCP/IP stack require

+	the command console to run at the idle priority.  Raise the priority for

+	the duration of the tests to ensure there are not multiple switches to the

+	idle task as in the simulated environment the idle task hook function may

+	include a (relatively) long delay. */

+	uxOriginalPriority = uxTaskPriorityGet( NULL );

+	vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );

+

+	f_dotest( 0 );

+

+	/* Reset back to the original priority. */

+	vTaskPrioritySet( NULL, uxOriginalPriority );

+

+	sprintf( ( char * ) pcWriteBuffer, "%s", "Test results were sent to Windows console" );

+

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcSourceFile, *pcDestinationFile;

+portBASE_TYPE xParameterStringLength;

+long lSourceLength, lDestinationLength = 0;

+

+	/* Obtain the name of the destination file. */

+	pcDestinationFile = ( int8_t * ) FreeRTOS_CLIGetParameter

+								(

+									pcCommandString,		/* The command string itself. */

+									2,						/* Return the second parameter. */

+									&xParameterStringLength	/* Store the parameter string length. */

+								);

+

+	/* Sanity check something was returned. */

+	configASSERT( pcDestinationFile );

+

+	/* Obtain the name of the source file. */

+	pcSourceFile = ( int8_t * ) FreeRTOS_CLIGetParameter

+								(

+									pcCommandString,		/* The command string itself. */

+									1,						/* Return the first parameter. */

+									&xParameterStringLength	/* Store the parameter string length. */

+								);

+

+	/* Sanity check something was returned. */

+	configASSERT( pcSourceFile );

+

+	/* Terminate the string. */

+	pcSourceFile[ xParameterStringLength ] = 0x00;

+

+	/* See if the source file exists, obtain its length if it does. */

+	lSourceLength = f_filelength( ( const char * ) pcSourceFile );

+

+	if( lSourceLength == 0 )

+	{

+		sprintf( ( char * ) pcWriteBuffer, "Source file does not exist" );

+	}

+	else

+	{

+		/* See if the destination file exists. */

+		lDestinationLength = f_filelength( ( const char * ) pcDestinationFile );

+

+		if( lDestinationLength != 0 )

+		{

+			sprintf( ( char * ) pcWriteBuffer, "Error: Destination file already exists" );

+		}

+	}

+

+	/* Continue only if the source file exists and the destination file does

+	not exist. */

+	if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) )

+	{

+		if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS )

+		{

+			sprintf( ( char * ) pcWriteBuffer, "Copy made" );

+		}

+		else

+		{

+			sprintf( ( char * ) pcWriteBuffer, "Error during copy" );

+		}

+	}

+

+	strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );

+

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,

+							int32_t lSourceFileLength,

+							int8_t *pcDestinationFile,

+							int8_t *pxWriteBuffer,

+							size_t xWriteBufferLen )

+{

+int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining;

+F_FILE *pxFile;

+portBASE_TYPE xReturn = pdPASS;

+

+	/* NOTE:  Error handling has been omitted for clarity. */

+

+	while( lBytesRead < lSourceFileLength )

+	{

+		/* How many bytes are left? */

+		lBytesRemaining = lSourceFileLength - lBytesRead;

+

+		/* How many bytes should be read this time around the loop.  Can't

+		read more bytes than will fit into the buffer. */

+		if( lBytesRemaining > ( long ) xWriteBufferLen )

+		{

+			lBytesToRead = ( long ) xWriteBufferLen;

+		}

+		else

+		{

+			lBytesToRead = lBytesRemaining;

+		}

+

+		/* Open the source file, seek past the data that has already been

+		read from the file, read the next block of data, then close the

+		file again so the destination file can be opened. */

+		pxFile = f_open( ( const char * ) pcSourceFile, "r" );

+		if( pxFile != NULL )

+		{

+			f_seek( pxFile, lBytesRead, F_SEEK_SET );

+			f_read( pxWriteBuffer, lBytesToRead, 1, pxFile );

+			f_close( pxFile );

+		}

+		else

+		{

+			xReturn = pdFAIL;

+			break;

+		}

+

+		/* Open the destination file and write the block of data to the end of

+		the file. */

+		pxFile = f_open( ( const char * ) pcDestinationFile, "a" );

+		if( pxFile != NULL )

+		{

+			f_write( pxWriteBuffer, lBytesToRead, 1, pxFile );

+			f_close( pxFile );

+		}

+		else

+		{

+			xReturn = pdFAIL;

+			break;

+		}

+

+		lBytesRead += lBytesToRead;

+	}

+

+	return xReturn;

+}

+/*-----------------------------------------------------------*/

+

+static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct )

+{

+const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory";

+const char * pcAttrib;

+

+	/* Point pcAttrib to a string that describes the file. */

+	if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 )

+	{

+		pcAttrib = pcDirectory;

+	}

+	else if( pxFindStruct->attr & F_ATTR_READONLY )

+	{

+		pcAttrib = pcReadOnlyFile;

+	}

+	else

+	{

+		pcAttrib = pcWritableFile;

+	}

+

+	/* Create a string that includes the file name, the file size and the

+	attributes string. */

+	sprintf( ( char * ) pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, pxFindStruct->filesize );

+}

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c
new file mode 100644
index 0000000..8f3915b
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c
@@ -0,0 +1,381 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High

+    Integrity Systems, who sell the code with commercial support,

+    indemnification and middleware, under the OpenRTOS brand.

+

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety

+    engineered and independently SIL3 certified version for use in safety and

+    mission critical applications that require provable dependability.

+*/

+

+/*******************************************************************************

+ * See the URL in the comments within main.c for the location of the online

+ * documentation.

+ ******************************************************************************/

+

+/* Standard includes. */

+#include <stdio.h>

+

+/* FreeRTOS includes. */

+#include "FreeRTOS.h"

+

+/* File system includes. */

+#include "fat_sl.h"

+#include "api_mdriver_ram.h"

+

+/* 8.3 format, plus null terminator. */

+#define fsMAX_FILE_NAME_LEN				13

+

+/* The number of bytes read/written to the example files at a time. */

+#define fsRAM_BUFFER_SIZE 				200

+

+/* The number of bytes written to the file that uses f_putc() and f_getc(). */

+#define fsPUTC_FILE_SIZE				100

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Creates and verifies different files on the volume, demonstrating the use of

+ * various different API functions.

+ */

+void vCreateAndVerifySampleFiles( void );

+

+/*

+ * Create a set of example files in the root directory of the volume using

+ * f_write().

+ */

+static void prvCreateDemoFilesUsing_f_write( void );

+

+/*

+ * Use f_read() to read back and verify the files that were created by

+ * prvCreateDemoFilesUsing_f_write().

+ */

+static void prvVerifyDemoFileUsing_f_read( void );

+

+/*

+ * Create an example file in a sub-directory using f_putc().

+ */

+static void prvCreateDemoFileUsing_f_putc( void );

+

+/*

+ * Use f_getc() to read back and verify the file that was created by

+ * prvCreateDemoFileUsing_f_putc().

+ */

+static void prvVerifyDemoFileUsing_f_getc( void );

+

+/*-----------------------------------------------------------*/

+

+/* A buffer used to both create content to write to disk, and read content back

+from a disk.  Note there is no mutual exclusion on this buffer. */

+static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];

+

+/* Names of directories that are created. */

+static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";

+

+/*-----------------------------------------------------------*/

+

+void vCreateAndVerifySampleFiles( void )

+{

+unsigned char ucStatus;

+

+	/* First create the volume. */

+	ucStatus = f_initvolume( ram_initfunc );

+

+	/* It is expected that the volume is not formatted. */

+	if( ucStatus == F_ERR_NOTFORMATTED )

+	{

+		/* Format the created volume. */

+		ucStatus = f_format( F_FAT12_MEDIA );

+	}

+

+	if( ucStatus == F_NO_ERROR )

+	{

+		/* Create a set of files using f_write(). */

+		prvCreateDemoFilesUsing_f_write();

+

+		/* Read back and verify the files that were created using f_write(). */

+		prvVerifyDemoFileUsing_f_read();

+

+		/* Create sub directories two deep then create a file using putc. */

+		prvCreateDemoFileUsing_f_putc();

+

+		/* Read back and verify the file created by

+		prvCreateDemoFileUsing_f_putc(). */

+		prvVerifyDemoFileUsing_f_getc();

+	}

+}

+/*-----------------------------------------------------------*/

+

+static void prvCreateDemoFilesUsing_f_write( void )

+{

+portBASE_TYPE xFileNumber, xWriteNumber;

+char cFileName[ fsMAX_FILE_NAME_LEN ];

+const portBASE_TYPE xMaxFiles = 5;

+long lItemsWritten;

+F_FILE *pxFile;

+

+	/* Create xMaxFiles files.  Each created file will be

+	( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled

+	with a different repeating character. */

+	for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )

+	{

+		/* Generate a file name. */

+		sprintf( cFileName, "root%03d.txt", xFileNumber );

+

+		/* Obtain the current working directory and print out the file name and

+		the	directory into which the file is being written. */

+		f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+		printf( "Creating file %s in %s\r\n", cFileName, cRAMBuffer );

+

+		/* Open the file, creating the file if it does not already exist. */

+		pxFile = f_open( cFileName, "w" );

+		configASSERT( pxFile );

+

+		/* Fill the RAM buffer with data that will be written to the file.  This

+		is just a repeating ascii character that indicates the file number. */

+		memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );

+

+		/* Write the RAM buffer to the opened file a number of times.  The

+		number of times the RAM buffer is written to the file depends on the

+		file number, so the length of each created file will be different. */

+		for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )

+		{

+			lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );

+			configASSERT( lItemsWritten == 1 );

+		}

+

+		/* Close the file so another file can be created. */

+		f_close( pxFile );

+	}

+}

+/*-----------------------------------------------------------*/

+

+static void prvVerifyDemoFileUsing_f_read( void )

+{

+portBASE_TYPE xFileNumber, xReadNumber;

+char cFileName[ fsMAX_FILE_NAME_LEN ];

+const portBASE_TYPE xMaxFiles = 5;

+long lItemsRead, lChar;

+F_FILE *pxFile;

+

+	/* Read back the files that were created by

+	prvCreateDemoFilesUsing_f_write(). */

+	for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )

+	{

+		/* Generate the file name. */

+		sprintf( cFileName, "root%03d.txt", xFileNumber );

+

+		/* Obtain the current working directory and print out the file name and

+		the	directory from which the file is being read. */

+		f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+		printf( "Reading file %s from %s\r\n", cFileName, cRAMBuffer );

+

+		/* Open the file for reading. */

+		pxFile = f_open( cFileName, "r" );

+		configASSERT( pxFile );

+

+		/* Read the file into the RAM buffer, checking the file contents are as

+		expected.  The size of the file depends on the file number. */

+		for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )

+		{

+			/* Start with the RAM buffer clear. */

+			memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );

+

+			lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );

+			configASSERT( lItemsRead == 1 );

+

+			/* Check the RAM buffer is filled with the expected data.  Each

+			file contains a different repeating ascii character that indicates

+			the number of the file. */

+			for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )

+			{

+				configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );

+			}

+		}

+

+		/* Close the file. */

+		f_close( pxFile );

+	}

+}

+/*-----------------------------------------------------------*/

+

+static void prvCreateDemoFileUsing_f_putc( void )

+{

+unsigned char ucReturn;

+int iByte, iReturned;

+F_FILE *pxFile;

+char cFileName[ fsMAX_FILE_NAME_LEN ];

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "In directory %s\r\n", cRAMBuffer );

+

+	/* Create a sub directory. */

+	ucReturn = f_mkdir( pcDirectory1 );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Move into the created sub-directory. */

+	ucReturn = f_chdir( pcDirectory1 );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "In directory %s\r\n", cRAMBuffer );

+

+	/* Create a subdirectory in the new directory. */

+	ucReturn = f_mkdir( pcDirectory2 );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Move into the directory just created - now two directories down from

+	the root. */

+	ucReturn = f_chdir( pcDirectory2 );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "In directory %s\r\n", cRAMBuffer );

+	configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );

+

+	/* Generate the file name. */

+	sprintf( cFileName, "%s.txt", pcDirectory2 );

+

+	/* Print out the file name and the directory into which the file is being

+	written. */

+	printf( "Writing file %s in %s\r\n", cFileName, cRAMBuffer );

+

+	pxFile = f_open( cFileName, "w" );

+

+	/* Create a file 1 byte at a time.  The file is filled with incrementing

+	ascii characters starting from '0'. */

+	for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )

+	{

+		iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );

+		configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );

+	}

+

+	/* Finished so close the file. */

+	f_close( pxFile );

+

+	/* Move back to the root directory. */

+	ucReturn = f_chdir( "../.." );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "Back in root directory %s\r\n", cRAMBuffer );

+	configASSERT( strcmp( ( const char * ) cRAMBuffer, pcRoot ) == 0 );

+}

+/*-----------------------------------------------------------*/

+

+static void prvVerifyDemoFileUsing_f_getc( void )

+{

+unsigned char ucReturn;

+int iByte, iReturned;

+F_FILE *pxFile;

+char cFileName[ fsMAX_FILE_NAME_LEN ];

+

+	/* Move into the directory in which the file was created. */

+	ucReturn = f_chdir( pcFullPath );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "Back in directory %s\r\n", cRAMBuffer );

+	configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );

+

+	/* Generate the file name. */

+	sprintf( cFileName, "%s.txt", pcDirectory2 );

+

+	/* Print out the file name and the directory from which the file is being

+	read. */

+	printf( "Reading file %s in %s\r\n", cFileName, cRAMBuffer );

+

+	/* This time the file is opened for reading. */

+	pxFile = f_open( cFileName, "r" );

+

+	/* Read the file 1 byte at a time. */

+	for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )

+	{

+		iReturned = f_getc( pxFile );

+		configASSERT( iReturned ==  ( ( int ) '0' + iByte ) );

+	}

+

+	/* Finished so close the file. */

+	f_close( pxFile );

+

+	/* Move back to the root directory. */

+	ucReturn = f_chdir( "../.." );

+	configASSERT( ucReturn == F_NO_ERROR );

+

+	/* Obtain and print out the working directory. */

+	f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );

+	printf( "Back in root directory %s\r\n", cRAMBuffer );

+}

+

+

+

+

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln
new file mode 100644
index 0000000..3f819af
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln
@@ -0,0 +1,20 @@
+

+Microsoft Visual Studio Solution File, Format Version 11.00

+# Visual C++ Express 2010

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WIN32", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32

+		{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32

+		{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32

+		{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url
new file mode 100644
index 0000000..9c6b614
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url
@@ -0,0 +1,5 @@
+[InternetShortcut]

+URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml

+IDList=

+[{000214A0-0000-0000-C000-000000000046}]

+Prop3=19,2

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c
new file mode 100644
index 0000000..40dca76
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c
@@ -0,0 +1,137 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions, 

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High 

+    Integrity Systems, who sell the code with commercial support, 

+    indemnification and middleware, under the OpenRTOS brand.

+    

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety 

+    engineered and independently SIL3 certified version for use in safety and 

+    mission critical applications that require provable dependability.

+*/

+

+/*

+ * Utility functions required to gather run time statistics.  See:

+ * http://www.freertos.org/rtos-run-time-stats.html

+ *

+ * Note that this is a simulated port, where simulated time is a lot slower than

+ * real time, therefore the run time counter values have no real meaningful

+ * units.

+ *

+ * Also note that it is assumed this demo is going to be used for short periods

+ * of time only, and therefore timer overflows are not handled.

+*/

+

+/* FreeRTOS includes. */

+#include <FreeRTOS.h>

+

+/* Variables used in the creation of the run time stats time base.  Run time 

+stats record how much time each task spends in the Running state. */

+static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL;

+

+/*-----------------------------------------------------------*/

+

+void vConfigureTimerForRunTimeStats( void )

+{

+LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue;

+

+	/* Initialise the variables used to create the run time stats time base.

+	Run time stats record how much time each task spends in the Running 

+	state. */

+

+	if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 )

+	{

+		llTicksPerHundedthMillisecond = 1;

+	}

+	else

+	{

+		/* How many times does the performance counter increment in 1/100th

+		millisecond. */

+		llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL;

+

+		/* What is the performance counter value now, this will be subtracted

+		from readings taken at run time. */

+		QueryPerformanceCounter( &liInitialRunTimeValue );

+		llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart;

+	}

+}

+/*-----------------------------------------------------------*/

+

+unsigned long ulGetRunTimeCounterValue( void )

+{

+LARGE_INTEGER liCurrentCount;

+unsigned long ulReturn;

+

+	/* What is the performance counter value now? */

+	QueryPerformanceCounter( &liCurrentCount );

+

+	/* Subtract the performance counter value reading taken when the 

+	application started to get a count from that reference point, then

+	scale to (simulated) 1/100ths of a millisecond. */

+	ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond );

+

+	return ulReturn;

+}

+/*-----------------------------------------------------------*/

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c
new file mode 100644
index 0000000..1fccb84
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c
@@ -0,0 +1,426 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions, 

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High 

+    Integrity Systems, who sell the code with commercial support, 

+    indemnification and middleware, under the OpenRTOS brand.

+    

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety 

+    engineered and independently SIL3 certified version for use in safety and 

+    mission critical applications that require provable dependability.

+*/

+

+ /******************************************************************************

+ *

+ * See the following URL for information on the commands defined in this file:

+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml

+ *

+ ******************************************************************************/

+

+

+/* FreeRTOS includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+

+/* Standard includes. */

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+

+/* FreeRTOS+CLI includes. */

+#include "FreeRTOS_CLI.h"

+

+#ifndef  configINCLUDE_TRACE_RELATED_CLI_COMMANDS

+	#define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0

+#endif

+

+

+/*

+ * Implements the run-time-stats command.

+ */

+static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the task-stats command.

+ */

+static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the echo-three-parameters command.

+ */

+static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the echo-parameters command.

+ */

+static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+

+/*

+ * Implements the "trace start" and "trace stop" commands;

+ */

+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1

+	static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );

+#endif

+

+/* Structure that defines the "run-time-stats" command line command.   This

+generates a table that shows how much run time each task has */

+static const CLI_Command_Definition_t xRunTimeStats =

+{

+	( const int8_t * const ) "run-time-stats", /* The command string to type. */

+	( const int8_t * const ) "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",

+	prvRunTimeStatsCommand, /* The function to run. */

+	0 /* No parameters are expected. */

+};

+

+/* Structure that defines the "task-stats" command line command.  This generates

+a table that gives information on each task in the system. */

+static const CLI_Command_Definition_t xTaskStats =

+{

+	( const int8_t * const ) "task-stats", /* The command string to type. */

+	( const int8_t * const ) "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",

+	prvTaskStatsCommand, /* The function to run. */

+	0 /* No parameters are expected. */

+};

+

+/* Structure that defines the "echo_3_parameters" command line command.  This

+takes exactly three parameters that the command simply echos back one at a

+time. */

+static const CLI_Command_Definition_t xThreeParameterEcho =

+{

+	( const int8_t * const ) "echo-3-parameters",

+	( const int8_t * const ) "\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",

+	prvThreeParameterEchoCommand, /* The function to run. */

+	3 /* Three parameters are expected, which can take any value. */

+};

+

+/* Structure that defines the "echo_parameters" command line command.  This

+takes a variable number of parameters that the command simply echos back one at

+a time. */

+static const CLI_Command_Definition_t xParameterEcho =

+{

+	( const int8_t * const ) "echo-parameters",

+	( const int8_t * const ) "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",

+	prvParameterEchoCommand, /* The function to run. */

+	-1 /* The user can enter any number of commands. */

+};

+

+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1

+	/* Structure that defines the "trace" command line command.  This takes a single

+	parameter, which can be either "start" or "stop". */

+	static const CLI_Command_Definition_t xStartStopTrace =

+	{

+		( const int8_t * const ) "trace",

+		( const int8_t * const ) "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",

+		prvStartStopTraceCommand, /* The function to run. */

+		1 /* One parameter is expected.  Valid values are "start" and "stop". */

+	};

+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */

+

+/*-----------------------------------------------------------*/

+

+void vRegisterSampleCLICommands( void )

+{

+	/* Register all the command line commands defined immediately above. */

+	FreeRTOS_CLIRegisterCommand( &xTaskStats );

+	FreeRTOS_CLIRegisterCommand( &xRunTimeStats );

+	FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );

+	FreeRTOS_CLIRegisterCommand( &xParameterEcho );

+

+	#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )

+	{

+		FreeRTOS_CLIRegisterCommand( & xStartStopTrace );

+	}

+	#endif

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+const int8_t *const pcHeader = ( int8_t * ) "Task          State  Priority  Stack	#\r\n************************************************\r\n";

+

+	/* Remove compile time warnings about unused parameters, and check the

+	write buffer is not NULL.  NOTE - for simplicity, this example assumes the

+	write buffer length is adequate, so does not check for buffer overflows. */

+	( void ) pcCommandString;

+	( void ) xWriteBufferLen;

+	configASSERT( pcWriteBuffer );

+

+	/* Generate a table of task stats. */

+	strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );

+	vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) );

+

+	/* There is no more data to return after this single string, so return

+	pdFALSE. */

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+const int8_t * const pcHeader = ( int8_t * ) "Task            Abs Time      % Time\r\n****************************************\r\n";

+

+	/* Remove compile time warnings about unused parameters, and check the

+	write buffer is not NULL.  NOTE - for simplicity, this example assumes the

+	write buffer length is adequate, so does not check for buffer overflows. */

+	( void ) pcCommandString;

+	( void ) xWriteBufferLen;

+	configASSERT( pcWriteBuffer );

+

+	/* Generate a table of task stats. */

+	strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );

+	vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) );

+

+	/* There is no more data to return after this single string, so return

+	pdFALSE. */

+	return pdFALSE;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcParameter;

+portBASE_TYPE xParameterStringLength, xReturn;

+static portBASE_TYPE lParameterNumber = 0;

+

+	/* Remove compile time warnings about unused parameters, and check the

+	write buffer is not NULL.  NOTE - for simplicity, this example assumes the

+	write buffer length is adequate, so does not check for buffer overflows. */

+	( void ) pcCommandString;

+	( void ) xWriteBufferLen;

+	configASSERT( pcWriteBuffer );

+

+	if( lParameterNumber == 0 )

+	{

+		/* The first time the function is called after the command has been

+		entered just a header string is returned. */

+		sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" );

+

+		/* Next time the function is called the first parameter will be echoed

+		back. */

+		lParameterNumber = 1L;

+

+		/* There is more data to be returned as no parameters have been echoed

+		back yet. */

+		xReturn = pdPASS;

+	}

+	else

+	{

+		/* Obtain the parameter string. */

+		pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+									(

+										pcCommandString,		/* The command string itself. */

+										lParameterNumber,		/* Return the next parameter. */

+										&xParameterStringLength	/* Store the parameter string length. */

+									);

+

+		/* Sanity check something was returned. */

+		configASSERT( pcParameter );

+

+		/* Return the parameter string. */

+		memset( pcWriteBuffer, 0x00, xWriteBufferLen );

+		sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );

+		strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );

+		strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );

+

+		/* If this is the last of the three parameters then there are no more

+		strings to return after this one. */

+		if( lParameterNumber == 3L )

+		{

+			/* If this is the last of the three parameters then there are no more

+			strings to return after this one. */

+			xReturn = pdFALSE;

+			lParameterNumber = 0L;

+		}

+		else

+		{

+			/* There are more parameters to return after this one. */

+			xReturn = pdTRUE;

+			lParameterNumber++;

+		}

+	}

+

+	return xReturn;

+}

+/*-----------------------------------------------------------*/

+

+static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+{

+int8_t *pcParameter;

+portBASE_TYPE xParameterStringLength, xReturn;

+static portBASE_TYPE lParameterNumber = 0;

+

+	/* Remove compile time warnings about unused parameters, and check the

+	write buffer is not NULL.  NOTE - for simplicity, this example assumes the

+	write buffer length is adequate, so does not check for buffer overflows. */

+	( void ) pcCommandString;

+	( void ) xWriteBufferLen;

+	configASSERT( pcWriteBuffer );

+

+	if( lParameterNumber == 0 )

+	{

+		/* The first time the function is called after the command has been

+		entered just a header string is returned. */

+		sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" );

+

+		/* Next time the function is called the first parameter will be echoed

+		back. */

+		lParameterNumber = 1L;

+

+		/* There is more data to be returned as no parameters have been echoed

+		back yet. */

+		xReturn = pdPASS;

+	}

+	else

+	{

+		/* Obtain the parameter string. */

+		pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+									(

+										pcCommandString,		/* The command string itself. */

+										lParameterNumber,		/* Return the next parameter. */

+										&xParameterStringLength	/* Store the parameter string length. */

+									);

+

+		if( pcParameter != NULL )

+		{

+			/* Return the parameter string. */

+			memset( pcWriteBuffer, 0x00, xWriteBufferLen );

+			sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );

+			strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );

+			strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );

+

+			/* There might be more parameters to return after this one. */

+			xReturn = pdTRUE;

+			lParameterNumber++;

+		}

+		else

+		{

+			/* No more parameters were found.  Make sure the write buffer does

+			not contain a valid string. */

+			pcWriteBuffer[ 0 ] = 0x00;

+

+			/* No more data to return. */

+			xReturn = pdFALSE;

+

+			/* Start over the next time this command is executed. */

+			lParameterNumber = 0;

+		}

+	}

+

+	return xReturn;

+}

+/*-----------------------------------------------------------*/

+

+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1

+

+	static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )

+	{

+	int8_t *pcParameter;

+	portBASE_TYPE lParameterStringLength;

+

+		/* Remove compile time warnings about unused parameters, and check the

+		write buffer is not NULL.  NOTE - for simplicity, this example assumes the

+		write buffer length is adequate, so does not check for buffer overflows. */

+		( void ) pcCommandString;

+		( void ) xWriteBufferLen;

+		configASSERT( pcWriteBuffer );

+

+		/* Obtain the parameter string. */

+		pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter

+									(

+										pcCommandString,		/* The command string itself. */

+										1,						/* Return the first parameter. */

+										&lParameterStringLength	/* Store the parameter string length. */

+									);

+

+		/* Sanity check something was returned. */

+		configASSERT( pcParameter );

+

+		/* There are only two valid parameter values. */

+		if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 )

+		{

+			/* Start or restart the trace. */

+			vTraceStop();

+			vTraceClear();

+			vTraceStart();

+

+			sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" );

+		}

+		else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 )

+		{

+			/* End the trace, if one is running. */

+			vTraceStop();

+			sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" );

+		}

+		else

+		{

+			sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );

+		}

+

+		/* There is no more data to return after this single string, so return

+		pdFALSE. */

+		return pdFALSE;

+	}

+

+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c
new file mode 100644
index 0000000..f5f65cf
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c
@@ -0,0 +1,276 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High

+    Integrity Systems, who sell the code with commercial support,

+    indemnification and middleware, under the OpenRTOS brand.

+

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety

+    engineered and independently SIL3 certified version for use in safety and

+    mission critical applications that require provable dependability.

+*/

+

+

+#pragma comment( lib, "ws2_32.lib" )

+

+/* Win32 includes. */

+#include <WinSock2.h>

+

+/* FreeRTOS includes. */

+#include "FreeRTOS.h"

+#include "task.h"

+

+/* Standard includes. */

+#include <stdint.h>

+#include <stdio.h>

+

+/* FreeRTOS+CLI includes. */

+#include "FreeRTOS_CLI.h"

+

+/* Dimensions the buffer into which input characters are placed. */

+#define cmdMAX_INPUT_SIZE	60

+

+/* Dimensions the buffer into which string outputs can be placed. */

+#define cmdMAX_OUTPUT_SIZE	1024

+

+/* Dimensions the buffer passed to the recvfrom() call. */

+#define cmdSOCKET_INPUT_BUFFER_SIZE 60

+

+/* DEL acts as a backspace. */

+#define cmdASCII_DEL		( 0x7F )

+

+/*

+ * Open and configure the UDP socket.

+ */

+static SOCKET prvOpenUDPSocket( void );

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Task that provides the input and output for the FreeRTOS+CLI command

+ * interpreter.  In this case a WinSock UDP port is used for convenience as this

+ * demo runs in a simulated environment on a Windows PC.  See the URL in the

+ * comments within main.c for the location of the online documentation.

+ */

+void vUDPCommandInterpreterTask( void *pvParameters )

+{

+long lBytes, lByte;

+signed char cInChar, cInputIndex = 0;

+static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];

+portBASE_TYPE xMoreDataToFollow;

+volatile int iErrorCode = 0;

+struct sockaddr_in xClient;

+int xClientAddressLength = sizeof( struct sockaddr_in );

+SOCKET xSocket;

+

+	/* Just to prevent compiler warnings. */

+	( void ) pvParameters;

+

+	/* Attempt to open the socket. */

+	xSocket = prvOpenUDPSocket();

+

+	if( xSocket != INVALID_SOCKET )

+	{

+		for( ;; )

+		{

+			/* Wait for incoming data on the opened socket. */

+			lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength );

+

+			if( lBytes == SOCKET_ERROR )

+			{

+				/* Something went wrong, but it is not handled by this simple

+				example. */

+				iErrorCode = WSAGetLastError();

+			}

+			else

+			{

+				/* Process each received byte in turn. */

+				lByte = 0;

+				while( lByte < lBytes )

+				{

+					/* The next character in the input buffer. */

+					cInChar = cLocalBuffer[ lByte ];

+					lByte++;

+

+					/* Newline characters are taken as the end of the command

+					string. */

+					if( cInChar == '\n' )

+					{

+						/* Process the input string received prior to the

+						newline. */

+						do

+						{

+							/* Pass the string to FreeRTOS+CLI. */

+							xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );

+

+							/* Send the output generated by the command's

+							implementation. */

+							sendto( xSocket, cOutputString,  strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );

+

+						} while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */

+

+						/* All the strings generated by the command processing

+						have been sent.  Clear the input string ready to receive

+						the next command. */

+						cInputIndex = 0;

+						memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );

+

+						/* Transmit a spacer, just to make the command console

+						easier to read. */

+						sendto( xSocket, "\r\n",  strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );

+					}

+					else

+					{

+						if( cInChar == '\r' )

+						{

+							/* Ignore the character.  Newlines are used to

+							detect the end of the input string. */

+						}

+						else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) )

+						{

+							/* Backspace was pressed.  Erase the last character

+							in the string - if any. */

+							if( cInputIndex > 0 )

+							{

+								cInputIndex--;

+								cInputString[ cInputIndex ] = '\0';

+							}

+						}

+						else

+						{

+							/* A character was entered.  Add it to the string

+							entered so far.  When a \n is entered the complete

+							string will be passed to the command interpreter. */

+							if( cInputIndex < cmdMAX_INPUT_SIZE )

+							{

+								cInputString[ cInputIndex ] = cInChar;

+								cInputIndex++;

+							}

+						}

+					}

+				}

+			}

+		}

+	}

+	else

+	{

+		/* The socket could not be opened. */

+		vTaskDelete( NULL );

+	}

+}

+/*-----------------------------------------------------------*/

+

+static SOCKET prvOpenUDPSocket( void )

+{

+WSADATA xWSAData;

+WORD wVersionRequested;

+struct sockaddr_in xServer;

+SOCKET xSocket = INVALID_SOCKET;

+

+	wVersionRequested = MAKEWORD( 2, 2 );

+

+	/* Prepare to use WinSock. */

+	if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )

+	{

+		fprintf( stderr, "Could not open Windows connection.\n" );

+	}

+	else

+	{

+		xSocket = socket( AF_INET, SOCK_DGRAM, 0 );

+		if( xSocket == INVALID_SOCKET)

+		{

+			fprintf( stderr, "Could not create socket.\n" );

+			WSACleanup();

+		}

+		else

+		{

+			/* Zero out the server structure. */

+			memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) );

+

+			/* Set family and port. */

+			xServer.sin_family = AF_INET;

+			xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER );

+

+			/* Assign the loopback address */

+			xServer.sin_addr.S_un.S_un_b.s_b1 = 127;

+			xServer.sin_addr.S_un.S_un_b.s_b2 = 0;

+			xServer.sin_addr.S_un.S_un_b.s_b3 = 0;

+			xServer.sin_addr.S_un.S_un_b.s_b4 = 1;

+

+			/* Bind the address to the socket. */

+			if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 )

+			{

+				fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER );

+				closesocket( xSocket );

+				xSocket = INVALID_SOCKET;

+				WSACleanup();

+			}

+		}

+	}

+

+	return xSocket;

+}

+

+

diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj
new file mode 100644
index 0000000..294c69b
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup Label="ProjectConfigurations">

+    <ProjectConfiguration Include="Debug|Win32">

+      <Configuration>Debug</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+    <ProjectConfiguration Include="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>

+    <ProjectName>RTOSDemo</ProjectName>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseOfMfc>false</UseOfMfc>

+    <CharacterSet>MultiByte</CharacterSet>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseOfMfc>false</UseOfMfc>

+    <CharacterSet>MultiByte</CharacterSet>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />

+  </ImportGroup>

+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup>

+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>

+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>

+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>

+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>

+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>

+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>

+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Midl>

+      <TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>

+      <HeaderFileName>

+      </HeaderFileName>

+    </Midl>

+    <ClCompile>

+      <Optimization>Disabled</Optimization>

+      <AdditionalIncludeDirectories>..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.;.\..\..\Source\FreeRTOS-Plus-FAT-SL\api;.\..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\test;.\ConfigurationFiles;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <MinimalRebuild>true</MinimalRebuild>

+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>

+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

+      <PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>

+      <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>

+      <ObjectFileName>.\Debug/</ObjectFileName>

+      <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>

+      <WarningLevel>Level4</WarningLevel>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <DisableLanguageExtensions>false</DisableLanguageExtensions>

+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0c09</Culture>

+    </ResourceCompile>

+    <Link>

+      <OutputFile>.\Debug/RTOSDemo.exe</OutputFile>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>

+      <SubSystem>Console</SubSystem>

+      <TargetMachine>MachineX86</TargetMachine>

+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>

+      <AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>

+    </Link>

+    <Bscmake>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <OutputFile>.\Debug/WIN32.bsc</OutputFile>

+    </Bscmake>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Midl>

+      <TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>

+      <HeaderFileName>

+      </HeaderFileName>

+    </Midl>

+    <ClCompile>

+      <Optimization>MaxSpeed</Optimization>

+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>

+      <PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <StringPooling>true</StringPooling>

+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>

+      <AssemblerListingLocation>.\Release/</AssemblerListingLocation>

+      <ObjectFileName>.\Release/</ObjectFileName>

+      <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>

+      <WarningLevel>Level3</WarningLevel>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ClCompile>

+    <ResourceCompile>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <Culture>0x0c09</Culture>

+    </ResourceCompile>

+    <Link>

+      <OutputFile>.\Release/RTOSDemo.exe</OutputFile>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>

+      <SubSystem>Console</SubSystem>

+      <TargetMachine>MachineX86</TargetMachine>

+      <AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>

+      <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>

+    </Link>

+    <Bscmake>

+      <SuppressStartupBanner>true</SuppressStartupBanner>

+      <OutputFile>.\Release/WIN32.bsc</OutputFile>

+    </Bscmake>

+  </ItemDefinitionGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />

+    <ClCompile Include="..\..\..\FreeRTOS\Source\list.c" />

+    <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />

+    <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c" />

+    <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c" />

+    <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\test\test.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\fat_sl\psp_test.c" />

+    <ClCompile Include="File-Releated-CLI-commands.c" />

+    <ClCompile Include="File-system-demo.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\media-drv\ram\ramdrv_f.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\rtc\psp_rtc.c" />

+    <ClCompile Include="main.c">

+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>

+    </ClCompile>

+    <ClCompile Include="Run-time-stats-utils.c" />

+    <ClCompile Include="Sample-CLI-commands.c" />

+    <ClCompile Include="UDPCommandServer.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h" />

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h" />

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h" />

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" />

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\api\fat_sl.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.h" />

+    <ClInclude Include="ConfigurationFiles\config_fat_sl.h" />

+    <ClInclude Include="FreeRTOSConfig.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.h" />

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.h" />

+  </ItemGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters
new file mode 100644
index 0000000..e230fae
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <ItemGroup>

+    <Filter Include="Resource Files">

+      <UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>

+      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>

+    </Filter>

+    <Filter Include="FreeRTOS">

+      <UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS\Source">

+      <UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>

+      <Extensions>*.c</Extensions>

+    </Filter>

+    <Filter Include="FreeRTOS\Source\Portable">

+      <UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+">

+      <UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+CLI">

+      <UniqueIdentifier>{fd43c0ed-fdbc-437f-a5a3-c50399690bd7}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+CLI\include">

+      <UniqueIdentifier>{c5889fe2-af0f-4cea-927f-6a6935ec5e14}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL">

+      <UniqueIdentifier>{d261611a-5416-4455-bb33-3bd84381ea40}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\Media_Driver">

+      <UniqueIdentifier>{17c1a794-a4a6-4358-850f-2a88bfe3bd33}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp">

+      <UniqueIdentifier>{fb7ccc1d-c4ad-475a-98d9-2e8ae2301c99}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp\target">

+      <UniqueIdentifier>{34bb4a98-fb88-41fc-81f2-4e3f1c50c528}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp\target\rtc">

+      <UniqueIdentifier>{286bf65c-93cd-4480-8363-0fb2c2bc7ce1}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="Configuration Files">

+      <UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>

+      <Extensions>h;hpp;hxx;hm;inl</Extensions>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\tests">

+      <UniqueIdentifier>{e4105d81-802a-4210-b40b-d5dd3cf6e643}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS\Source\include">

+      <UniqueIdentifier>{ab23827c-126c-4e5a-bc99-8efa44d8a8bd}</UniqueIdentifier>

+    </Filter>

+    <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\api">

+      <UniqueIdentifier>{9e1c9cf5-c2c7-4f8d-b09d-0b7f329eac57}</UniqueIdentifier>

+    </Filter>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">

+      <Filter>FreeRTOS\Source\Portable</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c">

+      <Filter>FreeRTOS\Source</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\list.c">

+      <Filter>FreeRTOS\Source</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c">

+      <Filter>FreeRTOS\Source</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c">

+      <Filter>FreeRTOS\Source</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">

+      <Filter>FreeRTOS\Source\Portable</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c">

+      <Filter>FreeRTOS+\FreeRTOS+CLI</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\media-drv\ram\ramdrv_f.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL\Media_Driver</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\rtc\psp_rtc.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL\psp\target\rtc</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="UDPCommandServer.c" />

+    <ClCompile Include="File-Releated-CLI-commands.c" />

+    <ClCompile Include="File-system-demo.c" />

+    <ClCompile Include="main.c" />

+    <ClCompile Include="Run-time-stats-utils.c" />

+    <ClCompile Include="Sample-CLI-commands.c" />

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\fat_sl\psp_test.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\test\test.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL\tests</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.c">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClCompile>

+  </ItemGroup>

+  <ItemGroup>

+    <ClInclude Include="FreeRTOSConfig.h">

+      <Filter>Configuration Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h">

+      <Filter>FreeRTOS+\FreeRTOS+CLI\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+    <ClInclude Include="ConfigurationFiles\config_fat_sl.h">

+      <Filter>Configuration Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h">

+      <Filter>FreeRTOS\Source\include</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\api\fat_sl.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL\api</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.h">

+      <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>

+    </ClInclude>

+  </ItemGroup>

+</Project>
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user
new file mode 100644
index 0000000..695b5c7
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+</Project>
\ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c
new file mode 100644
index 0000000..3925072
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c
@@ -0,0 +1,237 @@
+/*

+    FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.

+

+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT

+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

+

+    ***************************************************************************

+     *                                                                       *

+     *    FreeRTOS tutorial books are available in pdf and paperback.        *

+     *    Complete, revised, and edited pdf reference manuals are also       *

+     *    available.                                                         *

+     *                                                                       *

+     *    Purchasing FreeRTOS documentation will not only help you, by       *

+     *    ensuring you get running as quickly as possible and with an        *

+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *

+     *    the FreeRTOS project to continue with its mission of providing     *

+     *    professional grade, cross platform, de facto standard solutions    *

+     *    for microcontrollers - completely free of charge!                  *

+     *                                                                       *

+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *

+     *                                                                       *

+     *    Thank you for using FreeRTOS, and thank you for your support!      *

+     *                                                                       *

+    ***************************************************************************

+

+

+    This file is part of the FreeRTOS distribution.

+

+    FreeRTOS is free software; you can redistribute it and/or modify it under

+    the terms of the GNU General Public License (version 2) as published by the

+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.

+

+    >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to

+    distribute a combined work that includes FreeRTOS without being obliged to

+    provide the source code for proprietary components outside of the FreeRTOS

+    kernel.

+

+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY

+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS

+    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more

+    details. You should have received a copy of the GNU General Public License

+    and the FreeRTOS license exception along with FreeRTOS; if not itcan be

+    viewed here: http://www.freertos.org/a00114.html and also obtained by

+    writing to Real Time Engineers Ltd., contact details for whom are available

+    on the FreeRTOS WEB site.

+

+    1 tab == 4 spaces!

+

+    ***************************************************************************

+     *                                                                       *

+     *    Having a problem?  Start by reading the FAQ "My application does   *

+     *    not run, what could be wrong?"                                     *

+     *                                                                       *

+     *    http://www.FreeRTOS.org/FAQHelp.html                               *

+     *                                                                       *

+    ***************************************************************************

+

+

+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,

+    license and Real Time Engineers Ltd. contact details.

+

+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,

+    including FreeRTOS+Trace - an indispensable productivity tool, and our new

+    fully thread aware and reentrant UDP/IP stack.

+

+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High

+    Integrity Systems, who sell the code with commercial support,

+    indemnification and middleware, under the OpenRTOS brand.

+

+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety

+    engineered and independently SIL3 certified version for use in safety and

+    mission critical applications that require provable dependability.

+*/

+

+/******************************************************************************

+ *

+ * This demo is described on the following web page:

+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml

+ *

+ ******************************************************************************/

+

+/* Standard includes. */

+#include <stdio.h>

+#include <stdint.h>

+

+/* FreeRTOS includes. */

+#include <FreeRTOS.h>

+#include "task.h"

+#include "queue.h"

+#include "semphr.h"

+

+/* File system includes. */

+#include "config_fat_sl.h"

+

+/* Priorities at which the tasks are created. */

+#define mainUDP_CLI_TASK_PRIORITY			( tskIDLE_PRIORITY )

+

+/*-----------------------------------------------------------*/

+

+/*

+ * Register the generic commands that can be used with FreeRTOS+CLI.

+ */

+extern void vRegisterSampleCLICommands( void );

+

+/*

+ * Register the file system commands that can be used with FreeRTOS+CLI.

+ */

+extern void vRegisterFileSystemCLICommands( void );

+

+/*

+ * The task that implements the UDP command interpreter using FreeRTOS+CLI.

+ */

+extern void vUDPCommandInterpreterTask( void *pvParameters );

+

+/*

+ * Creates and verifies different files on the volume, demonstrating the use of

+ * various different API functions.

+ */

+extern void vCreateAndVerifySampleFiles( void );

+

+/*-----------------------------------------------------------*/

+

+/******************************************************************************

+ *

+ * This demo is described on the following web page:

+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml

+ *

+ ******************************************************************************/

+

+int main( void )

+{

+const uint32_t ulLongTime_ms = 250UL;

+

+	/* If the file system is only going to be accessed from one task then

+	F_FS_THREAD_AWARE can be set to 0 and the set of example files are created

+	before the RTOS scheduler is started.  If the file system is going to be

+	access from more than one task then F_FS_THREAD_AWARE must be set to 1 and

+	the	set of sample files are created from the idle task hook function

+	vApplicationIdleHook() - which is defined in this file. */

+	#if F_FS_THREAD_AWARE == 0

+	{

+		/* Initialise the drive and file system, then create a few example

+		files.  The output from this function just goes to the stdout window,

+		allowing the output to be viewed when the UDP command console is not

+		connected. */

+		vCreateAndVerifySampleFiles();

+	}

+	#endif

+

+	/* Register generic commands with the FreeRTOS+CLI command interpreter. */

+	vRegisterSampleCLICommands();

+

+	/* Register file system related commands with the FreeRTOS+CLI command

+	interpreter. */

+	vRegisterFileSystemCLICommands();

+

+	/* Create the task that handles the CLI on a UDP port.  The port number

+	is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */

+	xTaskCreate( vUDPCommandInterpreterTask, 	/* The function that implements the command interpreter IO handling. */

+				( signed char * ) "CLI", 		/* The name of the task - just to assist debugging. */

+				configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */

+				mainUDP_CLI_TASK_PRIORITY, 		/* The priority at which the task will run. */

+				NULL );							/* A handle to the task is not required, so NULL is passed. */

+

+	/* Start the RTOS scheduler. */

+	vTaskStartScheduler();

+

+	/* If all is well, the scheduler will now be running, and the following

+	line will never be reached.  If the following line does execute, then

+	there was insufficient FreeRTOS heap memory available for the idle and/or

+	timer tasks	to be created.  See the memory management section on the

+	FreeRTOS web site for more details (this is standard text that is not not

+	really applicable to the Win32 simulator port). */

+	for( ;; )

+	{

+		Sleep( ulLongTime_ms );

+	}

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationIdleHook( void )

+{

+const unsigned long ulMSToSleep = 5;

+

+	/* If the file system is only going to be accessed from one task then

+	F_FS_THREAD_AWARE can be set to 0 and the set of example files is created

+	before the RTOS scheduler is started.  If the file system is going to be

+	access from more than one task then F_FS_THREAD_AWARE must be set to 1 and

+	the	set of sample files are created from the idle task hook function. */

+	#if F_FS_THREAD_AWARE == 1

+	{

+		static portBASE_TYPE xCreatedSampleFiles = pdFALSE;

+

+		/* Initialise the drive and file system, then create a few example

+		files.  The output from this function just goes to the stdout window,

+		allowing the output to be viewed when the UDP command console is not

+		connected. */

+		if( xCreatedSampleFiles == pdFALSE )

+		{

+			vCreateAndVerifySampleFiles();

+			xCreatedSampleFiles = pdTRUE;

+		}

+	}

+	#endif

+

+	/* This function is called on each cycle of the idle task if

+	configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h.  Sleep to reduce CPU

+	load. */

+	Sleep( ulMSToSleep );

+}

+/*-----------------------------------------------------------*/

+

+void vAssertCalled( const char *pcFile, unsigned long ulLine )

+{

+	printf( "ASSERT FAILED: File %s, line %u\r\n", pcFile, ulLine );

+}

+/*-----------------------------------------------------------*/

+

+void vApplicationMallocFailedHook( void )

+{

+	/* vApplicationMallocFailedHook() will only be called if

+	configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook

+	function that will get called if a call to pvPortMalloc() fails.

+	pvPortMalloc() is called internally by the kernel whenever a task, queue,

+	timer or semaphore is created.  It is also called by various parts of the

+	demo application.  If heap_1.c, heap_2.c or heap_4.c are used, then the

+	size of the heap available to pvPortMalloc() is defined by

+	configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()

+	API function can be used to query the size of free heap space that remains

+	(although it does not provide information on how the remaining heap might

+	be fragmented). */

+	taskDISABLE_INTERRUPTS();

+	for( ;; );

+}

+

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url
new file mode 100644
index 0000000..c0924c3
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url
@@ -0,0 +1,5 @@
+[InternetShortcut]

+URL=http://www.freertos.org/fat

+IDList=

+[{000214A0-0000-0000-C000-000000000046}]

+Prop3=19,2

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h
new file mode 100644
index 0000000..c10ffec
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h
@@ -0,0 +1,102 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _API_MDRIVER_H_

+#define _API_MDRIVER_H_

+

+#include "../version/ver_mdriver.h"

+#if VER_MDRIVER_MAJOR != 1 || VER_MDRIVER_MINOR != 0

+ #error Incompatible MDRIVER version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+typedef struct

+{

+  unsigned short  number_of_cylinders;

+  unsigned short  sector_per_track;

+  unsigned short  number_of_heads;

+  unsigned long   number_of_sectors;

+  unsigned char   media_descriptor;

+

+  unsigned short  bytes_per_sector;

+} F_PHY;

+

+/* media descriptor to be set in getphy function */

+#define F_MEDIADESC_REMOVABLE 0xf0

+#define F_MEDIADESC_FIX       0xf8

+

+/* return bitpattern for driver getphy function */

+#define F_ST_MISSING          0x00000001

+#define F_ST_CHANGED          0x00000002

+#define F_ST_WRPROTECT        0x00000004

+

+/* Driver definitions */

+typedef struct F_DRIVER  F_DRIVER;

+

+typedef int           ( *F_WRITESECTOR )( F_DRIVER * driver, void * data, unsigned long sector );

+typedef int           ( *F_READSECTOR )( F_DRIVER * driver, void * data, unsigned long sector );

+typedef int           ( *F_GETPHY )( F_DRIVER * driver, F_PHY * phy );

+typedef long          ( *F_GETSTATUS )( F_DRIVER * driver );

+typedef void          ( *F_RELEASE )( F_DRIVER * driver );

+

+typedef struct F_DRIVER

+{

+  unsigned long  user_data;     /* user defined data */

+  void         * user_ptr;      /* user define pointer */

+

+  /* driver functions */

+  F_WRITESECTOR          writesector;

+  F_READSECTOR           readsector;

+  F_GETPHY               getphy;

+  F_GETSTATUS            getstatus;

+  F_RELEASE              release;

+} _F_DRIVER;

+

+typedef F_DRIVER *( *F_DRIVERINIT )( unsigned long driver_param );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* _API_MDRIVER_H_ */

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h
new file mode 100644
index 0000000..46dd1c6
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h
@@ -0,0 +1,70 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _API_MDRIVER_RAM_H_

+#define _API_MDRIVER_RAM_H_

+

+#include "api_mdriver.h"

+

+#include "../version/ver_mdriver_ram.h"

+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2

+ #error Incompatible MDRIVER_RAM version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define F_RAM_DRIVE0 0

+

+enum

+{

+  MDRIVER_RAM_NO_ERROR

+  , MDRIVER_RAM_ERR_SECTOR = 101

+  , MDRIVER_RAM_ERR_NOTAVAILABLE

+};

+

+F_DRIVER * ram_initfunc ( unsigned long driver_param );

+

+#ifdef __cplusplus

+}

+#endif

+

+

+#endif /* _API_MDRIVER_RAM_H_ */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h
new file mode 100644
index 0000000..f80ef27
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h
@@ -0,0 +1,479 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _API_FAT_SL_H_

+#define _API_FAT_SL_H_

+

+#include "config_fat_sl.h"

+

+#include "../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define F_MAXNAME 8                  /* 8 byte name */

+#define F_MAXEXT  3                  /* 3 byte extension */

+

+typedef struct

+{

+  char  path[F_MAXPATH];        /*  /directory1/dir2/  */

+  char  filename[F_MAXNAME];    /* filename */

+  char  fileext[F_MAXEXT];      /* extension */

+} F_NAME;

+

+typedef struct

+{

+  unsigned long  cluster;

+  unsigned long  sector;

+  unsigned long  sectorend;

+  unsigned long  pos;

+} F_POS;

+

+typedef struct

+{

+  char            filename[F_MAXPATH]; /*file name+ext*/

+  char            name[F_MAXNAME];     /*file name*/

+  char            ext[F_MAXEXT];       /*file extension*/

+  unsigned char   attr;                /*attribute of the file*/

+

+  unsigned short  ctime;        /*creation time*/

+  unsigned short  cdate;        /*creation date*/

+  unsigned long   cluster;

+

+  long            filesize;         /*length of file*/

+

+  F_NAME          findfsname;   /*find properties*/

+  F_POS           pos;

+} F_FIND;

+

+/* definitions for ctime */

+#define F_CTIME_SEC_SHIFT   0

+#define F_CTIME_SEC_MASK    0x001f  /*0-30 in 2seconds*/

+#define F_CTIME_MIN_SHIFT   5

+#define F_CTIME_MIN_MASK    0x07e0  /*0-59 */

+#define F_CTIME_HOUR_SHIFT  11

+#define F_CTIME_HOUR_MASK   0xf800  /*0-23*/

+

+

+/* definitions for cdate */

+#define F_CDATE_DAY_SHIFT   0

+#define F_CDATE_DAY_MASK    0x001f  /*0-31*/

+#define F_CDATE_MONTH_SHIFT 5

+#define F_CDATE_MONTH_MASK  0x01e0  /*1-12*/

+#define F_CDATE_YEAR_SHIFT  9

+#define F_CDATE_YEAR_MASK   0xfe00  /*0-119 (1980+value)*/

+

+#define F_ATTR_ARC         0x20

+#define F_ATTR_DIR         0x10

+#define F_ATTR_VOLUME      0x08

+#define F_ATTR_SYSTEM      0x04

+#define F_ATTR_HIDDEN      0x02

+#define F_ATTR_READONLY    0x01

+

+#define F_CLUSTER_FREE     ( (unsigned long)0x00000000 )

+#define F_CLUSTER_RESERVED ( (unsigned long)0x0ffffff0 )

+#define F_CLUSTER_BAD      ( (unsigned long)0x0ffffff7 )

+#define F_CLUSTER_LAST     ( (unsigned long)0x0ffffff8 )

+#define F_CLUSTER_LASTF32R ( (unsigned long)0x0fffffff )

+

+#define F_ST_MISSING       0x00000001

+#define F_ST_CHANGED       0x00000002

+#define F_ST_WRPROTECT     0x00000004

+

+typedef struct

+{

+  unsigned long  abspos;

+  unsigned long  filesize;

+  unsigned long  startcluster;

+  unsigned long  prevcluster;

+  unsigned long  relpos;

+  unsigned char  modified;

+  unsigned char  mode;

+  unsigned char  _tdata[F_SECTOR_SIZE];

+  F_POS          pos;

+  F_POS          dirpos;

+#if F_FILE_CHANGED_EVENT

+  char           filename[F_MAXPATH];   /* filename with full path */

+#endif

+} F_FILE;

+

+enum

+{

+  F_UNKNOWN_MEDIA

+  , F_FAT12_MEDIA

+  , F_FAT16_MEDIA

+  , F_FAT32_MEDIA

+};

+

+enum

+{

+/*  0 */

+  F_NO_ERROR,

+

+/*  1 */ F_ERR_RESERVED_1,

+

+/*  2 */ F_ERR_NOTFORMATTED,

+

+/*  3 */ F_ERR_INVALIDDIR,

+

+/*  4 */ F_ERR_INVALIDNAME,

+

+/*  5 */ F_ERR_NOTFOUND,

+

+/*  6 */ F_ERR_DUPLICATED,

+

+/*  7 */ F_ERR_NOMOREENTRY,

+

+/*  8 */ F_ERR_NOTOPEN,

+

+/*  9 */ F_ERR_EOF,

+

+/* 10 */ F_ERR_RESERVED_2,

+

+/* 11 */ F_ERR_NOTUSEABLE,

+

+/* 12 */ F_ERR_LOCKED,

+

+/* 13 */ F_ERR_ACCESSDENIED,

+

+/* 14 */ F_ERR_NOTEMPTY,

+

+/* 15 */ F_ERR_INITFUNC,

+

+/* 16 */ F_ERR_CARDREMOVED,

+

+/* 17 */ F_ERR_ONDRIVE,

+

+/* 18 */ F_ERR_INVALIDSECTOR,

+

+/* 19 */ F_ERR_READ,

+

+/* 20 */ F_ERR_WRITE,

+

+/* 21 */ F_ERR_INVALIDMEDIA,

+

+/* 22 */ F_ERR_BUSY,

+

+/* 23 */ F_ERR_WRITEPROTECT,

+

+/* 24 */ F_ERR_INVFATTYPE,

+

+/* 25 */ F_ERR_MEDIATOOSMALL,

+

+/* 26 */ F_ERR_MEDIATOOLARGE,

+

+/* 27 */ F_ERR_NOTSUPPSECTORSIZE

+

+/* 28 */, F_ERR_ALLOCATION

+

+#if F_FS_THREAD_AWARE == 1

+/* 29 */, F_ERR_OS = 29

+#endif /* F_FS_THREAD_AWARE */

+};

+

+typedef struct

+{

+  unsigned long  total;

+  unsigned long  free;

+  unsigned long  used;

+  unsigned long  bad;

+

+  unsigned long  total_high;

+  unsigned long  free_high;

+  unsigned long  used_high;

+  unsigned long  bad_high;

+} F_SPACE;

+

+enum

+{

+  F_SEEK_SET   /*Beginning of file*/

+  , F_SEEK_CUR /*Current position of file pointer*/

+  , F_SEEK_END /*End of file*/

+};

+

+

+/****************************************************************************

+ *

+ * for file changed events

+ *

+ ***************************************************************************/

+#ifndef F_FILE_CHANGED_EVENT

+	#define F_FILE_CHANGED_EVENT 0

+#endif

+

+#if F_FILE_CHANGED_EVENT

+

+typedef struct

+{

+  unsigned char   action;

+  unsigned char   flags;

+  unsigned char   attr;

+  unsigned short  ctime;

+  unsigned short  cdate;

+  unsigned long   filesize;

+  char            filename[F_MAXPATH];

+} ST_FILE_CHANGED;

+

+typedef void ( *F_FILE_CHANGED_EVENTFUNC )( ST_FILE_CHANGED * fc );

+

+extern F_FILE_CHANGED_EVENTFUNC  f_filechangedevent;

+

+ #define f_setfilechangedevent( filechangeevent ) f_filechangedevent = filechangeevent

+

+/* flags */

+

+ #define FFLAGS_NONE              0x00000000

+

+ #define FFLAGS_FILE_NAME         0x00000001

+ #define FFLAGS_DIR_NAME          0x00000002

+ #define FFLAGS_NAME              0x00000003

+ #define FFLAGS_ATTRIBUTES        0x00000004

+ #define FFLAGS_SIZE              0x00000008

+ #define FFLAGS_LAST_WRITE        0x00000010

+

+/* actions */

+

+ #define FACTION_ADDED            0x00000001

+ #define FACTION_REMOVED          0x00000002

+ #define FACTION_MODIFIED         0x00000003

+

+#endif /* if F_FILE_CHANGED_EVENT */

+

+unsigned char fn_initvolume ( F_DRIVERINIT initfunc );

+unsigned char fn_delvolume ( void );

+

+unsigned char fn_getfreespace ( F_SPACE * pspace );

+

+unsigned char fn_chdir ( const char * dirname );

+unsigned char fn_mkdir ( const char * dirname );

+unsigned char fn_rmdir ( const char * dirname );

+

+unsigned char fn_findfirst ( const char * filename, F_FIND * find );

+unsigned char fn_findnext ( F_FIND * find );

+

+long fn_filelength ( const char * filename );

+

+unsigned char fn_close ( F_FILE * filehandle );

+F_FILE * fn_open ( const char * filename, const char * mode );

+

+long fn_read ( void * buf, long size, long _size_t, F_FILE * filehandle );

+

+long fn_write ( const void * buf, long size, long _size_t, F_FILE * filehandle );

+

+unsigned char fn_seek ( F_FILE * filehandle, long offset, unsigned char whence );

+

+long fn_tell ( F_FILE * filehandle );

+int fn_getc ( F_FILE * filehandle );

+int fn_putc ( int ch, F_FILE * filehandle );

+unsigned char fn_rewind ( F_FILE * filehandle );

+unsigned char fn_eof ( F_FILE * filehandle );

+

+unsigned char fn_delete ( const char * filename );

+

+unsigned char fn_seteof ( F_FILE * );

+

+F_FILE * fn_truncate ( const char *, long );

+

+unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root );

+

+unsigned char fn_hardformat ( unsigned char fattype );

+unsigned char fn_format ( unsigned char fattype );

+

+unsigned char fn_getserial ( unsigned long * );

+

+

+#if F_FS_THREAD_AWARE == 1

+

+#include "FreeRTOS.h"

+#include "semphr.h"

+#ifndef FS_MUTEX_DEFINED

+	extern xSemaphoreHandle fs_lock_semaphore;

+#endif /* FS_MUTEX_DEFINED */

+

+unsigned char fn_init ( void );

+#define f_init fn_init

+#define f_initvolume fn_initvolume

+#define f_delvolume  fn_delvolume

+

+unsigned char fr_hardformat ( unsigned char fattype );

+#define f_hardformat( fattype ) fr_hardformat( fattype )

+#define f_format( fattype )    fr_hardformat( fattype )

+

+unsigned char fr_getcwd ( char * buffer, unsigned char maxlen, char root );

+#define f_getcwd( buffer, maxlen ) fr_getcwd( buffer, maxlen, 1 )

+

+unsigned char fr_getfreespace ( F_SPACE * pspace );

+#define f_getfreespace fr_getfreespace

+

+

+unsigned char fr_chdir ( const char * dirname );

+#define f_chdir( dirname ) fr_chdir( dirname )

+unsigned char fr_mkdir ( const char * dirname );

+#define f_mkdir( dirname ) fr_mkdir( dirname )

+unsigned char fr_rmdir ( const char * dirname );

+#define f_rmdir( dirname ) fr_rmdir( dirname )

+

+unsigned char fr_findfirst ( const char * filename, F_FIND * find );

+unsigned char fr_findnext ( F_FIND * find );

+#define f_findfirst( filename, find ) fr_findfirst( filename, find )

+#define f_findnext( find )            fr_findnext( find )

+

+long fr_filelength ( const char * filename );

+#define f_filelength( filename ) fr_filelength( filename )

+

+unsigned char fr_close ( F_FILE * filehandle );

+F_FILE * fr_open ( const char * filename, const char * mode );

+

+long fr_read ( void * buf, long size, long _size_t, F_FILE * filehandle );

+

+unsigned char fr_getserial ( unsigned long * );

+#define f_getserial( serial )  fr_getserial( serial )

+

+unsigned char fr_flush ( F_FILE * f );

+#define f_flush( filehandle ) fr_flush( filehandle )

+

+long fr_write ( const void * buf, long size, long _size_t, F_FILE * filehandle );

+#define f_write( buf, size, _size_t, filehandle ) fr_write( buf, size, _size_t, filehandle )

+

+unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence );

+#define f_seek( filehandle, offset, whence ) fr_seek( filehandle, offset, whence )

+

+long fr_tell ( F_FILE * filehandle );

+#define f_tell( filehandle )     fr_tell( filehandle )

+int fr_getc ( F_FILE * filehandle );

+#define f_getc( filehandle )     fr_getc( filehandle )

+int fr_putc ( int ch, F_FILE * filehandle );

+#define f_putc( ch, filehandle ) fr_putc( ch, filehandle )

+unsigned char fr_rewind ( F_FILE * filehandle );

+#define f_rewind( filehandle )   fr_rewind( filehandle )

+unsigned char fr_eof ( F_FILE * filehandle );

+#define f_eof( filehandle )      fr_eof( filehandle )

+

+unsigned char fr_delete ( const char * filename );

+#define f_delete( filename ) fr_delete( filename )

+

+unsigned char fr_seteof ( F_FILE * );

+#define f_seteof( file ) fr_seteof( file )

+

+F_FILE * fr_truncate ( const char *, long );

+#define f_truncate( filename, filesize ) fr_truncate( filename, filesize )

+

+#define f_close( filehandle )                    fr_close( filehandle )

+#define f_open( filename, mode )                 fr_open( filename, mode )

+#define f_read( buf, size, _size_t, filehandle ) fr_read( buf, size, _size_t, filehandle )

+

+#else /* F_FS_THREAD_AWARE */

+

+unsigned char fn_init ( void );

+#define f_init fn_init

+#define f_initvolume fn_initvolume

+#define f_delvolume  fn_delvolume

+

+#define f_hardformat( fattype ) fn_hardformat( fattype )

+#define f_format( fattype )    fn_hardformat( fattype )

+

+#define f_getcwd( buffer, maxlen ) fn_getcwd( buffer, maxlen, 1 )

+

+unsigned char fn_getfreespace ( F_SPACE * pspace );

+#define f_getfreespace fn_getfreespace

+

+

+unsigned char fn_chdir ( const char * dirname );

+#define f_chdir( dirname ) fn_chdir( dirname )

+unsigned char fn_mkdir ( const char * dirname );

+#define f_mkdir( dirname ) fn_mkdir( dirname )

+unsigned char fn_rmdir ( const char * dirname );

+#define f_rmdir( dirname ) fn_rmdir( dirname )

+

+unsigned char fn_findfirst ( const char * filename, F_FIND * find );

+unsigned char fn_findnext ( F_FIND * find );

+#define f_findfirst( filename, find ) fn_findfirst( filename, find )

+#define f_findnext( find )            fn_findnext( find )

+

+#define f_filelength( filename ) fn_filelength( filename )

+

+#define f_getserial( serial )  fn_getserial( serial )

+

+unsigned char fn_flush ( F_FILE * f );

+#define f_flush( filehandle ) fn_flush( filehandle )

+

+#define f_write( buf, size, _size_t, filehandle ) fn_write( buf, size, _size_t, filehandle )

+

+#define f_seek( filehandle, offset, whence ) fn_seek( filehandle, offset, whence )

+

+long fn_tell ( F_FILE * filehandle );

+#define f_tell( filehandle )     fn_tell( filehandle )

+int fn_getc ( F_FILE * filehandle );

+#define f_getc( filehandle )     fn_getc( filehandle )

+int fn_putc ( int ch, F_FILE * filehandle );

+#define f_putc( ch, filehandle ) fn_putc( ch, filehandle )

+unsigned char fn_rewind ( F_FILE * filehandle );

+#define f_rewind( filehandle )   fn_rewind( filehandle )

+unsigned char fn_eof ( F_FILE * filehandle );

+#define f_eof( filehandle )      fn_eof( filehandle )

+

+unsigned char fn_delete ( const char * filename );

+#define f_delete( filename ) fn_delete( filename )

+

+unsigned char fn_seteof ( F_FILE * );

+#define f_seteof( file ) fn_seteof( file )

+

+F_FILE * fn_truncate ( const char *, long );

+#define f_truncate( filename, filesize ) fn_truncate( filename, filesize )

+

+#define f_close( filehandle )                    fn_close( filehandle )

+#define f_open( filename, mode )                 fn_open( filename, mode )

+#define f_read( buf, size, _size_t, filehandle ) fn_read( buf, size, _size_t, filehandle )

+

+#endif /* F_FS_THREAD_AWARE */

+

+/****************************************************************************

+ *

+ * end of fat_sl.h

+ *

+ ***************************************************************************/

+#ifdef __cplusplus

+}

+#endif

+

+#endif /*_API_FAT_SL_H_*/

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h
new file mode 100644
index 0000000..2ecf569
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h
@@ -0,0 +1,69 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _CONFIG_FAT_SL_H

+#define _CONFIG_FAT_SL_H

+

+#include "../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#include "../api/api_mdriver.h"

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+/**************************************************************************

+**

+**  FAT SL user settings

+**

+**************************************************************************/

+#define F_SECTOR_SIZE           512u  /* Disk sector size. */

+#define F_FS_THREAD_AWARE       1     /* Set to one if the file system will be access from more than one task. */

+#define F_MAXPATH               64    /* Maximum length a file name (including its full path) can be. */

+#define F_MAX_LOCK_WAIT_TICKS   20    /* The maximum number of RTOS ticks to wait when attempting to obtain a lock on the file system when F_FS_THREAD_AWARE is set to 1. */

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* _CONFIG_FAT_SL_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h
new file mode 100644
index 0000000..5912ed0
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h
@@ -0,0 +1,54 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _CONFIG_MDRIVER_RAM_H_

+#define _CONFIG_MDRIVER_RAM_H_

+

+#include "../version/ver_mdriver_ram.h"

+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2

+ #error Incompatible MDRIVER_RAM version number!

+#endif

+

+#define MDRIVER_RAM_SECTOR_SIZE   512       /* Sector size */

+

+#define MDRIVER_RAM_VOLUME0_SIZE  (128 * 1024) /* defintion for size of ramdrive0 */

+

+#define MDRIVER_MEM_LONG_ACCESS   1         /* set this value to 1 if 32bit access available */

+

+#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c
new file mode 100644
index 0000000..815db86
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c
@@ -0,0 +1,1219 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+#include "../../psp/include/psp_string.h"

+

+#include "dir.h"

+#include "util.h"

+#include "volume.h"

+#include "drv.h"

+#include "fat.h"

+#include "file.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+

+/****************************************************************************

+ *

+ * _f_findfilewc

+ *

+ * internal function to finding file in directory entry with or without

+ * wildcard

+ *

+ * INPUTS

+ *

+ * name - filename

+ * ext - fileextension

+ * pos - where to start searching, and contains current position

+ * pde - store back the directory entry pointer

+ * wc - wildcard checking?

+ *

+ * RETURNS

+ *

+ * 0 - if file was not found

+ * 1 - if file was found

+ *

+ ***************************************************************************/

+unsigned char _f_findfilewc ( char * name, char * ext, F_POS * pos, F_DIRENTRY * * pde, unsigned char wc )

+{

+  while ( pos->cluster < F_CLUSTER_RESERVED )

+  {

+    for ( ; pos->sector < pos->sectorend ; pos->sector++ )

+    {

+      F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );

+

+      if ( _f_readglsector( pos->sector ) )

+      {

+        return 0;                                         /*not found*/

+      }

+

+      for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )

+      {

+        unsigned char  b, ok;

+

+        if ( !de->name[0] )

+        {

+          return 0;                                                /*empty*/

+        }

+

+        if ( (unsigned char)( de->name[0] ) == 0xe5 )

+        {

+          continue;                                                 /*deleted*/

+        }

+

+        if ( de->attr & F_ATTR_VOLUME )

+        {

+          continue;

+        }

+

+        if ( wc )

+        {

+          for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )

+          {

+            if ( name[b] == '*' )

+            {

+              break;

+            }

+

+            if ( name[b] != '?' )

+            {

+              if ( de->name[b] != name[b] )

+              {

+                ok = 0;

+                break;

+              }

+            }

+          }

+

+          if ( ok )

+          {

+            for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )

+            {

+              if ( ext[b] == '*' )

+              {

+                if ( pde )

+                {

+                  *pde = de;

+                }

+

+                return 1;

+              }

+

+              if ( ext[b] != '?' )

+              {

+                if ( de->ext[b] != ext[b] )

+                {

+                  ok = 0;

+                  break;

+                }

+              }

+            }

+

+            if ( ok )

+            {

+              if ( pde )

+              {

+                *pde = de;

+              }

+

+              return 1;

+            }

+          }

+        }

+        else

+        {

+          for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )

+          {

+            if ( de->name[b] != name[b] )

+            {

+              ok = 0;

+              break;

+            }

+          }

+

+          if ( ok )

+          {

+            for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )

+            {

+              if ( de->ext[b] != ext[b] )

+              {

+                ok = 0;

+                break;

+              }

+            }

+

+            if ( ok )

+            {

+              if ( pde )

+              {

+                *pde = de;

+              }

+

+              return 1;

+            }

+          }

+        }

+      }

+

+      pos->pos = 0;

+    }

+

+    if ( !pos->cluster )

+    {

+      if ( gl_volume.mediatype == F_FAT32_MEDIA )

+      {

+        pos->cluster = gl_volume.bootrecord.rootcluster;

+      }

+      else

+        return 0;

+    }

+

+    {

+      unsigned long  nextcluster;

+      gl_volume.fatsector = (unsigned long)-1;

+      if ( _f_getclustervalue( pos->cluster, &nextcluster ) )

+      {

+        return 0;                                                          /*not found*/

+      }

+

+      if ( nextcluster >= F_CLUSTER_RESERVED )

+      {

+        return 0;                                            /*eof*/

+      }

+

+      _f_clustertopos( nextcluster, pos );

+    }

+  } /* _f_findfilewc */

+

+  return 0;

+}

+

+

+/****************************************************************************

+ *

+ * _f_getfilename

+ *

+ * create a complete filename from name and extension

+ *

+ * INPUTS

+ *

+ * dest - where to store filename

+ * name - name of the file

+ * ext - extension of the file

+ *

+ ***************************************************************************/

+static void _f_getfilename ( char * dest, char * name, char * ext )

+{

+  unsigned char  a, len;

+

+  for ( len = a = F_MAXNAME ; a ; a--, len-- )

+  {

+    if ( name[a - 1] != ' ' )

+    {

+      break;

+    }

+  }

+

+  for ( a = 0 ; a < len ; a++ )

+  {

+    *dest++ = *name++;

+  }

+

+

+  for ( len = a = F_MAXEXT ; a ; a--, len-- )

+  {

+    if ( ext[a - 1] != ' ' )

+    {

+      break;

+    }

+  }

+

+  if ( len )

+  {

+    *dest++ = '.';

+  }

+

+  for ( a = 0 ; a < len ; a++ )

+  {

+    *dest++ = *ext++;

+  }

+

+  *dest = 0; /*terminateit*/

+} /* _f_getfilename */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_getdecluster

+ *

+ * get a directory entry structure start cluster value

+ *

+ * INPUTS

+ *

+ * de - directory entry

+ *

+ * RETURNS

+ *

+ * directory entry cluster value

+ *

+ ***************************************************************************/

+unsigned long _f_getdecluster ( F_DIRENTRY * de )

+{

+  unsigned long  cluster;

+  if ( gl_volume.mediatype == F_FAT32_MEDIA )

+  {

+    cluster = _f_getword( &de->clusterhi );

+    cluster <<= 16;

+    cluster |= _f_getword( &de->clusterlo );

+    return cluster;

+  }

+

+  return _f_getword( &de->clusterlo );

+}

+

+

+/****************************************************************************

+ *

+ * _f_setdecluster

+ *

+ * set a directory entry structure start cluster value

+ *

+ * INPUTS

+ *

+ * de - directory entry

+ * cluster - value of the start cluster

+ *

+ ***************************************************************************/

+void _f_setdecluster ( F_DIRENTRY * de, unsigned long cluster )

+{

+  _f_setword( &de->clusterlo, (unsigned short)( cluster & 0xffff ) );

+  if ( gl_volume.mediatype == F_FAT32_MEDIA )

+  {

+    _f_setword( &de->clusterhi, (unsigned short)( cluster >> 16 ) );

+  }

+  else

+  {

+    _f_setword( &de->clusterhi, (unsigned short)0 );

+  }

+}

+

+

+/****************************************************************************

+ *

+ * _f_findpath

+ *

+ * finding out if path is valid in F_NAME and

+ * correct path info with absolute path (removes relatives)

+ *

+ * INPUTS

+ *

+ * fsname - filled structure with path,drive

+ * pos - where to start searching, and contains current position

+ *

+ * RETURNS

+ *

+ * 0 - if path was not found or invalid

+ * 1 - if path was found

+ *

+ ***************************************************************************/

+unsigned char _f_findpath ( F_NAME * fsname, F_POS * pos )

+{

+  char       * path = fsname->path;

+  char       * mpath = path;

+  F_DIRENTRY * de;

+

+  _f_clustertopos( 0, pos );

+

+  for ( ; *path ; )

+  {

+    char           name[F_MAXNAME];

+    char           ext[F_MAXEXT];

+

+    unsigned char  len = _f_setnameext( path, name, ext );

+

+    if ( ( pos->cluster == 0 ) && ( len == 1 ) && ( name[0] == '.' ) )

+    {

+      _f_clustertopos( 0, pos );

+    }

+    else

+    {

+      if ( !_f_findfilewc( name, ext, pos, &de, 0 ) )

+      {

+        return 0;

+      }

+      if ( !( de->attr & F_ATTR_DIR ) )

+      {

+        return 0;

+      }

+

+      _f_clustertopos( _f_getdecluster( de ), pos );

+    }

+

+

+    if ( name[0] == '.' )

+    {

+      if ( len == 1 )

+      {

+        path += len;

+

+        if ( !( *path ) )

+        {

+          if ( mpath != fsname->path )

+          {

+            mpath--;                                  /*if we are now at the top*/

+          }

+

+          break;

+        }

+

+        path++;

+        continue;

+      }

+

+      if ( name[1] != '.' )

+      {

+        return 0;                       /*invalid name*/

+      }

+

+      if ( len != 2 )

+      {

+        return 0;                 /*invalid name !*/

+      }

+

+      path += len;

+

+      if ( mpath == fsname->path )

+      {

+        return 0;                              /*we are in the top*/

+      }

+

+      mpath--;       /*no on separator*/

+      for ( ; ; )

+      {

+        if ( mpath == fsname->path )

+        {

+          break;                                /*we are now at the top*/

+        }

+

+        mpath--;

+        if ( *mpath == '/' )

+        {

+          mpath++;

+          break;

+        }

+      }

+

+      if ( !( *path ) )

+      {

+        if ( mpath != fsname->path )

+        {

+          mpath--;                                /*if we are now at the top*/

+        }

+

+        break;

+      }

+

+      path++;

+      continue;

+    }

+    else

+    {

+      if ( path == mpath )                              /*if no was dots just step*/

+      {

+        path += len;

+        mpath += len;

+      }

+      else

+      {

+        unsigned char  a;

+        for ( a = 0 ; a < len ; a++ )

+        {

+          *mpath++ = *path++;                            /*copy if in different pos*/

+        }

+      }

+    }

+

+    if ( !( *path ) )

+    {

+      break;

+    }

+

+    path++;

+    *mpath++ = '/';   /*add separator*/

+  }

+

+  *mpath = 0; /*terminate it*/

+  return 1;

+} /* _f_findpath */

+

+

+/****************************************************************************

+ *

+ * fn_getcwd

+ *

+ * getting a current working directory of current drive

+ *

+ * INPUTS

+ *

+ * buffer - where to store current working folder

+ * maxlen - buffer length (possible size is F_MAXPATH)

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+

+unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root )

+{

+  unsigned char  a;

+

+  if ( !maxlen )

+  {

+    return F_NO_ERROR;

+  }

+

+  maxlen--;     /*need for termination*/

+  if ( root && maxlen )

+  {

+    *buffer++ = '/';

+    maxlen--;

+  }

+

+  for ( a = 0 ; a < maxlen ; a++ )

+  {

+    char  ch = gl_volume.cwd[a];

+    buffer[a] = ch;

+    if ( !ch )

+    {

+      break;

+    }

+  }

+

+  buffer[a] = 0;    /*add terminator at the end*/

+

+  return F_NO_ERROR;

+} /* fn_getcwd */

+

+

+

+/****************************************************************************

+ *

+ * fn_findfirst

+ *

+ * find a file(s) or directory(s) in directory

+ *

+ * INPUTS

+ *

+ * filename - filename (with or without wildcards)

+ * find - where to store found file information

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+

+unsigned char fn_findfirst ( const char * filename, F_FIND * find )

+{

+  unsigned char  ret;

+

+  if ( _f_setfsname( filename, &find->findfsname ) )

+  {

+    return F_ERR_INVALIDNAME;  /*invalid name*/

+  }

+

+  if ( _f_checkname( find->findfsname.filename, find->findfsname.fileext ) )

+  {

+    return F_ERR_INVALIDNAME;  /*invalid name, wildcard is ok*/

+  }

+

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( !_f_findpath( &find->findfsname, &find->pos ) )

+  {

+    return F_ERR_INVALIDDIR;   /*search for path*/

+  }

+

+  return fn_findnext( find );

+} /* fn_findfirst */

+

+

+

+/****************************************************************************

+ *

+ * fn_findnext

+ *

+ * find further file(s) or directory(s) in directory

+ *

+ * INPUTS

+ *

+ * find - where to store found file information (findfirst should call 1st)

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+

+unsigned char fn_findnext ( F_FIND * find )

+{

+  F_DIRENTRY   * de;

+  unsigned char  a;

+  unsigned char  ret;

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( !_f_findfilewc( find->findfsname.filename, find->findfsname.fileext, &find->pos, &de, 1 ) )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  for ( a = 0 ; a < F_MAXNAME ; a++ )

+  {

+    find->name[a] = de->name[a];

+  }

+

+  for ( a = 0 ; a < F_MAXEXT ; a++ )

+  {

+    find->ext[a] = de->ext[a];

+  }

+

+  _f_getfilename( find->filename, (char *)de->name, (char *)de->ext );

+

+  find->attr = de->attr;

+  find->cdate = _f_getword( &de->cdate );

+  find->ctime = _f_getword( &de->ctime );

+  find->filesize = (long)_f_getlong( &de->filesize );

+  find->cluster = _f_getdecluster( de );

+  find->pos.pos++;   /*goto next position*/

+

+  return 0;

+} /* fn_findnext */

+

+

+

+/****************************************************************************

+ *

+ * fn_chdir

+ *

+ * change current working directory

+ *

+ * INPUTS

+ *

+ * dirname - new working directory name

+ *

+ * RETURNS

+ *

+ * 0 - if successfully

+ * other - if any error

+ *

+ ***************************************************************************/

+unsigned char fn_chdir ( const char * dirname )

+{

+  F_POS          pos;

+  F_NAME         fsname;

+  unsigned char  len;

+  unsigned char  a;

+  unsigned char  ret;

+

+  ret = _f_setfsname( dirname, &fsname );

+

+  if ( ret == 1 )

+  {

+    return F_ERR_INVALIDNAME;             /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return F_ERR_INVALIDNAME;                                                    /*invalid name*/

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  for ( len = 0 ; fsname.path[len] ; )

+  {

+    len++;

+  }

+

+  if ( len && ( ( fsname.filename[0] != 32 ) || ( fsname.fileext[0] != 32 ) ) )

+  {

+    fsname.path[len++] = '/';

+  }

+

+  _f_getfilename( fsname.path + len, fsname.filename, fsname.fileext );

+

+  if ( !( _f_findpath( &fsname, &pos ) ) )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  for ( a = 0 ; a < F_MAXPATH ; a++ )

+  {

+    gl_volume.cwd[a] = fsname.path[a];

+  }

+

+  return F_NO_ERROR;

+} /* fn_chdir */

+

+

+

+/****************************************************************************

+ *

+ * _f_initentry

+ *

+ * init directory entry, this function is called if a new entry is coming

+ *

+ * INPUTS

+ *

+ * de - directory entry which needs to be initialized

+ * name - fil ename  (8)

+ * ext - file extension (3)

+ *

+ ***************************************************************************/

+static void _f_initentry ( F_DIRENTRY * de, char * name, char * ext )

+{

+  unsigned short  date;

+  unsigned short  time;

+

+  psp_memset( de, 0, sizeof( F_DIRENTRY ) ); /*reset all entries*/

+

+  psp_memcpy( de->name, name, sizeof( de->name ) );

+  psp_memcpy( de->ext, ext, sizeof( de->ext ) );

+

+  f_igettimedate( &time, &date );

+  _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/

+  _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/

+}

+

+

+

+

+

+/****************************************************************************

+ *

+ * _f_addentry

+ *

+ * Add a new directory entry into driectory list

+ *

+ * INPUTS

+ *

+ * fs_name - filled structure what to add into directory list

+ * pos - where directory cluster chains starts

+ * pde - F_DIRENTRY pointer where to store the entry where it was added

+ *

+ * RETURNS

+ *

+ * 0 - if successfully added

+ * other - if any error (see FS_xxx errorcodes)

+ *

+ ***************************************************************************/

+unsigned char _f_addentry ( F_NAME * fsname, F_POS * pos, F_DIRENTRY * * pde )

+{

+  unsigned char   ret;

+  unsigned short  date;

+  unsigned short  time;

+

+  if ( !fsname->filename[0] )

+  {

+    return F_ERR_INVALIDNAME;

+  }

+

+  if ( fsname->filename[0] == '.' )

+  {

+    return F_ERR_INVALIDNAME;

+  }

+

+  while ( pos->cluster < F_CLUSTER_RESERVED )

+  {

+    for ( ; pos->sector < pos->sectorend ; pos->sector++ )

+    {

+      F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );

+

+      ret = _f_readglsector( pos->sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )

+      {

+        if ( ( !de->name[0] ) || ( (unsigned char)( de->name[0] ) == 0xe5 ) )

+        {

+          _f_initentry( de, fsname->filename, fsname->fileext );

+          if ( gl_volume.mediatype == F_FAT32_MEDIA )

+          {

+            f_igettimedate( &time, &date );

+            _f_setword( &de->crtdate, date );             /*if there is realtime clock then creation date could be set from*/

+            _f_setword( &de->crttime, time );             /*if there is realtime clock then creation time could be set from*/

+            _f_setword( &de->lastaccessdate, date );      /*if there is realtime clock then creation date could be set from*/

+          }

+

+          if ( pde )

+          {

+            *pde = de;

+          }

+

+          return F_NO_ERROR;

+        }

+      }

+

+      pos->pos = 0;

+    }

+

+    if ( !pos->cluster )

+    {

+      if ( gl_volume.mediatype == F_FAT32_MEDIA )

+      {

+        pos->cluster = gl_volume.bootrecord.rootcluster;

+      }

+      else

+        return F_ERR_NOMOREENTRY;

+    }

+

+    {

+      unsigned long  cluster;

+

+      gl_volume.fatsector = (unsigned long)-1;

+      ret = _f_getclustervalue( pos->cluster, &cluster );    /*try to get next cluster*/

+      if ( ret )

+      {

+        return ret;

+      }

+

+      if ( cluster < F_CLUSTER_RESERVED )

+      {

+        _f_clustertopos( cluster, pos );

+      }

+      else

+      {

+        ret = _f_alloccluster( &cluster );        /*get a new one*/

+        if ( ret )

+        {

+          return ret;

+        }

+

+        if ( cluster < F_CLUSTER_RESERVED )

+        {

+          if ( gl_file.mode != F_FILE_CLOSE )

+          {

+            return F_ERR_NOMOREENTRY;

+          }

+

+          _f_clustertopos( cluster, &gl_file.pos );

+

+          ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );

+          if ( ret )

+          {

+            return ret;

+          }

+

+          ret = _f_setclustervalue( pos->cluster, gl_file.pos.cluster );

+          if ( ret )

+          {

+            return ret;

+          }

+

+          ret = _f_writefatsector();

+          if ( ret )

+          {

+            return ret;

+          }

+

+          gl_volume.fatsector = (unsigned long)-1;

+          psp_memset( gl_sector, 0, F_SECTOR_SIZE );

+          while ( gl_file.pos.sector < gl_file.pos.sectorend )

+          {

+            ret = _f_writeglsector( gl_file.pos.sector );

+            if ( ret )

+            {

+              return ret;

+            }

+

+            gl_file.pos.sector++;

+          }

+

+          _f_clustertopos( gl_file.pos.cluster, pos );

+        }

+        else

+        {

+          return F_ERR_NOMOREENTRY;

+        }

+      }

+    }

+  } /* _f_addentry */

+

+  return F_ERR_NOMOREENTRY;

+}

+

+

+

+/****************************************************************************

+ *

+ * fn_mkdir

+ *

+ * making a new directory

+ *

+ * INPUTS

+ *

+ * dirname - new directory name

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_mkdir ( const char * dirname )

+{

+  F_POS          posdir;

+  F_POS          pos;

+  F_DIRENTRY   * de;

+  F_NAME         fsname;

+  unsigned long  cluster;

+  unsigned char  ret;

+

+ #if F_FILE_CHANGED_EVENT

+  ST_FILE_CHANGED  fc;

+ #endif

+

+  if ( _f_setfsname( dirname, &fsname ) )

+  {

+    return F_ERR_INVALIDNAME;                                    /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return F_ERR_INVALIDNAME;                                                    /*invalid name*/

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( !_f_findpath( &fsname, &posdir ) )

+  {

+    return F_ERR_INVALIDDIR;

+  }

+

+  pos = posdir;

+

+  if ( fsname.filename[0] == '.' )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  if ( _f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )

+  {

+    return F_ERR_DUPLICATED;

+  }

+

+  pos = posdir;

+

+  gl_volume.fatsector = (unsigned long)-1;

+  ret = _f_alloccluster( &cluster );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  ret = _f_addentry( &fsname, &pos, &de );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  de->attr |= F_ATTR_DIR;       /*set as directory*/

+

+ #if F_FILE_CHANGED_EVENT

+  if ( f_filechangedevent )

+  {

+    fc.action = FACTION_ADDED;

+    fc.flags = FFLAGS_DIR_NAME | FFLAGS_ATTRIBUTES | FFLAGS_SIZE | FFLAGS_LAST_WRITE;

+    fc.attr = de->attr;

+    fc.ctime = _f_getword( de->ctime );

+    fc.cdate = _f_getword( de->cdate );

+    fc.filesize = _f_getlong( de->filesize );

+  }

+

+ #endif

+

+  if ( gl_file.mode != F_FILE_CLOSE )

+  {

+    return F_ERR_LOCKED;

+  }

+

+  _f_clustertopos( cluster, &gl_file.pos );

+  _f_setdecluster( de, cluster ); /*new dir*/

+

+  (void)_f_writeglsector( (unsigned long)-1 );  /*write actual directory sector*/

+

+

+  de = (F_DIRENTRY *)gl_sector;

+

+  _f_initentry( de, ".       ", "   " );

+  de->attr = F_ATTR_DIR;          /*set as directory*/

+  _f_setdecluster( de, cluster ); /*current*/

+  de++;

+

+  _f_initentry( de, "..      ", "   " );

+  de->attr = F_ATTR_DIR;                 /*set as directory*/

+  _f_setdecluster( de, posdir.cluster ); /*parent*/

+  de++;

+

+  psp_memset( de, 0, ( F_SECTOR_SIZE - 2 * sizeof( F_DIRENTRY ) ) );

+

+

+  ret = _f_writeglsector( gl_file.pos.sector );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  gl_file.pos.sector++;

+  psp_memset( gl_sector, 0, ( 2 * sizeof( F_DIRENTRY ) ) );

+  while ( gl_file.pos.sector < gl_file.pos.sectorend )

+  {

+    ret = _f_writeglsector( gl_file.pos.sector );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    gl_file.pos.sector++;

+  }

+

+  gl_volume.fatsector = (unsigned long)-1;

+  ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  ret = _f_writefatsector();

+ #if F_FILE_CHANGED_EVENT

+  if ( f_filechangedevent && !ret )

+  {

+    fc.action = FACTION_ADDED;

+    fc.flags = FFLAGS_DIR_NAME;

+

+    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )

+    {

+      f_filechangedevent( &fc );

+    }

+  }

+

+ #endif

+

+  return ret;

+} /* fn_mkdir */

+

+

+

+/****************************************************************************

+ *

+ * fn_rmdir

+ *

+ * Remove directory, only could be removed if empty

+ *

+ * INPUTS

+ *

+ * dirname - which directory needed to be removed

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_rmdir ( const char * dirname )

+{

+  unsigned char  ret;

+  F_POS          pos;

+  F_DIRENTRY   * de;

+  F_NAME         fsname;

+  unsigned long  dirsector;

+  unsigned char  a;

+

+  if ( _f_setfsname( dirname, &fsname ) )

+  {

+    return F_ERR_INVALIDNAME;                                    /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return F_ERR_INVALIDNAME;                                                    /*invalid name*/

+  }

+

+  if ( fsname.filename[0] == '.' )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( !( _f_findpath( &fsname, &pos ) ) )

+  {

+    return F_ERR_INVALIDDIR;

+  }

+

+  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  if ( !( de->attr & F_ATTR_DIR ) )

+  {

+    return F_ERR_INVALIDDIR;                                       /*not a directory*/

+  }

+

+  dirsector = gl_volume.actsector;

+

+  if ( gl_file.mode != F_FILE_CLOSE )

+  {

+    return F_ERR_LOCKED;

+  }

+

+  _f_clustertopos( _f_getdecluster( de ), &gl_file.pos );

+

+  for ( ; ; )

+  {

+    F_DIRENTRY * de2;

+    char         ch = 0;

+

+    ret = _f_getcurrsector();

+    if ( ret == F_ERR_EOF )

+    {

+      break;

+    }

+

+    if ( ret )

+    {

+      return ret;

+    }

+

+    de2 = (F_DIRENTRY *)gl_sector;

+    for ( a = 0 ; a < ( F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ) ; a++, de2++ )

+    {

+      ch = de2->name[0];

+      if ( !ch )

+      {

+        break;

+      }

+

+      if ( (unsigned char)ch == 0xe5 )

+      {

+        continue;

+      }

+

+      if ( ch == '.' )

+      {

+        continue;

+      }

+

+      return F_ERR_NOTEMPTY;       /*something is there*/

+    }

+

+    if ( !ch )

+    {

+      break;

+    }

+

+    gl_file.pos.sector++;

+  }

+

+  ret = _f_readglsector( dirsector );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  de->name[0] = (unsigned char)0xe5;

+

+  ret = _f_writeglsector( dirsector );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  gl_volume.fatsector = (unsigned long)-1;

+  ret = _f_removechain( _f_getdecluster( de ) );

+ #if F_FILE_CHANGED_EVENT

+  if ( f_filechangedevent && !ret )

+  {

+    ST_FILE_CHANGED  fc;

+    fc.action = FACTION_REMOVED;

+    fc.flags = FFLAGS_DIR_NAME;

+

+    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )

+    {

+      f_filechangedevent( &fc );

+    }

+  }

+

+ #endif

+  return ret;

+} /* fn_rmdir */

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h
new file mode 100644
index 0000000..467973c
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h
@@ -0,0 +1,90 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __DIR_H

+#define __DIR_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+

+

+#define NTRES_LOW           0x08 /*lower case name*/

+

+

+typedef struct

+{

+  unsigned char  name[F_MAXNAME];   /* 8+3 */

+  unsigned char  ext[F_MAXEXT];

+  unsigned char  attr;                  /* 00ADVSHR */

+

+  unsigned char  ntres;             /* FAT32 only  */

+  unsigned char  crttimetenth;      /* FAT32 only  */

+  unsigned char  crttime[2];        /* FAT32 only  */

+  unsigned char  crtdate[2];        /* FAT32 only */

+  unsigned char  lastaccessdate[2]; /* FAT32 only */

+

+  unsigned char  clusterhi[2]; /* FAT32 only */

+  unsigned char  ctime[2];

+  unsigned char  cdate[2];

+  unsigned char  clusterlo[2]; /* fat12,fat16,fat32 */

+  unsigned char  filesize[4];

+} F_DIRENTRY;

+

+

+unsigned char _f_getdirsector ( unsigned long );

+unsigned char _f_findfilewc ( char *, char *, F_POS *, F_DIRENTRY * *, unsigned char );

+unsigned char _f_findpath ( F_NAME *, F_POS * );

+unsigned long _f_getdecluster ( F_DIRENTRY * );

+

+unsigned char _f_writedirsector ( void );

+void _f_setdecluster ( F_DIRENTRY *, unsigned long );

+unsigned char _f_addentry ( F_NAME *, F_POS *, F_DIRENTRY * * );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __DIR_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c
new file mode 100644
index 0000000..82f19bd
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c
@@ -0,0 +1,216 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+#include "../../psp/include/psp_string.h"

+

+#include "drv.h"

+#include "util.h"

+#include "volume.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+F_DRIVER * mdrv = NULL;  /* driver structure */

+

+

+/****************************************************************************

+ *

+ * _f_checkstatus

+ *

+ * checking a volume driver status, if media is removed or has been changed

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_checkstatus ( void )

+{

+  if ( mdrv->getstatus != NULL )

+  {

+    if ( mdrv->getstatus( mdrv ) & ( F_ST_MISSING | F_ST_CHANGED ) )

+    {

+      gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/

+      return F_ERR_CARDREMOVED;

+    }

+  }

+

+  return F_NO_ERROR;

+}

+

+

+/****************************************************************************

+ *

+ * _f_writesector

+ *

+ * write sector data on a volume, it calls low level driver function, it

+ * writes a complete sector

+ *

+ * INPUTS

+ * sector - which physical sector

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_writeglsector ( unsigned long sector )

+{

+  unsigned char  retry;

+

+  if ( mdrv->writesector == NULL )

+  {

+    gl_volume.state = F_STATE_NEEDMOUNT; /*no write function*/

+    return F_ERR_ACCESSDENIED;

+  }

+

+  if ( sector == (unsigned long)-1 )

+  {

+    if ( gl_file.modified )

+    {

+      sector = gl_file.pos.sector;

+    }

+    else

+    {

+      sector = gl_volume.actsector;

+    }

+  }

+

+  if ( sector != (unsigned long)-1 )

+  {

+    if ( mdrv->getstatus != NULL )

+    {

+      unsigned int  status;

+

+      status = mdrv->getstatus( mdrv );

+

+      if ( status & ( F_ST_MISSING | F_ST_CHANGED ) )

+      {

+        gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/

+        return F_ERR_CARDREMOVED;

+      }

+

+      if ( status & ( F_ST_WRPROTECT ) )

+      {

+        gl_volume.state = F_STATE_NEEDMOUNT;  /*card has been removed;*/

+        return F_ERR_WRITEPROTECT;

+      }

+    }

+

+    gl_volume.modified = 0;

+    gl_file.modified = 0;

+    gl_volume.actsector = sector;

+    for ( retry = 3 ; retry ; retry-- )

+    {

+      int mdrv_ret;

+      mdrv_ret = mdrv->writesector( mdrv, (unsigned char *)gl_sector, sector );

+      if ( !mdrv_ret )

+      {

+        return F_NO_ERROR;

+      }

+

+      if ( mdrv_ret == -1 )

+      {

+        gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/

+        return F_ERR_CARDREMOVED;

+      }

+    }

+  }

+

+

+  return F_ERR_ONDRIVE;

+} /* _f_writeglsector */

+

+

+/****************************************************************************

+ *

+ * _f_readsector

+ *

+ * read sector data from a volume, it calls low level driver function, it

+ * reads a complete sector

+ *

+ * INPUTS

+ * sector - which physical sector is read

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_readglsector ( unsigned long sector )

+{

+  unsigned char  retry;

+  unsigned char  ret;

+

+  if ( sector == gl_volume.actsector )

+  {

+    return F_NO_ERROR;

+  }

+

+  if ( gl_volume.modified || gl_file.modified )

+  {

+    ret = _f_writeglsector( (unsigned long)-1 );

+    if ( ret )

+    {

+      return ret;

+    }

+  }

+

+

+  for ( retry = 3 ; retry ; retry-- )

+  {

+    int mdrv_ret;

+    mdrv_ret = mdrv->readsector( mdrv, (unsigned char *)gl_sector, sector );

+    if ( !mdrv_ret )

+    {

+      gl_volume.actsector = sector;

+      return F_NO_ERROR;

+    }

+

+    if ( mdrv_ret == -1 )

+    {

+      gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/

+      return F_ERR_CARDREMOVED;

+    }

+  }

+

+  gl_volume.actsector = (unsigned long)-1;

+  return F_ERR_ONDRIVE;

+} /* _f_readglsector */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h
new file mode 100644
index 0000000..10827a2
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h
@@ -0,0 +1,61 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __DRV_H

+#define __DRV_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+extern F_DRIVER * mdrv;  /* driver structure */

+

+unsigned char _f_checkstatus ( void );

+unsigned char _f_readglsector ( unsigned long );

+unsigned char _f_writeglsector ( unsigned long );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __DRV_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c
new file mode 100644
index 0000000..23ebbf2
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c
@@ -0,0 +1,642 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#define FS_MUTEX_DEFINED

+

+#include "../../api/fat_sl.h"

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#if F_FS_THREAD_AWARE == 1

+

+xSemaphoreHandle fs_lock_semaphore;

+

+

+/*

+** fr_findfirst

+**

+** find first time a file using wildcards

+**

+** INPUT : filename - name of the file

+**         *find - pointer to a pre-define F_FIND structure

+** RETURN: F_NOERR - on success

+**         F_ERR_NOTFOUND - if not found

+*/

+unsigned char fr_findfirst ( const char * filename, F_FIND * find )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_findfirst( filename, find );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_findnext

+**

+** find next time a file using wildcards

+**

+** INPUT : *find - pointer to a pre-define F_FIND structure

+** RETURN: F_NOERR - on success

+**         F_ERR_NOTFOUND - if not found

+*/

+unsigned char fr_findnext ( F_FIND * find )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_findnext( find );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_filelength

+**

+** Get the length of a file

+**

+** INPUT : filename - name of the file

+** RETURN: size of the file or F_ERR_INVALID if not exists or volume not working

+*/

+long fr_filelength ( const char * filename )

+{

+  unsigned long  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_filelength( filename );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = 0;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_open

+**

+** open a file

+**

+** INPUT : filename - file to be opened

+**         mode - open method (r,w,a,r+,w+,a+)

+** RETURN: pointer to a file descriptor or 0 on error

+*/

+F_FILE * fr_open ( const char * filename, const char * mode )

+{

+  F_FILE * rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_open( filename, mode );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = NULL;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_close

+**

+** Close a previously opened file.

+**

+** INPUT : *filehandle - pointer to the file descriptor

+** RETURN: F_NOERR on success, other if error

+*/

+unsigned char fr_close ( F_FILE * filehandle )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_close( filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_read

+**

+** Read from a file.

+**

+** INPUT : buf - buffer to read data

+**         size - number of unique

+**         size_st - size of unique

+**         *filehandle - pointer to file descriptor

+** OUTPUT: number of read bytes

+*/

+long fr_read ( void * bbuf, long size, long size_st, F_FILE * filehandle )

+{

+  long  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_read( bbuf, size, size_st, filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = 0;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_write

+**

+** INPUT : bbuf - buffer to write from

+**         size - number of unique

+**         size_st - size of unique

+**         *filehandle - pointer to the file descriptor

+** RETURN: number of written bytes

+*/

+long fr_write ( const void * bbuf, long size, long size_st, F_FILE * filehandle )

+{

+  long  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_write( bbuf, size, size_st, filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = 0;

+  }

+

+  return rc;

+}

+

+/*

+** fr_seek

+**

+** Seek in a file.

+**

+** INPUT : *filehandle - pointer to a file descriptor

+**         offset - offset

+**         whence - F_SEEK_SET: position = offset

+**                  F_SEEK_CUR: position = position + offset

+**                  F_SEEK_END: position = end of file (offset=0)

+** RETURN: F_NOERR on succes, other if error.

+*/

+unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_seek( filehandle, offset, whence );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+/*

+** fr_tell

+**

+** get current position in the file

+**

+** INPUT : *filehandle - pointer to a file descriptor

+** RETURN: -1 on error or current position.

+*/

+long fr_tell ( F_FILE * filehandle )

+{

+  long  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_tell( filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = -1;

+  }

+

+  return rc;

+}

+

+/*

+** fr_getc

+**

+** read one byte from a file

+**

+** INPUT : *filehandle - pointer to a file descriptor

+** RETURN: -1 if error, otherwise the read character.

+*/

+int fr_getc ( F_FILE * filehandle )

+{

+  int  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_getc( filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = -1;

+  }

+

+  return rc;

+}

+

+/*

+** fr_putc

+**

+** write one byte to a file

+**

+** INPUT : ch - character to write

+**         *filehandle - pointer to a file handler

+** RETURN: ch on success, -1 on error

+*/

+int fr_putc ( int ch, F_FILE * filehandle )

+{

+  int  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_putc( ch, filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = -1;

+  }

+

+  return rc;

+}

+

+/*

+** fr_rewind

+**

+** set current position in the file to the beginning

+**

+** INPUT : *filehandle - pointer to a file descriptor

+** RETURN: F_NOERR on succes, other if error.

+*/

+unsigned char fr_rewind ( F_FILE * filehandle )

+{

+  unsigned char rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_rewind( filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+/*

+** fr_eof

+**

+** check if current position is at the end of the file.

+**

+** INPUT : *filehandle - pointer to a file descriptor

+** RETURN: F_ERR_EOF - at the end of the file

+**         F_NOERR - no error, end of the file not reached

+**         other - on error

+*/

+unsigned char fr_eof ( F_FILE * filehandle )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_eof( filehandle );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+/*

+** Format the device

+*/

+unsigned char fr_hardformat ( unsigned char fattype )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_hardformat( fattype );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+/*

+** fr_get_serial

+**

+** Get serial number

+**

+** OUTPUT: serial - where to write the serial number

+** RETURN: error code

+*/

+unsigned char fr_getserial ( unsigned long * serial )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_getserial( serial );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_delete

+**

+** Delete a file. Removes the chain that belongs to the file and inserts a new descriptor

+** to the directory with first_cluster set to 0.

+**

+** INPUT : filename - name of the file to delete

+** RETURN: F_NOERR on success, other if error.

+*/

+unsigned char fr_delete ( const char * filename )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_delete( filename );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+/*

+** fr_truncate

+**

+** Open a file and set end of file

+**

+** INPUT:	filename - name of the file

+**		filesize - required new size

+** RETURN:	NULL on error, otherwise file pointer

+*/

+F_FILE * fr_truncate ( const char * filename, long filesize )

+{

+  F_FILE * f;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    f = fn_truncate( filename, filesize );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    f = NULL;

+  }

+

+  return f;

+}

+

+

+/*

+** fr_getfreespace

+**

+** Get free space on the volume

+**

+** OUTPUT: *sp - pre-defined F_SPACE structure, where information will be stored

+** RETURN: F_NOERR - on success

+**         F_ERR_NOTFORMATTED - if volume is not formatted

+*/

+unsigned char fr_getfreespace ( F_SPACE * sp )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_getfreespace( sp );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_chdir

+**

+** Change to a directory

+**

+** INPUT:  path - path to the dircetory

+** RETURN: 0 - on success, other if error

+*/

+unsigned char fr_chdir ( const char * path )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_chdir( path );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_mkdir

+**

+** Create a directory

+**

+** INPUT:  path - new directory path

+** RETURN: 0 - on success, other if error

+*/

+unsigned char fr_mkdir ( const char * path )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_mkdir( path );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_rmdir

+**

+** Removes a directory

+**

+** INPUT:  path - path to remove

+** RETURN: 0 - on success, other if error

+*/

+unsigned char fr_rmdir ( const char * path )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_rmdir( path );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_getcwd

+**

+** Get current working directory

+**

+** INPUT:  maxlen - maximum length allowed

+** OUTPUT: path - current working directory

+** RETURN: 0 - on success, other if error

+*/

+unsigned char fr_getcwd ( char * path, unsigned char maxlen, char root )

+{

+  unsigned char  rc;

+

+  if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )

+  {

+    rc = fn_getcwd( path, maxlen, root );

+    xSemaphoreGive( fs_lock_semaphore );

+  }

+  else

+  {

+    rc = F_ERR_OS;

+  }

+

+  return rc;

+}

+

+

+/*

+** fr_init

+**

+** Initialize FAT_SL OS module

+**

+** RETURN: F_NO_ERROR or F_ERR_OS

+*/

+unsigned char fr_init ( void )

+{

+  return F_NO_ERROR;

+}

+

+#endif /* F_FS_THREAD_AWARE */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h
new file mode 100644
index 0000000..c050559
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h
@@ -0,0 +1,59 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _F_RTOS_H

+#define _F_RTOS_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+unsigned char fr_init ( void );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef _F_RTOS_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c
new file mode 100644
index 0000000..771d1ff
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c
@@ -0,0 +1,598 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+#include "../../api/fat_sl.h"

+

+#include "fat.h"

+#include "util.h"

+#include "volume.h"

+#include "drv.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+/****************************************************************************

+ *

+ * _f_writefatsector

+ *

+ * writing fat sector into volume, this function check if fat was modified

+ * and writes data

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_writefatsector ( void )

+{

+  unsigned char  a;

+

+  if ( gl_volume.modified )

+  {

+    unsigned long  fatsector = gl_volume.firstfat.sector + gl_volume.fatsector;

+

+    if ( gl_volume.fatsector >= gl_volume.firstfat.num )

+    {

+      return F_ERR_INVALIDSECTOR;

+    }

+

+    for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ )

+    {

+      unsigned char  ret;

+      ret = _f_writeglsector( fatsector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      fatsector += gl_volume.firstfat.num;

+    }

+

+    gl_volume.modified = 0;

+  }

+

+  return F_NO_ERROR;

+} /* _f_writefatsector */

+

+

+

+/****************************************************************************

+ *

+ * _f_getfatsector

+ *

+ * read a fat sector from media

+ *

+ * INPUTS

+ *

+ * sector - which fat sector is needed, this sector number is zero based

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_getfatsector ( unsigned long sector )

+{

+  unsigned char  a;

+

+  if ( gl_volume.fatsector != sector )

+  {

+    unsigned long  fatsector;

+

+    gl_volume.fatsector = sector;

+

+    if ( gl_volume.fatsector >= gl_volume.firstfat.num )

+    {

+      return F_ERR_INVALIDSECTOR;

+    }

+

+    fatsector = gl_volume.firstfat.sector + gl_volume.fatsector;

+

+    for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ )

+    {

+      if ( !_f_readglsector( fatsector ) )

+      {

+        return F_NO_ERROR;

+      }

+

+      fatsector += gl_volume.firstfat.num;

+    }

+

+    return F_ERR_READ;

+  }

+

+  return F_NO_ERROR;

+} /* _f_getfatsector */

+

+

+

+/****************************************************************************

+ *

+ * _f_setclustervalue

+ *

+ * set a cluster value in the FAT

+ *

+ * INPUTS

+ *

+ * cluster - which cluster's value need to be modified

+ * data - new value of the cluster

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_setclustervalue ( unsigned long cluster, unsigned long _tdata )

+{

+  unsigned char  ret;

+

+  switch ( gl_volume.mediatype )

+  {

+    case F_FAT16_MEDIA:

+    {

+      unsigned long   sector = cluster;

+      unsigned short  s_data = (unsigned short)( _tdata & 0xffff ); /*keep 16 bit only*/

+

+      sector /= ( F_SECTOR_SIZE / 2 );

+      cluster -= sector * ( F_SECTOR_SIZE / 2 );

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      if ( _f_getword( &gl_sector[cluster << 1] ) != s_data )

+      {

+        _f_setword( &gl_sector[cluster << 1], s_data );

+        gl_volume.modified = 1;

+      }

+    }

+    break;

+

+    case F_FAT12_MEDIA:

+    {

+      unsigned char   f12new[2];

+      unsigned long   sector = cluster;

+      unsigned short  pos;

+      unsigned short  s_data = (unsigned short)( _tdata & 0x0fff ); /*keep 12 bit only*/

+

+      if ( cluster & 1 )

+      {

+        s_data <<= 4;

+      }

+

+      _f_setword( f12new, s_data ); /*create new data*/

+

+      sector += sector / 2;       /*1.5 bytes*/

+      pos = (unsigned short)( sector % F_SECTOR_SIZE );

+      sector /= F_SECTOR_SIZE;

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      if ( cluster & 1 )

+      {

+        f12new[0] |= gl_sector[pos] & 0x0f;

+      }

+

+      if ( gl_sector[pos] != f12new[0] )

+      {

+        gl_sector[pos] = f12new[0];

+        gl_volume.modified = 1;

+      }

+

+      pos++;

+      if ( pos >= 512 )

+      {

+        ret = _f_getfatsector( sector + 1 );

+        if ( ret )

+        {

+          return ret;

+        }

+

+        pos = 0;

+      }

+

+      if ( !( cluster & 1 ) )

+      {

+        f12new[1] |= gl_sector[pos] & 0xf0;

+      }

+

+      if ( gl_sector[pos] != f12new[1] )

+      {

+        gl_sector[pos] = f12new[1];

+        gl_volume.modified = 1;

+      }

+    }

+    break;

+

+    case F_FAT32_MEDIA:

+    {

+      unsigned long  sector = cluster;

+      unsigned long  oldv;

+

+      sector /= ( F_SECTOR_SIZE / 4 );

+      cluster -= sector * ( F_SECTOR_SIZE / 4 );

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      oldv = _f_getlong( &gl_sector[cluster << 2] );

+

+      _tdata &= 0x0fffffff;

+      _tdata |= oldv & 0xf0000000; /*keep 4 top bits*/

+

+      if ( _tdata != oldv )

+      {

+        _f_setlong( &gl_sector[cluster << 2], _tdata );

+        gl_volume.modified = 1;

+      }

+    }

+    break;

+

+    default:

+      return F_ERR_INVALIDMEDIA;

+  } /* switch */

+

+  return F_NO_ERROR;

+} /* _f_setclustervalue */

+

+

+/****************************************************************************

+ *

+ * _f_getclustervalue

+ *

+ * get a cluster value from FAT

+ *

+ * INPUTS

+ *

+ * cluster - which cluster value is requested

+ * pvalue - where to store data

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_getclustervalue ( unsigned long cluster, unsigned long * pvalue )

+{

+  unsigned long  val;

+  unsigned char  ret;

+

+  switch ( gl_volume.mediatype )

+  {

+    case F_FAT16_MEDIA:

+    {

+      unsigned long  sector = cluster;

+      sector /= ( F_SECTOR_SIZE / 2 );

+      cluster -= sector * ( F_SECTOR_SIZE / 2 );

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      val = _f_getword( &gl_sector[cluster << 1] );

+      if ( val >= ( F_CLUSTER_RESERVED & 0xffff ) )

+      {

+        val |= 0x0ffff000;                                       /*extends it*/

+      }

+

+      if ( pvalue )

+      {

+        *pvalue = val;

+      }

+    }

+    break;

+

+    case F_FAT12_MEDIA:

+    {

+      unsigned char   dataf12[2];

+      unsigned long   sector = cluster;

+      unsigned short  pos;

+

+      sector += sector / 2;       /*1.5 bytes*/

+      pos = (unsigned short)( sector % F_SECTOR_SIZE );

+      sector /= F_SECTOR_SIZE;

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      dataf12[0] = gl_sector[pos++];

+

+      if ( pos >= 512 )

+      {

+        ret = _f_getfatsector( sector + 1 );

+        if ( ret )

+        {

+          return ret;

+        }

+

+        pos = 0;

+      }

+

+      dataf12[1] = gl_sector[pos];

+

+      val = _f_getword( dataf12 );

+

+      if ( cluster & 1 )

+      {

+        val = val >> 4;

+      }

+      else

+      {

+        val = val & 0xfff;

+      }

+

+      if ( val >= ( F_CLUSTER_RESERVED & 0xfff ) )

+      {

+        val |= 0x0ffff000;                                      /*extends it*/

+      }

+

+      if ( pvalue )

+      {

+        *pvalue = val;

+      }

+    }

+    break;

+

+    case F_FAT32_MEDIA:

+    {

+      unsigned long  sector = cluster;

+      sector /= ( F_SECTOR_SIZE / 4 );

+      cluster -= sector * ( F_SECTOR_SIZE / 4 );

+

+      ret = _f_getfatsector( sector );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      if ( pvalue )

+      {

+        *pvalue = _f_getlong( &gl_sector[cluster << 2] ) & 0x0fffffff;       /*28bit*/

+      }

+    }

+    break;

+

+    default:

+      return F_ERR_INVALIDMEDIA;

+  } /* switch */

+

+  return F_NO_ERROR;

+} /* _f_getclustervalue */

+

+

+

+

+

+

+/****************************************************************************

+ *

+ * _f_clustertopos

+ *

+ * convert a cluster position into physical sector position

+ *

+ * INPUTS

+ *

+ * cluster - original cluster position

+ * pos - position structure to fills the position

+ *

+ ***************************************************************************/

+void _f_clustertopos ( unsigned long cluster, F_POS * pos )

+{

+  pos->cluster = cluster;

+

+  if ( !cluster )

+  {

+    pos->sector = gl_volume.root.sector;

+    pos->sectorend = pos->sector + gl_volume.root.num;

+  }

+  else

+  {

+    unsigned long  sectorcou = gl_volume.bootrecord.sector_per_cluster;

+    pos->sector = ( pos->cluster - 2 ) * sectorcou + gl_volume._tdata.sector;

+    pos->sectorend = pos->sector + sectorcou;

+  }

+

+  if ( cluster >= F_CLUSTER_RESERVED )

+  {

+    pos->sectorend = 0;

+  }

+

+  pos->pos = 0;

+} /* _f_clustertopos */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_getcurrsector

+ *

+ * read current sector according in file structure

+ *

+ * INPUTS

+ * f - internal file pointer

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_getcurrsector ( void )

+{

+  unsigned char  ret;

+  unsigned long  cluster;

+

+  if ( gl_file.pos.sector == gl_file.pos.sectorend )

+  {

+    gl_volume.fatsector = (unsigned long)-1;

+    ret = _f_getclustervalue( gl_file.pos.cluster, &cluster );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    if ( cluster >= F_CLUSTER_RESERVED )

+    {

+      return F_ERR_EOF;

+    }

+

+    gl_file.prevcluster = gl_file.pos.cluster;

+    _f_clustertopos( cluster, &gl_file.pos );

+  }

+

+  return _f_readglsector( gl_file.pos.sector );

+} /* _f_getcurrsector */

+

+

+

+/****************************************************************************

+ *

+ * _f_alloccluster

+ *

+ * allocate cluster from FAT

+ *

+ * INPUTS

+ * pcluster - where to store the allocated cluster number

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+unsigned char _f_alloccluster ( unsigned long * pcluster )

+{

+  unsigned long  maxcluster = gl_volume.maxcluster;

+  unsigned long  cou;

+  unsigned long  cluster = gl_volume.lastalloccluster;

+  unsigned long  value;

+  unsigned char  ret;

+

+  for ( cou = 0 ; cou < maxcluster ; cou++ )

+  {

+    if ( cluster >= maxcluster )

+    {

+      cluster = 0;

+    }

+

+    ret = _f_getclustervalue( cluster, &value );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    if ( !value )

+    {

+      gl_volume.lastalloccluster = cluster + 1;   /*set next one*/

+      *pcluster = cluster;

+

+      return F_NO_ERROR;

+    }

+

+    cluster++;

+  }

+

+  return F_ERR_NOMOREENTRY;

+} /* _f_alloccluster */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_removechain

+ *

+ * remove cluster chain from fat

+ *

+ * INPUTS

+ * cluster - first cluster in the cluster chain

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+unsigned char _f_removechain ( unsigned long cluster )

+{

+  gl_volume.fatsector = (unsigned long)-1;

+

+  if ( cluster < gl_volume.lastalloccluster ) /*this could be the begining of alloc*/

+  {

+    gl_volume.lastalloccluster = cluster;

+  }

+

+  while ( cluster < F_CLUSTER_RESERVED && cluster >= 2 )

+  {

+    unsigned long  nextcluster;

+

+    unsigned char  ret = _f_getclustervalue( cluster, &nextcluster );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    ret = _f_setclustervalue( cluster, F_CLUSTER_FREE );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    cluster = nextcluster;

+  }

+

+  return _f_writefatsector();

+} /* _f_removechain */

+

+

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h
new file mode 100644
index 0000000..bb8c727
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h
@@ -0,0 +1,65 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __FAT_H

+#define __FAT_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+unsigned char _f_getfatsector ( unsigned long );

+unsigned char _f_getclustervalue ( unsigned long, unsigned long * );

+void _f_clustertopos ( unsigned long, F_POS * );

+unsigned char _f_getcurrsector ( void );

+

+unsigned char _f_writefatsector ( void );

+unsigned char _f_setclustervalue ( unsigned long, unsigned long );

+unsigned char _f_alloccluster ( unsigned long * );

+unsigned char _f_removechain ( unsigned long );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __FAT_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c
new file mode 100644
index 0000000..ae08990
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c
@@ -0,0 +1,1492 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+#include "../../psp/include/psp_string.h"

+

+#include "util.h"

+#include "volume.h"

+#include "drv.h"

+#include "fat.h"

+#include "dir.h"

+#include "file.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+static unsigned char _f_emptywritebuffer ( void );

+

+

+/****************************************************************************

+ *

+ * fn_filelength

+ *

+ * Get a file length

+ *

+ * INPUTS

+ *

+ * filename - file whose length is needed

+ *

+ * RETURNS

+ *

+ * length of the file

+ *

+ ***************************************************************************/

+

+long fn_filelength ( const char * filename )

+{

+  F_POS        pos;

+  F_DIRENTRY * de;

+  F_NAME       fsname;

+

+  if ( _f_setfsname( filename, &fsname ) )

+  {

+    return 0;                                     /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return 0;                                                    /*invalid name*/

+  }

+

+  if ( _f_getvolume() )

+  {

+    return 0;                     /*can't get the size*/

+  }

+

+  if ( !_f_findpath( &fsname, &pos ) )

+  {

+    return 0;

+  }

+

+  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )

+  {

+    return 0;

+  }

+

+  if ( de->attr & F_ATTR_DIR )

+  {

+    return 0;                                           /*directory*/

+  }

+

+  return (long)_f_getlong( &de->filesize );

+} /* fn_filelength */

+

+

+

+

+

+/****************************************************************************

+ *

+ * _f_emptywritebuffer

+ *

+ * empty write buffer if it contains unwritten data

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+

+static unsigned char _f_emptywritebuffer ( void )

+{

+  unsigned char  ret;

+

+  ret = _f_writeglsector( gl_file.pos.sector );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  gl_file.modified = 0;

+

+  gl_file.pos.sector++;

+

+  if ( gl_file.pos.sector >= gl_file.pos.sectorend )

+  {

+    unsigned long  value;

+

+    gl_volume.fatsector = (unsigned long)-1;

+    ret = _f_getclustervalue( gl_file.pos.cluster, &value );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/

+    {

+      gl_file.prevcluster = gl_file.pos.cluster;

+      _f_clustertopos( value, &gl_file.pos );    /*go to next cluster*/

+    }

+    else

+    {

+      unsigned long  nextcluster;

+

+      ret = _f_alloccluster( &nextcluster );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster );

+      if ( ret )

+      {

+        return ret;

+      }

+

+      gl_file.prevcluster = gl_file.pos.cluster;

+

+      _f_clustertopos( nextcluster, &gl_file.pos );

+

+      return _f_writefatsector();

+    }

+  }

+

+

+  return F_NO_ERROR;

+} /* _f_emptywritebuffer */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_extend

+ *

+ * Extend file to a certain size

+ *

+ ***************************************************************************/

+static unsigned char _f_extend ( long size )

+{

+  unsigned long  _size;

+  unsigned char  rc;

+

+  size -= gl_file.filesize;

+  _size = (unsigned long)size;

+

+  rc = _f_getcurrsector();

+  if ( rc )

+  {

+    return rc;

+  }

+

+  psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) );

+

+  if ( gl_file.relpos + _size > F_SECTOR_SIZE )

+  {

+    _size -= ( F_SECTOR_SIZE - gl_file.relpos );

+    while ( _size )

+    {

+      if ( _f_emptywritebuffer() )

+      {

+        return F_ERR_WRITE;

+      }

+

+      psp_memset( gl_sector, 0, F_SECTOR_SIZE );

+      _size -= ( _size > F_SECTOR_SIZE ? F_SECTOR_SIZE : _size );

+    }

+  }

+  else

+  {

+    _size += gl_file.relpos;

+  }

+

+  gl_file.modified = 1;

+  gl_file.filesize += size;

+  gl_file.abspos = gl_file.filesize & ( ~( F_SECTOR_SIZE - 1 ) );

+  gl_file.relpos = _size;

+

+  return F_NO_ERROR;

+} /* _f_extend */

+

+

+

+/****************************************************************************

+ *

+ * _f_fseek

+ *

+ * subfunction for f_seek it moves position into given offset and read

+ * the current sector

+ *

+ * INPUTS

+ * offset - position from start

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static unsigned char _f_fseek ( long offset )

+{

+  unsigned long  cluster;

+  unsigned long  tmp;

+  unsigned char  ret = F_NO_ERROR;

+  long           remain;

+

+  if ( offset < 0 )

+  {

+    offset = 0;

+  }

+

+  if ( ( (unsigned long) offset <= gl_file.filesize )

+       && ( (unsigned long) offset >= gl_file.abspos )

+       && ( (unsigned long) offset < gl_file.abspos + F_SECTOR_SIZE ) )

+  {

+    gl_file.relpos = (unsigned short)( offset - gl_file.abspos );

+  }

+  else

+  {

+    if ( gl_file.modified )

+    {

+      ret = _f_writeglsector( (unsigned long)-1 );

+      if ( ret )

+      {

+        gl_file.mode = F_FILE_CLOSE; /*cant accessed any more*/

+        return ret;

+      }

+    }

+

+    if ( gl_file.startcluster )

+    {

+      gl_file.abspos = 0;

+      gl_file.relpos = 0;

+      gl_file.prevcluster = 0;

+      gl_file.pos.cluster = gl_file.startcluster;

+      remain = gl_file.filesize;

+

+      tmp = gl_volume.bootrecord.sector_per_cluster;

+      tmp *= F_SECTOR_SIZE;   /* set to cluster size */

+

+      /*calc cluster*/

+      gl_volume.fatsector = (unsigned long)-1;

+      while ( (unsigned long)offset >= tmp )

+      {

+        ret = _f_getclustervalue( gl_file.pos.cluster, &cluster );

+        if ( ret )

+        {

+          gl_file.mode = F_FILE_CLOSE;

+          return ret;

+        }

+

+        if ( (long) tmp >= remain )

+        {

+          break;

+        }

+

+        remain -= tmp;

+        offset -= tmp;

+        gl_file.abspos += tmp;

+        if ( cluster >= F_CLUSTER_RESERVED )

+        {

+          break;

+        }

+

+        gl_file.prevcluster = gl_file.pos.cluster;

+        gl_file.pos.cluster = cluster;

+      }

+

+      _f_clustertopos( gl_file.pos.cluster, &gl_file.pos );

+      if ( remain && offset )

+      {

+        while ( ( offset > (long) F_SECTOR_SIZE )

+               && ( remain > (long) F_SECTOR_SIZE ) )

+        {

+          gl_file.pos.sector++;

+          offset -= F_SECTOR_SIZE;

+          remain -= F_SECTOR_SIZE;

+          gl_file.abspos += F_SECTOR_SIZE;

+        }

+      }

+

+      if ( remain < offset )

+      {

+        gl_file.relpos = (unsigned short)remain;

+        ret = _f_extend( gl_file.filesize + offset - remain );

+      }

+      else

+      {

+        gl_file.relpos = (unsigned short)offset;

+      }

+    }

+  }

+

+  return ret;

+} /* _f_fseek */

+

+

+

+/****************************************************************************

+ *

+ * fn_open

+ *

+ * open a file for reading/writing/appending

+ *

+ * INPUTS

+ *

+ * filename - which file need to be opened

+ * mode - string how to open ("r"-read, "w"-write, "w+"-overwrite, "a"-append

+ *

+ * RETURNS

+ *

+ * F_FILE pointer if successfully

+ * 0 - if any error

+ *

+ ***************************************************************************/

+F_FILE * fn_open ( const char * filename, const char * mode )

+{

+  F_DIRENTRY    * de;

+  F_NAME          fsname;

+  unsigned short  date;

+  unsigned short  time;

+  unsigned char   m_mode = F_FILE_CLOSE;

+

+  if ( mode[1] == 0 )

+  {

+    if ( mode[0] == 'r' )

+    {

+      m_mode = F_FILE_RD;

+    }

+

+    if ( mode[0] == 'w' )

+    {

+      m_mode = F_FILE_WR;

+    }

+

+    if ( mode[0] == 'a' )

+    {

+      m_mode = F_FILE_A;

+    }

+  }

+

+  if ( ( mode[1] == '+' ) && ( mode[2] == 0 ) )

+  {

+    if ( mode[0] == 'r' )

+    {

+      m_mode = F_FILE_RDP;

+    }

+

+    if ( mode[0] == 'w' )

+    {

+      m_mode = F_FILE_WRP;

+    }

+

+    if ( mode[0] == 'a' )

+    {

+      m_mode = F_FILE_AP;

+    }

+

+  }

+

+  if ( m_mode == F_FILE_CLOSE )

+  {

+    return 0;                                       /*invalid mode*/

+  }

+

+  if ( _f_setfsname( filename, &fsname ) )

+  {

+    return 0;                                     /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return 0;                                                    /*invalid name*/

+  }

+

+  if ( fsname.filename[0] == '.' )

+  {

+    return 0;

+  }

+

+  if ( _f_getvolume() )

+  {

+    return 0;                     /*cant open any*/

+  }

+

+  if ( gl_file.mode != F_FILE_CLOSE )

+  {

+    return 0;

+  }

+

+  psp_memset( &gl_file, 0, 21 );

+

+  if ( !_f_findpath( &fsname, &gl_file.dirpos ) )

+  {

+    return 0;

+  }

+

+  switch ( m_mode )

+  {

+    case F_FILE_RDP:   /*r*/

+    case F_FILE_RD:   /*r*/

+      if ( !_f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )

+      {

+        return 0;

+      }

+

+      if ( de->attr & F_ATTR_DIR )

+      {

+        return 0;                                      /*directory*/

+      }

+

+      gl_file.startcluster = _f_getdecluster( de );

+

+      if ( gl_file.startcluster )

+      {

+        _f_clustertopos( gl_file.startcluster, &gl_file.pos );

+        gl_file.filesize = _f_getlong( &de->filesize );

+        gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE);

+        if ( _f_fseek( 0 ) )

+        {

+          return 0;

+        }

+      }

+

+#if F_FILE_CHANGED_EVENT

+      if ( m_mode == F_FILE_RDP )

+      {

+        _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );

+      }

+

+#endif

+

+      break;

+

+    case F_FILE_AP:

+    case F_FILE_A: /*a*/

+      psp_memcpy( &( gl_file.pos ), &( gl_file.dirpos ), sizeof( F_POS ) );

+      if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )

+      {

+        if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )

+        {

+          return 0;

+        }

+

+        gl_file.startcluster = _f_getdecluster( de );

+        gl_file.filesize = _f_getlong( &de->filesize );

+

+        if ( gl_file.startcluster )

+        {

+          _f_clustertopos( gl_file.startcluster, &gl_file.pos );

+          gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE);   /*forcing seek to read 1st sector! abspos=0;*/

+          if ( _f_fseek( (long)gl_file.filesize ) )

+          {

+            gl_file.mode = F_FILE_CLOSE;

+            return 0;

+          }

+        }

+      }

+      else

+      {

+        psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );

+        _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );

+

+        if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )

+        {

+          return 0;                                                  /*couldnt be added*/

+        }

+

+        de->attr |= F_ATTR_ARC;         /*set as archiv*/

+        if ( _f_writeglsector( (unsigned long)-1 ) )

+        {

+          return 0;

+        }

+      }

+

+ #if F_FILE_CHANGED_EVENT

+      _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );

+ #endif

+      break;

+

+

+    case F_FILE_WR:  /*w*/

+    case F_FILE_WRP: /*w+*/

+      _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );

+      if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.pos, &de, 0 ) )

+      {

+        unsigned long  cluster = _f_getdecluster( de );    /*exist*/

+

+        if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )

+        {

+          return 0;

+        }

+

+        psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );

+

+        _f_setlong( de->filesize, 0 );  /*reset size;*/

+        de->attr |= F_ATTR_ARC;         /*set as archiv*/

+        _f_setword( de->clusterlo, 0 ); /*no points anywhere*/

+        _f_setword( de->clusterhi, 0 );

+

+        if ( gl_volume.mediatype == F_FAT32_MEDIA )

+        {

+          f_igettimedate( &time, &date );

+          _f_setword( &de->crtdate, date );        /*if there is realtime clock then creation date could be set from*/

+          _f_setword( &de->crttime, time );        /*if there is realtime clock then creation time could be set from*/

+          _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/

+        }

+

+        if ( _f_writeglsector( (unsigned long)-1 ) )

+        {

+          return 0;

+        }

+

+        if ( _f_removechain( cluster ) )

+        {

+          return 0;                                /*remove */

+        }

+      }

+      else

+      {

+        if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )

+        {

+          return 0;                                                  /*couldnt be added*/

+        }

+

+        psp_memset( &gl_file, 0, 21 );

+        de->attr |= F_ATTR_ARC;         /*set as archiv*/

+        if ( _f_writeglsector( (unsigned long)-1 ) )

+        {

+          return 0;

+        }

+      }

+

+ #if F_FILE_CHANGED_EVENT

+      _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );

+ #endif

+

+      break;

+

+    default:

+      return 0;        /*invalid mode*/

+  } /* switch */

+

+  if ( ( m_mode != F_FILE_RD ) && ( gl_file.startcluster == 0 ) )

+  {

+    gl_volume.fatsector = (unsigned long)-1;

+    if ( _f_alloccluster( &( gl_file.startcluster ) ) )

+    {

+      return 0;

+    }

+

+    _f_clustertopos( gl_file.startcluster, &gl_file.pos );

+    if ( _f_setclustervalue( gl_file.startcluster, F_CLUSTER_LAST ) )

+    {

+      return 0;

+    }

+

+    if ( _f_writefatsector() )

+    {

+      return 0;

+    }

+  }

+

+

+  gl_file.mode = m_mode; /* lock it */

+  return (F_FILE *)1;

+} /* fn_open */

+

+

+/****************************************************************************

+ * _f_updatefileentry

+ * Updated a file directory entry or removes the entry

+ * and the fat chain belonging to it.

+ ***************************************************************************/

+static unsigned char _f_updatefileentry ( int remove )

+{

+  F_DIRENTRY    * de;

+  unsigned short  date;

+  unsigned short  time;

+

+  de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * gl_file.dirpos.pos );

+  if ( _f_readglsector( gl_file.dirpos.sector ) || remove )

+  {

+    _f_setdecluster( de, 0 );

+    _f_setlong( &de->filesize, 0 );

+    (void)_f_writeglsector( (unsigned long)-1 );

+    (void)_f_removechain( gl_file.startcluster );

+    return F_ERR_WRITE;

+  }

+

+  _f_setdecluster( de, gl_file.startcluster );

+  _f_setlong( &de->filesize, gl_file.filesize );

+  f_igettimedate( &time, &date );

+  _f_setword( &de->cdate, date );  /*if there is realtime clock then creation date could be set from*/

+  _f_setword( &de->ctime, time );  /*if there is realtime clock then creation time could be set from*/

+  if ( gl_volume.mediatype == F_FAT32_MEDIA )

+  {

+    _f_setword( &de->lastaccessdate, date );  /*if there is realtime clock then creation date could be set from*/

+  }

+

+  return _f_writeglsector( (unsigned long)-1 );

+} /* _f_updatefileentry */

+

+

+/****************************************************************************

+ *

+ * fn_close

+ *

+ * close a previously opened file

+ *

+ * INPUTS

+ *

+ * filehandle - which file needs to be closed

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_close ( F_FILE * f )

+{

+  unsigned char  ret;

+

+#if F_FILE_CHANGED_EVENT

+  unsigned char  mode;

+#endif

+

+  if ( !f )

+  {

+    return F_ERR_NOTOPEN;

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( gl_file.mode == F_FILE_CLOSE )

+  {

+    return F_ERR_NOTOPEN;

+  }

+

+  else if ( gl_file.mode == F_FILE_RD )

+  {

+    gl_file.mode = F_FILE_CLOSE;

+    return F_NO_ERROR;

+  }

+  else

+  {

+ #if F_FILE_CHANGED_EVENT

+    mode = f->mode;

+ #endif

+    gl_file.mode = F_FILE_CLOSE;

+

+    if ( gl_file.modified )

+    {

+      if ( _f_writeglsector( (unsigned long)-1 ) )

+      {

+        (void)_f_updatefileentry( 1 );

+        return F_ERR_WRITE;

+      }

+    }

+

+    ret = _f_updatefileentry( 0 );

+

+ #if F_FILE_CHANGED_EVENT

+    if ( f_filechangedevent && !ret )

+    {

+      ST_FILE_CHANGED  fc;

+      if ( ( mode == F_FILE_WR )  || ( mode == F_FILE_WRP ) )

+      {

+        fc.action = FACTION_ADDED;

+        fc.flags  = FFLAGS_FILE_NAME;

+      }

+      else if ( ( mode == F_FILE_A )  || ( mode == F_FILE_RDP ) )

+      {

+        fc.action = FACTION_MODIFIED;

+        fc.flags  = FFLAGS_FILE_NAME | FFLAGS_SIZE;

+      }

+

+      strcpy( fc.filename, f->filename );

+      if ( f->filename[0] )

+      {

+        f_filechangedevent( &fc );

+      }

+

+      f->filename[0] = '\0';

+    }

+

+ #endif /* if F_FILE_CHANGED_EVENT */

+    return ret;

+  }

+} /* fn_close */

+

+

+/****************************************************************************

+ *

+ * fn_flush

+ *

+ * flush a previously opened file

+ *

+ * INPUTS

+ *

+ * filehandle - which file needs to be closed

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_flush ( F_FILE * f )

+{

+  unsigned char  ret;

+

+  if ( !f )

+  {

+    return F_ERR_NOTOPEN;

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( gl_file.mode == F_FILE_CLOSE )

+  {

+    return F_ERR_NOTOPEN;

+  }

+  else if ( gl_file.mode != F_FILE_RD )

+  {

+    if ( gl_file.modified )

+    {

+      if ( _f_writeglsector( (unsigned long)-1 ) )

+      {

+        (void)_f_updatefileentry( 1 );

+        return F_ERR_WRITE;

+      }

+    }

+

+    return _f_updatefileentry( 0 );

+  }

+

+  return F_NO_ERROR;

+} /* fn_flush */

+

+

+/****************************************************************************

+ *

+ * fn_read

+ *

+ * read data from file

+ *

+ * INPUTS

+ *

+ * buf - where the store data

+ * size - size of items to be read

+ * _size_t - number of items need to be read

+ * filehandle - file where to read from

+ *

+ * RETURNS

+ *

+ * with the number of read bytes

+ *

+ ***************************************************************************/

+long fn_read ( void * buf, long size, long _size_st, F_FILE * f )

+{

+  char * buffer = (char *)buf;

+  long   retsize;

+

+  if ( !f )

+  {

+    return 0;

+  }

+

+  if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )

+  {

+    return 0;

+  }

+

+  retsize = size;

+  size *= _size_st;

+  _size_st = retsize;

+  retsize = 0;

+

+  if ( _f_getvolume() )

+  {

+    return 0;                     /*cant read any*/

+  }

+

+  if ( size + gl_file.relpos + gl_file.abspos >= gl_file.filesize ) /*read len longer than the file*/

+  {

+    size = (long)( ( gl_file.filesize ) - ( gl_file.relpos ) - ( gl_file.abspos ) ); /*calculate new size*/

+  }

+

+  if ( size <= 0 )

+  {

+    return 0;

+  }

+

+  if ( _f_getcurrsector() )

+  {

+    gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/

+    return 0;

+  }

+

+  for( ; ; )

+  {

+    unsigned long  rdsize = (unsigned long)size;

+

+    if ( gl_file.relpos == F_SECTOR_SIZE )

+    {

+      unsigned char  ret;

+

+      gl_file.abspos += gl_file.relpos;

+      gl_file.relpos = 0;

+

+      if ( gl_file.modified )

+      {

+        ret = _f_writeglsector( (unsigned long)-1 );     /*empty write buffer */

+        if ( ret )

+        {

+          gl_file.mode = F_FILE_CLOSE;         /*no more read allowed*/

+          return retsize;

+        }

+      }

+

+      gl_file.pos.sector++;         /*goto next*/

+

+      ret = _f_getcurrsector();

+      if ( ( ret == F_ERR_EOF ) && ( !size ) )

+      {

+        return retsize;

+      }

+

+      if ( ret )

+      {

+        gl_file.mode = F_FILE_CLOSE;       /*no more read allowed*/

+        return retsize;

+      }

+    }

+

+    if ( !size )

+    {

+      break;

+    }

+

+    if ( rdsize >= F_SECTOR_SIZE - gl_file.relpos )

+    {

+      rdsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );

+    }

+

+    psp_memcpy( buffer, gl_sector + gl_file.relpos, rdsize ); /*always less than 512*/

+

+    buffer += rdsize;

+    gl_file.relpos += rdsize;

+    size -= rdsize;

+    retsize += rdsize;

+  }

+

+  return retsize / _size_st;

+} /* fn_read */

+

+

+/****************************************************************************

+ *

+ * fn_write

+ *

+ * write data into file

+ *

+ * INPUTS

+ *

+ * buf - where the store data

+ * size - size of items to be read

+ * size_t - number of items need to be read

+ * filehandle - file where to read from

+ *

+ * RETURNS

+ *

+ * with the number of read bytes

+ *

+ ***************************************************************************/

+

+long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )

+{

+  char * buffer = (char *)buf;

+  long   retsize;

+  long   ret = 0;

+

+  if ( !f )

+  {

+    return 0;

+  }

+

+  if ( ( gl_file.mode & ( F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )

+  {

+    return 0;

+  }

+

+  retsize = size;

+  size *= _size_st;

+  _size_st = retsize;

+  retsize = 0;

+

+  if ( _f_getvolume() )

+  {

+    return 0;                     /*can't write*/

+  }

+

+  if ( ( gl_file.mode ) & ( F_FILE_A | F_FILE_AP ) )

+  {

+    if ( _f_fseek( (long)gl_file.filesize ) )

+    {

+      gl_file.mode = F_FILE_CLOSE;

+      return 0;

+    }

+  }

+

+  if ( _f_getcurrsector() )

+  {

+    gl_file.mode = F_FILE_CLOSE;

+    return 0;

+  }

+

+  for( ; ; )

+  {

+    unsigned long  wrsize = (unsigned long)size;

+

+    if ( gl_file.relpos == F_SECTOR_SIZE )

+    {     /*now full*/

+      if ( gl_file.modified )

+      {

+        if ( _f_emptywritebuffer() )

+        {

+          gl_file.mode = F_FILE_CLOSE;

+          if ( _f_updatefileentry( 0 ) == 0 )

+          {

+            return retsize;

+          }

+          else

+          {

+            return 0;

+          }

+        }

+      }

+      else

+      {

+        gl_file.pos.sector++;       /*goto next*/

+      }

+

+      gl_file.abspos += gl_file.relpos;

+      gl_file.relpos = 0;

+

+      if ( wrsize && ( wrsize < F_SECTOR_SIZE ) )

+      {

+        ret = _f_getcurrsector();

+

+        if ( ret )

+        {

+          if ( ret != F_ERR_EOF )

+          {

+            gl_file.mode = F_FILE_CLOSE;       /*no more read allowed*/

+            return retsize;

+          }

+        }

+      }

+    }

+

+    if ( !size )

+    {

+      break;

+    }

+

+    if ( wrsize >= F_SECTOR_SIZE - gl_file.relpos )

+    {

+      wrsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );

+    }

+

+

+    psp_memcpy( gl_sector + gl_file.relpos, buffer, wrsize );

+    gl_file.modified = 1;    /*sector is modified*/

+

+    buffer += wrsize;

+    gl_file.relpos += wrsize;

+    size -= wrsize;

+    retsize += wrsize;

+

+    if ( gl_file.filesize < gl_file.abspos + gl_file.relpos )

+    {

+      gl_file.filesize = gl_file.abspos + gl_file.relpos;

+    }

+  }

+

+  return retsize / _size_st;

+} /* fn_write */

+

+

+

+/****************************************************************************

+ *

+ * fn_seek

+ *

+ * moves position into given offset in given file

+ *

+ * INPUTS

+ *

+ * filehandle - F_FILE structure which file position needed to be modified

+ * offset - relative position

+ * whence - where to calculate position (F_SEEK_SET,F_SEEK_CUR,F_SEEK_END)

+ *

+ * RETURNS

+ *

+ * 0 - if successfully

+ * other - if any error

+ *

+ ***************************************************************************/

+

+

+unsigned char fn_seek ( F_FILE * f, long offset, unsigned char whence )

+{

+  unsigned char  ret;

+

+  if ( !f )

+  {

+    return F_ERR_NOTOPEN;

+  }

+

+  if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )

+  {

+    return F_ERR_NOTOPEN;

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( whence == F_SEEK_CUR )

+  {

+    return _f_fseek( (long)( gl_file.abspos + gl_file.relpos + offset ) );

+  }

+  else if ( whence == F_SEEK_END )

+  {

+    return _f_fseek( (long)( gl_file.filesize + offset ) );

+  }

+  else if ( whence == F_SEEK_SET )

+  {

+    return _f_fseek( offset );

+  }

+

+  return F_ERR_NOTUSEABLE;

+} /* fn_seek */

+

+

+

+/****************************************************************************

+ *

+ * fn_tell

+ *

+ * Tells the current position of opened file

+ *

+ * INPUTS

+ *

+ * filehandle - which file needs the position

+ *

+ * RETURNS

+ *

+ * position in the file from start

+ *

+ ***************************************************************************/

+

+long fn_tell ( F_FILE * f )

+{

+  if ( !f )

+  {

+    return 0;

+  }

+

+  if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )

+  {

+    return 0;

+  }

+

+  return (long)( gl_file.abspos + gl_file.relpos );

+}

+

+

+

+/****************************************************************************

+ *

+ * fn_eof

+ *

+ * Tells if the current position is end of file or not

+ *

+ * INPUTS

+ *

+ * filehandle - which file needs the checking

+ *

+ * RETURNS

+ *

+ * 0 - if not EOF

+ * other - if EOF or invalid file handle

+ *

+ ***************************************************************************/

+

+unsigned char fn_eof ( F_FILE * f )

+{

+  if ( !f )

+  {

+    return F_ERR_NOTOPEN;          /*if error*/

+  }

+

+  if ( gl_file.abspos + gl_file.relpos < gl_file.filesize )

+  {

+    return 0;

+  }

+

+  return F_ERR_EOF;  /*EOF*/

+}

+

+

+

+

+/****************************************************************************

+ *

+ * fn_rewind

+ *

+ * set the fileposition in the opened file to the begining

+ *

+ * INPUTS

+ *

+ * filehandle - which file needs to be rewinded

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+

+unsigned char fn_rewind ( F_FILE * filehandle )

+{

+  return fn_seek( filehandle, 0L, F_SEEK_SET );

+}

+

+

+

+/****************************************************************************

+ *

+ * fn_putc

+ *

+ * write a character into file

+ *

+ * INPUTS

+ *

+ * ch - what to write into file

+ * filehandle - file where to write

+ *

+ * RETURNS

+ *

+ * with the number of written bytes (1-success, 0-not successfully)

+ *

+ ***************************************************************************/

+

+int fn_putc ( int ch, F_FILE * filehandle )

+{

+  unsigned char  tmpch = (unsigned char)ch;

+

+  if ( fn_write( &tmpch, 1, 1, filehandle ) )

+  {

+    return ch;

+  }

+  else

+  {

+    return -1;

+  }

+}

+

+

+

+/****************************************************************************

+ *

+ * fn_getc

+ *

+ * get a character from file

+ *

+ * INPUTS

+ *

+ * filehandle - file where to read from

+ *

+ * RETURNS

+ *

+ * with the read character or -1 if read was not successfully

+ *

+ ***************************************************************************/

+int fn_getc ( F_FILE * filehandle )

+{

+  unsigned char  ch;

+

+  if ( !fn_read( &ch, 1, 1, filehandle ) )

+  {

+    return -1;

+  }

+

+  return (int)ch;

+}

+

+

+

+/****************************************************************************

+ *

+ * fn_delete

+ *

+ * delete a file

+ *

+ * INPUTS

+ *

+ * filename - file which wanted to be deleted (with or without path)

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_delete ( const char * filename )

+{

+  F_POS          pos;

+  F_DIRENTRY   * de;

+  F_NAME         fsname;

+  unsigned char  ret;

+

+  if ( _f_setfsname( filename, &fsname ) )

+  {

+    return F_ERR_INVALIDNAME;                                     /*invalid name*/

+  }

+

+  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )

+  {

+    return F_ERR_INVALIDNAME;                                                    /*invalid name*/

+  }

+

+  if ( fsname.filename[0] == '.' )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( !( _f_findpath( &fsname, &pos ) ) )

+  {

+    return F_ERR_INVALIDDIR;

+  }

+

+  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )

+  {

+    return F_ERR_NOTFOUND;

+  }

+

+  if ( de->attr & F_ATTR_DIR )

+  {

+    return F_ERR_INVALIDDIR;                                /*directory*/

+  }

+

+  if ( de->attr & F_ATTR_READONLY )

+  {

+    return F_ERR_ACCESSDENIED;                                      /*readonly*/

+  }

+

+  if ( ( gl_file.mode != F_FILE_CLOSE ) && ( gl_file.dirpos.sector == pos.sector ) && ( gl_file.dirpos.pos == pos.pos ) )

+  {

+    return F_ERR_LOCKED;

+  }

+

+  de->name[0] = (unsigned char)0xe5; /*removes it*/

+  ret = _f_writeglsector( (unsigned long)-1 );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  ret = _f_removechain( _f_getdecluster( de ) );

+

+ #if F_FILE_CHANGED_EVENT

+  if ( f_filechangedevent && !ret )

+  {

+    ST_FILE_CHANGED  fc;

+    fc.action = FACTION_REMOVED;

+    fc.flags = FFLAGS_FILE_NAME;

+

+    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )

+    {

+      f_filechangedevent( &fc );

+    }

+  }

+

+ #endif

+

+  return ret;

+} /* fn_delete */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_seteof

+ *

+ * Set end of file

+ *

+ * INPUT:	f - file pointer

+ *		filesize - required new size

+ * RETURN:	F_NO_ERROR - on success

+ *		other if error

+ *

+ ***************************************************************************/

+unsigned char _f_seteof ( F_FILE * f, long filesize )

+{

+  unsigned char  rc = F_NO_ERROR;

+

+  if ( !f )

+  {

+    return F_ERR_NOTOPEN;        /*if error*/

+  }

+

+  if ( ( unsigned long) filesize < gl_file.filesize )

+  {

+    rc = _f_fseek( filesize );

+    if ( rc == F_NO_ERROR )

+    {

+      unsigned long  cluster;

+      rc = _f_getclustervalue( gl_file.pos.cluster, &cluster );

+      if ( rc == F_NO_ERROR )

+      {

+        if ( cluster != F_CLUSTER_LAST )

+        {

+          rc = _f_removechain( cluster );

+          if ( rc )

+          {

+            return rc;

+          }

+

+          rc = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );

+          if ( rc )

+          {

+            return rc;

+          }

+

+          rc = _f_writefatsector();

+          if ( rc )

+          {

+            return rc;

+          }

+        }

+

+        gl_file.filesize = (unsigned long)filesize;

+      }

+    }

+  }

+  else if ( (unsigned long) filesize > gl_file.filesize )

+  {

+    rc = _f_fseek( filesize );

+  }

+

+  return rc;

+} /* _f_seteof */

+

+

+/****************************************************************************

+ *

+ * fn_seteof

+ *

+ * Set end of file

+ *

+ * INPUT:	f - file pointer

+ *		filesize - required new size

+ * RETURN:	F_NO_ERROR - on success

+ *		other if error

+ *

+ ***************************************************************************/

+unsigned char fn_seteof ( F_FILE * f )

+{

+  unsigned char  rc = F_NO_ERROR;

+

+  rc = _f_seteof( f, ( gl_file.abspos + gl_file.relpos ) );

+

+  return rc;

+} /* fn_seteof */

+

+

+

+

+/****************************************************************************

+ *

+ * fn_truncate

+ *

+ * Open a file and set end of file

+ *

+ * INPUT:	filename - name of the file

+ *		filesize - required new size

+ * RETURN:	NULL on error, otherwise file pointer

+ *

+ ***************************************************************************/

+F_FILE * fn_truncate ( const char * filename, long filesize )

+{

+  F_FILE       * f = fn_open( filename, "r+" );

+  unsigned char  rc;

+

+  if ( f != NULL )

+  {

+    rc = _f_fseek( (long)gl_file.filesize );

+    if ( rc == F_NO_ERROR )

+    {

+      rc = _f_seteof( f, filesize );

+    }

+

+    if ( rc )

+    {

+      fn_close( f );

+      f = NULL;

+    }

+  }

+

+  return f;

+} /* fn_truncate */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h
new file mode 100644
index 0000000..a124d07
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h
@@ -0,0 +1,63 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __FILE_H

+#define __FILE_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+#define F_FILE_CLOSE 0x00

+#define F_FILE_RD    0x01

+#define F_FILE_WR    0x02

+#define F_FILE_A     0x04

+#define F_FILE_RDP   0x08

+#define F_FILE_WRP   0x10

+#define F_FILE_AP    0x20

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __FILE_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c
new file mode 100644
index 0000000..590aecf
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c
@@ -0,0 +1,320 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+#include "../../psp/include/psp_rtc.h"

+#include "dir.h"

+

+#include "util.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+

+/****************************************************************************

+ *

+ * _f_getword

+ *

+ * get a word 16bit number from a memory (it uses LITTLE ENDIAN mode always)

+ *

+ * INPUTS

+ *

+ * ptr - pointer where data is

+ *

+ * RETURNS

+ *

+ * word number

+ *

+ ***************************************************************************/

+unsigned short _f_getword ( void * ptr )

+{

+  unsigned char * sptr = (unsigned char *)ptr;

+  unsigned short  ret;

+

+  ret = (unsigned short)( sptr[1] & 0xff );

+  ret <<= 8;

+  ret |= ( sptr[0] & 0xff );

+  return ret;

+}

+

+

+/****************************************************************************

+ *

+ * _f_setword

+ *

+ * set a word 16bit number into a memory (it uses LITTLE ENDIAN mode always)

+ *

+ * INPUTS

+ *

+ * ptr - where to store data

+ * num - 16 bit number to store

+ *

+ ***************************************************************************/

+void _f_setword ( void * ptr, unsigned short num )

+{

+  unsigned char * sptr = (unsigned char *)ptr;

+

+  sptr[1] = (unsigned char)( num >> 8 );

+  sptr[0] = (unsigned char)( num );

+}

+

+

+/****************************************************************************

+ *

+ * _f_getlong

+ *

+ * get a long 32bit number from a memory (it uses LITTLE ENDIAN mode always)

+ *

+ * INPUTS

+ *

+ * ptr - pointer where data is

+ *

+ * RETURNS

+ *

+ * long number

+ *

+ ***************************************************************************/

+unsigned long _f_getlong ( void * ptr )

+{

+  unsigned char * sptr = (unsigned char *)ptr;

+  unsigned long   ret;

+

+  ret = (unsigned long)( sptr[3] & 0xff );

+  ret <<= 8;

+  ret |= ( sptr[2] & 0xff );

+  ret <<= 8;

+  ret |= ( sptr[1] & 0xff );

+  ret <<= 8;

+  ret |= ( sptr[0] & 0xff );

+  return ret;

+}

+

+

+/****************************************************************************

+ *

+ * _f_setlong

+ *

+ * set a long 32bit number into a memory (it uses LITTLE ENDIAN mode always)

+ *

+ * INPUTS

+ *

+ * ptr - where to store data

+ * num - 32 bit number to store

+ *

+ ***************************************************************************/

+void _f_setlong ( void * ptr, unsigned long num )

+{

+  unsigned char * sptr = (unsigned char *)ptr;

+

+  sptr[3] = (unsigned char)( num >> 24 );

+  sptr[2] = (unsigned char)( num >> 16 );

+  sptr[1] = (unsigned char)( num >> 8 );

+  sptr[0] = (unsigned char)( num );

+}

+

+

+/****************************************************************************

+ *

+ * _setcharzero

+ *

+ * fills with zero charater to memory

+ *

+ * INPUTS

+ *

+ * num - number of characters

+ * ptr - where to store data

+ *

+ * RETURNS

+ *

+ * last write position

+ *

+ ***************************************************************************/

+unsigned char * _setcharzero ( int num, unsigned char * ptr )

+{

+  while ( num-- )

+  {

+    *ptr++ = 0;

+  }

+

+  return ptr;

+}

+

+

+/****************************************************************************

+ *

+ * _setchar

+ *

+ * copy a charater string to memory

+ *

+ * INPUTS

+ *

+ * array - original code what to copy

+ * num - number of characters

+ * ptr - where to store data

+ *

+ * RETURNS

+ *

+ * last write position

+ *

+ ***************************************************************************/

+unsigned char * _setchar ( const unsigned char * array, int num, unsigned char * ptr )

+{

+  if ( !array )

+  {

+    return _setcharzero( num, ptr );

+  }

+

+  while ( num-- )

+  {

+    *ptr++ = *array++;

+  }

+

+  return ptr;

+}

+

+

+/****************************************************************************

+ *

+ * _setword

+ *

+ * store a 16bit word into memory

+ *

+ * INPUTS

+ *

+ * num - 16bit number to store

+ * ptr - where to store data

+ *

+ * RETURNS

+ *

+ * last write position

+ *

+ ***************************************************************************/

+unsigned char * _setword ( unsigned short num, unsigned char * ptr )

+{

+  _f_setword( ptr, num );

+  return ptr + 2;

+}

+

+

+/****************************************************************************

+ *

+ * _setlong

+ *

+ * store a 32bit long number into memory

+ *

+ * INPUTS

+ *

+ * num - 32bit number to store

+ * ptr - where to store data

+ *

+ * RETURNS

+ *

+ * last write position

+ *

+ ***************************************************************************/

+unsigned char * _setlong ( unsigned long num, unsigned char * ptr )

+{

+  _f_setlong( ptr, num );

+  return ptr + 4;

+}

+

+

+/****************************************************************************

+ *

+ * _f_toupper

+ *

+ * convert a string into lower case

+ *

+ * INPUTS

+ *

+ * s - input string to convert

+ *

+ ***************************************************************************/

+char _f_toupper ( char ch )

+{

+  if ( ( ch >= 'a' ) && ( ch <= 'z' ) )

+  {

+    return (char)( ch - 'a' + 'A' );

+  }

+

+  return ch;

+}

+

+

+/****************************************************************************

+ *

+ * f_igettimedate

+ *

+ * INPUTS

+ *    time - pointer to time variable

+ *    date - pointer to date variable

+ * OUTPUTS

+ *    time - current time

+ *    date - current date

+ *

+ * RETURNS

+ *    none

+ *

+ ***************************************************************************/

+void f_igettimedate ( unsigned short * time, unsigned short * date )

+{

+  t_psp_timedate  s_timedate;

+

+  psp_getcurrenttimedate( &s_timedate );

+

+  *time = ( ( (uint16_t)s_timedate.hour << F_CTIME_HOUR_SHIFT ) & F_CTIME_HOUR_MASK )

+          | ( ( (uint16_t)s_timedate.min << F_CTIME_MIN_SHIFT )  & F_CTIME_MIN_MASK )

+          | ( ( ( (uint16_t)s_timedate.sec >> 1 ) << F_CTIME_SEC_SHIFT )  & F_CTIME_SEC_MASK );

+

+  *date = ( ( ( s_timedate.year - 1980 ) << F_CDATE_YEAR_SHIFT ) & F_CDATE_YEAR_MASK )

+          | ( ( (uint16_t)s_timedate.month << F_CDATE_MONTH_SHIFT ) & F_CDATE_MONTH_MASK )

+          | ( ( (uint16_t)s_timedate.day << F_CDATE_DAY_SHIFT ) & F_CDATE_DAY_MASK );

+

+  return;

+}

+

+

+

+

+

+

+

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h
new file mode 100644
index 0000000..9d23665
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h
@@ -0,0 +1,73 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __UTIL_H

+#define __UTIL_H

+

+#include "util_sfn.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+void f_igettimedate ( unsigned short * time, unsigned short * date );

+

+unsigned short _f_getword ( void * );

+unsigned long _f_getlong ( void * );

+char _f_toupper ( char );

+void _f_memset ( void *, unsigned char, int );

+void _f_memcpy ( void *, void *, int );

+

+void _f_setword ( void *, unsigned short );

+void _f_setlong ( void *, unsigned long );

+unsigned char * _setcharzero ( int, unsigned char * );

+unsigned char * _setchar ( const unsigned char *, int, unsigned char * );

+unsigned char * _setword ( unsigned short, unsigned char * );

+unsigned char * _setlong ( unsigned long, unsigned char * );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __UTIL_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c
new file mode 100644
index 0000000..1ddbee1
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c
@@ -0,0 +1,540 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+

+#include "util.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+

+

+/****************************************************************************

+ *

+ * _f_checknameprim

+ *

+ * checking a string if could be valid

+ *

+ * INPUTS

+ *

+ * ptr - pointer to name or extension

+ * len - number max char of name or extension

+ *

+ * RETURNS

+ *

+ ***************************************************************************/

+static unsigned char _f_checknameprim ( char * ptr, unsigned char len )

+{

+  unsigned char  inspace = 0;

+

+  while ( len-- )

+  {

+    char  ch = *ptr++;

+    if ( !inspace )

+    {

+      if ( ch == ' ' )

+      {

+        inspace = 1;

+      }

+

+      if ( ( ch == '|' ) || ( ch == '[' ) || ( ch == ']' ) || ( ch == '<' ) || ( ch == '>' ) || ( ch == '/' ) || ( ch == '\\' ) || ( ch == ':' ) )

+      {

+        return 1;

+      }

+    }

+    else if ( ch != ' ' )

+    {

+      return 1;                     /*no inspace allowed*/

+    }

+  }

+

+  return 0;

+} /* _f_checknameprim */

+

+

+/****************************************************************************

+ *

+ * _f_checkname

+ *

+ * checking filename and extension for special characters

+ *

+ * INPUTS

+ *

+ * name - filename (e.g.: filename)

+ * ext - extension of file (e.g.: txt)

+ *

+ * RETURNS

+ *

+ * 0 - if no contains invalid character

+ * other - if contains any invalid character

+ *

+ ***************************************************************************/

+unsigned char _f_checkname ( char * name, char * ext )

+{

+  if ( _f_checknameprim( name, F_MAXNAME ) )

+  {

+    return 1;

+  }

+

+  if ( _f_checknameprim( ext, F_MAXEXT ) )

+  {

+    return 1;

+  }

+

+  return 0;

+}

+

+

+/****************************************************************************

+ *

+ * _f_checknamewc

+ *

+ * checking filename and extension for wildcard character

+ *

+ * INPUTS

+ *

+ * name - filename (e.g.: filename)

+ * ext - extension of file (e.g.: txt)

+ *

+ * RETURNS

+ *

+ * 0 - if no contains wildcard character (? or *)

+ * other - if contains any wildcard character

+ *

+ ***************************************************************************/

+unsigned char _f_checknamewc ( const char * name, const char * ext )

+{

+  unsigned char  a = 0;

+

+  for ( a = 0 ; a < F_MAXNAME ; a++ )

+  {

+    char  ch = name[a];

+    if ( ( ch == '?' ) || ( ch == '*' ) )

+    {

+      return 1;

+    }

+  }

+

+  for ( a = 0 ; a < F_MAXEXT ; a++ )

+  {

+    char  ch = ext[a];

+    if ( ( ch == '?' ) || ( ch == '*' ) )

+    {

+      return 1;

+    }

+  }

+

+  return _f_checkname( (char *)name, (char *)ext );

+} /* _f_checknamewc */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_setnameext

+ *

+ * convert a string into filename and extension separatelly, the terminator

+ * character could be zero char, '/' or '\'

+ *

+ * INPUTS

+ *

+ * s - source string (e.g.: hello.txt)

+ * name - where to store name (this array size has to be F_MAXNAME (8))

+ * ext - where to store extension (this array size has to be F_MAXEXT (3))

+ *

+ * RETURNS

+ *

+ * length of the used bytes from source string array

+ *

+ ***************************************************************************/

+unsigned char _f_setnameext ( char * s, char * name, char * ext )

+{

+  unsigned char  len, extlen = 0;

+  unsigned char  a;

+  unsigned char  setext = 1;

+

+  for ( len = 0 ; ; )

+  {

+    unsigned char  ch = s[len];

+    if ( ( ch == 0 ) || ( ch == '\\' ) || ( ch == '/' ) )

+    {

+      break;

+    }

+

+    len++;                      /*calculate len*/

+  }

+

+  if ( len && ( s[0] == '.' ) )

+  {

+/*		if (len==1 || (s[1]=='.' && len==2)) goto dots;		*/

+    if ( ( len == 1 ) || ( s[1] == '.' ) )

+    {

+      goto dots;

+    }

+  }

+

+  for ( a = len ; a ; a-- )

+  {

+    if ( s[a - 1] == '.' )

+    {

+      unsigned char  b;

+

+      extlen = (unsigned char)( len - a + 1 );

+      len = (unsigned char)( a - 1 );

+

+      for ( b = 0 ; b < F_MAXEXT ; b++ )

+      {

+        if ( b < extlen - 1 )

+        {

+          ext[b] = _f_toupper( s[a++] );

+        }

+        else

+        {

+          ext[b] = ' ';

+        }

+      }

+

+      setext = 0;

+      break;

+    }

+  }

+

+dots:

+  if ( setext )

+  {

+    for ( a = 0 ; a < F_MAXEXT ; a++ )

+    {

+      ext[a] = ' ';

+    }

+  }

+

+  for ( a = 0 ; a < F_MAXNAME ; a++ )

+  {

+    if ( a < len )

+    {

+      name[a] = _f_toupper( s[a] );

+    }

+    else

+    {

+      name[a] = ' ';

+    }

+  }

+

+  return (unsigned char)( len + extlen );

+} /* _f_setnameext */

+

+

+

+/****************************************************************************

+ *

+ * _f_setfsname

+ *

+ * convert a single string into F_NAME structure

+ *

+ * INPUTS

+ *

+ * name - combined name with drive,path,filename,extension used for source

+ * fsname - where to fill this structure with separated drive,path,name,ext

+ *

+ * RETURNS

+ *

+ * 0 - if successfully

+ * other - if name contains invalid path or name

+ *

+ ***************************************************************************/

+unsigned char _f_setfsname ( const char * name, F_NAME * fsname )

+{

+  char           s[F_MAXPATH];

+  unsigned char  namepos = 0;

+

+  unsigned char  pathpos = 0;

+  unsigned char  a;

+

+  s[0] = 0;

+

+  if ( !name[0] )

+  {

+    return 1;               /*no name*/

+  }

+

+  if ( name[1] == ':' )

+  {

+    name += 2;

+  }

+

+  if ( ( name[0] != '/' ) && ( name[0] != '\\' ) )

+  {

+    if ( fn_getcwd( fsname->path, F_MAXPATH, 0 ) )

+    {

+      return 1;                                            /*error*/

+    }

+

+    for ( pathpos = 0 ; fsname->path[pathpos] ; )

+    {

+      pathpos++;

+    }

+  }

+

+

+  for ( ; ; )

+  {

+    char  ch = _f_toupper( *name++ );

+

+    if ( !ch )

+    {

+      break;

+    }

+

+    if ( ch == ':' )

+    {

+      return 1;                /*not allowed*/

+    }

+

+    if ( ( ch == '/' ) || ( ch == '\\' ) )

+    {

+      if ( pathpos )

+      {

+        if ( fsname->path[pathpos - 1] == '/' )

+        {

+          return 1;                                         /*not allowed double */

+        }

+

+        if ( pathpos >= F_MAXPATH - 2 )

+        {

+          return 1;                                 /*path too long*/

+        }

+

+        fsname->path[pathpos++] = '/';

+      }

+

+      for ( ; namepos ; )

+      {

+        if ( s[namepos - 1] != ' ' )

+        {

+          break;

+        }

+

+        namepos--;                /*remove end spaces*/

+      }

+

+      for ( a = 0 ; a < namepos ; a++ )

+      {

+        if ( pathpos >= F_MAXPATH - 2 )

+        {

+          return 1;                                 /*path too long*/

+        }

+

+        fsname->path[pathpos++] = s[a];

+      }

+

+      namepos = 0;

+      continue;

+    }

+

+    if ( ( ch == ' ' ) && ( !namepos ) )

+    {

+      continue;                              /*remove start spaces*/

+    }

+

+    if ( namepos >= ( sizeof( s ) - 2 ) )

+    {

+      return 1;                               /*name too long*/

+    }

+

+    s[namepos++] = ch;

+  }

+

+  s[namepos] = 0; /*terminates it*/

+  fsname->path[pathpos] = 0;  /*terminates it*/

+

+  for ( ; namepos ; )

+  {

+    if ( s[namepos - 1] != ' ' )

+    {

+      break;

+    }

+

+    s[namepos - 1] = 0; /*remove end spaces*/

+    namepos--;

+  }

+

+  if ( !_f_setnameext( s, fsname->filename, fsname->fileext ) )

+  {

+    return 2;                                                         /*no name*/

+  }

+

+  if ( fsname->filename[0] == ' ' )

+  {

+    return 1;                               /*cannot be*/

+  }

+

+  return 0;

+} /* _f_setfsname */

+

+

+/****************************************************************************

+ *

+ * _f_createfullname

+ *

+ * create full name

+ *

+ * INPUTS

+ *

+ * buffer - where to create

+ * buffersize - size of the buffer

+ * drivenum - drive number

+ * path - path of the file

+ * filename - file name

+ * fileext - file extension

+ *

+ * RETURNS

+ *

+ * 1 - if found and osize is filled

+ * 0 - not found

+ *

+ ***************************************************************************/

+int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext )

+{

+  char * fullname = buffer;

+  int    a;

+

+  /* adding drive letter */

+  if ( buffersize < 1 )

+  {

+    return 1;

+  }

+

+  *fullname++ = '/';

+  buffersize -= 1;

+

+  /* adding path */

+  if ( path[0] )

+  {

+    for ( ; ; )

+    {

+      char  ch = *path++;

+

+      if ( !ch )

+      {

+        break;

+      }

+

+      if ( buffersize <= 0 )

+      {

+        return 1;

+      }

+

+      *fullname++ = ch;

+      buffersize--;

+    }

+

+    /* adding separator */

+    if ( buffersize <= 0 )

+    {

+      return 1;

+    }

+

+    *fullname++ = '/';

+  }

+

+  /* adding name */

+  for ( a = 0 ; a < F_MAXNAME ; a++ )

+  {

+    char  ch = *filename++;

+

+    if ( ( !ch ) || ( ch == 32 ) )

+    {

+      break;

+    }

+

+    if ( buffersize <= 0 )

+    {

+      return 1;

+    }

+

+    *fullname++ = ch;

+    buffersize--;

+  }

+

+  /* adding ext*/

+  if ( fileext[0] && ( fileext[0] != 32 ) )

+  {

+    /* adding dot */

+    if ( !buffersize )

+    {

+      return 1;

+    }

+

+    *fullname++ = '.';

+

+    for ( a = 0 ; a < F_MAXEXT ; a++ )

+    {

+      char  ch = *fileext++;

+

+      if ( ( !ch ) || ( ch == 32 ) )

+      {

+        break;

+      }

+

+      if ( buffersize <= 0 )

+      {

+        return 1;

+      }

+

+      *fullname++ = ch;

+      buffersize--;

+    }

+  }

+

+  /* adding terminator */

+  if ( buffersize <= 0 )

+  {

+    return 1;

+  }

+

+  *fullname++ = 0;

+

+  return 0;

+} /* _f_createfullname */

+

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h
new file mode 100644
index 0000000..8e9751a
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h
@@ -0,0 +1,62 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __UTIL_SFN_H

+#define __UTIL_SFN_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+unsigned char _f_checknamewc ( const char *, const char * );

+unsigned char _f_checkname ( char *, char * );

+

+unsigned char _f_setnameext ( char *, char *, char * );

+unsigned char _f_setfsname ( const char *, F_NAME * );

+int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __UTIL_SFN_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c
new file mode 100644
index 0000000..2260983
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c
@@ -0,0 +1,939 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/fat_sl.h"

+#include "../../psp/include/psp_string.h"

+

+#include "volume.h"

+#include "util.h"

+#include "drv.h"

+#include "fat.h"

+#include "dir.h"

+#include "file.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#if F_FS_THREAD_AWARE == 1

+  #include "f_lock.h"

+#endif

+

+F_VOLUME  gl_volume;                /* only one volume */

+F_FILE    gl_file;                  /* file */

+char      gl_sector[F_SECTOR_SIZE]; /* actual sector */

+

+#if F_FILE_CHANGED_EVENT

+F_FILE_CHANGED_EVENTFUNC  f_filechangedevent;

+#endif

+

+

+/* Defines the number of sectors per cluster on a sector number basis */

+typedef struct

+{

+  unsigned long  max_sectors;

+  unsigned char  sector_per_cluster;

+} t_FAT32_CS;

+

+static const t_FAT32_CS  FAT32_CS[] =

+{

+  { 0x00020000, 1 }     /* ->64MB */

+  , { 0x00040000, 2 }   /* ->128MB */

+  , { 0x00080000, 4 }   /* ->256MB */

+  , { 0x01000000, 8 }   /* ->8GB */

+  , { 0x02000000, 16 }  /* ->16GB */

+  , { 0x0ffffff0, 32 }  /* -> ... */

+};

+

+

+/****************************************************************************

+ *

+ * _f_writebootrecord

+ *

+ * writing boot record onto a volume, it uses number of hidden sector variable

+ *

+ * INPUTS

+ * phy - media physical descriptor

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static unsigned char _f_writebootrecord ( F_PHY * phy )

+{

+  unsigned char   jump_code[] =

+  {

+    0xeb, 0x3c, 0x90

+  };

+  unsigned char   oem_name[] = "MSDOS5.0";

+  unsigned char   executable_marker[] =

+  {

+    0x55, 0xaa

+  };

+  unsigned char * ptr = (unsigned char *)gl_sector;

+  unsigned char   rs;

+  unsigned short  mre;

+

+  unsigned char  ret;

+  unsigned char  _n = 0;

+

+  if ( gl_volume.mediatype == F_FAT32_MEDIA )

+  {  /*write FS_INFO*/

+    unsigned char  a;

+

+    rs = 32 + 4;

+    mre = 0;

+

+    psp_memset( ptr, 0, F_SECTOR_SIZE );

+

+    for ( a = 0 ; a < rs ; a++ )

+    {

+      ret = _f_writeglsector( a ); /*erase reserved area*/

+      if ( ret )

+      {

+        return ret;

+      }

+    }

+

+    ptr = _setlong( 0x41615252, ptr ); /*signature*/

+    ptr = _setcharzero( 480, ptr );    /*reserved*/

+    ptr = _setlong( 0x61417272, ptr ); /*signature*/

+    ptr = _setlong( 0xffffffff, ptr ); /*no last*/

+    ptr = _setlong( 0xffffffff, ptr ); /*no hint*/

+    ptr = _setcharzero( 12, ptr );     /*reserved*/

+    ptr = _setlong( 0xaa550000, ptr ); /*trail*/

+

+

+    ret = _f_writeglsector( 1 ); /*write FSINFO*/

+    if ( ret )

+    {

+      return ret;

+    }

+

+    ret = _f_writeglsector( 1 + 6 ); /*write FSINFO*/

+    if ( ret )

+    {

+      return ret;

+    }

+  }

+  else

+  {

+    rs = 1;

+    mre = 512;

+  }

+

+  ptr = (unsigned char *)gl_sector;

+  ptr = _setchar( jump_code, sizeof( jump_code ), ptr );

+  ptr = _setchar( oem_name, sizeof( oem_name ) - 1, ptr );

+  ptr = _setword( F_SECTOR_SIZE, ptr );

+  *ptr++ = gl_volume.bootrecord.sector_per_cluster;

+  ptr = _setword( rs, ptr );  /* reserved sectors */

+  *ptr++ = 2;                 /* number of FATs */

+  ptr = _setword( mre, ptr ); /* max root entry */

+  if ( phy->number_of_sectors < 0x10000 )

+  {

+    ptr = _setword( (unsigned short)phy->number_of_sectors, ptr );

+  }

+  else

+  {

+    ptr = _setword( 0, ptr );

+  }

+

+  *ptr++ = 0xf0;                /* media descriptor */

+  ptr = _setword( (unsigned short)gl_volume.bootrecord.sector_per_FAT, ptr );

+  ptr = _setword( phy->sector_per_track, ptr );

+  ptr = _setword( phy->number_of_heads, ptr );

+  ptr = _setlong( 0, ptr ); /* number of hidden sectors */

+  if ( phy->number_of_sectors >= 0x10000 )

+  {

+    ptr = _setlong( phy->number_of_sectors, ptr );

+  }

+  else

+  {

+    ptr = _setlong( 0, ptr );                                       /* number of sectors */

+  }

+

+  if ( gl_volume.mediatype == F_FAT32_MEDIA )

+  {

+    ptr = _setlong( gl_volume.bootrecord.sector_per_FAT32, ptr );

+    ptr = _setword( 0, ptr );

+    ptr = _setword( 0, ptr );

+    ptr = _setlong( 2, ptr );

+    ptr = _setword( 1, ptr );

+    ptr = _setword( 6, ptr );

+    ptr = _setchar( NULL, 12, ptr );

+    _n = 28;

+  }

+

+

+  ptr = _setword( 0, ptr ); /* logical drive num */

+  *ptr++ = 0x29;            /* extended signature */

+  ptr = _setlong( 0x11223344, ptr );

+  ptr = _setchar( (const unsigned char *)"NO NAME    ", 11, ptr ); /* volume name */

+

+  switch ( gl_volume.mediatype )

+  {

+    case F_FAT12_MEDIA:

+      ptr = _setchar( (const unsigned char *)"FAT12   ", 8, ptr );

+      break;

+

+    case F_FAT16_MEDIA:

+      ptr = _setchar( (const unsigned char *)"FAT16   ", 8, ptr );

+      break;

+

+    case F_FAT32_MEDIA:

+      ptr = _setchar( (const unsigned char *)"FAT32   ", 8, ptr );

+      break;

+

+    default:

+      return F_ERR_INVALIDMEDIA;

+  } /* switch */

+

+  ptr = _setchar( 0, 448 - _n, ptr );

+  ptr = _setchar( executable_marker, sizeof( executable_marker ), ptr );

+

+  if ( _n )

+  {

+    ret = _f_writeglsector( 6 );

+    if ( ret )

+    {

+      return ret;

+    }

+  }

+

+

+  return _f_writeglsector( 0 ); /*write bootrecord*/

+} /* _f_writebootrecord */

+

+

+/****************************************************************************

+ *

+ * _f_buildsectors

+ *

+ * INPUTS

+ * phy - media physical descriptor

+ *

+ * calculate relative sector position from boot record

+ *

+ ***************************************************************************/

+static unsigned char _f_buildsectors ( F_PHY * phy )

+{

+  gl_volume.mediatype = F_UNKNOWN_MEDIA;

+

+

+  if ( gl_volume.bootrecord.sector_per_FAT )

+  {

+    gl_volume.firstfat.sector = 1;

+    gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT;

+    gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs ) );

+    gl_volume.root.num = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE;

+

+    gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num;

+    gl_volume._tdata.num = 0;  /*??*/

+  }

+  else

+  {

+    gl_volume.firstfat.sector = ( 32 + 4 );

+    gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT32;

+    gl_volume._tdata.sector = gl_volume.firstfat.sector;

+    gl_volume._tdata.sector += gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs );

+    gl_volume._tdata.num = 0;  /*??*/

+

+    {

+      unsigned long  sectorcou = gl_volume.bootrecord.sector_per_cluster;

+      gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * sectorcou ) + gl_volume._tdata.sector;

+      gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster;

+    }

+  }

+

+  {

+    unsigned long  maxcluster;

+    maxcluster = phy->number_of_sectors;

+    maxcluster -= gl_volume._tdata.sector;

+    maxcluster /= gl_volume.bootrecord.sector_per_cluster;

+    gl_volume.maxcluster = maxcluster;

+  }

+

+  if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) )

+  {

+    gl_volume.mediatype = F_FAT12_MEDIA;

+  }

+  else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) )

+  {

+    gl_volume.mediatype = F_FAT16_MEDIA;

+  }

+  else

+  {

+    gl_volume.mediatype = F_FAT32_MEDIA;

+  }

+

+  return F_NO_ERROR;

+} /* _f_buildsectors */

+

+

+

+/****************************************************************************

+ *

+ * _f_prepareformat

+ *

+ * preparing boot record for formatting, it sets and calculates values

+ *

+ * INPUTS

+ * phy - media physical descriptor

+ * f_bootrecord - which bootrecord need to be prepare

+ * number_of_hidden_sectors - where boot record starts

+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static unsigned char _f_prepareformat ( F_PHY * phy, unsigned char fattype )

+{

+  if ( !phy->number_of_sectors )

+  {

+    return F_ERR_INVALIDSECTOR;

+  }

+

+  gl_volume.bootrecord.number_of_FATs = 2;

+  gl_volume.bootrecord.media_descriptor = 0xf0;

+

+  if ( fattype != F_FAT32_MEDIA )

+  {

+    unsigned long  _n;

+    switch ( fattype )

+    {

+      case F_FAT12_MEDIA:

+        _n = F_CLUSTER_RESERVED & 0xfff;

+        break;

+

+      case F_FAT16_MEDIA:

+        _n = F_CLUSTER_RESERVED & 0xffff;

+        break;

+

+      default:

+        return F_ERR_INVFATTYPE;

+    }

+

+    gl_volume.bootrecord.sector_per_cluster = 1;

+    while ( gl_volume.bootrecord.sector_per_cluster )

+    {

+      if ( phy->number_of_sectors / gl_volume.bootrecord.sector_per_cluster < _n )

+      {

+        break;

+      }

+

+      gl_volume.bootrecord.sector_per_cluster <<= 1;

+    }

+

+    if ( !gl_volume.bootrecord.sector_per_cluster )

+    {

+      return F_ERR_MEDIATOOLARGE;

+    }

+  }

+

+  else

+  {

+    unsigned char  i;

+    for ( i = 0 ; i<( sizeof( FAT32_CS ) / sizeof( t_FAT32_CS ) ) - 1 && phy->number_of_sectors>FAT32_CS[i].max_sectors ; i++ )

+    {

+    }

+

+    gl_volume.bootrecord.sector_per_cluster = FAT32_CS[i].sector_per_cluster;

+  }

+  if ( !gl_volume.bootrecord.sector_per_cluster )

+  {

+    return F_ERR_INVALIDMEDIA;                                               /*fat16 cannot be there*/

+  }

+

+  {

+    long           secpercl = gl_volume.bootrecord.sector_per_cluster;

+    long           nfat = gl_volume.bootrecord.number_of_FATs;

+    unsigned long  roots;

+    unsigned long  fatsec;

+

+    roots = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE;

+

+    switch ( fattype )

+    {

+      case F_FAT32_MEDIA:

+      {

+        unsigned long  _n = (unsigned long)( 128 * secpercl + nfat );

+        fatsec = ( phy->number_of_sectors - ( 32 + 4 ) + 2 * secpercl );

+        fatsec += ( _n - 1 );

+        fatsec /= _n;

+        gl_volume.bootrecord.sector_per_FAT32 = fatsec;

+        gl_volume.bootrecord.sector_per_FAT = 0;

+      }

+      break;

+

+      case F_FAT16_MEDIA:

+      {

+        unsigned long  _n = (unsigned long)( 256 * secpercl + nfat );

+        fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl );

+        fatsec += ( _n - 1 );

+        fatsec /= _n;

+        gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec );

+      }

+      break;

+

+      case F_FAT12_MEDIA:

+      {

+        unsigned long  _n = (unsigned long)( 1024 * secpercl + 3 * nfat );

+        fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl );

+        fatsec *= 3;

+        fatsec += ( _n - 1 );

+        fatsec /= _n;

+        gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec );

+      }

+      break;

+

+      default:

+        return F_ERR_INVALIDMEDIA;

+    } /* switch */

+

+    return F_NO_ERROR;

+  }

+} /* _f_prepareformat */

+

+

+

+/****************************************************************************

+ *

+ * _f_postformat

+ *

+ * erase fats, erase root directory, reset variables after formatting

+ *

+ * INPUTS

+ * phy - media physical descriptor

+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static unsigned char _f_postformat ( F_PHY * phy, unsigned char fattype )

+{

+  unsigned long  a;

+  unsigned char  ret;

+

+  _f_buildsectors( phy ); /*get positions*/

+  if ( gl_volume.mediatype != fattype )

+  {

+    return F_ERR_MEDIATOOSMALL;

+  }

+

+  gl_volume.fatsector = (unsigned long)( -1 );

+

+  {

+    unsigned char * ptr = (unsigned char *)gl_sector;

+    unsigned char   j = 2;

+    unsigned long   i;

+

+    psp_memset( ptr, 0, F_SECTOR_SIZE );

+

+    switch ( gl_volume.mediatype )

+    {

+      case F_FAT16_MEDIA:

+        j = 3;

+        break;

+

+      case F_FAT32_MEDIA:

+        j = 11;

+        break;

+    }

+

+    *ptr = gl_volume.bootrecord.media_descriptor;

+    psp_memset( ptr + 1, 0xff, j );

+    if ( gl_volume.mediatype == F_FAT32_MEDIA )

+    {

+      *( ptr + 8 ) = (unsigned char)( F_CLUSTER_LAST & 0xff );

+    }

+

+    (void)_f_writeglsector( gl_volume.firstfat.sector );

+    (void)_f_writeglsector( gl_volume.firstfat.sector + gl_volume.firstfat.num );

+    psp_memset( ptr, 0, ( j + 1 ) );

+

+    for ( i = 1 ; i < gl_volume.firstfat.num ; i++ )

+    {

+      (void)_f_writeglsector( gl_volume.firstfat.sector + i );

+      (void)_f_writeglsector( gl_volume.firstfat.sector + i + gl_volume.firstfat.num );

+    }

+  }

+

+  for ( a = 0 ; a < gl_volume.root.num ; a++ ) /*reset root direntries*/

+  {

+    ret = _f_writeglsector( gl_volume.root.sector + a );

+    if ( ret )

+    {

+      return ret;

+    }

+  }

+

+  return _f_writebootrecord( phy );

+} /* _f_postformat */

+

+

+/****************************************************************************

+ *

+ * fn_hardformat

+ *

+ * Making a complete format on media, independently from master boot record,

+ * according to media physical

+ *

+ * INPUTS

+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA

+ *

+ * RETURNS

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_hardformat ( unsigned char fattype )

+{

+  unsigned char  ret;

+  int            mdrv_ret;

+  F_PHY          phy;

+

+  ret = _f_getvolume();

+  if ( ret && ( ret != F_ERR_NOTFORMATTED ) )

+  {

+    return ret;

+  }

+

+  gl_volume.state = F_STATE_NEEDMOUNT;

+

+  psp_memset( &phy, 0, sizeof( F_PHY ) );

+

+  mdrv_ret = mdrv->getphy( mdrv, &phy );

+  if ( mdrv_ret )

+  {

+    return F_ERR_ONDRIVE;

+  }

+

+  ret = _f_prepareformat( &phy, fattype ); /*no partition*/

+  if ( ret )

+  {

+    return ret;

+  }

+

+  return _f_postformat( &phy, fattype );

+} /* fn_hardformat */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_readbootrecord

+ *

+ * read boot record from a volume, it detects if there is MBR on the media

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static unsigned char _f_readbootrecord ( void )

+{

+  unsigned char   ret;

+  unsigned char * ptr = (unsigned char *)gl_sector;

+  unsigned long   maxcluster, _n;

+  unsigned long   first_sector = 0;

+

+  gl_volume.mediatype = F_UNKNOWN_MEDIA;

+

+

+  ret = _f_readglsector( 0 );

+  if ( ret )

+  {

+    return ret;

+  }

+

+

+  if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) )

+  {

+    return F_ERR_NOTFORMATTED;                                              /*??*/

+  }

+

+  if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) )

+  {

+    first_sector = _f_getlong( &ptr[0x08 + 0x1be] ); /*start sector for 1st partioon*/

+

+    ret = _f_readglsector( first_sector );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) )

+    {

+      return F_ERR_NOTFORMATTED;                                                /*??*/

+    }

+

+    if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) )

+    {

+      return F_ERR_NOTFORMATTED;                                        /*??*/

+    }

+  }

+

+  ptr += 11;

+  if ( _f_getword( ptr ) != F_SECTOR_SIZE )

+  {

+    return F_ERR_NOTSUPPSECTORSIZE;

+  }

+

+  ptr += 2;

+  gl_volume.bootrecord.sector_per_cluster = *ptr++;

+  gl_volume.firstfat.sector = _f_getword( ptr );

+  ptr += 2;

+  gl_volume.bootrecord.number_of_FATs = *ptr++;

+  gl_volume.root.num = _f_getword( ptr );

+  ptr += 2;

+  gl_volume.root.num *= sizeof( F_DIRENTRY );

+  gl_volume.root.num /= F_SECTOR_SIZE;

+  maxcluster = _f_getword( ptr );

+  ptr += 2;

+  gl_volume.bootrecord.media_descriptor = *ptr++;

+  gl_volume.firstfat.num = _f_getword( ptr );

+  ptr += 6;

+  _n = _f_getlong( ptr );

+  ptr += 4;

+  if ( _n < first_sector )

+  {

+    _n = first_sector;

+  }

+

+  gl_volume.firstfat.sector += _n;

+  if ( !maxcluster )

+  {

+    maxcluster = _f_getlong( ptr );

+  }

+

+  ptr += 4;

+

+

+  if ( gl_volume.firstfat.num )

+  {

+    gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs );

+    gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num;

+    gl_volume._tdata.num = 0;

+    ptr += 3;

+  }

+  else

+  {

+    gl_volume.firstfat.num = _f_getlong( ptr );

+    ptr += 8;

+    gl_volume._tdata.sector = gl_volume.firstfat.sector;

+    gl_volume._tdata.sector += gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs;

+    gl_volume._tdata.num = 0;

+    gl_volume.bootrecord.rootcluster = _f_getlong( ptr );

+    ptr += 23;

+    gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster;

+    gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * gl_volume.root.num ) + gl_volume._tdata.sector;

+  }

+

+  gl_volume.bootrecord.serial_number = _f_getlong( ptr );

+

+  maxcluster -= gl_volume._tdata.sector;

+  maxcluster += _n;

+  gl_volume.maxcluster = maxcluster / gl_volume.bootrecord.sector_per_cluster;

+

+  if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) )

+  {

+    gl_volume.mediatype = F_FAT12_MEDIA;

+  }

+  else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) )

+  {

+    gl_volume.mediatype = F_FAT16_MEDIA;

+  }

+  else

+  {

+    gl_volume.mediatype = F_FAT32_MEDIA;

+  }

+

+  if ( gl_volume.bootrecord.media_descriptor != 0xf8 )    /*fixdrive*/

+  {

+    if ( gl_volume.bootrecord.media_descriptor != 0xf0 )  /*removable*/

+    {

+      return F_ERR_NOTFORMATTED;      /*??*/

+    }

+  }

+

+  return F_NO_ERROR;

+} /* _f_readbootrecord */

+

+

+

+

+/****************************************************************************

+ *

+ * _f_getvolume

+ *

+ * getting back a volume info structure of a given drive, it try to mounts

+ * drive if it was not mounted before

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char _f_getvolume ( void )

+{

+  switch ( gl_volume.state )

+  {

+    case F_STATE_NONE:

+      return F_ERR_ONDRIVE;

+

+    case F_STATE_WORKING:

+

+      if ( !_f_checkstatus() )

+      {

+        return F_NO_ERROR;

+      }

+

+    /* here we don't stop case flow,  */

+    /* because we have to clean up this volume! */

+

+    case F_STATE_NEEDMOUNT:

+    {

+      gl_file.modified = 0;

+      gl_volume.modified = 0;

+      gl_volume.lastalloccluster = 0;

+      gl_volume.actsector = (unsigned long)( -1 );

+      gl_volume.fatsector = (unsigned long)( -1 );

+

+      gl_file.mode = F_FILE_CLOSE;

+

+      gl_volume.cwd[0] = 0;     /*reset cwd*/

+      gl_volume.mediatype = F_UNKNOWN_MEDIA;

+

+      if ( mdrv->getstatus != NULL )

+      {

+        if ( mdrv->getstatus( mdrv ) & F_ST_MISSING )

+        {

+          gl_volume.state = F_STATE_NEEDMOUNT;         /*card missing*/

+          return F_ERR_CARDREMOVED;

+        }

+      }

+

+      if ( !_f_readbootrecord() )

+      {

+        gl_volume.state = F_STATE_WORKING;

+        return F_NO_ERROR;

+      }

+

+      gl_volume.mediatype = F_UNKNOWN_MEDIA;

+      return F_ERR_NOTFORMATTED;

+    }

+  } /* switch */

+

+  return F_ERR_ONDRIVE;

+} /* _f_getvolume */

+

+

+

+/****************************************************************************

+ *

+ * fn_getfreespace

+ *

+ * get total/free/used/bad diskspace

+ *

+ * INPUTS

+ * pspace - pointer where to store the information

+ *

+ * RETURNS

+ * error code

+ *

+ ***************************************************************************/

+unsigned char fn_getfreespace ( F_SPACE * pspace )

+{

+  unsigned char  ret;

+  unsigned long  a;

+  unsigned long  clustersize;

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  psp_memset( pspace, 0, sizeof( F_SPACE ) );

+  pspace->total = gl_volume.maxcluster;

+

+  gl_volume.fatsector = (unsigned long)-1;

+  for ( a = 2 ; a < gl_volume.maxcluster + 2 ; a++ )

+  {

+    unsigned long  value;

+

+    ret = _f_getclustervalue( a, &value );

+    if ( ret )

+    {

+      return ret;

+    }

+

+    if ( !value )

+    {

+      ++( pspace->free );

+    }

+    else if ( value == F_CLUSTER_BAD )

+    {

+      ++( pspace->bad );

+    }

+    else

+    {

+      ++( pspace->used );

+    }

+  }

+

+  clustersize = (unsigned long)( gl_volume.bootrecord.sector_per_cluster * F_SECTOR_SIZE );

+  for ( a = 0 ; ( clustersize & 1 ) == 0 ; a++ )

+  {

+    clustersize >>= 1;

+  }

+

+  pspace->total_high = ( pspace->total ) >> ( 32 - a );

+  pspace->total <<= a;

+  pspace->free_high = ( pspace->free ) >> ( 32 - a );

+  pspace->free <<= a;

+  pspace->used_high = ( pspace->used ) >> ( 32 - a );

+  pspace->used <<= a;

+  pspace->bad_high = ( pspace->bad ) >> ( 32 - a );

+  pspace->bad <<= a;

+

+  return F_NO_ERROR;

+} /* fn_getfreespace */

+

+

+/****************************************************************************

+ *

+ * fn_getserial

+ *

+ * get serial number

+ *

+ * INPUTS

+ * serial - pointer where to store the serial number

+ *

+ * RETURNS

+ * error code

+ *

+ ***************************************************************************/

+unsigned char fn_getserial ( unsigned long * serial )

+{

+  unsigned char  ret;

+

+  ret = _f_getvolume();

+  if ( ret )

+  {

+    return ret;

+  }

+

+  *serial = gl_volume.bootrecord.serial_number;

+  return 0;

+}

+

+/*

+** fn_init

+**

+** Initialize FAT_SL file system

+**

+** RETURN: F_NO_ERROR on success, other if error.

+*/

+unsigned char fn_init ( void )

+{

+  return F_NO_ERROR;

+} /* fn_init */

+

+/****************************************************************************

+ *

+ * fn_initvolume

+ *

+ * initiate a volume, this function has to be called 1st to set physical

+ * driver function to a given volume

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+unsigned char fn_initvolume ( F_DRIVERINIT initfunc )

+{

+#if F_FS_THREAD_AWARE == 1

+  {

+    if( fs_lock_semaphore == NULL )

+    {

+      fs_lock_semaphore = xSemaphoreCreateMutex();

+      if( fs_lock_semaphore == NULL )

+      {

+        return F_ERR_OS;

+      }

+    }

+  }

+#endif /* F_FS_THREAD_AWARE */

+

+  gl_volume.state = F_STATE_NONE;

+

+  mdrv = initfunc( 0 );

+  if ( mdrv == NULL )

+  {

+    return F_ERR_INITFUNC;

+  }

+

+  gl_volume.state = F_STATE_NEEDMOUNT;

+

+#if F_FILE_CHANGED_EVENT

+  f_filechangedevent = 0;

+#endif

+

+  return _f_getvolume();

+} /* fn_initvolume */

+

+/****************************************************************************

+ *

+ * fn_delvolume

+ *

+ ***************************************************************************/

+unsigned char fn_delvolume ( void )

+{

+  if ( mdrv->release )

+  {

+    (void)mdrv->release( mdrv );

+  }

+

+  return 0;

+}

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h
new file mode 100644
index 0000000..e65a44f
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h
@@ -0,0 +1,113 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __VOLUME_H

+#define __VOLUME_H

+

+#include "config_fat_sl.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+typedef struct

+{

+  unsigned char  sector_per_cluster;

+  unsigned char  number_of_FATs;

+  unsigned char  media_descriptor;

+  unsigned long  rootcluster;

+  unsigned long  sector_per_FAT;

+  unsigned long  sector_per_FAT32;

+  unsigned long  serial_number;

+} F_BOOTRECORD;

+

+

+typedef struct

+{

+  unsigned long  sector; /*start sector*/

+  unsigned long  num;    /*number of sectors*/

+} F_SECTOR;

+

+

+typedef struct

+{

+  unsigned char  state;

+  F_BOOTRECORD   bootrecord;

+  F_SECTOR       firstfat;

+  F_SECTOR       root;

+  F_SECTOR       _tdata;

+

+  unsigned long  actsector;

+  unsigned long  fatsector;

+

+  unsigned long  lastalloccluster;

+  unsigned char  modified;

+  char           cwd[F_MAXPATH]; /*current working folder in this volume*/

+  unsigned char  mediatype;

+  unsigned long  maxcluster;

+} F_VOLUME;

+

+

+enum

+{

+/*  0 */

+  F_STATE_NONE,

+

+/*  1 */ F_STATE_NEEDMOUNT,

+

+/*  2 */ F_STATE_WORKING

+};

+

+

+extern F_VOLUME  gl_volume;

+extern F_FILE    gl_file;

+extern char      gl_sector[F_SECTOR_SIZE]; /* actual sector */

+

+unsigned char _f_getvolume ( void );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __VOLUME_H */

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c
new file mode 100644
index 0000000..ef67ad0
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c
@@ -0,0 +1,2752 @@
+#ifndef _TEST_C_

+#define _TEST_C_

+

+

+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "test.h"

+#include "../../api/fat_sl.h"

+#include "../../psp/target/fat_sl/psp_test.h"

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+static char  cwd[F_MAXPATH];

+

+static F_FIND  find;

+

+static void _f_deleteall ( void )

+{

+  F_FIND         f2;

+  unsigned char  sd = 0, rc, fl = 0;

+

+  f2 = find;

+  do

+  {

+    rc = f_findfirst( "*.*", &find );

+    while ( rc == 0 && find.filename[0] == '.' )

+    {

+      rc = f_findnext( &find );

+    }

+

+    if ( rc == 0 )

+    {

+      if ( find.attr & F_ATTR_DIR )

+      {

+        ++sd;

+        fl = 1;

+        f2 = find;

+        (void)f_chdir( find.filename );

+        continue;

+      }

+      else

+      {

+        (void)f_delete( find.filename );

+        rc = f_findnext( &find );

+      }

+    }

+

+    if ( rc && sd && fl )

+    {

+      (void)f_chdir( ".." );

+      --sd;

+      fl = 0;

+      find = f2;

+      (void)f_rmdir( find.filename );

+      rc = f_findnext( &find );

+    }

+

+    if ( rc && sd && !fl )

+    {

+      (void)f_chdir( "/" );

+      sd = 0;

+      rc = 0;

+    }

+  }

+  while ( rc == 0 );

+} /* _f_deleteall */

+

+char  stmp[20];

+static char * f_nameconv ( char * s )

+{

+  char * ss = stmp;

+

+  for ( ; ; )

+  {

+    char  ch = *s++;

+    if ( ( ch >= 'a' ) && ( ch <= 'z' ) )

+    {

+      ch += 'A' - 'a';

+    }

+

+    *ss++ = ch;

+    if ( !ch )

+    {

+      break;

+    }

+  }

+

+  return stmp;

+} /* f_nameconv */

+

+static unsigned char f_formatting ( void )

+{

+  unsigned char  ret;

+

+  _f_dump( "f_formatting" );

+

+/*checking formatting*/

+  ret = f_format( F_FAT_TYPE );

+  if ( ret )

+  {

+    return _f_result( 0, ret );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 1, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 2, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_formatting */

+

+static unsigned char _f_checkcwd ( char * orig )

+{

+  unsigned char  ret;

+

+  ret = f_getcwd( cwd, F_MAXPATH );

+  if ( ret )

+  {

+    return ret;

+  }

+

+  if ( strcmp( orig, cwd ) )

+  {

+    return (unsigned char)-1;

+  }

+

+  return 0;

+}

+

+static unsigned char f_dirtest ( void )

+{

+  unsigned char  ret;

+

+  _f_dump( "f_dirtest" );

+

+  _f_deleteall();

+

+/*creates a ab abc abcd*/

+  ret = f_mkdir( "a" );

+  if ( ret )

+  {

+    return _f_result( 1, ret );

+  }

+

+  ret = f_mkdir( "ab" );

+  if ( ret )

+  {

+    return _f_result( 2, ret );

+  }

+

+  ret = f_mkdir( "abc" );

+  if ( ret )

+  {

+    return _f_result( 3, ret );

+  }

+

+  ret = f_mkdir( "abca" );

+  if ( ret )

+  {

+    return _f_result( 4, ret );

+  }

+

+/*creates directories in /a  -  a ab abc abcd*/

+  ret = f_mkdir( "a/a" );

+  if ( ret )

+  {

+    return _f_result( 5, ret );

+  }

+

+  ret = f_mkdir( "a/ab" );

+  if ( ret )

+  {

+    return _f_result( 6, ret );

+  }

+

+  ret = f_mkdir( "a/abc" );

+  if ( ret )

+  {

+    return _f_result( 7, ret );

+  }

+

+  ret = f_mkdir( "a/abcd" );

+  if ( ret )

+  {

+    return _f_result( 8, ret );

+  }

+

+/*change into a/abcd and check cwd*/

+  ret = f_chdir( "a/abcd" );

+  if ( ret )

+  {

+    return _f_result( 9, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );

+  if ( ret )

+  {

+    return _f_result( 10, ret );

+  }

+

+/*make directory t change into t and check cwd="a/abcd/t"*/

+  ret = f_mkdir( "t" );

+  if ( ret )

+  {

+    return _f_result( 11, ret );

+  }

+

+  ret = f_chdir( "t" );

+  if ( ret )

+  {

+    return _f_result( 12, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) );

+  if ( ret )

+  {

+    return _f_result( 13, ret );

+  }

+

+  ret = f_chdir( "." );

+  if ( ret )

+  {

+    return _f_result( 14, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) );

+  if ( ret )

+  {

+    return _f_result( 15, ret );

+  }

+

+  ret = f_chdir( "../." );

+  if ( ret )

+  {

+    return _f_result( 16, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );

+  if ( ret )

+  {

+    return _f_result( 17, ret );

+  }

+

+/*removing t dir*/

+  ret = f_rmdir( "t" );

+  if ( ret )

+  {

+    return _f_result( 18, ret );

+  }

+

+  ret = f_chdir( "t" );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 19, ret );

+  }

+

+/*removing /a dir*/

+  ret = f_rmdir( "/ab" );

+  if ( ret )

+  {

+    return _f_result( 20, ret );

+  }

+

+  ret = f_chdir( "/ab" );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 21, ret );

+  }

+

+/*removing /a dir*/

+  ret = f_rmdir( "../../a" );

+  if ( ret != F_ERR_NOTEMPTY )

+  {

+    return _f_result( 22, ret );

+  }

+

+/*removing /abca dir*/

+  ret = f_rmdir( "a:/abca" );

+  if ( ret )

+  {

+    return _f_result( 24, ret );

+  }

+

+/*changing invalid dirs*/

+  ret = f_chdir( "" );

+  if ( ret != F_ERR_INVALIDNAME )

+  {

+    return _f_result( 25, ret );

+  }

+

+  ret = f_chdir( " " );

+  if ( ret )

+  {

+    return _f_result( 26, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );

+  if ( ret )

+  {

+    return _f_result( 27, ret );

+  }

+

+  ret = f_chdir( "?" );

+  if ( ret != F_ERR_INVALIDNAME )

+  {

+    return _f_result( 28, ret );

+  }

+

+  ret = f_chdir( "*.*" );

+  if ( ret != F_ERR_INVALIDNAME )

+  {

+    return _f_result( 29, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );

+  if ( ret )

+  {

+    return _f_result( 30, ret );

+  }

+

+/*changing into /abc and removes subfolder from /a/ */

+  ret = f_chdir( "/abc" );

+  if ( ret )

+  {

+    return _f_result( 31, ret );

+  }

+

+  ret = f_rmdir( "/a/a" );

+  if ( ret )

+  {

+    return _f_result( 32, ret );

+  }

+

+  ret = f_rmdir( "A:../a/ab" );

+  if ( ret )

+  {

+    return _f_result( 33, ret );

+  }

+

+  ret = f_rmdir( "A:/a/abc" );

+  if ( ret )

+  {

+    return _f_result( 34, ret );

+  }

+

+  ret = f_rmdir( ".././abc/.././a/../a/abcd" );

+  if ( ret )

+  {

+    return _f_result( 35, ret );

+  }

+

+/*some invalid rmdir*/

+  ret = f_rmdir( "." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 36, ret );

+  }

+

+  ret = f_rmdir( ".." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 37, ret );

+  }

+

+/*create again abc remove abc*/

+  ret = f_mkdir( ".././abc" );

+  if ( ret != F_ERR_DUPLICATED )

+  {

+    return _f_result( 38, ret );

+  }

+

+  ret = f_rmdir( "../abc" );

+  if ( ret )

+  {

+    return _f_result( 39, ret );

+  }

+

+  ret = f_mkdir( ".././abc" );

+  if ( ret != F_ERR_INVALIDDIR )

+  {

+    return _f_result( 40, ret );                         /*cwd is not exist*/

+  }

+

+  ret = f_chdir( "/" );

+  if ( ret )

+  {

+    return _f_result( 41, ret );

+  }

+

+/*try . and .. in the root*/

+  ret = f_chdir( "." );

+  if ( ret )

+  {

+    return _f_result( 42, ret );

+  }

+

+  ret = f_chdir( "./././." );

+  if ( ret )

+  {

+    return _f_result( 43, ret );

+  }

+

+  ret = f_chdir( ".." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 44, ret );

+  }

+

+  ret = _f_checkcwd( "/" ); /*root!*/

+  if ( ret )

+  {

+    return _f_result( 45, ret );

+  }

+

+/*test . and .. in a and remove a*/

+  ret = f_chdir( "a" );

+  if ( ret )

+  {

+    return _f_result( 46, ret );

+  }

+

+  ret = f_chdir( ".." );

+  if ( ret )

+  {

+    return _f_result( 47, ret );

+  }

+

+  ret = f_chdir( "a" );

+  if ( ret )

+  {

+    return _f_result( 48, ret );

+  }

+

+  ret = f_chdir( "." );

+  if ( ret )

+  {

+    return _f_result( 49, ret );

+  }

+

+  ret = f_chdir( "a" );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 50, ret );

+  }

+

+  ret = f_chdir( "./.." );

+  if ( ret )

+  {

+    return _f_result( 51, ret );

+  }

+

+  ret = f_rmdir( "a" );

+  if ( ret )

+  {

+    return _f_result( 52, ret );

+  }

+

+/*check if all are removed*/

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 53, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_dirtest */

+

+

+static unsigned char f_findingtest ( void )

+{

+  unsigned char  ret;

+

+  _f_dump( "f_findingtest" );

+

+  _f_deleteall();

+

+/*check empty*/

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 0, ret );

+  }

+

+/*create Hello.dir*/

+  ret = f_mkdir( "Hello.dir" );

+  if ( ret )

+  {

+    return _f_result( 1, ret );

+  }

+

+/*check if it is exist, and only exist*/

+  ret = f_findfirst( "*.*", &find );

+  if ( ret )

+  {

+    return _f_result( 2, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "Hello.dir" ) ) )

+  {

+    return _f_result( 3, 0 );

+  }

+

+  if ( find.attr != F_ATTR_DIR )

+  {

+    return _f_result( 4, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 5, ret );

+  }

+

+/*check some not founds*/

+  ret = f_findfirst( "q*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 6, ret );

+  }

+

+  ret = f_findfirst( "Hello.", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 7, ret );

+  }

+

+  ret = f_findfirst( "a/*.*", &find );

+  if ( ret != F_ERR_INVALIDDIR )

+  {

+    return _f_result( 8, ret );

+  }

+

+  ret = f_findfirst( ".", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 9, ret );

+  }

+

+  ret = f_findfirst( "..", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 10, ret );

+  }

+

+  ret = f_findfirst( "?e.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 11, ret );

+  }

+

+  ret = f_findfirst( "*.", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 12, ret );

+  }

+

+  ret = f_findfirst( "*.?", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 13, ret );

+  }

+

+  ret = f_findfirst( "*.??", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 14, ret );

+  }

+

+

+/*check some founds*/

+  ret = f_findfirst( "*.dir", &find );

+  if ( ret )

+  {

+    return _f_result( 15, ret );

+  }

+

+  ret = f_findfirst( "*.d?r", &find );

+  if ( ret )

+  {

+    return _f_result( 16, ret );

+  }

+

+  ret = f_findfirst( "*.d??", &find );

+  if ( ret )

+  {

+    return _f_result( 17, ret );

+  }

+

+  ret = f_findfirst( "*.???", &find );

+  if ( ret )

+  {

+    return _f_result( 18, ret );

+  }

+

+  ret = f_findfirst( "?ello.???", &find );

+  if ( ret )

+  {

+    return _f_result( 19, ret );

+  }

+

+  ret = f_findfirst( "he??o.dir", &find );

+  if ( ret )

+  {

+    return _f_result( 20, ret );

+  }

+

+  ret = f_findfirst( "he?*.dir", &find );

+  if ( ret )

+  {

+    return _f_result( 21, ret );

+  }

+

+  ret = f_findfirst( "HELLO.DIR", &find ); /*no capitals sensitivity in find!!*/

+  if ( ret )

+  {

+    return _f_result( 22, ret );

+  }

+

+/*change into hello.dir*/

+  ret = f_chdir( "hello.dir" );

+  if ( ret )

+  {

+    return _f_result( 23, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret )

+  {

+    return _f_result( 24, ret );

+  }

+

+  ret = f_findfirst( "..", &find );

+  if ( ret )

+  {

+    return _f_result( 25, ret );

+  }

+

+  ret = f_findfirst( "??", &find );

+  if ( ret )

+  {

+    return _f_result( 26, ret );

+  }

+

+  ret = f_findfirst( ".", &find );

+  if ( ret )

+  {

+    return _f_result( 27, ret );

+  }

+

+  ret = f_findfirst( "k*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 28, ret );

+  }

+

+  ret = f_findfirst( "*.", &find );

+  if ( ret )

+  {

+    return _f_result( 29, ret );

+  }

+

+  if ( strcmp( find.filename, "." ) )

+  {

+    return _f_result( 29, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 29, ret );

+  }

+

+  if ( strcmp( find.filename, ".." ) )

+  {

+    return _f_result( 29, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 29, ret );

+  }

+

+

+  ret = f_findfirst( "*.a", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 30, ret );

+  }

+

+/*creating testdir and find it*/

+  ret = f_mkdir( "testdir" );

+  if ( ret )

+  {

+    return _f_result( 31, ret );

+  }

+

+  ret = f_findfirst( "*.", &find );

+  if ( ret )

+  {

+    return _f_result( 32, ret );

+  }

+

+  if ( strcmp( find.filename, "." ) )

+  {

+    return _f_result( 32, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 32, ret );

+  }

+

+  if ( strcmp( find.filename, ".." ) )

+  {

+    return _f_result( 32, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 32, ret );

+  }

+

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 33, 0 );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret )

+  {

+    return _f_result( 34, ret );

+  }

+

+  if ( strcmp( find.filename, "." ) )

+  {

+    return _f_result( 35, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 35, ret );

+  }

+

+  if ( strcmp( find.filename, ".." ) )

+  {

+    return _f_result( 35, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 36, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 37, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 38, ret );

+  }

+

+/*search exact file*/

+  ret = f_findfirst( "testDir", &find ); /*no capitals!*/

+  if ( ret )

+  {

+    return _f_result( 39, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 40, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 41, ret );

+  }

+

+

+/*go back to root and remove dirs*/

+  ret = f_chdir( "\\" );

+  if ( ret )

+  {

+    return _f_result( 42, ret );

+  }

+

+  ret = f_rmdir( "Hello.dir/testdir" );

+  if ( ret )

+  {

+    return _f_result( 43, ret );

+  }

+

+  ret = f_rmdir( "Hello.dir" );

+  if ( ret )

+  {

+    return _f_result( 44, ret );

+  }

+

+/*check if all are removed*/

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 45, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_findingtest */

+

+static unsigned char f_powerfail ( void )

+{

+  unsigned char  ret;

+

+  _f_dump( "f_powerfail" );

+

+/*checking if its power fail system (RAMDRIVE is not powerfail!)*/

+  ret = f_mkdir( "testdir" );

+  if ( ret )

+  {

+    return _f_result( 0, ret );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 1, ret );

+  }

+

+  ret = f_findfirst( "testdir", &find );

+  if ( ret )

+  {

+    return _f_result( 2, ret );

+  }

+

+/*checking formatting*/

+  ret = f_format( F_FAT_TYPE );

+  if ( ret )

+  {

+    return _f_result( 3, ret );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 4, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 5, ret );

+  }

+

+/*checking formatting, 1st creating*/

+  ret = f_format( F_FAT_TYPE );

+  if ( ret )

+  {

+    return _f_result( 6, ret );

+  }

+

+  ret = f_mkdir( "testdir" );

+  if ( ret )

+  {

+    return _f_result( 7, ret );

+  }

+

+  ret = f_findfirst( "testdir", &find );

+  if ( ret )

+  {

+    return _f_result( 8, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 9, 0 );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 10, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret )

+  {

+    return _f_result( 11, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 12, 0 );

+  }

+

+/*checking formatting, 2nd creating*/

+  ret = f_format( F_FAT_TYPE );

+  if ( ret )

+  {

+    return _f_result( 13, ret );

+  }

+

+  ret = f_mkdir( "testdir" );

+  if ( ret )

+  {

+    return _f_result( 14, ret );

+  }

+

+  ret = f_findfirst( "testdir", &find );

+  if ( ret )

+  {

+    return _f_result( 15, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 16, 0 );

+  }

+

+  ret = f_mkdir( "testdir2" );

+  if ( ret )

+  {

+    return _f_result( 17, ret );

+  }

+

+  ret = f_findfirst( "testdir2", &find );

+  if ( ret )

+  {

+    return _f_result( 18, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) )

+  {

+    return _f_result( 19, 0 );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 20, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret )

+  {

+    return _f_result( 21, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )

+  {

+    return _f_result( 22, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret )

+  {

+    return _f_result( 23, ret );

+  }

+

+  if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) )

+  {

+    return _f_result( 24, 0 );

+  }

+

+  ret = f_findnext( &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 25, ret );

+  }

+

+

+/*checking empty*/

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 26, ret );

+  }

+

+  ret = f_format( F_FAT_TYPE );

+  if ( ret )

+  {

+    return _f_result( 27, ret );

+  }

+

+  ret = _f_poweron();

+  if ( ret )

+  {

+    return _f_result( 28, ret );

+  }

+

+  ret = f_findfirst( "*.*", &find );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 29, ret );

+  }

+

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_powerfail */

+

+

+char  testbuffer[F_MAX_SEEK_TEST + 16]; /* +16 for f_appending test */

+

+static unsigned char checkfilecontent ( long nums, unsigned char value, F_FILE * file )

+{

+  unsigned char  ch;

+

+  while ( nums-- )

+  {

+    if ( f_eof( file ) )

+    {

+      return 1;                    /*eof ?*/

+    }

+

+    if ( 1 != f_read( &ch, 1, 1, file ) )

+    {

+      return 1;

+    }

+

+    if ( ch != value )

+    {

+      return 1;

+    }

+  }

+

+  return 0;

+} /* checkfilecontent */

+

+static unsigned char f_seeking ( int sectorsize )

+{

+  F_FILE       * file;

+  unsigned char  ret;

+  unsigned long  size;

+  unsigned long  pos;

+

+  if ( sectorsize == 128 )

+  {

+    _f_dump( "f_seeking with 128" );

+  }

+

+  #if ( F_MAX_SEEK_TEST > 128 )

+  else if ( sectorsize == 256 )

+  {

+    _f_dump( "f_seeking with 256" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 256 )

+  else if ( sectorsize == 512 )

+  {

+    _f_dump( "f_seeking with 512" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 512 )

+  else if ( sectorsize == 1024 )

+  {

+    _f_dump( "f_seeking with 1024" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 1024 )

+  else if ( sectorsize == 2048 )

+  {

+    _f_dump( "f_seeking with 2048" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 2048 )

+  else if ( sectorsize == 4096 )

+  {

+    _f_dump( "f_seeking with 4096" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 4096 )

+  else if ( sectorsize == 8192 )

+  {

+    _f_dump( "f_seeking with 8192" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 8192 )

+  else if ( sectorsize == 16384 )

+  {

+    _f_dump( "f_seeking with 16384" );

+  }

+  #endif

+  #if ( F_MAX_SEEK_TEST > 16384 )

+  else if ( sectorsize == 32768 )

+  {

+    _f_dump( "f_seeking with 32768" );

+  }

+  #endif

+  else

+  {

+    _f_dump( "f_seeking with random" );

+  }

+

+/*checking sector boundary seekeng*/

+  file = f_open( "test.bin", "w+" );

+  if ( !file )

+  {

+    return _f_result( 0, 0 );

+  }

+

+/*write sectorsize times 0*/

+  psp_memset( testbuffer, 0, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, (long)sectorsize, file );

+  if ( size != (unsigned long) sectorsize )

+  {

+    return _f_result( 1, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) sectorsize )

+  {

+    return _f_result( 2, pos );

+  }

+

+/*seek back and read some*/

+  ret = f_seek( file, 0, F_SEEK_SET ); /*seek back*/

+  if ( ret )

+  {

+    return _f_result( 3, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos )

+  {

+    return _f_result( 4, pos );

+  }

+

+  size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );

+  if ( size != (unsigned long) sectorsize )

+  {

+    return _f_result( 5, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) sectorsize )

+  {

+    return _f_result( 6, pos );

+  }

+

+/*fake read at eof*/

+  size = (unsigned long)f_read( testbuffer, 1, 2, file ); /*eof!*/

+  if ( size != 0 )

+  {

+    return _f_result( 7, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) sectorsize )

+  {

+    return _f_result( 8, pos );

+  }

+

+/*writing sectorsize times 1 at the end*/

+  psp_memset( testbuffer, 1, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, sectorsize, file );

+  if ( size != (unsigned long) sectorsize )

+  {

+    return _f_result( 11, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( sectorsize * 2 ) )

+  {

+    return _f_result( 12, pos );

+  }

+

+/*seeking back and read 1byte less*/

+  ret = f_seek( file, 0, F_SEEK_SET );

+  if ( ret )

+  {

+    return _f_result( 13, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos )

+  {

+    return _f_result( 14, pos );

+  }

+

+  size = (unsigned long)f_read( testbuffer, 1, sectorsize - 1, file );

+  if ( size != (unsigned long) ( sectorsize - 1 ) )

+  {

+    return _f_result( 15, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( sectorsize - 1 ) )

+  {

+    return _f_result( 16, pos );

+  }

+

+

+/*write 2 times 2*/

+  psp_memset( testbuffer, 2, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 2, file );

+  if ( size != 2 )

+  {

+    return _f_result( 17, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( sectorsize + 1 ) )

+  {

+    return _f_result( 18, pos );

+  }

+

+/*read 2 bytes*/

+  size = (unsigned long)f_read( testbuffer, 2, 1, file );

+  if ( size != 1 )

+  {

+    return _f_result( 19, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( sectorsize + 3 ) )

+  {

+    return _f_result( 20, pos );

+  }

+

+

+/*write 4 times 3*/

+  psp_memset( testbuffer, 3, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 4, file );

+  if ( size != 4 )

+  {

+    return _f_result( 21, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( sectorsize + 3 + 4 ) )

+  {

+    return _f_result( 22, pos );

+  }

+

+/*seek at 2*/

+  ret = f_seek( file, 2, F_SEEK_SET );

+  if ( ret )

+  {

+    return _f_result( 23, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != 2 )

+  {

+    return _f_result( 24, pos );

+  }

+

+/*write 6 times 4*/

+  psp_memset( testbuffer, 4, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 6, file );

+  if ( size != 6 )

+  {

+    return _f_result( 25, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != 8 )

+  {

+    return _f_result( 26, pos );

+  }

+

+/*seek end -4*/

+  ret = f_seek( file, -4, F_SEEK_END );

+  if ( ret )

+  {

+    return _f_result( 27, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize - 4 ) )

+  {

+    return _f_result( 28, pos );

+  }

+

+/*read 2 bytes*/

+  size = (unsigned long)f_read( testbuffer, 1, 2, file );

+  if ( size != 2 )

+  {

+    return _f_result( 29, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize - 2 ) )

+  {

+    return _f_result( 30, pos );

+  }

+

+/*write 8 times 5*/

+  psp_memset( testbuffer, 5, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 8, file );

+  if ( size != 8 )

+  {

+    return _f_result( 31, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) )

+  {

+    return _f_result( 32, pos );

+  }

+

+/*seek to the begining*/

+  ret = f_seek( file, 0, F_SEEK_SET );

+  if ( ret )

+  {

+    return _f_result( 33, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos )

+  {

+    return _f_result( 34, pos );

+  }

+

+/*seek to the end*/

+  ret = f_seek( file, 2 * sectorsize + 6, F_SEEK_SET );

+  if ( ret )

+  {

+    return _f_result( 35, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) )

+  {

+    return _f_result( 36, pos );

+  }

+

+/*write 2 times 6*/

+  psp_memset( testbuffer, 6, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 2, file );

+  if ( size != 2 )

+  {

+    return _f_result( 37, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) )

+  {

+    return _f_result( 38, pos );

+  }

+

+/*seek to the begining*/

+  (void)f_seek( file, -( 2 * sectorsize + 8 ), F_SEEK_CUR );

+  if ( ret )

+  {

+    return _f_result( 39, ret );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos )

+  {

+    return _f_result( 40, pos );

+  }

+

+/*read 2 times sector*/

+  size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );

+  if ( size != (unsigned long) sectorsize )

+  {

+    return _f_result( 41, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) sectorsize )

+  {

+    return _f_result( 42, pos );

+  }

+

+  size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );

+  if ( size != (unsigned long) sectorsize )

+  {

+    return _f_result( 43, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize ) )

+  {

+    return _f_result( 44, pos );

+  }

+

+/*write 1 once 7*/

+  psp_memset( testbuffer, 7, sectorsize );

+  size = (unsigned long)f_write( testbuffer, 1, 1, file );

+  if ( size != 1 )

+  {

+    return _f_result( 45, size );

+  }

+

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize + 1 ) )

+  {

+    return _f_result( 46, pos );

+  }

+

+/*close it*/

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 47, ret );

+  }

+

+

+/*check the result*/

+  size = (unsigned long)f_filelength( "test.bin" );

+  if ( size != (unsigned long) ( 2 * sectorsize + 8 ) )

+  {

+    return _f_result( 48, size );

+  }

+

+/*opens it*/

+  file = f_open( "test.bin", "r" );

+  if ( !file )

+  {

+    return _f_result( 49, size );

+  }

+

+  if ( checkfilecontent( 2, 0, file ) )

+  {

+    return _f_result( 50, 0 );

+  }

+

+  if ( checkfilecontent( 6, 4, file ) )

+  {

+    return _f_result( 51, 0 );

+  }

+

+  if ( checkfilecontent( sectorsize - 8 - 1, 0, file ) )

+  {

+    return _f_result( 52, 0 );

+  }

+

+  if ( checkfilecontent( 2, 2, file ) )

+  {

+    return _f_result( 53, 0 );

+  }

+

+  if ( checkfilecontent( 2, 1, file ) )

+  {

+    return _f_result( 54, 0 );

+  }

+

+  if ( checkfilecontent( 4, 3, file ) )

+  {

+    return _f_result( 55, 0 );

+  }

+

+  if ( checkfilecontent( sectorsize - 7 - 2, 1, file ) )

+  {

+    return _f_result( 56, 0 );

+  }

+

+  if ( checkfilecontent( 2, 5, file ) )

+  {

+    return _f_result( 57, 0 );

+  }

+

+  if ( checkfilecontent( 1, 7, file ) )

+  {

+    return _f_result( 58, 0 );

+  }

+

+  if ( checkfilecontent( 5, 5, file ) )

+  {

+    return _f_result( 59, 0 );

+  }

+

+  if ( checkfilecontent( 2, 6, file ) )

+  {

+    return _f_result( 60, 0 );

+  }

+

+/*check pos result*/

+  pos = (unsigned long)f_tell( file );

+  if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) )

+  {

+    return _f_result( 61, pos );

+  }

+

+/*this has to be eof*/

+  pos = f_eof( file );

+  if ( !pos )

+  {

+    return _f_result( 62, pos );

+  }

+

+/*close it*/

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 63, ret );

+  }

+

+/*deletes it*/

+  ret = f_delete( "test.bin" );

+  if ( ret )

+  {

+    return _f_result( 64, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_seeking */

+

+static unsigned char f_opening ( void )

+{

+  F_FILE        * file;

+  F_FILE        * file2;

+  unsigned char   ret;

+  unsigned short  size, pos;

+

+  _f_dump( "f_opening" );

+

+/*test non existing file open r, r+*/

+  file = f_open( "file.bin", "r" );

+  if ( file )

+  {

+    return _f_result( 0, 0 );

+  }

+

+  file = f_open( "file.bin", "r+" );

+  if ( file )

+  {

+    return _f_result( 1, 0 );

+  }

+

+/*test non existing appends	"a" a+*/

+  file = f_open( "file.bin", "a" );

+  if ( !file )

+  {

+    return _f_result( 2, 0 );

+  }

+

+  file2 = f_open( "file.bin", "a+" ); /*open again*/

+  if ( file2 )

+  {

+    return _f_result( 3, 0 );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 3, 1 );

+  }

+

+  ret = f_close( file2 );

+  if ( ret != F_ERR_NOTOPEN )

+  {

+    return _f_result( 3, 2 );

+  }

+

+

+/*try to creates it w*/

+  file = f_open( "file.bin", "w" );

+  if ( !file )

+  {

+    return _f_result( 4, 0 );

+  }

+

+/*write 512 times 1*/

+  psp_memset( testbuffer, 1, 512 );                           /*set all 1*/

+  size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/

+  if ( size != 512 )

+  {

+    return _f_result( 5, size );

+  }

+

+/*go back, and read it*/

+  ret = f_rewind( file ); /*back to the begining*/

+  if ( ret )

+  {

+    return _f_result( 6, ret );       /*it should fail*/

+  }

+

+  size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/

+  if ( size )

+  {

+    return _f_result( 7, size );        /*it should fail*/

+  }

+

+/*close and check size*/

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size )

+  {

+    return _f_result( 8, size );        /*has to be zero*/

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 9, ret );

+  }

+

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size != 512 )

+  {

+    return _f_result( 10, size );

+  }

+

+/*try to owerwrites it it*/

+  file = f_open( "file.bin", "w+" );

+  if ( !file )

+  {

+    return _f_result( 11, 0 );

+  }

+

+/*close and check size*/

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size )

+  {

+    return _f_result( 12, size );        /*has to be zero*/

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 13, ret );

+  }

+

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size )

+  {

+    return _f_result( 14, size );

+  }

+

+

+

+/*test non existing appends	"a" */

+  file = f_open( "file.bin", "r+" );

+  if ( !file )

+  {

+    return _f_result( 15, 0 );

+  }

+

+/*write 512 times 1*/

+  psp_memset( testbuffer, 1, 512 );                           /*set all 1*/

+  size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/

+  if ( size != 512 )

+  {

+    return _f_result( 16, size );

+  }

+

+/*go back, and read it*/

+  ret = f_rewind( file );                                    /*back to the begining*/

+  size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/

+  if ( size != 512 )

+  {

+    return _f_result( 17, size );             /*it should fail*/

+  }

+

+  ret = f_rewind( file ); /*back to the begining*/

+

+/*write 256 times 2*/

+  psp_memset( testbuffer, 2, 512 );                           /*set all 2*/

+  size = (unsigned short)f_write( testbuffer, 1, 256, file ); /*test write*/

+  if ( size != 256 )

+  {

+    return _f_result( 18, size );

+  }

+

+  pos = (unsigned short)f_tell( file );

+  if ( pos != 256 )

+  {

+    return _f_result( 19, pos );            /*position has to be 512*/

+  }

+

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size )

+  {

+    return _f_result( 20, size );        /*has to be zero*/

+  }

+

+/*close and check size*/

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 21, ret );

+  }

+

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size != 512 )

+  {

+    return _f_result( 22, size );

+  }

+

+

+/*test non existing appends a+*/

+  file = f_open( "file.bin", "a+" );

+  if ( !file )

+  {

+    return _f_result( 23, 0 );

+  }

+

+  pos = (unsigned short)f_tell( file );

+  if ( pos != 512 )

+  {

+    return _f_result( 24, pos );            /*position has to be 512*/

+  }

+

+/*write 512 times 3*/

+  psp_memset( testbuffer, 3, 512 );                           /*set all 3*/

+  size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/

+  if ( size != 512 )

+  {

+    return _f_result( 25, size );

+  }

+

+/*go back, and read it*/

+  ret = f_rewind( file ); /*back to the begining*/

+  if ( ret )

+  {

+    return _f_result( 26, ret );       /*it should fail*/

+  }

+

+  size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/

+  if ( size != 512 )

+  {

+    return _f_result( 27, size );             /*it should fail*/

+  }

+

+  pos = (unsigned short)f_tell( file );

+  if ( pos != 512 )

+  {

+    return _f_result( 28, pos );            /*position has to be 512*/

+  }

+

+/*close and check size*/

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size != 512 )

+  {

+    return _f_result( 29, size );             /*has to be zero*/

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 30, ret );

+  }

+

+  size = (unsigned short)f_filelength( "file.bin" );

+  if ( size != 1024 )

+  {

+    return _f_result( 31, size );

+  }

+

+/*close again!*/

+  ret = f_close( file );

+  if ( ret != F_ERR_NOTOPEN )

+  {

+    return _f_result( 32, pos );

+  }

+

+  ret = f_delete( "file.bin" );

+  if ( ret )

+  {

+    return _f_result( 33, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_opening */

+

+static unsigned char f_appending ( void )

+{

+  F_FILE        * file;

+  unsigned short  size, tsize, pos;

+  unsigned char   a, b, ret;

+

+  _f_dump( "f_appending" );

+

+  _f_deleteall();

+

+  for ( tsize = 0, a = 0 ; a < 16 ; a++ )

+  {

+    file = f_open( "ap.bin", "a" );

+    if ( !file )

+    {

+      return _f_result( 1, 0 );

+    }

+

+    psp_memset( testbuffer, a, sizeof( testbuffer ) );

+    size = (unsigned short)f_write( testbuffer, 1, a + 128, file );

+    if ( size != a + 128 )

+    {

+      return _f_result( 2, size );

+    }

+

+    size = (unsigned short)f_filelength( "ap.bin" );

+    if ( size != tsize )

+    {

+      return _f_result( 3, size );

+    }

+

+    tsize += a + 128;

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 4, ret );

+    }

+

+    size = (unsigned short)f_filelength( "ap.bin" );

+    if ( size != tsize )

+    {

+      return _f_result( 5, size );

+    }

+  }

+

+  file = f_open( "ap.bin", "r" );

+  if ( !file )

+  {

+    return _f_result( 6, 0 );

+  }

+

+  for ( tsize = 0, a = 0 ; a < 16 ; a++ )

+  {

+    if ( checkfilecontent( a + 128, (char)a, file ) )

+    {

+      return _f_result( 7, a );

+    }

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 8, ret );

+  }

+

+  for ( tsize = 0, a = 0 ; a < 16 ; a++ )

+  {

+    file = f_open( "ap.bin", "r" );

+    if ( !file )

+    {

+      return _f_result( 9, 0 );

+    }

+

+    ret = f_seek( file, tsize, F_SEEK_SET );

+    if ( ret )

+    {

+      return _f_result( 10, ret );

+    }

+

+    pos = (unsigned short)f_tell( file );

+    if ( pos != tsize )

+    {

+      return _f_result( 11, pos );

+    }

+

+    size = (unsigned short)f_read( testbuffer, 1, a + 128, file );

+    if ( size != a + 128 )

+    {

+      return _f_result( 12, size );

+    }

+

+    for ( b = 0 ; b < a + 128 ; b++ )

+    {

+      if ( testbuffer[b] != (char)a )

+      {

+        return _f_result( 13, a );

+      }

+    }

+

+    tsize += a + 128;

+

+    pos = (unsigned short)f_tell( file );

+    if ( pos != tsize )

+    {

+      return _f_result( 13, pos );

+    }

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 14, ret );

+    }

+  }

+

+  ret = f_close( file );

+  if ( ret != F_ERR_NOTOPEN )

+  {

+    return _f_result( 9, ret );

+  }

+

+  ret = f_delete( "ap.bin" );

+  if ( ret )

+  {

+    return _f_result( 14, ret );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_appending */

+

+static unsigned char f_writing ( void )

+{

+  F_FILE        * file;

+  unsigned short  size;

+  unsigned char   a, ret;

+  F_SPACE         before, after;

+

+  _f_dump( "f_writing" );

+

+  ret = f_getfreespace( &before );

+  if ( ret )

+  {

+    return _f_result( 0, ret );

+  }

+

+  for ( a = 0 ; a < 4 ; a++ )

+  {

+    file = f_open( "wr.bin", "w" );

+    if ( !file )

+    {

+      return _f_result( 1, 0 );

+    }

+

+    psp_memset( testbuffer, a, sizeof( testbuffer ) );

+    size = (unsigned short)f_write( testbuffer, 1, a * 128, file );

+    if ( size != a * 128 )

+    {

+      return _f_result( 2, size );

+    }

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 3, ret );

+    }

+

+    size = (unsigned short)f_filelength( "wr.bin" );

+    if ( size != a * 128 )

+    {

+      return _f_result( 4, size );

+    }

+

+    file = f_open( "wr.bin", "r" );

+    if ( !file )

+    {

+      return _f_result( 5, 0 );

+    }

+

+    if ( checkfilecontent( a * 128, (char)a, file ) )

+    {

+      return _f_result( 6, a );

+    }

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 7, ret );

+    }

+  }

+

+

+  for ( a = 0 ; a < 4 ; a++ )

+  {

+    file = f_open( "wr.bin", "w+" );

+    if ( !file )

+    {

+      return _f_result( 8, 0 );

+    }

+

+    psp_memset( testbuffer, a, sizeof( testbuffer ) );

+    size = (unsigned short)f_write( testbuffer, 1, a * 128, file );

+    if ( size != a * 128 )

+    {

+      return _f_result( 9, size );

+    }

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 10, ret );

+    }

+

+    size = (unsigned short)f_filelength( "wr.bin" );

+    if ( size != a * 128 )

+    {

+      return _f_result( 11, size );

+    }

+

+    file = f_open( "wr.bin", "r+" );

+    if ( !file )

+    {

+      return _f_result( 12, 0 );

+    }

+

+    if ( checkfilecontent( a * 128, (char)a, file ) )

+    {

+      return _f_result( 13, a );

+    }

+

+    ret = f_close( file );

+    if ( ret )

+    {

+      return _f_result( 14, ret );

+    }

+  }

+

+  ret = f_getfreespace( &after );

+  if ( ret )

+  {

+    return _f_result( 15, ret );

+  }

+

+  if ( before.bad != after.bad )

+  {

+    return _f_result( 16, 0 );

+  }

+

+  if ( before.free == after.free )

+  {

+    return _f_result( 17, 0 );

+  }

+

+  if ( before.used == after.used )

+  {

+    return _f_result( 18, 0 );

+  }

+

+  if ( before.total != after.total )

+  {

+    return _f_result( 19, 0 );

+  }

+

+  if ( before.used + before.free != after.used + after.free )

+  {

+    return _f_result( 20, 0 );

+  }

+

+  ret = f_delete( "wr.bin" );

+  if ( ret )

+  {

+    return _f_result( 21, ret );

+  }

+

+  ret = f_getfreespace( &after );

+  if ( ret )

+  {

+    return _f_result( 22, ret );

+  }

+

+  if ( before.bad != after.bad )

+  {

+    return _f_result( 23, 0 );

+  }

+

+  if ( before.free != after.free )

+  {

+    return _f_result( 24, 0 );

+  }

+

+  if ( before.used != after.used )

+  {

+    return _f_result( 25, 0 );

+  }

+

+  if ( before.total != after.total )

+  {

+    return _f_result( 26, 0 );

+  }

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_writing */

+

+static unsigned char f_dots ( void )

+{

+  unsigned char  ret;

+  unsigned char  a, size;

+  F_FILE       * file;

+

+  _f_dump( "f_dots" );

+

+  ret = f_mkdir( "/tt" );

+  if ( ret )

+  {

+    return _f_result( 0, ret );

+  }

+

+  ret = f_chdir( "/tt" );

+  if ( ret )

+  {

+    return _f_result( 1, ret );

+  }

+

+  ret = f_rmdir( "." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 4, ret );

+  }

+

+  ret = f_rmdir( ".." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 5, ret );

+  }

+

+  ret = f_chdir( "." );

+  if ( ret )

+  {

+    return _f_result( 6, ret );

+  }

+

+  ret = _f_checkcwd( f_nameconv( "/tt" ) );

+  if ( ret )

+  {

+    return _f_result( 7, ret );

+  }

+

+  ret = f_delete( "." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 8, ret );

+  }

+

+  ret = f_delete( ".." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 9, ret );

+  }

+

+  ret = f_mkdir( "." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 10, ret );

+  }

+

+  ret = f_mkdir( ".." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 11, ret );

+  }

+

+  ret = f_mkdir( "..." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 12, ret );

+  }

+

+  for ( a = 0 ; a < 6 ; a++ )

+  {

+    char * mode;

+    switch ( a )

+    {

+      case 0:

+        mode = "r";

+        break;

+

+      case 1:

+        mode = "r+";

+        break;

+

+      case 2:

+        mode = "w";

+        break;

+

+      case 3:

+        mode = "w+";

+        break;

+

+      case 4:

+        mode = "a";

+        break;

+

+      case 5:

+        mode = "a+";

+        break;

+

+      default:

+        return _f_result( 13, a );

+    } /* switch */

+

+    file = f_open( ".", mode );

+    if ( file )

+    {

+      return _f_result( 14, a );

+    }

+

+    file = f_open( "..", mode );

+    if ( file )

+    {

+      return _f_result( 15, a );

+    }

+

+    file = f_open( "...", mode );

+    if ( file )

+    {

+      return _f_result( 16, a );

+    }

+  }

+

+  size = (unsigned char)f_filelength( "." );

+  if ( size )

+  {

+    return _f_result( 17, size );

+  }

+

+  size = (unsigned char)f_filelength( ".." );

+  if ( size )

+  {

+    return _f_result( 18, size );

+  }

+

+  size = (unsigned char)f_filelength( "..." );

+  if ( size )

+  {

+    return _f_result( 19, size );

+  }

+

+

+  ret = f_chdir( "..." );

+  if ( ret != F_ERR_NOTFOUND )

+  {

+    return _f_result( 20, ret );

+  }

+

+  ret = f_chdir( ".." );

+  if ( ret )

+  {

+    return _f_result( 21, ret );

+  }

+

+  ret = f_rmdir( "tt" );

+  if ( ret )

+  {

+    return _f_result( 27, ret );

+  }

+

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_dots */

+

+

+typedef struct

+{

+  unsigned char  MagicNum;

+  unsigned char  Line;

+  unsigned char  Buf[87];

+} struct_TestFileSysEntry;

+  #define NUM_OF_RECORDS 10

+static unsigned char f_rit ( void )

+{

+  unsigned char             i;

+  unsigned char             ret;

+  F_FILE                  * File;

+  struct_TestFileSysEntry * Entry = (struct_TestFileSysEntry *)( ( ( (long)testbuffer + 3 ) >> 2 ) << 2 );

+  unsigned short            Pos;

+  unsigned char             Ch;

+  unsigned char             Founded;

+

+  _f_dump( "f_rit" );

+

+  (void)f_delete( "MyTest" );

+  File = f_open( "MyTest", "a+" );

+  if ( !File )

+  {

+    return _f_result( 1, 0 );

+  }

+

+  /* add records  */

+  for ( i = 0 ; i < NUM_OF_RECORDS ; i++ )

+  {

+    Ch = (char)( i % 10 );

+    Entry->MagicNum = 0xbc;

+    Entry->Line = i;

+    Entry->Buf[0] = Ch;

+    Entry->Buf[10] = (unsigned char)( Ch + 1 );

+

+    if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_END ) )

+    {

+      return _f_result( 2, 0 ); /* Fail, could not go to the end of the file */

+    }

+

+    if ( sizeof( struct_TestFileSysEntry ) != f_write( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )

+    {

+      return _f_result( 3, 0 ); /* Fail, could not write new entry */

+    }

+

+    Pos = (unsigned short)f_tell( File );

+    if ( ( ( Pos / sizeof( struct_TestFileSysEntry ) ) - 1 ) != i )

+    {

+      return _f_result( 4, 0 ); /* Fail, wrong file position */

+    }

+

+    if ( F_NO_ERROR != f_seek( File, (long)( Pos - sizeof( struct_TestFileSysEntry ) ), F_SEEK_SET ) )

+    {

+      return _f_result( 5, 0 ); /* Fail, could not go to new entry position */

+    }

+

+    if ( sizeof( struct_TestFileSysEntry ) != f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )

+    {

+      return _f_result( 6, 0 ); /* Fail, could not read the new entry */

+    }

+

+    if ( ( Entry->MagicNum != 0xbc ) || ( Entry->Line != (int)i ) || ( Entry->Buf[0] != Ch ) || ( Entry->Buf[10] != Ch + 1 ) )

+    {

+      return _f_result( 7, 0 ); /*Fail, the new entry is corrupted"*/

+    }

+  }

+

+  ret = f_close( File );

+  if ( ret )

+  {

+    return _f_result( 8, ret );

+  }

+

+

+  /*Open file again*/

+  File = f_open( "MyTest", "a+" );

+  if ( !File )

+  {

+    return _f_result( 9, 0 );

+  }

+

+  /* read records  */

+  for ( i = 0 ; i < NUM_OF_RECORDS ; i++ )

+  {

+    Ch = (char)( i % 10 );

+

+    if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_SET ) )

+    {

+      return _f_result( 10, 0 ); /* Fail, could not go to the start of the file */

+    }

+

+    Founded = 0;

+    while ( sizeof( struct_TestFileSysEntry ) == f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )

+    {

+      if ( ( Entry->MagicNum == 0xbc )

+          && ( Entry->Line == (int)i )

+          && ( Entry->Buf[0] == Ch )

+          && ( Entry->Buf[10] == Ch + 1 ) )

+      {

+        Founded = 1;

+        break;

+      }

+    }

+

+    if ( !Founded )

+    {

+      return _f_result( 11, i );      /* Entry not founded */

+    }

+  }

+

+  ret = f_close( File );

+  if ( ret )

+  {

+    return _f_result( 12, ret );

+  }

+

+

+  ret = f_delete( "MyTest" );

+  if ( ret )

+  {

+    return _f_result( 13, ret );

+  }

+

+  _f_dump( "passed..." );

+

+  return 0;

+} /* f_rit */

+

+

+

+

+static unsigned char f_truncating ( void )

+{

+  F_FILE       * file;

+  unsigned long  size;

+  unsigned char  ret;

+

+  _f_dump( "f_truncating" );

+

+  file = f_open( "test.bin", "w+" );

+  if ( !file )

+  {

+    return _f_result( 0, 0 );

+  }

+

+  (void)psp_memset( testbuffer, 1, F_MAX_SEEK_TEST );

+  size = (unsigned long)f_write( testbuffer, 1, F_MAX_SEEK_TEST, file );

+  if ( size != F_MAX_SEEK_TEST )

+  {

+    return _f_result( 1, size );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 2, ret );

+  }

+

+  file = f_truncate( "test.bin", F_MAX_SEEK_TEST - 4 );

+  if ( !file )

+  {

+    return _f_result( 3, 0 );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 4, ret );

+  }

+

+  size = (unsigned long)f_filelength( "test.bin" );

+  if ( size != F_MAX_SEEK_TEST - 4 )

+  {

+    return _f_result( 5, size );

+  }

+

+

+  file = f_truncate( "test.bin", F_MAX_SEEK_TEST );

+  if ( !file )

+  {

+    return _f_result( 3, 0 );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 4, ret );

+  }

+

+  size = (unsigned long)f_filelength( "test.bin" );

+  if ( size != F_MAX_SEEK_TEST )

+  {

+    return _f_result( 5, size );

+  }

+

+

+  file = f_truncate( "test.bin", ( F_MAX_SEEK_TEST / 2 ) - 92 );

+  if ( !file )

+  {

+    return _f_result( 6, 0 );

+  }

+

+  (void)psp_memset( testbuffer, 2, 92 );

+  size = (unsigned long)f_write( testbuffer, 1, 92, file );

+  if ( size != 92 )

+  {

+    return _f_result( 7, size );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 8, ret );

+  }

+

+  size = (unsigned long)f_filelength( "test.bin" );

+  if ( size != ( F_MAX_SEEK_TEST / 2 ) )

+  {

+    return _f_result( 9, size );

+  }

+

+

+  file = f_truncate( "test.bin", 1 );

+  if ( !file )

+  {

+    return _f_result( 10, 0 );

+  }

+

+  (void)psp_memset( testbuffer, 3, 2 );

+  size = (unsigned long)f_write( testbuffer, 1, 2, file );

+  if ( size != 2 )

+  {

+    return _f_result( 11, size );

+  }

+

+  ret = f_close( file );

+  if ( ret )

+  {

+    return _f_result( 12, ret );

+  }

+

+  size = (unsigned long)f_filelength( "test.bin" );

+  if ( size != 3 )

+  {

+    return _f_result( 13, size );

+  }

+

+

+

+  _f_dump( "passed..." );

+  return 0;

+} /* f_truncating */

+

+

+void f_dotest ( unsigned char t )

+{

+  _f_dump( "File system test started..." );

+  _f_dump( "WARNING: The contents of your drive will be destroyed!\n" );

+

+  (void)_f_poweron();

+

+  switch ( t )

+  {

+    case 0:

+    case 1:

+      (void)f_formatting();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 2:

+      (void)f_dirtest();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 3:

+      (void)f_findingtest();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 4:

+      (void)f_powerfail();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 5:

+      (void)f_seeking( 128 );

+      if ( t )

+      {

+        break;

+      }

+

+  #if ( F_MAX_SEEK_TEST > 128 )

+

+    /* fall through */

+    case 6:

+      (void)f_seeking( 256 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 256 )

+

+    /* fall through */

+    case 7:

+      (void)f_seeking( 512 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 512 )

+

+    /* fall through */

+    case 8:

+      (void)f_seeking( 1024 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 1024 )

+

+    /* fall through */

+    case 9:

+      (void)f_seeking( 2048 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 2048 )

+

+    /* fall through */

+    case 10:

+      (void)f_seeking( 4096 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 4096 )

+

+    /* fall through */

+    case 11:

+      (void)f_seeking( 8192 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 8192 )

+

+    /* fall through */

+    case 12:

+      (void)f_seeking( 16384 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+  #if ( F_MAX_SEEK_TEST > 16384 )

+

+    /* fall through */

+    case 13:

+      (void)f_seeking( 32768 );

+      if ( t )

+      {

+        break;

+      }

+

+  #endif

+

+    /* fall through */

+    case 14:

+      (void)f_opening();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 15:

+      (void)f_appending();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 16:

+      (void)f_writing();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 17:

+      (void)f_dots();

+      if ( t )

+      {

+        break;

+      }

+

+

+    /* fall through */

+    case 18:

+      (void)f_rit();

+      if ( t )

+      {

+        break;

+      }

+

+    case 19:

+      (void)f_truncating();

+      if ( t )

+      {

+        break;

+      }

+

+      break;

+  } /* switch */

+

+  _f_dump( "End of tests..." );

+} /* f_dotest */

+

+

+

+/****************************************************************************

+ *

+ * end of test.c

+ *

+ ***************************************************************************/

+#endif  /*_TEST_C_*/

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h
new file mode 100644
index 0000000..cc62749
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h
@@ -0,0 +1,116 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef __TEST_H

+#define __TEST_H

+

+#include "../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2

+ #error Incompatible FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+

+/*

+** Maximum size for seek test.

+** Options: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768

+*/

+#define F_MAX_SEEK_TEST 16384

+

+

+/*

+** Defines media type for testing.

+** Options: F_FAT12_MEDIA, F_FAT16_MEDIA

+*/

+#define F_FAT_TYPE      F_FAT12_MEDIA

+

+

+/*

+** Start filesystem test.

+** Parameter:

+**	0  - run all the tests

+**

+**	2  - directory

+**	3  - find

+**

+**	5* - seek 128

+**	6* - seek 256

+**	7* - seek 512

+**	8* - seek 1024

+**	9* - seek 2048

+**	10*- seek 4096

+**	11*- seek 8192

+**	12*- seek 16384

+**	13*- seek 32768

+**	14 - open

+**	15 - append

+**	16 - write

+**	17 - dots

+**	18 - rit

+**  *Note that only seek tests allowed by F_MAX_SEEK_TEST are executed.

+**

+**  The following defines are required for the specific test:

+**			                  1 1 1 1 1 1 1 1 1

+**			  2 3   5 6 7 8 9 0 1 2 3 4 5 6 7 8

+** F_CHDIR		  x x   - - - - - - - - - - x - x -

+** F_MKDIR		  x x   - - - - - - - - - - - - x -

+** F_RMDIR		  x x   - - - - - - - - - - x - x -

+** F_DELETE		  x x   x x x x x x x x x x x x x x

+** F_FILELENGTH		  - -   x x x x x x x x x x x x - -

+** F_FINDING		  x x   - - - - - - - - - - x - - -

+** F_TELL		  - -   x x x x x x x x x x x x - x

+** F_REWIND		  - -   - - - - - - - - - x - - - -

+** F_EOF		  - -   x x x x x x x x x - - x - -

+** F_SEEK		  - -   x x x x x x x x x - x x - x

+** F_WRITE		  - -   x x x x x x x x x x x x - x

+** F_WRITING		  x x   x x x x x x x x x x x x x x

+** F_DIRECTORIES	  x x   - - - - - - - - - - x - x -

+** F_CHECKNAME		  x -   - - - - - - - - - - - - x -

+*/

+void f_dotest ( unsigned char );

+

+#ifdef __cplusplus

+}

+#endif

+

+#endif /* ifndef __TEST_H */

+

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c
new file mode 100644
index 0000000..5d1d49f
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c
@@ -0,0 +1,247 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include "../../api/api_mdriver_ram.h"

+#include "config_mdriver_ram.h"

+#include "../../psp/include/psp_string.h"

+

+#include "../../version/ver_mdriver_ram.h"

+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2

+ #error Incompatible MDRIVER_RAM version number!

+#endif

+

+

+char  ramdrv0[MDRIVER_RAM_VOLUME0_SIZE];

+

+typedef struct

+{

+  char         * ramdrv;

+  unsigned long  maxsector;

+  int            use;

+  F_DRIVER     * driver;

+} t_RamDrv;

+

+static F_DRIVER  t_drivers[1];

+

+static t_RamDrv  RamDrv[1] =

+{

+  { ramdrv0, ( MDRIVER_RAM_VOLUME0_SIZE / MDRIVER_RAM_SECTOR_SIZE ), 0, &t_drivers[0] }

+};

+

+

+/****************************************************************************

+ * Read one sector

+ ***************************************************************************/

+static int ram_readsector ( F_DRIVER * driver, void * data, unsigned long sector )

+{

+  long       len;

+  char     * d = (char *)data;

+  char     * s;

+  t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );

+

+  if ( sector >= p->maxsector )

+  {

+    return MDRIVER_RAM_ERR_SECTOR;

+  }

+

+  s = p->ramdrv;

+  s += sector * MDRIVER_RAM_SECTOR_SIZE;

+  len = MDRIVER_RAM_SECTOR_SIZE;

+

+#if MDRIVER_MEM_LONG_ACCESS

+  if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) )

+  {

+    long * dd = (long *)d;

+    long * ss = (long *)s;

+    len >>= 2;

+    while ( len-- )

+    {

+      *dd++ = *ss++;

+    }

+

+    return MDRIVER_RAM_NO_ERROR;

+  }

+

+#endif /* if MDRIVER_MEM_LONG_ACCESS */

+

+  while ( len-- )

+  {

+    *d++ = *s++;

+  }

+

+  return MDRIVER_RAM_NO_ERROR;

+}

+

+/****************************************************************************

+ * Write one sector

+ ***************************************************************************/

+static int ram_writesector ( F_DRIVER * driver, void * data, unsigned long sector )

+{

+  long       len;

+  char     * s = (char *)data;

+  char     * d;

+  t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );

+

+  if ( sector >= p->maxsector )

+  {

+    return MDRIVER_RAM_ERR_SECTOR;

+  }

+

+  d = p->ramdrv;

+  d += sector * MDRIVER_RAM_SECTOR_SIZE;

+  len = MDRIVER_RAM_SECTOR_SIZE;

+

+#if MDRIVER_MEM_LONG_ACCESS

+  if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) )

+  {

+    long * dd = (long *)d;

+    long * ss = (long *)s;

+    len >>= 2;

+    while ( len-- )

+    {

+      *dd++ = *ss++;

+    }

+

+    return MDRIVER_RAM_NO_ERROR;

+  }

+

+#endif /* if MDRIVER_MEM_LONG_ACCESS */

+

+  while ( len-- )

+  {

+    *d++ = *s++;

+  }

+

+  return MDRIVER_RAM_NO_ERROR;

+}

+

+

+/****************************************************************************

+ *

+ * ram_getphy

+ *

+ * determinate ramdrive physicals

+ *

+ * INPUTS

+ *

+ * driver - driver structure

+ * phy - this structure has to be filled with physical information

+ *

+ * RETURNS

+ *

+ * error code or zero if successful

+ *

+ ***************************************************************************/

+static int ram_getphy ( F_DRIVER * driver, F_PHY * phy )

+{

+  t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );

+

+  phy->number_of_sectors = p->maxsector;

+  phy->bytes_per_sector = MDRIVER_RAM_SECTOR_SIZE;

+

+  return MDRIVER_RAM_NO_ERROR;

+}

+

+

+/****************************************************************************

+ *

+ * ram_release

+ *

+ * Releases a drive

+ *

+ * INPUTS

+ *

+ * driver_param - driver parameter

+ *

+ ***************************************************************************/

+static void ram_release ( F_DRIVER * driver )

+{

+  t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );

+

+  if ( p == RamDrv )

+  {

+    p->use = 0;

+  }

+}

+

+

+/****************************************************************************

+ *

+ * ram_initfunc

+ *

+ * this init function has to be passed for highlevel to initiate the

+ * driver functions

+ *

+ * INPUTS

+ *

+ * driver_param - driver parameter

+ *

+ * RETURNS

+ *

+ * driver structure pointer

+ *

+ ***************************************************************************/

+F_DRIVER * ram_initfunc ( unsigned long driver_param )

+{

+  t_RamDrv    * p;

+

+  p = RamDrv + driver_param;

+

+  if ( p != RamDrv )

+  {

+    return 0;

+  }

+

+  if ( p->use )

+  {

+    return 0;

+  }

+

+  (void)psp_memset( p->driver, 0, sizeof( F_DRIVER ) );

+

+  p->driver->readsector = ram_readsector;

+  p->driver->writesector = ram_writesector;

+  p->driver->getphy = ram_getphy;

+  p->driver->release = ram_release;

+  p->driver->user_ptr = p;

+

+  p->use = 1;

+

+  return p->driver;

+} /* ram_initfunc */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h
new file mode 100644
index 0000000..7f1d560
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h
@@ -0,0 +1,71 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _PSP_RTC_H

+#define _PSP_RTC_H

+

+#include <stdint.h>

+

+#include "../../version/ver_psp_rtc.h"

+#if VER_PSP_RTC_MAJOR != 1

+ #error "VER_PSP_RTC_MAJOR invalid"

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+typedef struct

+{

+  uint8_t   sec;

+  uint8_t   min;

+  uint8_t   hour;

+  uint8_t   day;

+  uint8_t   month;

+  uint16_t  year;

+} t_psp_timedate;

+

+void psp_getcurrenttimedate ( t_psp_timedate * p_timedate );

+

+#ifdef __cplusplus

+}

+#endif

+

+

+#endif /* _PSP_RTC_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h
new file mode 100644
index 0000000..310e439
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h
@@ -0,0 +1,60 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _PSP_STRING_H_

+#define _PSP_STRING_H_

+

+#include <stddef.h>

+#include <string.h>

+

+#include "../../version/ver_psp_string.h"

+#if VER_PSP_STRING_MAJOR != 1 || VER_PSP_STRING_MINOR != 4

+ #error Incompatible PSP_STRING version number!

+#endif

+

+#define psp_memcpy( d, s, l )    memcpy( ( d ), ( s ), (size_t)( l ) )

+#define psp_memmove( d, s, l )   memmove( ( d ), ( s ), (size_t)( l ) )

+#define psp_memset( d, c, l )    memset( ( d ), ( c ), (size_t)( l ) )

+#define psp_memcmp( s1, s2, l )  memcmp( ( s1 ), ( s2 ), (size_t)( l ) )

+#define psp_strnlen( s, l )      strnlen( ( s ), ( size_t )( l ) )

+#define psp_strncat( d, s, l )   strncat( ( d ), ( s ), (size_t)( l ) )

+#define psp_strncpy( d, s, l )   strncpy( ( d ), ( s ), (size_t)( l ) )

+#define psp_strncmp( s1, s2, l ) strncmp( ( s1 ), ( s2 ), (size_t)( l ) )

+

+#endif /* ifndef _PSP_STRING_H_ */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c
new file mode 100644
index 0000000..62446fe
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c
@@ -0,0 +1,86 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include <stdio.h>

+#include "psp_test.h"

+#include "config_fat_sl.h"

+#include "config_mdriver_ram.h"

+#include "../../../api/fat_sl.h"

+#include "../../../api/api_mdriver_ram.h"

+

+#include "../../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3

+ #error Incompatible FAT_SL version number!

+#endif

+#include "../../../version/ver_psp_fat_sl.h"

+#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1

+ #error Incompatible PSP_FAT_FAT_SL version number!

+#endif

+

+uint8_t  all_tests_passed = 1u;

+

+/* Use to display text (printf). */

+void _f_dump ( char * s )

+{

+  printf( "%s\r\n", s );

+}

+

+/* Use to display test result (printf). */

+uint8_t _f_result ( uint8_t testnum, uint32_t result )

+{

+  (void)testnum;

+  if ( result == 0 )

+  {

+    printf( "Passed\r\n" );

+  }

+  else

+  {

+    printf( "FAILED! Error code: %u\r\n", result );

+    all_tests_passed = 0u;

+  }

+

+  return 0;

+}

+

+/* Use to build file system (mount). */

+uint8_t _f_poweron ( void )

+{

+  f_delvolume();

+  return f_initvolume( ram_initfunc );

+}

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h
new file mode 100644
index 0000000..630c60f
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h
@@ -0,0 +1,75 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _PSP_FAT_FAT_SL_H

+#define _PSP_FAT_FAT_SL_H

+

+#include <stdint.h>

+#include "../../../psp/include/psp_string.h"

+

+#include "../../../version/ver_fat_sl.h"

+#if VER_FAT_SL_MAJOR != 3

+ #error Incompatible FAT_SL version number!

+#endif

+#include "../../../version/ver_psp_fat_sl.h"

+#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1

+ #error Incompatible PSP_FAT_FAT_SL version number!

+#endif

+

+#ifdef __cplusplus

+extern "C" {

+#endif

+

+extern uint8_t  all_tests_passed;

+

+/* Use to display text (printf). */

+void _f_dump ( char * s );

+

+/* Use to display test result (printf). */

+uint8_t _f_result ( uint8_t testnum, uint32_t result );

+

+/* Use to build file system (mount). */

+uint8_t _f_poweron ( void );

+

+#ifdef __cplusplus

+}

+#endif

+

+

+#endif /* _PSP_FAT_FAT_SL_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c
new file mode 100644
index 0000000..45b3a99
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c
@@ -0,0 +1,80 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#include <stdint.h>

+#include <stddef.h>

+#include "../../include/psp_rtc.h"

+

+#include "../../../version/ver_psp_rtc.h"

+#if VER_PSP_RTC_MAJOR != 1

+ #error "VER_PSP_RTC_MAJOR invalid"

+#endif

+#if VER_PSP_RTC_MINOR != 0

+ #error "VER_PSP_RTC_MINOR invalid"

+#endif

+

+

+/****************************************************************************

+ *

+ * psp_getcurrenttimedate

+ *

+ * Need to be ported depending on system, it retreives the

+ * current time and date.

+ * Please take care of correct roll-over handling.

+ * Roll-over problem is to read a date at 23.59.59 and then reading time at

+ * 00:00.00.

+ *

+ * INPUT

+ *

+ * p_timedate - pointer where to store time and date

+ *

+ ***************************************************************************/

+void psp_getcurrenttimedate ( t_psp_timedate * p_timedate )

+{

+  if ( p_timedate != NULL )

+  {

+    p_timedate->sec = 0;

+    p_timedate->min = 0;

+    p_timedate->hour = 12u;

+

+    p_timedate->day = 1u;

+    p_timedate->month = 1u;

+    p_timedate->year = 1980u;

+  }

+} /* psp_getcurrenttimedate */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h
new file mode 100644
index 0000000..f521ffb
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_FAT_SL_H

+#define _VER_FAT_SL_H

+

+#define VER_FAT_SL_MAJOR 3

+#define VER_FAT_SL_MINOR 2

+

+#endif

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h
new file mode 100644
index 0000000..4a9468d
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_MDRIVER_H

+#define _VER_MDRIVER_H

+

+#define VER_MDRIVER_MAJOR 1

+#define VER_MDRIVER_MINOR 0

+

+#endif

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h
new file mode 100644
index 0000000..384a091
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_MDRIVER_RAM_H

+#define _VER_MDRIVER_RAM_H

+

+#define VER_MDRIVER_RAM_MAJOR 1

+#define VER_MDRIVER_RAM_MINOR 2

+

+#endif

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h
new file mode 100644
index 0000000..98a22e1
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_PSP_FAT_FAT_SL_H

+#define _VER_PSP_FAT_FAT_SL_H

+

+#define VER_PSP_FAT_FAT_SL_MAJOR 1

+#define VER_PSP_FAT_FAT_SL_MINOR 1

+

+#endif  /* _VER_PSP_FAT_FAT_SL_H */

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h
new file mode 100644
index 0000000..8a65db0
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_PSP_RTC_H

+#define _VER_PSP_RTC_H

+

+#define VER_PSP_RTC_MAJOR 1

+#define VER_PSP_RTC_MINOR 0

+

+#endif

+

diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h
new file mode 100644
index 0000000..2ed0415
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h
@@ -0,0 +1,46 @@
+/*

+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded

+ *

+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 

+ * terms.

+ * 

+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used

+ * under a pure GPL open source license (as opposed to the modified GPL licence

+ * under which FreeRTOS is distributed) or a commercial license.  Details of 

+ * both license options follow:

+ * 

+ * - Open source licensing -

+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and

+ * distributed without charge provided the user adheres to version two of the 

+ * GNU General Public License (GPL) and does not remove the copyright notice or 

+ * this text.  The GPL V2 text is available on the gnu.org web site, and on the

+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.

+ * 

+ * - Commercial licensing -

+ * Businesses and individuals who for commercial or other reasons cannot comply

+ * with the terms of the GPL V2 license must obtain a commercial license before 

+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 

+ * any form.  Commercial licenses can be purchased from 

+ * http://shop.freertos.org/fat_sl and do not require any source files to be 

+ * changed.

+ *

+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You

+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as

+ * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the

+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A

+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all

+ * conditions and terms, be they implied, expressed, or statutory.

+ *

+ * http://www.FreeRTOS.org

+ * http://www.FreeRTOS.org/FreeRTOS-Plus

+ *

+ */

+

+#ifndef _VER_PSP_STRING_H

+#define _VER_PSP_STRING_H

+

+#define VER_PSP_STRING_MAJOR 1

+#define VER_PSP_STRING_MINOR 4

+

+#endif

+

diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h
index 64cb0bb..e6aabb8 100644
--- a/FreeRTOS/Source/include/FreeRTOS.h
+++ b/FreeRTOS/Source/include/FreeRTOS.h
@@ -568,10 +568,6 @@
 	#define configUSE_QUEUE_SETS 0

 #endif

 

-#ifndef portTASK_USES_FLOATING_POINT

-	#defeine portTASK_USES_FLOATING_POINT()

-#endif

-

 /* For backward compatability. */

 #define eTaskStateGet eTaskGetState