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