--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
+ Integrity Systems, who sell the code with commercial support, \r
+ indemnification and middleware, under the OpenRTOS brand.\r
+ \r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
+ engineered and independently SIL3 certified version for use in safety and \r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
+ * http://www.freertos.org/a00110.html\r
+ *\r
+ * The bottom of this file contains some constants specific to running the UDP\r
+ * stack in this demo. Constants specific to FreeRTOS+UDP itself (rather than\r
+ * the demo) are contained in FreeRTOSIPConfig.h.\r
+ *----------------------------------------------------------*/\r
+\r
+#define configUSE_PREEMPTION 1\r
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 7 )\r
+#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. */\r
+#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. */\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32U * 1024U ) )\r
+#define configMAX_TASK_NAME_LEN ( 7 )\r
+#define configUSE_TRACE_FACILITY 1\r
+#define configUSE_16_BIT_TICKS 0\r
+#define configIDLE_SHOULD_YIELD 1\r
+#define configUSE_CO_ROUTINES 0\r
+#define configUSE_MUTEXES 1\r
+#define configUSE_RECURSIVE_MUTEXES 1\r
+#define configQUEUE_REGISTRY_SIZE 0\r
+#define configUSE_APPLICATION_TASK_TAG 0\r
+#define configUSE_COUNTING_SEMAPHORES 1\r
+#define configUSE_ALTERNATIVE_API 0\r
+\r
+/* Hook function related definitions. */\r
+#define configUSE_TICK_HOOK 0\r
+#define configUSE_IDLE_HOOK 1\r
+#define configUSE_MALLOC_FAILED_HOOK 1\r
+#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */\r
+\r
+/* Software timer related definitions. */\r
+#define configUSE_TIMERS 1\r
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )\r
+#define configTIMER_QUEUE_LENGTH 5\r
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )\r
+\r
+/* Run time stats gathering definitions. */\r
+unsigned long ulGetRunTimeCounterValue( void );\r
+void vConfigureTimerForRunTimeStats( void );\r
+#define configGENERATE_RUN_TIME_STATS 1\r
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()\r
+#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()\r
+\r
+/* Co-routine definitions. */\r
+#define configUSE_CO_ROUTINES 0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero\r
+to exclude the API function. */\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 1\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+#define INCLUDE_xTaskGetSchedulerState 1\r
+#define INCLUDE_xTimerGetTimerTaskHandle 0\r
+#define INCLUDE_xTaskGetIdleTaskHandle 0\r
+#define INCLUDE_xQueueGetMutexHolder 1\r
+\r
+/* Assert call defined for debug builds. */\r
+#ifdef _DEBUG\r
+ extern void vAssertCalled( const char *pcFile, unsigned long ulLine );\r
+ #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )\r
+#endif /* _DEBUG */\r
+\r
+\r
+\r
+/* Application specific definitions follow. **********************************/\r
+\r
+/* The UDP port to use for incoming command inputs. The outgoing port is\r
+set to ( configUDP_CLI_PORT_NUMBER + 1 ). */\r
+#define configUDP_CLI_PORT_NUMBER 5001\r
+\r
+/* The size of the global output buffer that is available for use when there\r
+are multiple command interpreters running at once (for example, one on a UART\r
+and one on TCP/IP). This is done to prevent an output buffer being defined by\r
+each implementation - which would waste RAM. In this case, there is only one\r
+command interpreter running, and it has its own local output buffer, so the\r
+global buffer is just set to be one byte long as it is not used and should not\r
+take up unnecessary RAM. */\r
+#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1\r
+\r
+#endif /* FREERTOS_CONFIG_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers\r
+ * Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of\r
+ * the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS,\r
+ * and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual\r
+ * license model, information on which is provided below:\r
+ *\r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified and distributed\r
+ * without charge provided the user adheres to version two of the GNU General\r
+ * Public license (GPL) and does not remove the copyright notice or this text.\r
+ * The GPL V2 text is available on the gnu.org web site, and on the following\r
+ * URL: http://www.FreeRTOS.org/gpl-2.0.txt\r
+ *\r
+ * - Commercial licensing -\r
+ * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into\r
+ * proprietary software for redistribution in any form must first obtain a\r
+ * commercial license - and in-so-doing support the maintenance, support and\r
+ * further development of the FreeRTOS+FAT SL product. Commercial licenses can\r
+ * be obtained from http://shop.freertos.org and do not require any source files\r
+ * to be changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _CONFIG_FAT_SL_H\r
+#define _CONFIG_FAT_SL_H\r
+\r
+#include "../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#include "../api/api_mdriver.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/**************************************************************************\r
+**\r
+** FAT SL user settings\r
+**\r
+**************************************************************************/\r
+#define F_SECTOR_SIZE 512u /* Disk sector size. */\r
+#define F_FS_THREAD_AWARE 1 /* Set to one if the file system will be access from more than one task. */\r
+#define F_MAXPATH 64 /* Maximum length a file name (including its full path) can be. */\r
+#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. */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _CONFIG_FAT_SL_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers\r
+ * Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of\r
+ * the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS,\r
+ * and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual\r
+ * license model, information on which is provided below:\r
+ *\r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified and distributed\r
+ * without charge provided the user adheres to version two of the GNU General\r
+ * Public license (GPL) and does not remove the copyright notice or this text.\r
+ * The GPL V2 text is available on the gnu.org web site, and on the following\r
+ * URL: http://www.FreeRTOS.org/gpl-2.0.txt\r
+ *\r
+ * - Commercial licensing -\r
+ * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into\r
+ * proprietary software for redistribution in any form must first obtain a\r
+ * commercial license - and in-so-doing support the maintenance, support and\r
+ * further development of the FreeRTOS+FAT SL product. Commercial licenses can\r
+ * be obtained from http://shop.freertos.org and do not require any source files\r
+ * to be changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _CONFIG_MDRIVER_RAM_H_\r
+#define _CONFIG_MDRIVER_RAM_H_\r
+\r
+#include "../version/ver_mdriver_ram.h"\r
+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2\r
+ #error Incompatible MDRIVER_RAM version number!\r
+#endif\r
+\r
+#define MDRIVER_RAM_SECTOR_SIZE 512 /* Sector size */\r
+\r
+#define MDRIVER_RAM_VOLUME0_SIZE (128 * 1024) /* defintion for size of ramdrive0 */\r
+\r
+#define MDRIVER_MEM_LONG_ACCESS 1 /* set this value to 1 if 32bit access available */\r
+\r
+#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems, who sell the code with commercial support,\r
+ indemnification and middleware, under the OpenRTOS brand.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+/* File system includes. */\r
+#include "fat_sl.h"\r
+#include "api_mdriver_ram.h"\r
+#include "test.h"\r
+\r
+#ifdef _WINDOWS_\r
+ #define snprintf _snprintf\r
+#endif\r
+\r
+#define cliNEW_LINE "\r\n"\r
+\r
+/*******************************************************************************\r
+ * See the URL in the comments within main.c for the location of the online\r
+ * documentation.\r
+ ******************************************************************************/\r
+\r
+/*\r
+ * Print out information on a single file.\r
+ */\r
+static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct );\r
+\r
+/*\r
+ * Copies an existing file into a newly created file.\r
+ */\r
+static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,\r
+ int32_t lSourceFileLength,\r
+ int8_t *pcDestinationFile,\r
+ int8_t *pxWriteBuffer,\r
+ size_t xWriteBufferLen );\r
+\r
+/*\r
+ * Implements the DIR command.\r
+ */\r
+static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the CD command.\r
+ */\r
+static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the DEL command.\r
+ */\r
+static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the TYPE command.\r
+ */\r
+static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the COPY command.\r
+ */\r
+static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the TEST command.\r
+ */\r
+static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/* Structure that defines the DIR command line command, which lists all the\r
+files in the current directory. */\r
+static const CLI_Command_Definition_t xDIR =\r
+{\r
+ ( const int8_t * const ) "dir", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ndir:\r\n Lists the files in the current directory\r\n",\r
+ prvDIRCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the CD command line command, which changes the\r
+working directory. */\r
+static const CLI_Command_Definition_t xCD =\r
+{\r
+ ( const int8_t * const ) "cd", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ncd <dir name>:\r\n Changes the working directory\r\n",\r
+ prvCDCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the TYPE command line command, which prints the\r
+contents of a file to the console. */\r
+static const CLI_Command_Definition_t xTYPE =\r
+{\r
+ ( const int8_t * const ) "type", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",\r
+ prvTYPECommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the DEL command line command, which deletes a file. */\r
+static const CLI_Command_Definition_t xDEL =\r
+{\r
+ ( const int8_t * const ) "del", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ndel <filename>:\r\n deletes a file or directory\r\n",\r
+ prvDELCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the COPY command line command, which deletes a file. */\r
+static const CLI_Command_Definition_t xCOPY =\r
+{\r
+ ( const int8_t * const ) "copy", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",\r
+ prvCOPYCommand, /* The function to run. */\r
+ 2 /* Two parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the TEST command line command, which executes some\r
+file system driver tests. */\r
+static const CLI_Command_Definition_t xTEST_FS =\r
+{\r
+ ( const int8_t * const ) "testfs", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ntest_fs:\r\n Executes some file system test. ALL FILES WILL BE DELETED!!!\r\n",\r
+ prvTESTFSCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vRegisterFileSystemCLICommands( void )\r
+{\r
+ /* Register all the command line commands defined immediately above. */\r
+ FreeRTOS_CLIRegisterCommand( &xDIR );\r
+ FreeRTOS_CLIRegisterCommand( &xCD );\r
+ FreeRTOS_CLIRegisterCommand( &xTYPE );\r
+ FreeRTOS_CLIRegisterCommand( &xDEL );\r
+ FreeRTOS_CLIRegisterCommand( &xCOPY );\r
+ FreeRTOS_CLIRegisterCommand( &xTEST_FS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcParameter;\r
+portBASE_TYPE xParameterStringLength, xReturn = pdTRUE;\r
+static F_FILE *pxFile = NULL;\r
+int iChar;\r
+size_t xByte;\r
+size_t xColumns = 50U;\r
+\r
+ /* Ensure there is always a null terminator after each character written. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ if( xWriteBufferLen < xColumns )\r
+ {\r
+ /* Ensure the loop that uses xColumns as an end condition does not\r
+ write off the end of the buffer. */\r
+ xColumns = xWriteBufferLen;\r
+ }\r
+\r
+ if( pxFile == NULL )\r
+ {\r
+ /* The file has not been opened yet. Find the file name. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to open the requested file. */\r
+ pxFile = f_open( ( const char * ) pcParameter, "r" );\r
+ }\r
+\r
+ if( pxFile != NULL )\r
+ {\r
+ /* Read the next chunk of data from the file. */\r
+ for( xByte = 0; xByte < xColumns; xByte++ )\r
+ {\r
+ iChar = f_getc( pxFile );\r
+\r
+ if( iChar == -1 )\r
+ {\r
+ /* No more characters to return. */\r
+ f_close( pxFile );\r
+ pxFile = NULL;\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ pcWriteBuffer[ xByte ] = ( int8_t ) iChar;\r
+ }\r
+ }\r
+ }\r
+\r
+ if( pxFile == NULL )\r
+ {\r
+ /* Either the file was not opened, or all the data from the file has\r
+ been returned and the file is now closed. */\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcParameter;\r
+portBASE_TYPE xParameterStringLength;\r
+unsigned char ucReturned;\r
+size_t xStringLength;\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to move to the requested directory. */\r
+ ucReturned = f_chdir( ( char * ) pcParameter );\r
+\r
+ if( ucReturned == F_NO_ERROR )\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "In: " );\r
+ xStringLength = strlen( ( const char * ) pcWriteBuffer );\r
+ f_getcwd( ( char * ) &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) );\r
+ }\r
+ else\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Error" );\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+static F_FIND *pxFindStruct = NULL;\r
+unsigned char ucReturned;\r
+portBASE_TYPE xReturn = pdFALSE;\r
+\r
+ /* This assumes pcWriteBuffer is long enough. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ if( pxFindStruct == NULL )\r
+ {\r
+ /* This is the first time this function has been executed since the Dir\r
+ command was run. Create the find structure. */\r
+ pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) );\r
+\r
+ if( pxFindStruct != NULL )\r
+ {\r
+ ucReturned = f_findfirst( "*.*", pxFindStruct );\r
+\r
+ if( ucReturned == F_NO_ERROR )\r
+ {\r
+ prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The find struct has already been created. Find the next file in\r
+ the directory. */\r
+ ucReturned = f_findnext( pxFindStruct );\r
+\r
+ if( ucReturned == F_NO_ERROR )\r
+ {\r
+ prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* There are no more files. Free the find structure. */\r
+ vPortFree( pxFindStruct );\r
+ pxFindStruct = NULL;\r
+\r
+ /* No string to return. */\r
+ pcWriteBuffer[ 0 ] = 0x00;\r
+ }\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcParameter;\r
+portBASE_TYPE xParameterStringLength;\r
+unsigned char ucReturned;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to delete the file. */\r
+ ucReturned = f_delete( ( const char * ) pcParameter );\r
+\r
+ if( ucReturned == F_NO_ERROR )\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "%s was deleted", pcParameter );\r
+ }\r
+ else\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Error" );\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+unsigned portBASE_TYPE uxOriginalPriority;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) xWriteBufferLen;\r
+ ( void ) pcCommandString;\r
+\r
+ /* Limitations in the interaction with the Windows TCP/IP stack require\r
+ the command console to run at the idle priority. Raise the priority for\r
+ the duration of the tests to ensure there are not multiple switches to the\r
+ idle task as in the simulated environment the idle task hook function may\r
+ include a (relatively) long delay. */\r
+ uxOriginalPriority = uxTaskPriorityGet( NULL );\r
+ vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );\r
+\r
+ f_dotest( 0 );\r
+\r
+ /* Reset back to the original priority. */\r
+ vTaskPrioritySet( NULL, uxOriginalPriority );\r
+\r
+ sprintf( ( char * ) pcWriteBuffer, "%s", "Test results were sent to Windows console" );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcSourceFile, *pcDestinationFile;\r
+portBASE_TYPE xParameterStringLength;\r
+long lSourceLength, lDestinationLength = 0;\r
+\r
+ /* Obtain the name of the destination file. */\r
+ pcDestinationFile = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 2, /* Return the second parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcDestinationFile );\r
+\r
+ /* Obtain the name of the source file. */\r
+ pcSourceFile = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcSourceFile );\r
+\r
+ /* Terminate the string. */\r
+ pcSourceFile[ xParameterStringLength ] = 0x00;\r
+\r
+ /* See if the source file exists, obtain its length if it does. */\r
+ lSourceLength = f_filelength( ( const char * ) pcSourceFile );\r
+\r
+ if( lSourceLength == 0 )\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Source file does not exist" );\r
+ }\r
+ else\r
+ {\r
+ /* See if the destination file exists. */\r
+ lDestinationLength = f_filelength( ( const char * ) pcDestinationFile );\r
+\r
+ if( lDestinationLength != 0 )\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Error: Destination file already exists" );\r
+ }\r
+ }\r
+\r
+ /* Continue only if the source file exists and the destination file does\r
+ not exist. */\r
+ if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) )\r
+ {\r
+ if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS )\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Copy made" );\r
+ }\r
+ else\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Error during copy" );\r
+ }\r
+ }\r
+\r
+ strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,\r
+ int32_t lSourceFileLength,\r
+ int8_t *pcDestinationFile,\r
+ int8_t *pxWriteBuffer,\r
+ size_t xWriteBufferLen )\r
+{\r
+int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining;\r
+F_FILE *pxFile;\r
+portBASE_TYPE xReturn = pdPASS;\r
+\r
+ /* NOTE: Error handling has been omitted for clarity. */\r
+\r
+ while( lBytesRead < lSourceFileLength )\r
+ {\r
+ /* How many bytes are left? */\r
+ lBytesRemaining = lSourceFileLength - lBytesRead;\r
+\r
+ /* How many bytes should be read this time around the loop. Can't\r
+ read more bytes than will fit into the buffer. */\r
+ if( lBytesRemaining > ( long ) xWriteBufferLen )\r
+ {\r
+ lBytesToRead = ( long ) xWriteBufferLen;\r
+ }\r
+ else\r
+ {\r
+ lBytesToRead = lBytesRemaining;\r
+ }\r
+\r
+ /* Open the source file, seek past the data that has already been\r
+ read from the file, read the next block of data, then close the\r
+ file again so the destination file can be opened. */\r
+ pxFile = f_open( ( const char * ) pcSourceFile, "r" );\r
+ if( pxFile != NULL )\r
+ {\r
+ f_seek( pxFile, lBytesRead, F_SEEK_SET );\r
+ f_read( pxWriteBuffer, lBytesToRead, 1, pxFile );\r
+ f_close( pxFile );\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ break;\r
+ }\r
+\r
+ /* Open the destination file and write the block of data to the end of\r
+ the file. */\r
+ pxFile = f_open( ( const char * ) pcDestinationFile, "a" );\r
+ if( pxFile != NULL )\r
+ {\r
+ f_write( pxWriteBuffer, lBytesToRead, 1, pxFile );\r
+ f_close( pxFile );\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ break;\r
+ }\r
+\r
+ lBytesRead += lBytesToRead;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct )\r
+{\r
+const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory";\r
+const char * pcAttrib;\r
+\r
+ /* Point pcAttrib to a string that describes the file. */\r
+ if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 )\r
+ {\r
+ pcAttrib = pcDirectory;\r
+ }\r
+ else if( pxFindStruct->attr & F_ATTR_READONLY )\r
+ {\r
+ pcAttrib = pcReadOnlyFile;\r
+ }\r
+ else\r
+ {\r
+ pcAttrib = pcWritableFile;\r
+ }\r
+\r
+ /* Create a string that includes the file name, the file size and the\r
+ attributes string. */\r
+ sprintf( ( char * ) pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, pxFindStruct->filesize );\r
+}\r
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems, who sell the code with commercial support,\r
+ indemnification and middleware, under the OpenRTOS brand.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+/*******************************************************************************\r
+ * See the URL in the comments within main.c for the location of the online\r
+ * documentation.\r
+ ******************************************************************************/\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* File system includes. */\r
+#include "fat_sl.h"\r
+#include "api_mdriver_ram.h"\r
+\r
+/* 8.3 format, plus null terminator. */\r
+#define fsMAX_FILE_NAME_LEN 13\r
+\r
+/* The number of bytes read/written to the example files at a time. */\r
+#define fsRAM_BUFFER_SIZE 200\r
+\r
+/* The number of bytes written to the file that uses f_putc() and f_getc(). */\r
+#define fsPUTC_FILE_SIZE 100\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Creates and verifies different files on the volume, demonstrating the use of\r
+ * various different API functions.\r
+ */\r
+void vCreateAndVerifySampleFiles( void );\r
+\r
+/*\r
+ * Create a set of example files in the root directory of the volume using\r
+ * f_write().\r
+ */\r
+static void prvCreateDemoFilesUsing_f_write( void );\r
+\r
+/*\r
+ * Use f_read() to read back and verify the files that were created by\r
+ * prvCreateDemoFilesUsing_f_write().\r
+ */\r
+static void prvVerifyDemoFileUsing_f_read( void );\r
+\r
+/*\r
+ * Create an example file in a sub-directory using f_putc().\r
+ */\r
+static void prvCreateDemoFileUsing_f_putc( void );\r
+\r
+/*\r
+ * Use f_getc() to read back and verify the file that was created by\r
+ * prvCreateDemoFileUsing_f_putc().\r
+ */\r
+static void prvVerifyDemoFileUsing_f_getc( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* A buffer used to both create content to write to disk, and read content back\r
+from a disk. Note there is no mutual exclusion on this buffer. */\r
+static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];\r
+\r
+/* Names of directories that are created. */\r
+static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCreateAndVerifySampleFiles( void )\r
+{\r
+unsigned char ucStatus;\r
+\r
+ /* First create the volume. */\r
+ ucStatus = f_initvolume( ram_initfunc );\r
+\r
+ /* It is expected that the volume is not formatted. */\r
+ if( ucStatus == F_ERR_NOTFORMATTED )\r
+ {\r
+ /* Format the created volume. */\r
+ ucStatus = f_format( F_FAT12_MEDIA );\r
+ }\r
+\r
+ if( ucStatus == F_NO_ERROR )\r
+ {\r
+ /* Create a set of files using f_write(). */\r
+ prvCreateDemoFilesUsing_f_write();\r
+\r
+ /* Read back and verify the files that were created using f_write(). */\r
+ prvVerifyDemoFileUsing_f_read();\r
+\r
+ /* Create sub directories two deep then create a file using putc. */\r
+ prvCreateDemoFileUsing_f_putc();\r
+\r
+ /* Read back and verify the file created by\r
+ prvCreateDemoFileUsing_f_putc(). */\r
+ prvVerifyDemoFileUsing_f_getc();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateDemoFilesUsing_f_write( void )\r
+{\r
+portBASE_TYPE xFileNumber, xWriteNumber;\r
+char cFileName[ fsMAX_FILE_NAME_LEN ];\r
+const portBASE_TYPE xMaxFiles = 5;\r
+long lItemsWritten;\r
+F_FILE *pxFile;\r
+\r
+ /* Create xMaxFiles files. Each created file will be\r
+ ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled\r
+ with a different repeating character. */\r
+ for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
+ {\r
+ /* Generate a file name. */\r
+ sprintf( cFileName, "root%03d.txt", xFileNumber );\r
+\r
+ /* Obtain the current working directory and print out the file name and\r
+ the directory into which the file is being written. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "Creating file %s in %s\r\n", cFileName, cRAMBuffer );\r
+\r
+ /* Open the file, creating the file if it does not already exist. */\r
+ pxFile = f_open( cFileName, "w" );\r
+ configASSERT( pxFile );\r
+\r
+ /* Fill the RAM buffer with data that will be written to the file. This\r
+ is just a repeating ascii character that indicates the file number. */\r
+ memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );\r
+\r
+ /* Write the RAM buffer to the opened file a number of times. The\r
+ number of times the RAM buffer is written to the file depends on the\r
+ file number, so the length of each created file will be different. */\r
+ for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )\r
+ {\r
+ lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );\r
+ configASSERT( lItemsWritten == 1 );\r
+ }\r
+\r
+ /* Close the file so another file can be created. */\r
+ f_close( pxFile );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvVerifyDemoFileUsing_f_read( void )\r
+{\r
+portBASE_TYPE xFileNumber, xReadNumber;\r
+char cFileName[ fsMAX_FILE_NAME_LEN ];\r
+const portBASE_TYPE xMaxFiles = 5;\r
+long lItemsRead, lChar;\r
+F_FILE *pxFile;\r
+\r
+ /* Read back the files that were created by\r
+ prvCreateDemoFilesUsing_f_write(). */\r
+ for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
+ {\r
+ /* Generate the file name. */\r
+ sprintf( cFileName, "root%03d.txt", xFileNumber );\r
+\r
+ /* Obtain the current working directory and print out the file name and\r
+ the directory from which the file is being read. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "Reading file %s from %s\r\n", cFileName, cRAMBuffer );\r
+\r
+ /* Open the file for reading. */\r
+ pxFile = f_open( cFileName, "r" );\r
+ configASSERT( pxFile );\r
+\r
+ /* Read the file into the RAM buffer, checking the file contents are as\r
+ expected. The size of the file depends on the file number. */\r
+ for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )\r
+ {\r
+ /* Start with the RAM buffer clear. */\r
+ memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );\r
+\r
+ lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );\r
+ configASSERT( lItemsRead == 1 );\r
+\r
+ /* Check the RAM buffer is filled with the expected data. Each\r
+ file contains a different repeating ascii character that indicates\r
+ the number of the file. */\r
+ for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )\r
+ {\r
+ configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );\r
+ }\r
+ }\r
+\r
+ /* Close the file. */\r
+ f_close( pxFile );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateDemoFileUsing_f_putc( void )\r
+{\r
+unsigned char ucReturn;\r
+int iByte, iReturned;\r
+F_FILE *pxFile;\r
+char cFileName[ fsMAX_FILE_NAME_LEN ];\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "In directory %s\r\n", cRAMBuffer );\r
+\r
+ /* Create a sub directory. */\r
+ ucReturn = f_mkdir( pcDirectory1 );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Move into the created sub-directory. */\r
+ ucReturn = f_chdir( pcDirectory1 );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "In directory %s\r\n", cRAMBuffer );\r
+\r
+ /* Create a subdirectory in the new directory. */\r
+ ucReturn = f_mkdir( pcDirectory2 );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Move into the directory just created - now two directories down from\r
+ the root. */\r
+ ucReturn = f_chdir( pcDirectory2 );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "In directory %s\r\n", cRAMBuffer );\r
+ configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );\r
+\r
+ /* Generate the file name. */\r
+ sprintf( cFileName, "%s.txt", pcDirectory2 );\r
+\r
+ /* Print out the file name and the directory into which the file is being\r
+ written. */\r
+ printf( "Writing file %s in %s\r\n", cFileName, cRAMBuffer );\r
+\r
+ pxFile = f_open( cFileName, "w" );\r
+\r
+ /* Create a file 1 byte at a time. The file is filled with incrementing\r
+ ascii characters starting from '0'. */\r
+ for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )\r
+ {\r
+ iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );\r
+ configASSERT( iReturned == ( ( int ) '0' + iByte ) );\r
+ }\r
+\r
+ /* Finished so close the file. */\r
+ f_close( pxFile );\r
+\r
+ /* Move back to the root directory. */\r
+ ucReturn = f_chdir( "../.." );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "Back in root directory %s\r\n", cRAMBuffer );\r
+ configASSERT( strcmp( ( const char * ) cRAMBuffer, pcRoot ) == 0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvVerifyDemoFileUsing_f_getc( void )\r
+{\r
+unsigned char ucReturn;\r
+int iByte, iReturned;\r
+F_FILE *pxFile;\r
+char cFileName[ fsMAX_FILE_NAME_LEN ];\r
+\r
+ /* Move into the directory in which the file was created. */\r
+ ucReturn = f_chdir( pcFullPath );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "Back in directory %s\r\n", cRAMBuffer );\r
+ configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );\r
+\r
+ /* Generate the file name. */\r
+ sprintf( cFileName, "%s.txt", pcDirectory2 );\r
+\r
+ /* Print out the file name and the directory from which the file is being\r
+ read. */\r
+ printf( "Reading file %s in %s\r\n", cFileName, cRAMBuffer );\r
+\r
+ /* This time the file is opened for reading. */\r
+ pxFile = f_open( cFileName, "r" );\r
+\r
+ /* Read the file 1 byte at a time. */\r
+ for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )\r
+ {\r
+ iReturned = f_getc( pxFile );\r
+ configASSERT( iReturned == ( ( int ) '0' + iByte ) );\r
+ }\r
+\r
+ /* Finished so close the file. */\r
+ f_close( pxFile );\r
+\r
+ /* Move back to the root directory. */\r
+ ucReturn = f_chdir( "../.." );\r
+ configASSERT( ucReturn == F_NO_ERROR );\r
+\r
+ /* Obtain and print out the working directory. */\r
+ f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ printf( "Back in root directory %s\r\n", cRAMBuffer );\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual C++ Express 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WIN32", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+[InternetShortcut]\r
+URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml\r
+IDList=\r
+[{000214A0-0000-0000-C000-000000000046}]\r
+Prop3=19,2\r
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
+ Integrity Systems, who sell the code with commercial support, \r
+ indemnification and middleware, under the OpenRTOS brand.\r
+ \r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
+ engineered and independently SIL3 certified version for use in safety and \r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+/*\r
+ * Utility functions required to gather run time statistics. See:\r
+ * http://www.freertos.org/rtos-run-time-stats.html\r
+ *\r
+ * Note that this is a simulated port, where simulated time is a lot slower than\r
+ * real time, therefore the run time counter values have no real meaningful\r
+ * units.\r
+ *\r
+ * Also note that it is assumed this demo is going to be used for short periods\r
+ * of time only, and therefore timer overflows are not handled.\r
+*/\r
+\r
+/* FreeRTOS includes. */\r
+#include <FreeRTOS.h>\r
+\r
+/* Variables used in the creation of the run time stats time base. Run time \r
+stats record how much time each task spends in the Running state. */\r
+static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vConfigureTimerForRunTimeStats( void )\r
+{\r
+LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue;\r
+\r
+ /* Initialise the variables used to create the run time stats time base.\r
+ Run time stats record how much time each task spends in the Running \r
+ state. */\r
+\r
+ if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 )\r
+ {\r
+ llTicksPerHundedthMillisecond = 1;\r
+ }\r
+ else\r
+ {\r
+ /* How many times does the performance counter increment in 1/100th\r
+ millisecond. */\r
+ llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL;\r
+\r
+ /* What is the performance counter value now, this will be subtracted\r
+ from readings taken at run time. */\r
+ QueryPerformanceCounter( &liInitialRunTimeValue );\r
+ llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulGetRunTimeCounterValue( void )\r
+{\r
+LARGE_INTEGER liCurrentCount;\r
+unsigned long ulReturn;\r
+\r
+ /* What is the performance counter value now? */\r
+ QueryPerformanceCounter( &liCurrentCount );\r
+\r
+ /* Subtract the performance counter value reading taken when the \r
+ application started to get a count from that reference point, then\r
+ scale to (simulated) 1/100ths of a millisecond. */\r
+ ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond );\r
+\r
+ return ulReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
+ Integrity Systems, who sell the code with commercial support, \r
+ indemnification and middleware, under the OpenRTOS brand.\r
+ \r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
+ engineered and independently SIL3 certified version for use in safety and \r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+ /******************************************************************************\r
+ *\r
+ * See the following URL for information on the commands defined in this file:\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS\r
+ #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0\r
+#endif\r
+\r
+\r
+/*\r
+ * Implements the run-time-stats command.\r
+ */\r
+static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the task-stats command.\r
+ */\r
+static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the echo-three-parameters command.\r
+ */\r
+static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the echo-parameters command.\r
+ */\r
+static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+\r
+/*\r
+ * Implements the "trace start" and "trace stop" commands;\r
+ */\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+ static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );\r
+#endif\r
+\r
+/* Structure that defines the "run-time-stats" command line command. This\r
+generates a table that shows how much run time each task has */\r
+static const CLI_Command_Definition_t xRunTimeStats =\r
+{\r
+ ( const int8_t * const ) "run-time-stats", /* The command string to type. */\r
+ ( 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",\r
+ prvRunTimeStatsCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the "task-stats" command line command. This generates\r
+a table that gives information on each task in the system. */\r
+static const CLI_Command_Definition_t xTaskStats =\r
+{\r
+ ( const int8_t * const ) "task-stats", /* The command string to type. */\r
+ ( const int8_t * const ) "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",\r
+ prvTaskStatsCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the "echo_3_parameters" command line command. This\r
+takes exactly three parameters that the command simply echos back one at a\r
+time. */\r
+static const CLI_Command_Definition_t xThreeParameterEcho =\r
+{\r
+ ( const int8_t * const ) "echo-3-parameters",\r
+ ( const int8_t * const ) "\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",\r
+ prvThreeParameterEchoCommand, /* The function to run. */\r
+ 3 /* Three parameters are expected, which can take any value. */\r
+};\r
+\r
+/* Structure that defines the "echo_parameters" command line command. This\r
+takes a variable number of parameters that the command simply echos back one at\r
+a time. */\r
+static const CLI_Command_Definition_t xParameterEcho =\r
+{\r
+ ( const int8_t * const ) "echo-parameters",\r
+ ( const int8_t * const ) "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",\r
+ prvParameterEchoCommand, /* The function to run. */\r
+ -1 /* The user can enter any number of commands. */\r
+};\r
+\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+ /* Structure that defines the "trace" command line command. This takes a single\r
+ parameter, which can be either "start" or "stop". */\r
+ static const CLI_Command_Definition_t xStartStopTrace =\r
+ {\r
+ ( const int8_t * const ) "trace",\r
+ ( const int8_t * const ) "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",\r
+ prvStartStopTraceCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. Valid values are "start" and "stop". */\r
+ };\r
+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vRegisterSampleCLICommands( void )\r
+{\r
+ /* Register all the command line commands defined immediately above. */\r
+ FreeRTOS_CLIRegisterCommand( &xTaskStats );\r
+ FreeRTOS_CLIRegisterCommand( &xRunTimeStats );\r
+ FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );\r
+ FreeRTOS_CLIRegisterCommand( &xParameterEcho );\r
+\r
+ #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )\r
+ {\r
+ FreeRTOS_CLIRegisterCommand( & xStartStopTrace );\r
+ }\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+const int8_t *const pcHeader = ( int8_t * ) "Task State Priority Stack #\r\n************************************************\r\n";\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Generate a table of task stats. */\r
+ strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );\r
+ vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) );\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+const int8_t * const pcHeader = ( int8_t * ) "Task Abs Time % Time\r\n****************************************\r\n";\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Generate a table of task stats. */\r
+ strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );\r
+ vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) );\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcParameter;\r
+portBASE_TYPE xParameterStringLength, xReturn;\r
+static portBASE_TYPE lParameterNumber = 0;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ if( lParameterNumber == 0 )\r
+ {\r
+ /* The first time the function is called after the command has been\r
+ entered just a header string is returned. */\r
+ sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" );\r
+\r
+ /* Next time the function is called the first parameter will be echoed\r
+ back. */\r
+ lParameterNumber = 1L;\r
+\r
+ /* There is more data to be returned as no parameters have been echoed\r
+ back yet. */\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* Obtain the parameter string. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ lParameterNumber, /* Return the next parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Return the parameter string. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+ sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );\r
+ strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );\r
+ strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
+\r
+ /* If this is the last of the three parameters then there are no more\r
+ strings to return after this one. */\r
+ if( lParameterNumber == 3L )\r
+ {\r
+ /* If this is the last of the three parameters then there are no more\r
+ strings to return after this one. */\r
+ xReturn = pdFALSE;\r
+ lParameterNumber = 0L;\r
+ }\r
+ else\r
+ {\r
+ /* There are more parameters to return after this one. */\r
+ xReturn = pdTRUE;\r
+ lParameterNumber++;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+{\r
+int8_t *pcParameter;\r
+portBASE_TYPE xParameterStringLength, xReturn;\r
+static portBASE_TYPE lParameterNumber = 0;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ if( lParameterNumber == 0 )\r
+ {\r
+ /* The first time the function is called after the command has been\r
+ entered just a header string is returned. */\r
+ sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" );\r
+\r
+ /* Next time the function is called the first parameter will be echoed\r
+ back. */\r
+ lParameterNumber = 1L;\r
+\r
+ /* There is more data to be returned as no parameters have been echoed\r
+ back yet. */\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* Obtain the parameter string. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ lParameterNumber, /* Return the next parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ if( pcParameter != NULL )\r
+ {\r
+ /* Return the parameter string. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+ sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );\r
+ strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );\r
+ strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
+\r
+ /* There might be more parameters to return after this one. */\r
+ xReturn = pdTRUE;\r
+ lParameterNumber++;\r
+ }\r
+ else\r
+ {\r
+ /* No more parameters were found. Make sure the write buffer does\r
+ not contain a valid string. */\r
+ pcWriteBuffer[ 0 ] = 0x00;\r
+\r
+ /* No more data to return. */\r
+ xReturn = pdFALSE;\r
+\r
+ /* Start over the next time this command is executed. */\r
+ lParameterNumber = 0;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+\r
+ static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )\r
+ {\r
+ int8_t *pcParameter;\r
+ portBASE_TYPE lParameterStringLength;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &lParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* There are only two valid parameter values. */\r
+ if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 )\r
+ {\r
+ /* Start or restart the trace. */\r
+ vTraceStop();\r
+ vTraceClear();\r
+ vTraceStart();\r
+\r
+ sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" );\r
+ }\r
+ else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 )\r
+ {\r
+ /* End the trace, if one is running. */\r
+ vTraceStop();\r
+ sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" );\r
+ }\r
+ else\r
+ {\r
+ sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );\r
+ }\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+ }\r
+\r
+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems, who sell the code with commercial support,\r
+ indemnification and middleware, under the OpenRTOS brand.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+\r
+#pragma comment( lib, "ws2_32.lib" )\r
+\r
+/* Win32 includes. */\r
+#include <WinSock2.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+/* Dimensions the buffer into which input characters are placed. */\r
+#define cmdMAX_INPUT_SIZE 60\r
+\r
+/* Dimensions the buffer into which string outputs can be placed. */\r
+#define cmdMAX_OUTPUT_SIZE 1024\r
+\r
+/* Dimensions the buffer passed to the recvfrom() call. */\r
+#define cmdSOCKET_INPUT_BUFFER_SIZE 60\r
+\r
+/* DEL acts as a backspace. */\r
+#define cmdASCII_DEL ( 0x7F )\r
+\r
+/*\r
+ * Open and configure the UDP socket.\r
+ */\r
+static SOCKET prvOpenUDPSocket( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Task that provides the input and output for the FreeRTOS+CLI command\r
+ * interpreter. In this case a WinSock UDP port is used for convenience as this\r
+ * demo runs in a simulated environment on a Windows PC. See the URL in the\r
+ * comments within main.c for the location of the online documentation.\r
+ */\r
+void vUDPCommandInterpreterTask( void *pvParameters )\r
+{\r
+long lBytes, lByte;\r
+signed char cInChar, cInputIndex = 0;\r
+static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];\r
+portBASE_TYPE xMoreDataToFollow;\r
+volatile int iErrorCode = 0;\r
+struct sockaddr_in xClient;\r
+int xClientAddressLength = sizeof( struct sockaddr_in );\r
+SOCKET xSocket;\r
+\r
+ /* Just to prevent compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ /* Attempt to open the socket. */\r
+ xSocket = prvOpenUDPSocket();\r
+\r
+ if( xSocket != INVALID_SOCKET )\r
+ {\r
+ for( ;; )\r
+ {\r
+ /* Wait for incoming data on the opened socket. */\r
+ lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength );\r
+\r
+ if( lBytes == SOCKET_ERROR )\r
+ {\r
+ /* Something went wrong, but it is not handled by this simple\r
+ example. */\r
+ iErrorCode = WSAGetLastError();\r
+ }\r
+ else\r
+ {\r
+ /* Process each received byte in turn. */\r
+ lByte = 0;\r
+ while( lByte < lBytes )\r
+ {\r
+ /* The next character in the input buffer. */\r
+ cInChar = cLocalBuffer[ lByte ];\r
+ lByte++;\r
+\r
+ /* Newline characters are taken as the end of the command\r
+ string. */\r
+ if( cInChar == '\n' )\r
+ {\r
+ /* Process the input string received prior to the\r
+ newline. */\r
+ do\r
+ {\r
+ /* Pass the string to FreeRTOS+CLI. */\r
+ xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );\r
+\r
+ /* Send the output generated by the command's\r
+ implementation. */\r
+ sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
+\r
+ } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */\r
+\r
+ /* All the strings generated by the command processing\r
+ have been sent. Clear the input string ready to receive\r
+ the next command. */\r
+ cInputIndex = 0;\r
+ memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );\r
+\r
+ /* Transmit a spacer, just to make the command console\r
+ easier to read. */\r
+ sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
+ }\r
+ else\r
+ {\r
+ if( cInChar == '\r' )\r
+ {\r
+ /* Ignore the character. Newlines are used to\r
+ detect the end of the input string. */\r
+ }\r
+ else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) )\r
+ {\r
+ /* Backspace was pressed. Erase the last character\r
+ in the string - if any. */\r
+ if( cInputIndex > 0 )\r
+ {\r
+ cInputIndex--;\r
+ cInputString[ cInputIndex ] = '\0';\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* A character was entered. Add it to the string\r
+ entered so far. When a \n is entered the complete\r
+ string will be passed to the command interpreter. */\r
+ if( cInputIndex < cmdMAX_INPUT_SIZE )\r
+ {\r
+ cInputString[ cInputIndex ] = cInChar;\r
+ cInputIndex++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The socket could not be opened. */\r
+ vTaskDelete( NULL );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static SOCKET prvOpenUDPSocket( void )\r
+{\r
+WSADATA xWSAData;\r
+WORD wVersionRequested;\r
+struct sockaddr_in xServer;\r
+SOCKET xSocket = INVALID_SOCKET;\r
+\r
+ wVersionRequested = MAKEWORD( 2, 2 );\r
+\r
+ /* Prepare to use WinSock. */\r
+ if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )\r
+ {\r
+ fprintf( stderr, "Could not open Windows connection.\n" );\r
+ }\r
+ else\r
+ {\r
+ xSocket = socket( AF_INET, SOCK_DGRAM, 0 );\r
+ if( xSocket == INVALID_SOCKET)\r
+ {\r
+ fprintf( stderr, "Could not create socket.\n" );\r
+ WSACleanup();\r
+ }\r
+ else\r
+ {\r
+ /* Zero out the server structure. */\r
+ memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) );\r
+\r
+ /* Set family and port. */\r
+ xServer.sin_family = AF_INET;\r
+ xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER );\r
+\r
+ /* Assign the loopback address */\r
+ xServer.sin_addr.S_un.S_un_b.s_b1 = 127;\r
+ xServer.sin_addr.S_un.S_un_b.s_b2 = 0;\r
+ xServer.sin_addr.S_un.S_un_b.s_b3 = 0;\r
+ xServer.sin_addr.S_un.S_un_b.s_b4 = 1;\r
+\r
+ /* Bind the address to the socket. */\r
+ if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 )\r
+ {\r
+ fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER );\r
+ closesocket( xSocket );\r
+ xSocket = INVALID_SOCKET;\r
+ WSACleanup();\r
+ }\r
+ }\r
+ }\r
+\r
+ return xSocket;\r
+}\r
+\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup Label="ProjectConfigurations">\r
+ <ProjectConfiguration Include="Debug|Win32">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|Win32">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>\r
+ <ProjectName>RTOSDemo</ProjectName>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseOfMfc>false</UseOfMfc>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseOfMfc>false</UseOfMfc>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+ </ImportGroup>\r
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+ </ImportGroup>\r
+ <PropertyGroup Label="UserMacros" />\r
+ <PropertyGroup>\r
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>\r
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>\r
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <Midl>\r
+ <TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>\r
+ <HeaderFileName>\r
+ </HeaderFileName>\r
+ </Midl>\r
+ <ClCompile>\r
+ <Optimization>Disabled</Optimization>\r
+ <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>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <MinimalRebuild>true</MinimalRebuild>\r
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+ <PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>\r
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>\r
+ <ObjectFileName>.\Debug/</ObjectFileName>\r
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>\r
+ <WarningLevel>Level4</WarningLevel>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+ </ClCompile>\r
+ <ResourceCompile>\r
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <Culture>0x0c09</Culture>\r
+ </ResourceCompile>\r
+ <Link>\r
+ <OutputFile>.\Debug/RTOSDemo.exe</OutputFile>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>\r
+ <SubSystem>Console</SubSystem>\r
+ <TargetMachine>MachineX86</TargetMachine>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>\r
+ </Link>\r
+ <Bscmake>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <OutputFile>.\Debug/WIN32.bsc</OutputFile>\r
+ </Bscmake>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Midl>\r
+ <TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>\r
+ <HeaderFileName>\r
+ </HeaderFileName>\r
+ </Midl>\r
+ <ClCompile>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+ <PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <StringPooling>true</StringPooling>\r
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>\r
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>\r
+ <ObjectFileName>.\Release/</ObjectFileName>\r
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <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>\r
+ </ClCompile>\r
+ <ResourceCompile>\r
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <Culture>0x0c09</Culture>\r
+ </ResourceCompile>\r
+ <Link>\r
+ <OutputFile>.\Release/RTOSDemo.exe</OutputFile>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>\r
+ <SubSystem>Console</SubSystem>\r
+ <TargetMachine>MachineX86</TargetMachine>\r
+ <AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ <Bscmake>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <OutputFile>.\Release/WIN32.bsc</OutputFile>\r
+ </Bscmake>\r
+ </ItemDefinitionGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\list.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\test\test.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\fat_sl\psp_test.c" />\r
+ <ClCompile Include="File-Releated-CLI-commands.c" />\r
+ <ClCompile Include="File-system-demo.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\media-drv\ram\ramdrv_f.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\rtc\psp_rtc.c" />\r
+ <ClCompile Include="main.c">\r
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ </ClCompile>\r
+ <ClCompile Include="Run-time-stats-utils.c" />\r
+ <ClCompile Include="Sample-CLI-commands.c" />\r
+ <ClCompile Include="UDPCommandServer.c" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\api\fat_sl.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.h" />\r
+ <ClInclude Include="ConfigurationFiles\config_fat_sl.h" />\r
+ <ClInclude Include="FreeRTOSConfig.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.h" />\r
+ </ItemGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="Resource Files">\r
+ <UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>\r
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS">\r
+ <UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source">\r
+ <UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>\r
+ <Extensions>*.c</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source\Portable">\r
+ <UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+">\r
+ <UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+CLI">\r
+ <UniqueIdentifier>{fd43c0ed-fdbc-437f-a5a3-c50399690bd7}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+CLI\include">\r
+ <UniqueIdentifier>{c5889fe2-af0f-4cea-927f-6a6935ec5e14}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL">\r
+ <UniqueIdentifier>{d261611a-5416-4455-bb33-3bd84381ea40}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\Media_Driver">\r
+ <UniqueIdentifier>{17c1a794-a4a6-4358-850f-2a88bfe3bd33}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp">\r
+ <UniqueIdentifier>{fb7ccc1d-c4ad-475a-98d9-2e8ae2301c99}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp\target">\r
+ <UniqueIdentifier>{34bb4a98-fb88-41fc-81f2-4e3f1c50c528}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\psp\target\rtc">\r
+ <UniqueIdentifier>{286bf65c-93cd-4480-8363-0fb2c2bc7ce1}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="Configuration Files">\r
+ <UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>\r
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\tests">\r
+ <UniqueIdentifier>{e4105d81-802a-4210-b40b-d5dd3cf6e643}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source\include">\r
+ <UniqueIdentifier>{ab23827c-126c-4e5a-bc99-8efa44d8a8bd}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+FAT SL\api">\r
+ <UniqueIdentifier>{9e1c9cf5-c2c7-4f8d-b09d-0b7f329eac57}</UniqueIdentifier>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">\r
+ <Filter>FreeRTOS\Source\Portable</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\list.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">\r
+ <Filter>FreeRTOS\Source\Portable</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+CLI</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\media-drv\ram\ramdrv_f.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL\Media_Driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\rtc\psp_rtc.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL\psp\target\rtc</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="UDPCommandServer.c" />\r
+ <ClCompile Include="File-Releated-CLI-commands.c" />\r
+ <ClCompile Include="File-system-demo.c" />\r
+ <ClCompile Include="main.c" />\r
+ <ClCompile Include="Run-time-stats-utils.c" />\r
+ <ClCompile Include="Sample-CLI-commands.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\psp\target\fat_sl\psp_test.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\test\test.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL\tests</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="FreeRTOSConfig.h">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+CLI\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\volume.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\dir.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\drv.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\fat.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\file.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\util_sfn.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ConfigurationFiles\config_fat_sl.h">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\api\fat_sl.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL\api</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-FAT-SL\fat_sl\common\f_lock.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+FAT SL</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
--- /dev/null
+/*\r
+ FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+ FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
+ http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+\r
+ >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel.\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details. You should have received a copy of the GNU General Public License\r
+ and the FreeRTOS license exception along with FreeRTOS; if not itcan be\r
+ viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+ writing to Real Time Engineers Ltd., contact details for whom are available\r
+ on the FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * Having a problem? Start by reading the FAQ "My application does *\r
+ * not run, what could be wrong?" *\r
+ * *\r
+ * http://www.FreeRTOS.org/FAQHelp.html *\r
+ * *\r
+ ***************************************************************************\r
+\r
+\r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+ license and Real Time Engineers Ltd. contact details.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+ fully thread aware and reentrant UDP/IP stack.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems, who sell the code with commercial support,\r
+ indemnification and middleware, under the OpenRTOS brand.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+*/\r
+\r
+/******************************************************************************\r
+ *\r
+ * This demo is described on the following web page:\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml\r
+ *\r
+ ******************************************************************************/\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include <FreeRTOS.h>\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* File system includes. */\r
+#include "config_fat_sl.h"\r
+\r
+/* Priorities at which the tasks are created. */\r
+#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Register the generic commands that can be used with FreeRTOS+CLI.\r
+ */\r
+extern void vRegisterSampleCLICommands( void );\r
+\r
+/*\r
+ * Register the file system commands that can be used with FreeRTOS+CLI.\r
+ */\r
+extern void vRegisterFileSystemCLICommands( void );\r
+\r
+/*\r
+ * The task that implements the UDP command interpreter using FreeRTOS+CLI.\r
+ */\r
+extern void vUDPCommandInterpreterTask( void *pvParameters );\r
+\r
+/*\r
+ * Creates and verifies different files on the volume, demonstrating the use of\r
+ * various different API functions.\r
+ */\r
+extern void vCreateAndVerifySampleFiles( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/******************************************************************************\r
+ *\r
+ * This demo is described on the following web page:\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml\r
+ *\r
+ ******************************************************************************/\r
+\r
+int main( void )\r
+{\r
+const uint32_t ulLongTime_ms = 250UL;\r
+\r
+ /* If the file system is only going to be accessed from one task then\r
+ F_FS_THREAD_AWARE can be set to 0 and the set of example files are created\r
+ before the RTOS scheduler is started. If the file system is going to be\r
+ access from more than one task then F_FS_THREAD_AWARE must be set to 1 and\r
+ the set of sample files are created from the idle task hook function\r
+ vApplicationIdleHook() - which is defined in this file. */\r
+ #if F_FS_THREAD_AWARE == 0\r
+ {\r
+ /* Initialise the drive and file system, then create a few example\r
+ files. The output from this function just goes to the stdout window,\r
+ allowing the output to be viewed when the UDP command console is not\r
+ connected. */\r
+ vCreateAndVerifySampleFiles();\r
+ }\r
+ #endif\r
+\r
+ /* Register generic commands with the FreeRTOS+CLI command interpreter. */\r
+ vRegisterSampleCLICommands();\r
+\r
+ /* Register file system related commands with the FreeRTOS+CLI command\r
+ interpreter. */\r
+ vRegisterFileSystemCLICommands();\r
+\r
+ /* Create the task that handles the CLI on a UDP port. The port number\r
+ is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */\r
+ xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */\r
+ ( signed char * ) "CLI", /* The name of the task - just to assist debugging. */\r
+ configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */\r
+ mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */\r
+ NULL ); /* A handle to the task is not required, so NULL is passed. */\r
+\r
+ /* Start the RTOS scheduler. */\r
+ vTaskStartScheduler();\r
+\r
+ /* If all is well, the scheduler will now be running, and the following\r
+ line will never be reached. If the following line does execute, then\r
+ there was insufficient FreeRTOS heap memory available for the idle and/or\r
+ timer tasks to be created. See the memory management section on the\r
+ FreeRTOS web site for more details (this is standard text that is not not\r
+ really applicable to the Win32 simulator port). */\r
+ for( ;; )\r
+ {\r
+ Sleep( ulLongTime_ms );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+const unsigned long ulMSToSleep = 5;\r
+\r
+ /* If the file system is only going to be accessed from one task then\r
+ F_FS_THREAD_AWARE can be set to 0 and the set of example files is created\r
+ before the RTOS scheduler is started. If the file system is going to be\r
+ access from more than one task then F_FS_THREAD_AWARE must be set to 1 and\r
+ the set of sample files are created from the idle task hook function. */\r
+ #if F_FS_THREAD_AWARE == 1\r
+ {\r
+ static portBASE_TYPE xCreatedSampleFiles = pdFALSE;\r
+\r
+ /* Initialise the drive and file system, then create a few example\r
+ files. The output from this function just goes to the stdout window,\r
+ allowing the output to be viewed when the UDP command console is not\r
+ connected. */\r
+ if( xCreatedSampleFiles == pdFALSE )\r
+ {\r
+ vCreateAndVerifySampleFiles();\r
+ xCreatedSampleFiles = pdTRUE;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ /* This function is called on each cycle of the idle task if\r
+ configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU\r
+ load. */\r
+ Sleep( ulMSToSleep );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vAssertCalled( const char *pcFile, unsigned long ulLine )\r
+{\r
+ printf( "ASSERT FAILED: File %s, line %u\r\n", pcFile, ulLine );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+ /* vApplicationMallocFailedHook() will only be called if\r
+ configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook\r
+ function that will get called if a call to pvPortMalloc() fails.\r
+ pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
+ timer or semaphore is created. It is also called by various parts of the\r
+ demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the\r
+ size of the heap available to pvPortMalloc() is defined by\r
+ configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()\r
+ API function can be used to query the size of free heap space that remains\r
+ (although it does not provide information on how the remaining heap might\r
+ be fragmented). */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+\r
+\r
+\r
--- /dev/null
+[InternetShortcut]\r
+URL=http://www.freertos.org/fat\r
+IDList=\r
+[{000214A0-0000-0000-C000-000000000046}]\r
+Prop3=19,2\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _API_MDRIVER_H_\r
+#define _API_MDRIVER_H_\r
+\r
+#include "../version/ver_mdriver.h"\r
+#if VER_MDRIVER_MAJOR != 1 || VER_MDRIVER_MINOR != 0\r
+ #error Incompatible MDRIVER version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned short number_of_cylinders;\r
+ unsigned short sector_per_track;\r
+ unsigned short number_of_heads;\r
+ unsigned long number_of_sectors;\r
+ unsigned char media_descriptor;\r
+\r
+ unsigned short bytes_per_sector;\r
+} F_PHY;\r
+\r
+/* media descriptor to be set in getphy function */\r
+#define F_MEDIADESC_REMOVABLE 0xf0\r
+#define F_MEDIADESC_FIX 0xf8\r
+\r
+/* return bitpattern for driver getphy function */\r
+#define F_ST_MISSING 0x00000001\r
+#define F_ST_CHANGED 0x00000002\r
+#define F_ST_WRPROTECT 0x00000004\r
+\r
+/* Driver definitions */\r
+typedef struct F_DRIVER F_DRIVER;\r
+\r
+typedef int ( *F_WRITESECTOR )( F_DRIVER * driver, void * data, unsigned long sector );\r
+typedef int ( *F_READSECTOR )( F_DRIVER * driver, void * data, unsigned long sector );\r
+typedef int ( *F_GETPHY )( F_DRIVER * driver, F_PHY * phy );\r
+typedef long ( *F_GETSTATUS )( F_DRIVER * driver );\r
+typedef void ( *F_RELEASE )( F_DRIVER * driver );\r
+\r
+typedef struct F_DRIVER\r
+{\r
+ unsigned long user_data; /* user defined data */\r
+ void * user_ptr; /* user define pointer */\r
+\r
+ /* driver functions */\r
+ F_WRITESECTOR writesector;\r
+ F_READSECTOR readsector;\r
+ F_GETPHY getphy;\r
+ F_GETSTATUS getstatus;\r
+ F_RELEASE release;\r
+} _F_DRIVER;\r
+\r
+typedef F_DRIVER *( *F_DRIVERINIT )( unsigned long driver_param );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _API_MDRIVER_H_ */\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _API_MDRIVER_RAM_H_\r
+#define _API_MDRIVER_RAM_H_\r
+\r
+#include "api_mdriver.h"\r
+\r
+#include "../version/ver_mdriver_ram.h"\r
+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2\r
+ #error Incompatible MDRIVER_RAM version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define F_RAM_DRIVE0 0\r
+\r
+enum\r
+{\r
+ MDRIVER_RAM_NO_ERROR\r
+ , MDRIVER_RAM_ERR_SECTOR = 101\r
+ , MDRIVER_RAM_ERR_NOTAVAILABLE\r
+};\r
+\r
+F_DRIVER * ram_initfunc ( unsigned long driver_param );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* _API_MDRIVER_RAM_H_ */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _API_FAT_SL_H_\r
+#define _API_FAT_SL_H_\r
+\r
+#include "config_fat_sl.h"\r
+\r
+#include "../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define F_MAXNAME 8 /* 8 byte name */\r
+#define F_MAXEXT 3 /* 3 byte extension */\r
+\r
+typedef struct\r
+{\r
+ char path[F_MAXPATH]; /* /directory1/dir2/ */\r
+ char filename[F_MAXNAME]; /* filename */\r
+ char fileext[F_MAXEXT]; /* extension */\r
+} F_NAME;\r
+\r
+typedef struct\r
+{\r
+ unsigned long cluster;\r
+ unsigned long sector;\r
+ unsigned long sectorend;\r
+ unsigned long pos;\r
+} F_POS;\r
+\r
+typedef struct\r
+{\r
+ char filename[F_MAXPATH]; /*file name+ext*/\r
+ char name[F_MAXNAME]; /*file name*/\r
+ char ext[F_MAXEXT]; /*file extension*/\r
+ unsigned char attr; /*attribute of the file*/\r
+\r
+ unsigned short ctime; /*creation time*/\r
+ unsigned short cdate; /*creation date*/\r
+ unsigned long cluster;\r
+\r
+ long filesize; /*length of file*/\r
+\r
+ F_NAME findfsname; /*find properties*/\r
+ F_POS pos;\r
+} F_FIND;\r
+\r
+/* definitions for ctime */\r
+#define F_CTIME_SEC_SHIFT 0\r
+#define F_CTIME_SEC_MASK 0x001f /*0-30 in 2seconds*/\r
+#define F_CTIME_MIN_SHIFT 5\r
+#define F_CTIME_MIN_MASK 0x07e0 /*0-59 */\r
+#define F_CTIME_HOUR_SHIFT 11\r
+#define F_CTIME_HOUR_MASK 0xf800 /*0-23*/\r
+\r
+\r
+/* definitions for cdate */\r
+#define F_CDATE_DAY_SHIFT 0\r
+#define F_CDATE_DAY_MASK 0x001f /*0-31*/\r
+#define F_CDATE_MONTH_SHIFT 5\r
+#define F_CDATE_MONTH_MASK 0x01e0 /*1-12*/\r
+#define F_CDATE_YEAR_SHIFT 9\r
+#define F_CDATE_YEAR_MASK 0xfe00 /*0-119 (1980+value)*/\r
+\r
+#define F_ATTR_ARC 0x20\r
+#define F_ATTR_DIR 0x10\r
+#define F_ATTR_VOLUME 0x08\r
+#define F_ATTR_SYSTEM 0x04\r
+#define F_ATTR_HIDDEN 0x02\r
+#define F_ATTR_READONLY 0x01\r
+\r
+#define F_CLUSTER_FREE ( (unsigned long)0x00000000 )\r
+#define F_CLUSTER_RESERVED ( (unsigned long)0x0ffffff0 )\r
+#define F_CLUSTER_BAD ( (unsigned long)0x0ffffff7 )\r
+#define F_CLUSTER_LAST ( (unsigned long)0x0ffffff8 )\r
+#define F_CLUSTER_LASTF32R ( (unsigned long)0x0fffffff )\r
+\r
+#define F_ST_MISSING 0x00000001\r
+#define F_ST_CHANGED 0x00000002\r
+#define F_ST_WRPROTECT 0x00000004\r
+\r
+typedef struct\r
+{\r
+ unsigned long abspos;\r
+ unsigned long filesize;\r
+ unsigned long startcluster;\r
+ unsigned long prevcluster;\r
+ unsigned long relpos;\r
+ unsigned char modified;\r
+ unsigned char mode;\r
+ unsigned char _tdata[F_SECTOR_SIZE];\r
+ F_POS pos;\r
+ F_POS dirpos;\r
+#if F_FILE_CHANGED_EVENT\r
+ char filename[F_MAXPATH]; /* filename with full path */\r
+#endif\r
+} F_FILE;\r
+\r
+enum\r
+{\r
+ F_UNKNOWN_MEDIA\r
+ , F_FAT12_MEDIA\r
+ , F_FAT16_MEDIA\r
+ , F_FAT32_MEDIA\r
+};\r
+\r
+enum\r
+{\r
+/* 0 */\r
+ F_NO_ERROR,\r
+\r
+/* 1 */ F_ERR_RESERVED_1,\r
+\r
+/* 2 */ F_ERR_NOTFORMATTED,\r
+\r
+/* 3 */ F_ERR_INVALIDDIR,\r
+\r
+/* 4 */ F_ERR_INVALIDNAME,\r
+\r
+/* 5 */ F_ERR_NOTFOUND,\r
+\r
+/* 6 */ F_ERR_DUPLICATED,\r
+\r
+/* 7 */ F_ERR_NOMOREENTRY,\r
+\r
+/* 8 */ F_ERR_NOTOPEN,\r
+\r
+/* 9 */ F_ERR_EOF,\r
+\r
+/* 10 */ F_ERR_RESERVED_2,\r
+\r
+/* 11 */ F_ERR_NOTUSEABLE,\r
+\r
+/* 12 */ F_ERR_LOCKED,\r
+\r
+/* 13 */ F_ERR_ACCESSDENIED,\r
+\r
+/* 14 */ F_ERR_NOTEMPTY,\r
+\r
+/* 15 */ F_ERR_INITFUNC,\r
+\r
+/* 16 */ F_ERR_CARDREMOVED,\r
+\r
+/* 17 */ F_ERR_ONDRIVE,\r
+\r
+/* 18 */ F_ERR_INVALIDSECTOR,\r
+\r
+/* 19 */ F_ERR_READ,\r
+\r
+/* 20 */ F_ERR_WRITE,\r
+\r
+/* 21 */ F_ERR_INVALIDMEDIA,\r
+\r
+/* 22 */ F_ERR_BUSY,\r
+\r
+/* 23 */ F_ERR_WRITEPROTECT,\r
+\r
+/* 24 */ F_ERR_INVFATTYPE,\r
+\r
+/* 25 */ F_ERR_MEDIATOOSMALL,\r
+\r
+/* 26 */ F_ERR_MEDIATOOLARGE,\r
+\r
+/* 27 */ F_ERR_NOTSUPPSECTORSIZE\r
+\r
+/* 28 */, F_ERR_ALLOCATION\r
+\r
+#if F_FS_THREAD_AWARE == 1\r
+/* 29 */, F_ERR_OS = 29\r
+#endif /* F_FS_THREAD_AWARE */\r
+};\r
+\r
+typedef struct\r
+{\r
+ unsigned long total;\r
+ unsigned long free;\r
+ unsigned long used;\r
+ unsigned long bad;\r
+\r
+ unsigned long total_high;\r
+ unsigned long free_high;\r
+ unsigned long used_high;\r
+ unsigned long bad_high;\r
+} F_SPACE;\r
+\r
+enum\r
+{\r
+ F_SEEK_SET /*Beginning of file*/\r
+ , F_SEEK_CUR /*Current position of file pointer*/\r
+ , F_SEEK_END /*End of file*/\r
+};\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * for file changed events\r
+ *\r
+ ***************************************************************************/\r
+#ifndef F_FILE_CHANGED_EVENT\r
+ #define F_FILE_CHANGED_EVENT 0\r
+#endif\r
+\r
+#if F_FILE_CHANGED_EVENT\r
+\r
+typedef struct\r
+{\r
+ unsigned char action;\r
+ unsigned char flags;\r
+ unsigned char attr;\r
+ unsigned short ctime;\r
+ unsigned short cdate;\r
+ unsigned long filesize;\r
+ char filename[F_MAXPATH];\r
+} ST_FILE_CHANGED;\r
+\r
+typedef void ( *F_FILE_CHANGED_EVENTFUNC )( ST_FILE_CHANGED * fc );\r
+\r
+extern F_FILE_CHANGED_EVENTFUNC f_filechangedevent;\r
+\r
+ #define f_setfilechangedevent( filechangeevent ) f_filechangedevent = filechangeevent\r
+\r
+/* flags */\r
+\r
+ #define FFLAGS_NONE 0x00000000\r
+\r
+ #define FFLAGS_FILE_NAME 0x00000001\r
+ #define FFLAGS_DIR_NAME 0x00000002\r
+ #define FFLAGS_NAME 0x00000003\r
+ #define FFLAGS_ATTRIBUTES 0x00000004\r
+ #define FFLAGS_SIZE 0x00000008\r
+ #define FFLAGS_LAST_WRITE 0x00000010\r
+\r
+/* actions */\r
+\r
+ #define FACTION_ADDED 0x00000001\r
+ #define FACTION_REMOVED 0x00000002\r
+ #define FACTION_MODIFIED 0x00000003\r
+\r
+#endif /* if F_FILE_CHANGED_EVENT */\r
+\r
+unsigned char fn_initvolume ( F_DRIVERINIT initfunc );\r
+unsigned char fn_delvolume ( void );\r
+\r
+unsigned char fn_getfreespace ( F_SPACE * pspace );\r
+\r
+unsigned char fn_chdir ( const char * dirname );\r
+unsigned char fn_mkdir ( const char * dirname );\r
+unsigned char fn_rmdir ( const char * dirname );\r
+\r
+unsigned char fn_findfirst ( const char * filename, F_FIND * find );\r
+unsigned char fn_findnext ( F_FIND * find );\r
+\r
+long fn_filelength ( const char * filename );\r
+\r
+unsigned char fn_close ( F_FILE * filehandle );\r
+F_FILE * fn_open ( const char * filename, const char * mode );\r
+\r
+long fn_read ( void * buf, long size, long _size_t, F_FILE * filehandle );\r
+\r
+long fn_write ( const void * buf, long size, long _size_t, F_FILE * filehandle );\r
+\r
+unsigned char fn_seek ( F_FILE * filehandle, long offset, unsigned char whence );\r
+\r
+long fn_tell ( F_FILE * filehandle );\r
+int fn_getc ( F_FILE * filehandle );\r
+int fn_putc ( int ch, F_FILE * filehandle );\r
+unsigned char fn_rewind ( F_FILE * filehandle );\r
+unsigned char fn_eof ( F_FILE * filehandle );\r
+\r
+unsigned char fn_delete ( const char * filename );\r
+\r
+unsigned char fn_seteof ( F_FILE * );\r
+\r
+F_FILE * fn_truncate ( const char *, long );\r
+\r
+unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root );\r
+\r
+unsigned char fn_hardformat ( unsigned char fattype );\r
+unsigned char fn_format ( unsigned char fattype );\r
+\r
+unsigned char fn_getserial ( unsigned long * );\r
+\r
+\r
+#if F_FS_THREAD_AWARE == 1\r
+\r
+#include "FreeRTOS.h"\r
+#include "semphr.h"\r
+#ifndef FS_MUTEX_DEFINED\r
+ extern xSemaphoreHandle fs_lock_semaphore;\r
+#endif /* FS_MUTEX_DEFINED */\r
+\r
+unsigned char fn_init ( void );\r
+#define f_init fn_init\r
+#define f_initvolume fn_initvolume\r
+#define f_delvolume fn_delvolume\r
+\r
+unsigned char fr_hardformat ( unsigned char fattype );\r
+#define f_hardformat( fattype ) fr_hardformat( fattype )\r
+#define f_format( fattype ) fr_hardformat( fattype )\r
+\r
+unsigned char fr_getcwd ( char * buffer, unsigned char maxlen, char root );\r
+#define f_getcwd( buffer, maxlen ) fr_getcwd( buffer, maxlen, 1 )\r
+\r
+unsigned char fr_getfreespace ( F_SPACE * pspace );\r
+#define f_getfreespace fr_getfreespace\r
+\r
+\r
+unsigned char fr_chdir ( const char * dirname );\r
+#define f_chdir( dirname ) fr_chdir( dirname )\r
+unsigned char fr_mkdir ( const char * dirname );\r
+#define f_mkdir( dirname ) fr_mkdir( dirname )\r
+unsigned char fr_rmdir ( const char * dirname );\r
+#define f_rmdir( dirname ) fr_rmdir( dirname )\r
+\r
+unsigned char fr_findfirst ( const char * filename, F_FIND * find );\r
+unsigned char fr_findnext ( F_FIND * find );\r
+#define f_findfirst( filename, find ) fr_findfirst( filename, find )\r
+#define f_findnext( find ) fr_findnext( find )\r
+\r
+long fr_filelength ( const char * filename );\r
+#define f_filelength( filename ) fr_filelength( filename )\r
+\r
+unsigned char fr_close ( F_FILE * filehandle );\r
+F_FILE * fr_open ( const char * filename, const char * mode );\r
+\r
+long fr_read ( void * buf, long size, long _size_t, F_FILE * filehandle );\r
+\r
+unsigned char fr_getserial ( unsigned long * );\r
+#define f_getserial( serial ) fr_getserial( serial )\r
+\r
+unsigned char fr_flush ( F_FILE * f );\r
+#define f_flush( filehandle ) fr_flush( filehandle )\r
+\r
+long fr_write ( const void * buf, long size, long _size_t, F_FILE * filehandle );\r
+#define f_write( buf, size, _size_t, filehandle ) fr_write( buf, size, _size_t, filehandle )\r
+\r
+unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence );\r
+#define f_seek( filehandle, offset, whence ) fr_seek( filehandle, offset, whence )\r
+\r
+long fr_tell ( F_FILE * filehandle );\r
+#define f_tell( filehandle ) fr_tell( filehandle )\r
+int fr_getc ( F_FILE * filehandle );\r
+#define f_getc( filehandle ) fr_getc( filehandle )\r
+int fr_putc ( int ch, F_FILE * filehandle );\r
+#define f_putc( ch, filehandle ) fr_putc( ch, filehandle )\r
+unsigned char fr_rewind ( F_FILE * filehandle );\r
+#define f_rewind( filehandle ) fr_rewind( filehandle )\r
+unsigned char fr_eof ( F_FILE * filehandle );\r
+#define f_eof( filehandle ) fr_eof( filehandle )\r
+\r
+unsigned char fr_delete ( const char * filename );\r
+#define f_delete( filename ) fr_delete( filename )\r
+\r
+unsigned char fr_seteof ( F_FILE * );\r
+#define f_seteof( file ) fr_seteof( file )\r
+\r
+F_FILE * fr_truncate ( const char *, long );\r
+#define f_truncate( filename, filesize ) fr_truncate( filename, filesize )\r
+\r
+#define f_close( filehandle ) fr_close( filehandle )\r
+#define f_open( filename, mode ) fr_open( filename, mode )\r
+#define f_read( buf, size, _size_t, filehandle ) fr_read( buf, size, _size_t, filehandle )\r
+\r
+#else /* F_FS_THREAD_AWARE */\r
+\r
+unsigned char fn_init ( void );\r
+#define f_init fn_init\r
+#define f_initvolume fn_initvolume\r
+#define f_delvolume fn_delvolume\r
+\r
+#define f_hardformat( fattype ) fn_hardformat( fattype )\r
+#define f_format( fattype ) fn_hardformat( fattype )\r
+\r
+#define f_getcwd( buffer, maxlen ) fn_getcwd( buffer, maxlen, 1 )\r
+\r
+unsigned char fn_getfreespace ( F_SPACE * pspace );\r
+#define f_getfreespace fn_getfreespace\r
+\r
+\r
+unsigned char fn_chdir ( const char * dirname );\r
+#define f_chdir( dirname ) fn_chdir( dirname )\r
+unsigned char fn_mkdir ( const char * dirname );\r
+#define f_mkdir( dirname ) fn_mkdir( dirname )\r
+unsigned char fn_rmdir ( const char * dirname );\r
+#define f_rmdir( dirname ) fn_rmdir( dirname )\r
+\r
+unsigned char fn_findfirst ( const char * filename, F_FIND * find );\r
+unsigned char fn_findnext ( F_FIND * find );\r
+#define f_findfirst( filename, find ) fn_findfirst( filename, find )\r
+#define f_findnext( find ) fn_findnext( find )\r
+\r
+#define f_filelength( filename ) fn_filelength( filename )\r
+\r
+#define f_getserial( serial ) fn_getserial( serial )\r
+\r
+unsigned char fn_flush ( F_FILE * f );\r
+#define f_flush( filehandle ) fn_flush( filehandle )\r
+\r
+#define f_write( buf, size, _size_t, filehandle ) fn_write( buf, size, _size_t, filehandle )\r
+\r
+#define f_seek( filehandle, offset, whence ) fn_seek( filehandle, offset, whence )\r
+\r
+long fn_tell ( F_FILE * filehandle );\r
+#define f_tell( filehandle ) fn_tell( filehandle )\r
+int fn_getc ( F_FILE * filehandle );\r
+#define f_getc( filehandle ) fn_getc( filehandle )\r
+int fn_putc ( int ch, F_FILE * filehandle );\r
+#define f_putc( ch, filehandle ) fn_putc( ch, filehandle )\r
+unsigned char fn_rewind ( F_FILE * filehandle );\r
+#define f_rewind( filehandle ) fn_rewind( filehandle )\r
+unsigned char fn_eof ( F_FILE * filehandle );\r
+#define f_eof( filehandle ) fn_eof( filehandle )\r
+\r
+unsigned char fn_delete ( const char * filename );\r
+#define f_delete( filename ) fn_delete( filename )\r
+\r
+unsigned char fn_seteof ( F_FILE * );\r
+#define f_seteof( file ) fn_seteof( file )\r
+\r
+F_FILE * fn_truncate ( const char *, long );\r
+#define f_truncate( filename, filesize ) fn_truncate( filename, filesize )\r
+\r
+#define f_close( filehandle ) fn_close( filehandle )\r
+#define f_open( filename, mode ) fn_open( filename, mode )\r
+#define f_read( buf, size, _size_t, filehandle ) fn_read( buf, size, _size_t, filehandle )\r
+\r
+#endif /* F_FS_THREAD_AWARE */\r
+\r
+/****************************************************************************\r
+ *\r
+ * end of fat_sl.h\r
+ *\r
+ ***************************************************************************/\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /*_API_FAT_SL_H_*/\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _CONFIG_FAT_SL_H\r
+#define _CONFIG_FAT_SL_H\r
+\r
+#include "../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#include "../api/api_mdriver.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/**************************************************************************\r
+**\r
+** FAT SL user settings\r
+**\r
+**************************************************************************/\r
+#define F_SECTOR_SIZE 512u /* Disk sector size. */\r
+#define F_FS_THREAD_AWARE 1 /* Set to one if the file system will be access from more than one task. */\r
+#define F_MAXPATH 64 /* Maximum length a file name (including its full path) can be. */\r
+#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. */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _CONFIG_FAT_SL_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _CONFIG_MDRIVER_RAM_H_\r
+#define _CONFIG_MDRIVER_RAM_H_\r
+\r
+#include "../version/ver_mdriver_ram.h"\r
+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2\r
+ #error Incompatible MDRIVER_RAM version number!\r
+#endif\r
+\r
+#define MDRIVER_RAM_SECTOR_SIZE 512 /* Sector size */\r
+\r
+#define MDRIVER_RAM_VOLUME0_SIZE (128 * 1024) /* defintion for size of ramdrive0 */\r
+\r
+#define MDRIVER_MEM_LONG_ACCESS 1 /* set this value to 1 if 32bit access available */\r
+\r
+#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/include/psp_string.h"\r
+\r
+#include "dir.h"\r
+#include "util.h"\r
+#include "volume.h"\r
+#include "drv.h"\r
+#include "fat.h"\r
+#include "file.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_findfilewc\r
+ *\r
+ * internal function to finding file in directory entry with or without\r
+ * wildcard\r
+ *\r
+ * INPUTS\r
+ *\r
+ * name - filename\r
+ * ext - fileextension\r
+ * pos - where to start searching, and contains current position\r
+ * pde - store back the directory entry pointer\r
+ * wc - wildcard checking?\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if file was not found\r
+ * 1 - if file was found\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_findfilewc ( char * name, char * ext, F_POS * pos, F_DIRENTRY * * pde, unsigned char wc )\r
+{\r
+ while ( pos->cluster < F_CLUSTER_RESERVED )\r
+ {\r
+ for ( ; pos->sector < pos->sectorend ; pos->sector++ )\r
+ {\r
+ F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );\r
+\r
+ if ( _f_readglsector( pos->sector ) )\r
+ {\r
+ return 0; /*not found*/\r
+ }\r
+\r
+ for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )\r
+ {\r
+ unsigned char b, ok;\r
+\r
+ if ( !de->name[0] )\r
+ {\r
+ return 0; /*empty*/\r
+ }\r
+\r
+ if ( (unsigned char)( de->name[0] ) == 0xe5 )\r
+ {\r
+ continue; /*deleted*/\r
+ }\r
+\r
+ if ( de->attr & F_ATTR_VOLUME )\r
+ {\r
+ continue;\r
+ }\r
+\r
+ if ( wc )\r
+ {\r
+ for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )\r
+ {\r
+ if ( name[b] == '*' )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( name[b] != '?' )\r
+ {\r
+ if ( de->name[b] != name[b] )\r
+ {\r
+ ok = 0;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( ok )\r
+ {\r
+ for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )\r
+ {\r
+ if ( ext[b] == '*' )\r
+ {\r
+ if ( pde )\r
+ {\r
+ *pde = de;\r
+ }\r
+\r
+ return 1;\r
+ }\r
+\r
+ if ( ext[b] != '?' )\r
+ {\r
+ if ( de->ext[b] != ext[b] )\r
+ {\r
+ ok = 0;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( ok )\r
+ {\r
+ if ( pde )\r
+ {\r
+ *pde = de;\r
+ }\r
+\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )\r
+ {\r
+ if ( de->name[b] != name[b] )\r
+ {\r
+ ok = 0;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( ok )\r
+ {\r
+ for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )\r
+ {\r
+ if ( de->ext[b] != ext[b] )\r
+ {\r
+ ok = 0;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( ok )\r
+ {\r
+ if ( pde )\r
+ {\r
+ *pde = de;\r
+ }\r
+\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ pos->pos = 0;\r
+ }\r
+\r
+ if ( !pos->cluster )\r
+ {\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ pos->cluster = gl_volume.bootrecord.rootcluster;\r
+ }\r
+ else\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ unsigned long nextcluster;\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ if ( _f_getclustervalue( pos->cluster, &nextcluster ) )\r
+ {\r
+ return 0; /*not found*/\r
+ }\r
+\r
+ if ( nextcluster >= F_CLUSTER_RESERVED )\r
+ {\r
+ return 0; /*eof*/\r
+ }\r
+\r
+ _f_clustertopos( nextcluster, pos );\r
+ }\r
+ } /* _f_findfilewc */\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getfilename\r
+ *\r
+ * create a complete filename from name and extension\r
+ *\r
+ * INPUTS\r
+ *\r
+ * dest - where to store filename\r
+ * name - name of the file\r
+ * ext - extension of the file\r
+ *\r
+ ***************************************************************************/\r
+static void _f_getfilename ( char * dest, char * name, char * ext )\r
+{\r
+ unsigned char a, len;\r
+\r
+ for ( len = a = F_MAXNAME ; a ; a--, len-- )\r
+ {\r
+ if ( name[a - 1] != ' ' )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ for ( a = 0 ; a < len ; a++ )\r
+ {\r
+ *dest++ = *name++;\r
+ }\r
+\r
+\r
+ for ( len = a = F_MAXEXT ; a ; a--, len-- )\r
+ {\r
+ if ( ext[a - 1] != ' ' )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( len )\r
+ {\r
+ *dest++ = '.';\r
+ }\r
+\r
+ for ( a = 0 ; a < len ; a++ )\r
+ {\r
+ *dest++ = *ext++;\r
+ }\r
+\r
+ *dest = 0; /*terminateit*/\r
+} /* _f_getfilename */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getdecluster\r
+ *\r
+ * get a directory entry structure start cluster value\r
+ *\r
+ * INPUTS\r
+ *\r
+ * de - directory entry\r
+ *\r
+ * RETURNS\r
+ *\r
+ * directory entry cluster value\r
+ *\r
+ ***************************************************************************/\r
+unsigned long _f_getdecluster ( F_DIRENTRY * de )\r
+{\r
+ unsigned long cluster;\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ cluster = _f_getword( &de->clusterhi );\r
+ cluster <<= 16;\r
+ cluster |= _f_getword( &de->clusterlo );\r
+ return cluster;\r
+ }\r
+\r
+ return _f_getword( &de->clusterlo );\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setdecluster\r
+ *\r
+ * set a directory entry structure start cluster value\r
+ *\r
+ * INPUTS\r
+ *\r
+ * de - directory entry\r
+ * cluster - value of the start cluster\r
+ *\r
+ ***************************************************************************/\r
+void _f_setdecluster ( F_DIRENTRY * de, unsigned long cluster )\r
+{\r
+ _f_setword( &de->clusterlo, (unsigned short)( cluster & 0xffff ) );\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ _f_setword( &de->clusterhi, (unsigned short)( cluster >> 16 ) );\r
+ }\r
+ else\r
+ {\r
+ _f_setword( &de->clusterhi, (unsigned short)0 );\r
+ }\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_findpath\r
+ *\r
+ * finding out if path is valid in F_NAME and\r
+ * correct path info with absolute path (removes relatives)\r
+ *\r
+ * INPUTS\r
+ *\r
+ * fsname - filled structure with path,drive\r
+ * pos - where to start searching, and contains current position\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if path was not found or invalid\r
+ * 1 - if path was found\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_findpath ( F_NAME * fsname, F_POS * pos )\r
+{\r
+ char * path = fsname->path;\r
+ char * mpath = path;\r
+ F_DIRENTRY * de;\r
+\r
+ _f_clustertopos( 0, pos );\r
+\r
+ for ( ; *path ; )\r
+ {\r
+ char name[F_MAXNAME];\r
+ char ext[F_MAXEXT];\r
+\r
+ unsigned char len = _f_setnameext( path, name, ext );\r
+\r
+ if ( ( pos->cluster == 0 ) && ( len == 1 ) && ( name[0] == '.' ) )\r
+ {\r
+ _f_clustertopos( 0, pos );\r
+ }\r
+ else\r
+ {\r
+ if ( !_f_findfilewc( name, ext, pos, &de, 0 ) )\r
+ {\r
+ return 0;\r
+ }\r
+ if ( !( de->attr & F_ATTR_DIR ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ _f_clustertopos( _f_getdecluster( de ), pos );\r
+ }\r
+\r
+\r
+ if ( name[0] == '.' )\r
+ {\r
+ if ( len == 1 )\r
+ {\r
+ path += len;\r
+\r
+ if ( !( *path ) )\r
+ {\r
+ if ( mpath != fsname->path )\r
+ {\r
+ mpath--; /*if we are now at the top*/\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ path++;\r
+ continue;\r
+ }\r
+\r
+ if ( name[1] != '.' )\r
+ {\r
+ return 0; /*invalid name*/\r
+ }\r
+\r
+ if ( len != 2 )\r
+ {\r
+ return 0; /*invalid name !*/\r
+ }\r
+\r
+ path += len;\r
+\r
+ if ( mpath == fsname->path )\r
+ {\r
+ return 0; /*we are in the top*/\r
+ }\r
+\r
+ mpath--; /*no on separator*/\r
+ for ( ; ; )\r
+ {\r
+ if ( mpath == fsname->path )\r
+ {\r
+ break; /*we are now at the top*/\r
+ }\r
+\r
+ mpath--;\r
+ if ( *mpath == '/' )\r
+ {\r
+ mpath++;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( !( *path ) )\r
+ {\r
+ if ( mpath != fsname->path )\r
+ {\r
+ mpath--; /*if we are now at the top*/\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ path++;\r
+ continue;\r
+ }\r
+ else\r
+ {\r
+ if ( path == mpath ) /*if no was dots just step*/\r
+ {\r
+ path += len;\r
+ mpath += len;\r
+ }\r
+ else\r
+ {\r
+ unsigned char a;\r
+ for ( a = 0 ; a < len ; a++ )\r
+ {\r
+ *mpath++ = *path++; /*copy if in different pos*/\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( !( *path ) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ path++;\r
+ *mpath++ = '/'; /*add separator*/\r
+ }\r
+\r
+ *mpath = 0; /*terminate it*/\r
+ return 1;\r
+} /* _f_findpath */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_getcwd\r
+ *\r
+ * getting a current working directory of current drive\r
+ *\r
+ * INPUTS\r
+ *\r
+ * buffer - where to store current working folder\r
+ * maxlen - buffer length (possible size is F_MAXPATH)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+\r
+unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root )\r
+{\r
+ unsigned char a;\r
+\r
+ if ( !maxlen )\r
+ {\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ maxlen--; /*need for termination*/\r
+ if ( root && maxlen )\r
+ {\r
+ *buffer++ = '/';\r
+ maxlen--;\r
+ }\r
+\r
+ for ( a = 0 ; a < maxlen ; a++ )\r
+ {\r
+ char ch = gl_volume.cwd[a];\r
+ buffer[a] = ch;\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ buffer[a] = 0; /*add terminator at the end*/\r
+\r
+ return F_NO_ERROR;\r
+} /* fn_getcwd */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_findfirst\r
+ *\r
+ * find a file(s) or directory(s) in directory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filename - filename (with or without wildcards)\r
+ * find - where to store found file information\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+\r
+unsigned char fn_findfirst ( const char * filename, F_FIND * find )\r
+{\r
+ unsigned char ret;\r
+\r
+ if ( _f_setfsname( filename, &find->findfsname ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checkname( find->findfsname.filename, find->findfsname.fileext ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name, wildcard is ok*/\r
+ }\r
+\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !_f_findpath( &find->findfsname, &find->pos ) )\r
+ {\r
+ return F_ERR_INVALIDDIR; /*search for path*/\r
+ }\r
+\r
+ return fn_findnext( find );\r
+} /* fn_findfirst */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_findnext\r
+ *\r
+ * find further file(s) or directory(s) in directory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * find - where to store found file information (findfirst should call 1st)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+\r
+unsigned char fn_findnext ( F_FIND * find )\r
+{\r
+ F_DIRENTRY * de;\r
+ unsigned char a;\r
+ unsigned char ret;\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !_f_findfilewc( find->findfsname.filename, find->findfsname.fileext, &find->pos, &de, 1 ) )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ for ( a = 0 ; a < F_MAXNAME ; a++ )\r
+ {\r
+ find->name[a] = de->name[a];\r
+ }\r
+\r
+ for ( a = 0 ; a < F_MAXEXT ; a++ )\r
+ {\r
+ find->ext[a] = de->ext[a];\r
+ }\r
+\r
+ _f_getfilename( find->filename, (char *)de->name, (char *)de->ext );\r
+\r
+ find->attr = de->attr;\r
+ find->cdate = _f_getword( &de->cdate );\r
+ find->ctime = _f_getword( &de->ctime );\r
+ find->filesize = (long)_f_getlong( &de->filesize );\r
+ find->cluster = _f_getdecluster( de );\r
+ find->pos.pos++; /*goto next position*/\r
+\r
+ return 0;\r
+} /* fn_findnext */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_chdir\r
+ *\r
+ * change current working directory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * dirname - new working directory name\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if successfully\r
+ * other - if any error\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_chdir ( const char * dirname )\r
+{\r
+ F_POS pos;\r
+ F_NAME fsname;\r
+ unsigned char len;\r
+ unsigned char a;\r
+ unsigned char ret;\r
+\r
+ ret = _f_setfsname( dirname, &fsname );\r
+\r
+ if ( ret == 1 )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ for ( len = 0 ; fsname.path[len] ; )\r
+ {\r
+ len++;\r
+ }\r
+\r
+ if ( len && ( ( fsname.filename[0] != 32 ) || ( fsname.fileext[0] != 32 ) ) )\r
+ {\r
+ fsname.path[len++] = '/';\r
+ }\r
+\r
+ _f_getfilename( fsname.path + len, fsname.filename, fsname.fileext );\r
+\r
+ if ( !( _f_findpath( &fsname, &pos ) ) )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ for ( a = 0 ; a < F_MAXPATH ; a++ )\r
+ {\r
+ gl_volume.cwd[a] = fsname.path[a];\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* fn_chdir */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_initentry\r
+ *\r
+ * init directory entry, this function is called if a new entry is coming\r
+ *\r
+ * INPUTS\r
+ *\r
+ * de - directory entry which needs to be initialized\r
+ * name - fil ename (8)\r
+ * ext - file extension (3)\r
+ *\r
+ ***************************************************************************/\r
+static void _f_initentry ( F_DIRENTRY * de, char * name, char * ext )\r
+{\r
+ unsigned short date;\r
+ unsigned short time;\r
+\r
+ psp_memset( de, 0, sizeof( F_DIRENTRY ) ); /*reset all entries*/\r
+\r
+ psp_memcpy( de->name, name, sizeof( de->name ) );\r
+ psp_memcpy( de->ext, ext, sizeof( de->ext ) );\r
+\r
+ f_igettimedate( &time, &date );\r
+ _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_addentry\r
+ *\r
+ * Add a new directory entry into driectory list\r
+ *\r
+ * INPUTS\r
+ *\r
+ * fs_name - filled structure what to add into directory list\r
+ * pos - where directory cluster chains starts\r
+ * pde - F_DIRENTRY pointer where to store the entry where it was added\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if successfully added\r
+ * other - if any error (see FS_xxx errorcodes)\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_addentry ( F_NAME * fsname, F_POS * pos, F_DIRENTRY * * pde )\r
+{\r
+ unsigned char ret;\r
+ unsigned short date;\r
+ unsigned short time;\r
+\r
+ if ( !fsname->filename[0] )\r
+ {\r
+ return F_ERR_INVALIDNAME;\r
+ }\r
+\r
+ if ( fsname->filename[0] == '.' )\r
+ {\r
+ return F_ERR_INVALIDNAME;\r
+ }\r
+\r
+ while ( pos->cluster < F_CLUSTER_RESERVED )\r
+ {\r
+ for ( ; pos->sector < pos->sectorend ; pos->sector++ )\r
+ {\r
+ F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );\r
+\r
+ ret = _f_readglsector( pos->sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )\r
+ {\r
+ if ( ( !de->name[0] ) || ( (unsigned char)( de->name[0] ) == 0xe5 ) )\r
+ {\r
+ _f_initentry( de, fsname->filename, fsname->fileext );\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ f_igettimedate( &time, &date );\r
+ _f_setword( &de->crtdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ _f_setword( &de->crttime, time ); /*if there is realtime clock then creation time could be set from*/\r
+ _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ }\r
+\r
+ if ( pde )\r
+ {\r
+ *pde = de;\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+ }\r
+ }\r
+\r
+ pos->pos = 0;\r
+ }\r
+\r
+ if ( !pos->cluster )\r
+ {\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ pos->cluster = gl_volume.bootrecord.rootcluster;\r
+ }\r
+ else\r
+ return F_ERR_NOMOREENTRY;\r
+ }\r
+\r
+ {\r
+ unsigned long cluster;\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_getclustervalue( pos->cluster, &cluster ); /*try to get next cluster*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( cluster < F_CLUSTER_RESERVED )\r
+ {\r
+ _f_clustertopos( cluster, pos );\r
+ }\r
+ else\r
+ {\r
+ ret = _f_alloccluster( &cluster ); /*get a new one*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( cluster < F_CLUSTER_RESERVED )\r
+ {\r
+ if ( gl_file.mode != F_FILE_CLOSE )\r
+ {\r
+ return F_ERR_NOMOREENTRY;\r
+ }\r
+\r
+ _f_clustertopos( cluster, &gl_file.pos );\r
+\r
+ ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_setclustervalue( pos->cluster, gl_file.pos.cluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_writefatsector();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ psp_memset( gl_sector, 0, F_SECTOR_SIZE );\r
+ while ( gl_file.pos.sector < gl_file.pos.sectorend )\r
+ {\r
+ ret = _f_writeglsector( gl_file.pos.sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_file.pos.sector++;\r
+ }\r
+\r
+ _f_clustertopos( gl_file.pos.cluster, pos );\r
+ }\r
+ else\r
+ {\r
+ return F_ERR_NOMOREENTRY;\r
+ }\r
+ }\r
+ }\r
+ } /* _f_addentry */\r
+\r
+ return F_ERR_NOMOREENTRY;\r
+}\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_mkdir\r
+ *\r
+ * making a new directory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * dirname - new directory name\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_mkdir ( const char * dirname )\r
+{\r
+ F_POS posdir;\r
+ F_POS pos;\r
+ F_DIRENTRY * de;\r
+ F_NAME fsname;\r
+ unsigned long cluster;\r
+ unsigned char ret;\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ ST_FILE_CHANGED fc;\r
+ #endif\r
+\r
+ if ( _f_setfsname( dirname, &fsname ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !_f_findpath( &fsname, &posdir ) )\r
+ {\r
+ return F_ERR_INVALIDDIR;\r
+ }\r
+\r
+ pos = posdir;\r
+\r
+ if ( fsname.filename[0] == '.' )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ if ( _f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )\r
+ {\r
+ return F_ERR_DUPLICATED;\r
+ }\r
+\r
+ pos = posdir;\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_alloccluster( &cluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_addentry( &fsname, &pos, &de );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ de->attr |= F_ATTR_DIR; /*set as directory*/\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ if ( f_filechangedevent )\r
+ {\r
+ fc.action = FACTION_ADDED;\r
+ fc.flags = FFLAGS_DIR_NAME | FFLAGS_ATTRIBUTES | FFLAGS_SIZE | FFLAGS_LAST_WRITE;\r
+ fc.attr = de->attr;\r
+ fc.ctime = _f_getword( de->ctime );\r
+ fc.cdate = _f_getword( de->cdate );\r
+ fc.filesize = _f_getlong( de->filesize );\r
+ }\r
+\r
+ #endif\r
+\r
+ if ( gl_file.mode != F_FILE_CLOSE )\r
+ {\r
+ return F_ERR_LOCKED;\r
+ }\r
+\r
+ _f_clustertopos( cluster, &gl_file.pos );\r
+ _f_setdecluster( de, cluster ); /*new dir*/\r
+\r
+ (void)_f_writeglsector( (unsigned long)-1 ); /*write actual directory sector*/\r
+\r
+\r
+ de = (F_DIRENTRY *)gl_sector;\r
+\r
+ _f_initentry( de, ". ", " " );\r
+ de->attr = F_ATTR_DIR; /*set as directory*/\r
+ _f_setdecluster( de, cluster ); /*current*/\r
+ de++;\r
+\r
+ _f_initentry( de, ".. ", " " );\r
+ de->attr = F_ATTR_DIR; /*set as directory*/\r
+ _f_setdecluster( de, posdir.cluster ); /*parent*/\r
+ de++;\r
+\r
+ psp_memset( de, 0, ( F_SECTOR_SIZE - 2 * sizeof( F_DIRENTRY ) ) );\r
+\r
+\r
+ ret = _f_writeglsector( gl_file.pos.sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_file.pos.sector++;\r
+ psp_memset( gl_sector, 0, ( 2 * sizeof( F_DIRENTRY ) ) );\r
+ while ( gl_file.pos.sector < gl_file.pos.sectorend )\r
+ {\r
+ ret = _f_writeglsector( gl_file.pos.sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_file.pos.sector++;\r
+ }\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_writefatsector();\r
+ #if F_FILE_CHANGED_EVENT\r
+ if ( f_filechangedevent && !ret )\r
+ {\r
+ fc.action = FACTION_ADDED;\r
+ fc.flags = FFLAGS_DIR_NAME;\r
+\r
+ if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )\r
+ {\r
+ f_filechangedevent( &fc );\r
+ }\r
+ }\r
+\r
+ #endif\r
+\r
+ return ret;\r
+} /* fn_mkdir */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_rmdir\r
+ *\r
+ * Remove directory, only could be removed if empty\r
+ *\r
+ * INPUTS\r
+ *\r
+ * dirname - which directory needed to be removed\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_rmdir ( const char * dirname )\r
+{\r
+ unsigned char ret;\r
+ F_POS pos;\r
+ F_DIRENTRY * de;\r
+ F_NAME fsname;\r
+ unsigned long dirsector;\r
+ unsigned char a;\r
+\r
+ if ( _f_setfsname( dirname, &fsname ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( fsname.filename[0] == '.' )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !( _f_findpath( &fsname, &pos ) ) )\r
+ {\r
+ return F_ERR_INVALIDDIR;\r
+ }\r
+\r
+ if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ if ( !( de->attr & F_ATTR_DIR ) )\r
+ {\r
+ return F_ERR_INVALIDDIR; /*not a directory*/\r
+ }\r
+\r
+ dirsector = gl_volume.actsector;\r
+\r
+ if ( gl_file.mode != F_FILE_CLOSE )\r
+ {\r
+ return F_ERR_LOCKED;\r
+ }\r
+\r
+ _f_clustertopos( _f_getdecluster( de ), &gl_file.pos );\r
+\r
+ for ( ; ; )\r
+ {\r
+ F_DIRENTRY * de2;\r
+ char ch = 0;\r
+\r
+ ret = _f_getcurrsector();\r
+ if ( ret == F_ERR_EOF )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ de2 = (F_DIRENTRY *)gl_sector;\r
+ for ( a = 0 ; a < ( F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ) ; a++, de2++ )\r
+ {\r
+ ch = de2->name[0];\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( (unsigned char)ch == 0xe5 )\r
+ {\r
+ continue;\r
+ }\r
+\r
+ if ( ch == '.' )\r
+ {\r
+ continue;\r
+ }\r
+\r
+ return F_ERR_NOTEMPTY; /*something is there*/\r
+ }\r
+\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+\r
+ gl_file.pos.sector++;\r
+ }\r
+\r
+ ret = _f_readglsector( dirsector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ de->name[0] = (unsigned char)0xe5;\r
+\r
+ ret = _f_writeglsector( dirsector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_removechain( _f_getdecluster( de ) );\r
+ #if F_FILE_CHANGED_EVENT\r
+ if ( f_filechangedevent && !ret )\r
+ {\r
+ ST_FILE_CHANGED fc;\r
+ fc.action = FACTION_REMOVED;\r
+ fc.flags = FFLAGS_DIR_NAME;\r
+\r
+ if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )\r
+ {\r
+ f_filechangedevent( &fc );\r
+ }\r
+ }\r
+\r
+ #endif\r
+ return ret;\r
+} /* fn_rmdir */\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __DIR_H\r
+#define __DIR_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+\r
+\r
+#define NTRES_LOW 0x08 /*lower case name*/\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned char name[F_MAXNAME]; /* 8+3 */\r
+ unsigned char ext[F_MAXEXT];\r
+ unsigned char attr; /* 00ADVSHR */\r
+\r
+ unsigned char ntres; /* FAT32 only */\r
+ unsigned char crttimetenth; /* FAT32 only */\r
+ unsigned char crttime[2]; /* FAT32 only */\r
+ unsigned char crtdate[2]; /* FAT32 only */\r
+ unsigned char lastaccessdate[2]; /* FAT32 only */\r
+\r
+ unsigned char clusterhi[2]; /* FAT32 only */\r
+ unsigned char ctime[2];\r
+ unsigned char cdate[2];\r
+ unsigned char clusterlo[2]; /* fat12,fat16,fat32 */\r
+ unsigned char filesize[4];\r
+} F_DIRENTRY;\r
+\r
+\r
+unsigned char _f_getdirsector ( unsigned long );\r
+unsigned char _f_findfilewc ( char *, char *, F_POS *, F_DIRENTRY * *, unsigned char );\r
+unsigned char _f_findpath ( F_NAME *, F_POS * );\r
+unsigned long _f_getdecluster ( F_DIRENTRY * );\r
+\r
+unsigned char _f_writedirsector ( void );\r
+void _f_setdecluster ( F_DIRENTRY *, unsigned long );\r
+unsigned char _f_addentry ( F_NAME *, F_POS *, F_DIRENTRY * * );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __DIR_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/include/psp_string.h"\r
+\r
+#include "drv.h"\r
+#include "util.h"\r
+#include "volume.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+F_DRIVER * mdrv = NULL; /* driver structure */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_checkstatus\r
+ *\r
+ * checking a volume driver status, if media is removed or has been changed\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_checkstatus ( void )\r
+{\r
+ if ( mdrv->getstatus != NULL )\r
+ {\r
+ if ( mdrv->getstatus( mdrv ) & ( F_ST_MISSING | F_ST_CHANGED ) )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/\r
+ return F_ERR_CARDREMOVED;\r
+ }\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_writesector\r
+ *\r
+ * write sector data on a volume, it calls low level driver function, it\r
+ * writes a complete sector\r
+ *\r
+ * INPUTS\r
+ * sector - which physical sector\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_writeglsector ( unsigned long sector )\r
+{\r
+ unsigned char retry;\r
+\r
+ if ( mdrv->writesector == NULL )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*no write function*/\r
+ return F_ERR_ACCESSDENIED;\r
+ }\r
+\r
+ if ( sector == (unsigned long)-1 )\r
+ {\r
+ if ( gl_file.modified )\r
+ {\r
+ sector = gl_file.pos.sector;\r
+ }\r
+ else\r
+ {\r
+ sector = gl_volume.actsector;\r
+ }\r
+ }\r
+\r
+ if ( sector != (unsigned long)-1 )\r
+ {\r
+ if ( mdrv->getstatus != NULL )\r
+ {\r
+ unsigned int status;\r
+\r
+ status = mdrv->getstatus( mdrv );\r
+\r
+ if ( status & ( F_ST_MISSING | F_ST_CHANGED ) )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/\r
+ return F_ERR_CARDREMOVED;\r
+ }\r
+\r
+ if ( status & ( F_ST_WRPROTECT ) )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/\r
+ return F_ERR_WRITEPROTECT;\r
+ }\r
+ }\r
+\r
+ gl_volume.modified = 0;\r
+ gl_file.modified = 0;\r
+ gl_volume.actsector = sector;\r
+ for ( retry = 3 ; retry ; retry-- )\r
+ {\r
+ int mdrv_ret;\r
+ mdrv_ret = mdrv->writesector( mdrv, (unsigned char *)gl_sector, sector );\r
+ if ( !mdrv_ret )\r
+ {\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ if ( mdrv_ret == -1 )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/\r
+ return F_ERR_CARDREMOVED;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ return F_ERR_ONDRIVE;\r
+} /* _f_writeglsector */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_readsector\r
+ *\r
+ * read sector data from a volume, it calls low level driver function, it\r
+ * reads a complete sector\r
+ *\r
+ * INPUTS\r
+ * sector - which physical sector is read\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_readglsector ( unsigned long sector )\r
+{\r
+ unsigned char retry;\r
+ unsigned char ret;\r
+\r
+ if ( sector == gl_volume.actsector )\r
+ {\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ if ( gl_volume.modified || gl_file.modified )\r
+ {\r
+ ret = _f_writeglsector( (unsigned long)-1 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+ }\r
+\r
+\r
+ for ( retry = 3 ; retry ; retry-- )\r
+ {\r
+ int mdrv_ret;\r
+ mdrv_ret = mdrv->readsector( mdrv, (unsigned char *)gl_sector, sector );\r
+ if ( !mdrv_ret )\r
+ {\r
+ gl_volume.actsector = sector;\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ if ( mdrv_ret == -1 )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/\r
+ return F_ERR_CARDREMOVED;\r
+ }\r
+ }\r
+\r
+ gl_volume.actsector = (unsigned long)-1;\r
+ return F_ERR_ONDRIVE;\r
+} /* _f_readglsector */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __DRV_H\r
+#define __DRV_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern F_DRIVER * mdrv; /* driver structure */\r
+\r
+unsigned char _f_checkstatus ( void );\r
+unsigned char _f_readglsector ( unsigned long );\r
+unsigned char _f_writeglsector ( unsigned long );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __DRV_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#define FS_MUTEX_DEFINED\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#if F_FS_THREAD_AWARE == 1\r
+\r
+xSemaphoreHandle fs_lock_semaphore;\r
+\r
+\r
+/*\r
+** fr_findfirst\r
+**\r
+** find first time a file using wildcards\r
+**\r
+** INPUT : filename - name of the file\r
+** *find - pointer to a pre-define F_FIND structure\r
+** RETURN: F_NOERR - on success\r
+** F_ERR_NOTFOUND - if not found\r
+*/\r
+unsigned char fr_findfirst ( const char * filename, F_FIND * find )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_findfirst( filename, find );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_findnext\r
+**\r
+** find next time a file using wildcards\r
+**\r
+** INPUT : *find - pointer to a pre-define F_FIND structure\r
+** RETURN: F_NOERR - on success\r
+** F_ERR_NOTFOUND - if not found\r
+*/\r
+unsigned char fr_findnext ( F_FIND * find )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_findnext( find );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_filelength\r
+**\r
+** Get the length of a file\r
+**\r
+** INPUT : filename - name of the file\r
+** RETURN: size of the file or F_ERR_INVALID if not exists or volume not working\r
+*/\r
+long fr_filelength ( const char * filename )\r
+{\r
+ unsigned long rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_filelength( filename );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = 0;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_open\r
+**\r
+** open a file\r
+**\r
+** INPUT : filename - file to be opened\r
+** mode - open method (r,w,a,r+,w+,a+)\r
+** RETURN: pointer to a file descriptor or 0 on error\r
+*/\r
+F_FILE * fr_open ( const char * filename, const char * mode )\r
+{\r
+ F_FILE * rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_open( filename, mode );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = NULL;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_close\r
+**\r
+** Close a previously opened file.\r
+**\r
+** INPUT : *filehandle - pointer to the file descriptor\r
+** RETURN: F_NOERR on success, other if error\r
+*/\r
+unsigned char fr_close ( F_FILE * filehandle )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_close( filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_read\r
+**\r
+** Read from a file.\r
+**\r
+** INPUT : buf - buffer to read data\r
+** size - number of unique\r
+** size_st - size of unique\r
+** *filehandle - pointer to file descriptor\r
+** OUTPUT: number of read bytes\r
+*/\r
+long fr_read ( void * bbuf, long size, long size_st, F_FILE * filehandle )\r
+{\r
+ long rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_read( bbuf, size, size_st, filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = 0;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_write\r
+**\r
+** INPUT : bbuf - buffer to write from\r
+** size - number of unique\r
+** size_st - size of unique\r
+** *filehandle - pointer to the file descriptor\r
+** RETURN: number of written bytes\r
+*/\r
+long fr_write ( const void * bbuf, long size, long size_st, F_FILE * filehandle )\r
+{\r
+ long rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_write( bbuf, size, size_st, filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = 0;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_seek\r
+**\r
+** Seek in a file.\r
+**\r
+** INPUT : *filehandle - pointer to a file descriptor\r
+** offset - offset\r
+** whence - F_SEEK_SET: position = offset\r
+** F_SEEK_CUR: position = position + offset\r
+** F_SEEK_END: position = end of file (offset=0)\r
+** RETURN: F_NOERR on succes, other if error.\r
+*/\r
+unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_seek( filehandle, offset, whence );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_tell\r
+**\r
+** get current position in the file\r
+**\r
+** INPUT : *filehandle - pointer to a file descriptor\r
+** RETURN: -1 on error or current position.\r
+*/\r
+long fr_tell ( F_FILE * filehandle )\r
+{\r
+ long rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_tell( filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = -1;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_getc\r
+**\r
+** read one byte from a file\r
+**\r
+** INPUT : *filehandle - pointer to a file descriptor\r
+** RETURN: -1 if error, otherwise the read character.\r
+*/\r
+int fr_getc ( F_FILE * filehandle )\r
+{\r
+ int rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_getc( filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = -1;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_putc\r
+**\r
+** write one byte to a file\r
+**\r
+** INPUT : ch - character to write\r
+** *filehandle - pointer to a file handler\r
+** RETURN: ch on success, -1 on error\r
+*/\r
+int fr_putc ( int ch, F_FILE * filehandle )\r
+{\r
+ int rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_putc( ch, filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = -1;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_rewind\r
+**\r
+** set current position in the file to the beginning\r
+**\r
+** INPUT : *filehandle - pointer to a file descriptor\r
+** RETURN: F_NOERR on succes, other if error.\r
+*/\r
+unsigned char fr_rewind ( F_FILE * filehandle )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_rewind( filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_eof\r
+**\r
+** check if current position is at the end of the file.\r
+**\r
+** INPUT : *filehandle - pointer to a file descriptor\r
+** RETURN: F_ERR_EOF - at the end of the file\r
+** F_NOERR - no error, end of the file not reached\r
+** other - on error\r
+*/\r
+unsigned char fr_eof ( F_FILE * filehandle )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_eof( filehandle );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** Format the device\r
+*/\r
+unsigned char fr_hardformat ( unsigned char fattype )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_hardformat( fattype );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_get_serial\r
+**\r
+** Get serial number\r
+**\r
+** OUTPUT: serial - where to write the serial number\r
+** RETURN: error code\r
+*/\r
+unsigned char fr_getserial ( unsigned long * serial )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_getserial( serial );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_delete\r
+**\r
+** Delete a file. Removes the chain that belongs to the file and inserts a new descriptor\r
+** to the directory with first_cluster set to 0.\r
+**\r
+** INPUT : filename - name of the file to delete\r
+** RETURN: F_NOERR on success, other if error.\r
+*/\r
+unsigned char fr_delete ( const char * filename )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_delete( filename );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+/*\r
+** fr_truncate\r
+**\r
+** Open a file and set end of file\r
+**\r
+** INPUT: filename - name of the file\r
+** filesize - required new size\r
+** RETURN: NULL on error, otherwise file pointer\r
+*/\r
+F_FILE * fr_truncate ( const char * filename, long filesize )\r
+{\r
+ F_FILE * f;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ f = fn_truncate( filename, filesize );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ f = NULL;\r
+ }\r
+\r
+ return f;\r
+}\r
+\r
+\r
+/*\r
+** fr_getfreespace\r
+**\r
+** Get free space on the volume\r
+**\r
+** OUTPUT: *sp - pre-defined F_SPACE structure, where information will be stored\r
+** RETURN: F_NOERR - on success\r
+** F_ERR_NOTFORMATTED - if volume is not formatted\r
+*/\r
+unsigned char fr_getfreespace ( F_SPACE * sp )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_getfreespace( sp );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_chdir\r
+**\r
+** Change to a directory\r
+**\r
+** INPUT: path - path to the dircetory\r
+** RETURN: 0 - on success, other if error\r
+*/\r
+unsigned char fr_chdir ( const char * path )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_chdir( path );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_mkdir\r
+**\r
+** Create a directory\r
+**\r
+** INPUT: path - new directory path\r
+** RETURN: 0 - on success, other if error\r
+*/\r
+unsigned char fr_mkdir ( const char * path )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_mkdir( path );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_rmdir\r
+**\r
+** Removes a directory\r
+**\r
+** INPUT: path - path to remove\r
+** RETURN: 0 - on success, other if error\r
+*/\r
+unsigned char fr_rmdir ( const char * path )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_rmdir( path );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_getcwd\r
+**\r
+** Get current working directory\r
+**\r
+** INPUT: maxlen - maximum length allowed\r
+** OUTPUT: path - current working directory\r
+** RETURN: 0 - on success, other if error\r
+*/\r
+unsigned char fr_getcwd ( char * path, unsigned char maxlen, char root )\r
+{\r
+ unsigned char rc;\r
+\r
+ if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS )\r
+ {\r
+ rc = fn_getcwd( path, maxlen, root );\r
+ xSemaphoreGive( fs_lock_semaphore );\r
+ }\r
+ else\r
+ {\r
+ rc = F_ERR_OS;\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+\r
+/*\r
+** fr_init\r
+**\r
+** Initialize FAT_SL OS module\r
+**\r
+** RETURN: F_NO_ERROR or F_ERR_OS\r
+*/\r
+unsigned char fr_init ( void )\r
+{\r
+ return F_NO_ERROR;\r
+}\r
+\r
+#endif /* F_FS_THREAD_AWARE */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _F_RTOS_H\r
+#define _F_RTOS_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+unsigned char fr_init ( void );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef _F_RTOS_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+#include "../../api/fat_sl.h"\r
+\r
+#include "fat.h"\r
+#include "util.h"\r
+#include "volume.h"\r
+#include "drv.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_writefatsector\r
+ *\r
+ * writing fat sector into volume, this function check if fat was modified\r
+ * and writes data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_writefatsector ( void )\r
+{\r
+ unsigned char a;\r
+\r
+ if ( gl_volume.modified )\r
+ {\r
+ unsigned long fatsector = gl_volume.firstfat.sector + gl_volume.fatsector;\r
+\r
+ if ( gl_volume.fatsector >= gl_volume.firstfat.num )\r
+ {\r
+ return F_ERR_INVALIDSECTOR;\r
+ }\r
+\r
+ for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ )\r
+ {\r
+ unsigned char ret;\r
+ ret = _f_writeglsector( fatsector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ fatsector += gl_volume.firstfat.num;\r
+ }\r
+\r
+ gl_volume.modified = 0;\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_writefatsector */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getfatsector\r
+ *\r
+ * read a fat sector from media\r
+ *\r
+ * INPUTS\r
+ *\r
+ * sector - which fat sector is needed, this sector number is zero based\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_getfatsector ( unsigned long sector )\r
+{\r
+ unsigned char a;\r
+\r
+ if ( gl_volume.fatsector != sector )\r
+ {\r
+ unsigned long fatsector;\r
+\r
+ gl_volume.fatsector = sector;\r
+\r
+ if ( gl_volume.fatsector >= gl_volume.firstfat.num )\r
+ {\r
+ return F_ERR_INVALIDSECTOR;\r
+ }\r
+\r
+ fatsector = gl_volume.firstfat.sector + gl_volume.fatsector;\r
+\r
+ for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ )\r
+ {\r
+ if ( !_f_readglsector( fatsector ) )\r
+ {\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ fatsector += gl_volume.firstfat.num;\r
+ }\r
+\r
+ return F_ERR_READ;\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_getfatsector */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setclustervalue\r
+ *\r
+ * set a cluster value in the FAT\r
+ *\r
+ * INPUTS\r
+ *\r
+ * cluster - which cluster's value need to be modified\r
+ * data - new value of the cluster\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_setclustervalue ( unsigned long cluster, unsigned long _tdata )\r
+{\r
+ unsigned char ret;\r
+\r
+ switch ( gl_volume.mediatype )\r
+ {\r
+ case F_FAT16_MEDIA:\r
+ {\r
+ unsigned long sector = cluster;\r
+ unsigned short s_data = (unsigned short)( _tdata & 0xffff ); /*keep 16 bit only*/\r
+\r
+ sector /= ( F_SECTOR_SIZE / 2 );\r
+ cluster -= sector * ( F_SECTOR_SIZE / 2 );\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( _f_getword( &gl_sector[cluster << 1] ) != s_data )\r
+ {\r
+ _f_setword( &gl_sector[cluster << 1], s_data );\r
+ gl_volume.modified = 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case F_FAT12_MEDIA:\r
+ {\r
+ unsigned char f12new[2];\r
+ unsigned long sector = cluster;\r
+ unsigned short pos;\r
+ unsigned short s_data = (unsigned short)( _tdata & 0x0fff ); /*keep 12 bit only*/\r
+\r
+ if ( cluster & 1 )\r
+ {\r
+ s_data <<= 4;\r
+ }\r
+\r
+ _f_setword( f12new, s_data ); /*create new data*/\r
+\r
+ sector += sector / 2; /*1.5 bytes*/\r
+ pos = (unsigned short)( sector % F_SECTOR_SIZE );\r
+ sector /= F_SECTOR_SIZE;\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( cluster & 1 )\r
+ {\r
+ f12new[0] |= gl_sector[pos] & 0x0f;\r
+ }\r
+\r
+ if ( gl_sector[pos] != f12new[0] )\r
+ {\r
+ gl_sector[pos] = f12new[0];\r
+ gl_volume.modified = 1;\r
+ }\r
+\r
+ pos++;\r
+ if ( pos >= 512 )\r
+ {\r
+ ret = _f_getfatsector( sector + 1 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ pos = 0;\r
+ }\r
+\r
+ if ( !( cluster & 1 ) )\r
+ {\r
+ f12new[1] |= gl_sector[pos] & 0xf0;\r
+ }\r
+\r
+ if ( gl_sector[pos] != f12new[1] )\r
+ {\r
+ gl_sector[pos] = f12new[1];\r
+ gl_volume.modified = 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case F_FAT32_MEDIA:\r
+ {\r
+ unsigned long sector = cluster;\r
+ unsigned long oldv;\r
+\r
+ sector /= ( F_SECTOR_SIZE / 4 );\r
+ cluster -= sector * ( F_SECTOR_SIZE / 4 );\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ oldv = _f_getlong( &gl_sector[cluster << 2] );\r
+\r
+ _tdata &= 0x0fffffff;\r
+ _tdata |= oldv & 0xf0000000; /*keep 4 top bits*/\r
+\r
+ if ( _tdata != oldv )\r
+ {\r
+ _f_setlong( &gl_sector[cluster << 2], _tdata );\r
+ gl_volume.modified = 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return F_ERR_INVALIDMEDIA;\r
+ } /* switch */\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_setclustervalue */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getclustervalue\r
+ *\r
+ * get a cluster value from FAT\r
+ *\r
+ * INPUTS\r
+ *\r
+ * cluster - which cluster value is requested\r
+ * pvalue - where to store data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_getclustervalue ( unsigned long cluster, unsigned long * pvalue )\r
+{\r
+ unsigned long val;\r
+ unsigned char ret;\r
+\r
+ switch ( gl_volume.mediatype )\r
+ {\r
+ case F_FAT16_MEDIA:\r
+ {\r
+ unsigned long sector = cluster;\r
+ sector /= ( F_SECTOR_SIZE / 2 );\r
+ cluster -= sector * ( F_SECTOR_SIZE / 2 );\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ val = _f_getword( &gl_sector[cluster << 1] );\r
+ if ( val >= ( F_CLUSTER_RESERVED & 0xffff ) )\r
+ {\r
+ val |= 0x0ffff000; /*extends it*/\r
+ }\r
+\r
+ if ( pvalue )\r
+ {\r
+ *pvalue = val;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case F_FAT12_MEDIA:\r
+ {\r
+ unsigned char dataf12[2];\r
+ unsigned long sector = cluster;\r
+ unsigned short pos;\r
+\r
+ sector += sector / 2; /*1.5 bytes*/\r
+ pos = (unsigned short)( sector % F_SECTOR_SIZE );\r
+ sector /= F_SECTOR_SIZE;\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ dataf12[0] = gl_sector[pos++];\r
+\r
+ if ( pos >= 512 )\r
+ {\r
+ ret = _f_getfatsector( sector + 1 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ pos = 0;\r
+ }\r
+\r
+ dataf12[1] = gl_sector[pos];\r
+\r
+ val = _f_getword( dataf12 );\r
+\r
+ if ( cluster & 1 )\r
+ {\r
+ val = val >> 4;\r
+ }\r
+ else\r
+ {\r
+ val = val & 0xfff;\r
+ }\r
+\r
+ if ( val >= ( F_CLUSTER_RESERVED & 0xfff ) )\r
+ {\r
+ val |= 0x0ffff000; /*extends it*/\r
+ }\r
+\r
+ if ( pvalue )\r
+ {\r
+ *pvalue = val;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case F_FAT32_MEDIA:\r
+ {\r
+ unsigned long sector = cluster;\r
+ sector /= ( F_SECTOR_SIZE / 4 );\r
+ cluster -= sector * ( F_SECTOR_SIZE / 4 );\r
+\r
+ ret = _f_getfatsector( sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( pvalue )\r
+ {\r
+ *pvalue = _f_getlong( &gl_sector[cluster << 2] ) & 0x0fffffff; /*28bit*/\r
+ }\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return F_ERR_INVALIDMEDIA;\r
+ } /* switch */\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_getclustervalue */\r
+\r
+\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_clustertopos\r
+ *\r
+ * convert a cluster position into physical sector position\r
+ *\r
+ * INPUTS\r
+ *\r
+ * cluster - original cluster position\r
+ * pos - position structure to fills the position\r
+ *\r
+ ***************************************************************************/\r
+void _f_clustertopos ( unsigned long cluster, F_POS * pos )\r
+{\r
+ pos->cluster = cluster;\r
+\r
+ if ( !cluster )\r
+ {\r
+ pos->sector = gl_volume.root.sector;\r
+ pos->sectorend = pos->sector + gl_volume.root.num;\r
+ }\r
+ else\r
+ {\r
+ unsigned long sectorcou = gl_volume.bootrecord.sector_per_cluster;\r
+ pos->sector = ( pos->cluster - 2 ) * sectorcou + gl_volume._tdata.sector;\r
+ pos->sectorend = pos->sector + sectorcou;\r
+ }\r
+\r
+ if ( cluster >= F_CLUSTER_RESERVED )\r
+ {\r
+ pos->sectorend = 0;\r
+ }\r
+\r
+ pos->pos = 0;\r
+} /* _f_clustertopos */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getcurrsector\r
+ *\r
+ * read current sector according in file structure\r
+ *\r
+ * INPUTS\r
+ * f - internal file pointer\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_getcurrsector ( void )\r
+{\r
+ unsigned char ret;\r
+ unsigned long cluster;\r
+\r
+ if ( gl_file.pos.sector == gl_file.pos.sectorend )\r
+ {\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_getclustervalue( gl_file.pos.cluster, &cluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( cluster >= F_CLUSTER_RESERVED )\r
+ {\r
+ return F_ERR_EOF;\r
+ }\r
+\r
+ gl_file.prevcluster = gl_file.pos.cluster;\r
+ _f_clustertopos( cluster, &gl_file.pos );\r
+ }\r
+\r
+ return _f_readglsector( gl_file.pos.sector );\r
+} /* _f_getcurrsector */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_alloccluster\r
+ *\r
+ * allocate cluster from FAT\r
+ *\r
+ * INPUTS\r
+ * pcluster - where to store the allocated cluster number\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+unsigned char _f_alloccluster ( unsigned long * pcluster )\r
+{\r
+ unsigned long maxcluster = gl_volume.maxcluster;\r
+ unsigned long cou;\r
+ unsigned long cluster = gl_volume.lastalloccluster;\r
+ unsigned long value;\r
+ unsigned char ret;\r
+\r
+ for ( cou = 0 ; cou < maxcluster ; cou++ )\r
+ {\r
+ if ( cluster >= maxcluster )\r
+ {\r
+ cluster = 0;\r
+ }\r
+\r
+ ret = _f_getclustervalue( cluster, &value );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !value )\r
+ {\r
+ gl_volume.lastalloccluster = cluster + 1; /*set next one*/\r
+ *pcluster = cluster;\r
+\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ cluster++;\r
+ }\r
+\r
+ return F_ERR_NOMOREENTRY;\r
+} /* _f_alloccluster */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_removechain\r
+ *\r
+ * remove cluster chain from fat\r
+ *\r
+ * INPUTS\r
+ * cluster - first cluster in the cluster chain\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+unsigned char _f_removechain ( unsigned long cluster )\r
+{\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+\r
+ if ( cluster < gl_volume.lastalloccluster ) /*this could be the begining of alloc*/\r
+ {\r
+ gl_volume.lastalloccluster = cluster;\r
+ }\r
+\r
+ while ( cluster < F_CLUSTER_RESERVED && cluster >= 2 )\r
+ {\r
+ unsigned long nextcluster;\r
+\r
+ unsigned char ret = _f_getclustervalue( cluster, &nextcluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_setclustervalue( cluster, F_CLUSTER_FREE );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ cluster = nextcluster;\r
+ }\r
+\r
+ return _f_writefatsector();\r
+} /* _f_removechain */\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __FAT_H\r
+#define __FAT_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+unsigned char _f_getfatsector ( unsigned long );\r
+unsigned char _f_getclustervalue ( unsigned long, unsigned long * );\r
+void _f_clustertopos ( unsigned long, F_POS * );\r
+unsigned char _f_getcurrsector ( void );\r
+\r
+unsigned char _f_writefatsector ( void );\r
+unsigned char _f_setclustervalue ( unsigned long, unsigned long );\r
+unsigned char _f_alloccluster ( unsigned long * );\r
+unsigned char _f_removechain ( unsigned long );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __FAT_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/include/psp_string.h"\r
+\r
+#include "util.h"\r
+#include "volume.h"\r
+#include "drv.h"\r
+#include "fat.h"\r
+#include "dir.h"\r
+#include "file.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+static unsigned char _f_emptywritebuffer ( void );\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_filelength\r
+ *\r
+ * Get a file length\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filename - file whose length is needed\r
+ *\r
+ * RETURNS\r
+ *\r
+ * length of the file\r
+ *\r
+ ***************************************************************************/\r
+\r
+long fn_filelength ( const char * filename )\r
+{\r
+ F_POS pos;\r
+ F_DIRENTRY * de;\r
+ F_NAME fsname;\r
+\r
+ if ( _f_setfsname( filename, &fsname ) )\r
+ {\r
+ return 0; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return 0; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_getvolume() )\r
+ {\r
+ return 0; /*can't get the size*/\r
+ }\r
+\r
+ if ( !_f_findpath( &fsname, &pos ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( de->attr & F_ATTR_DIR )\r
+ {\r
+ return 0; /*directory*/\r
+ }\r
+\r
+ return (long)_f_getlong( &de->filesize );\r
+} /* fn_filelength */\r
+\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_emptywritebuffer\r
+ *\r
+ * empty write buffer if it contains unwritten data\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+\r
+static unsigned char _f_emptywritebuffer ( void )\r
+{\r
+ unsigned char ret;\r
+\r
+ ret = _f_writeglsector( gl_file.pos.sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_file.modified = 0;\r
+\r
+ gl_file.pos.sector++;\r
+\r
+ if ( gl_file.pos.sector >= gl_file.pos.sectorend )\r
+ {\r
+ unsigned long value;\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ ret = _f_getclustervalue( gl_file.pos.cluster, &value );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/\r
+ {\r
+ gl_file.prevcluster = gl_file.pos.cluster;\r
+ _f_clustertopos( value, &gl_file.pos ); /*go to next cluster*/\r
+ }\r
+ else\r
+ {\r
+ unsigned long nextcluster;\r
+\r
+ ret = _f_alloccluster( &nextcluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_file.prevcluster = gl_file.pos.cluster;\r
+\r
+ _f_clustertopos( nextcluster, &gl_file.pos );\r
+\r
+ return _f_writefatsector();\r
+ }\r
+ }\r
+\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_emptywritebuffer */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_extend\r
+ *\r
+ * Extend file to a certain size\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_extend ( long size )\r
+{\r
+ unsigned long _size;\r
+ unsigned char rc;\r
+\r
+ size -= gl_file.filesize;\r
+ _size = (unsigned long)size;\r
+\r
+ rc = _f_getcurrsector();\r
+ if ( rc )\r
+ {\r
+ return rc;\r
+ }\r
+\r
+ psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) );\r
+\r
+ if ( gl_file.relpos + _size > F_SECTOR_SIZE )\r
+ {\r
+ _size -= ( F_SECTOR_SIZE - gl_file.relpos );\r
+ while ( _size )\r
+ {\r
+ if ( _f_emptywritebuffer() )\r
+ {\r
+ return F_ERR_WRITE;\r
+ }\r
+\r
+ psp_memset( gl_sector, 0, F_SECTOR_SIZE );\r
+ _size -= ( _size > F_SECTOR_SIZE ? F_SECTOR_SIZE : _size );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ _size += gl_file.relpos;\r
+ }\r
+\r
+ gl_file.modified = 1;\r
+ gl_file.filesize += size;\r
+ gl_file.abspos = gl_file.filesize & ( ~( F_SECTOR_SIZE - 1 ) );\r
+ gl_file.relpos = _size;\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_extend */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_fseek\r
+ *\r
+ * subfunction for f_seek it moves position into given offset and read\r
+ * the current sector\r
+ *\r
+ * INPUTS\r
+ * offset - position from start\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_fseek ( long offset )\r
+{\r
+ unsigned long cluster;\r
+ unsigned long tmp;\r
+ unsigned char ret = F_NO_ERROR;\r
+ long remain;\r
+\r
+ if ( offset < 0 )\r
+ {\r
+ offset = 0;\r
+ }\r
+\r
+ if ( ( (unsigned long) offset <= gl_file.filesize )\r
+ && ( (unsigned long) offset >= gl_file.abspos )\r
+ && ( (unsigned long) offset < gl_file.abspos + F_SECTOR_SIZE ) )\r
+ {\r
+ gl_file.relpos = (unsigned short)( offset - gl_file.abspos );\r
+ }\r
+ else\r
+ {\r
+ if ( gl_file.modified )\r
+ {\r
+ ret = _f_writeglsector( (unsigned long)-1 );\r
+ if ( ret )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE; /*cant accessed any more*/\r
+ return ret;\r
+ }\r
+ }\r
+\r
+ if ( gl_file.startcluster )\r
+ {\r
+ gl_file.abspos = 0;\r
+ gl_file.relpos = 0;\r
+ gl_file.prevcluster = 0;\r
+ gl_file.pos.cluster = gl_file.startcluster;\r
+ remain = gl_file.filesize;\r
+\r
+ tmp = gl_volume.bootrecord.sector_per_cluster;\r
+ tmp *= F_SECTOR_SIZE; /* set to cluster size */\r
+\r
+ /*calc cluster*/\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ while ( (unsigned long)offset >= tmp )\r
+ {\r
+ ret = _f_getclustervalue( gl_file.pos.cluster, &cluster );\r
+ if ( ret )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ return ret;\r
+ }\r
+\r
+ if ( (long) tmp >= remain )\r
+ {\r
+ break;\r
+ }\r
+\r
+ remain -= tmp;\r
+ offset -= tmp;\r
+ gl_file.abspos += tmp;\r
+ if ( cluster >= F_CLUSTER_RESERVED )\r
+ {\r
+ break;\r
+ }\r
+\r
+ gl_file.prevcluster = gl_file.pos.cluster;\r
+ gl_file.pos.cluster = cluster;\r
+ }\r
+\r
+ _f_clustertopos( gl_file.pos.cluster, &gl_file.pos );\r
+ if ( remain && offset )\r
+ {\r
+ while ( ( offset > (long) F_SECTOR_SIZE )\r
+ && ( remain > (long) F_SECTOR_SIZE ) )\r
+ {\r
+ gl_file.pos.sector++;\r
+ offset -= F_SECTOR_SIZE;\r
+ remain -= F_SECTOR_SIZE;\r
+ gl_file.abspos += F_SECTOR_SIZE;\r
+ }\r
+ }\r
+\r
+ if ( remain < offset )\r
+ {\r
+ gl_file.relpos = (unsigned short)remain;\r
+ ret = _f_extend( gl_file.filesize + offset - remain );\r
+ }\r
+ else\r
+ {\r
+ gl_file.relpos = (unsigned short)offset;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+} /* _f_fseek */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_open\r
+ *\r
+ * open a file for reading/writing/appending\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filename - which file need to be opened\r
+ * mode - string how to open ("r"-read, "w"-write, "w+"-overwrite, "a"-append\r
+ *\r
+ * RETURNS\r
+ *\r
+ * F_FILE pointer if successfully\r
+ * 0 - if any error\r
+ *\r
+ ***************************************************************************/\r
+F_FILE * fn_open ( const char * filename, const char * mode )\r
+{\r
+ F_DIRENTRY * de;\r
+ F_NAME fsname;\r
+ unsigned short date;\r
+ unsigned short time;\r
+ unsigned char m_mode = F_FILE_CLOSE;\r
+\r
+ if ( mode[1] == 0 )\r
+ {\r
+ if ( mode[0] == 'r' )\r
+ {\r
+ m_mode = F_FILE_RD;\r
+ }\r
+\r
+ if ( mode[0] == 'w' )\r
+ {\r
+ m_mode = F_FILE_WR;\r
+ }\r
+\r
+ if ( mode[0] == 'a' )\r
+ {\r
+ m_mode = F_FILE_A;\r
+ }\r
+ }\r
+\r
+ if ( ( mode[1] == '+' ) && ( mode[2] == 0 ) )\r
+ {\r
+ if ( mode[0] == 'r' )\r
+ {\r
+ m_mode = F_FILE_RDP;\r
+ }\r
+\r
+ if ( mode[0] == 'w' )\r
+ {\r
+ m_mode = F_FILE_WRP;\r
+ }\r
+\r
+ if ( mode[0] == 'a' )\r
+ {\r
+ m_mode = F_FILE_AP;\r
+ }\r
+\r
+ }\r
+\r
+ if ( m_mode == F_FILE_CLOSE )\r
+ {\r
+ return 0; /*invalid mode*/\r
+ }\r
+\r
+ if ( _f_setfsname( filename, &fsname ) )\r
+ {\r
+ return 0; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return 0; /*invalid name*/\r
+ }\r
+\r
+ if ( fsname.filename[0] == '.' )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( _f_getvolume() )\r
+ {\r
+ return 0; /*cant open any*/\r
+ }\r
+\r
+ if ( gl_file.mode != F_FILE_CLOSE )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ psp_memset( &gl_file, 0, 21 );\r
+\r
+ if ( !_f_findpath( &fsname, &gl_file.dirpos ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ switch ( m_mode )\r
+ {\r
+ case F_FILE_RDP: /*r*/\r
+ case F_FILE_RD: /*r*/\r
+ if ( !_f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( de->attr & F_ATTR_DIR )\r
+ {\r
+ return 0; /*directory*/\r
+ }\r
+\r
+ gl_file.startcluster = _f_getdecluster( de );\r
+\r
+ if ( gl_file.startcluster )\r
+ {\r
+ _f_clustertopos( gl_file.startcluster, &gl_file.pos );\r
+ gl_file.filesize = _f_getlong( &de->filesize );\r
+ gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE);\r
+ if ( _f_fseek( 0 ) )\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+\r
+#if F_FILE_CHANGED_EVENT\r
+ if ( m_mode == F_FILE_RDP )\r
+ {\r
+ _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );\r
+ }\r
+\r
+#endif\r
+\r
+ break;\r
+\r
+ case F_FILE_AP:\r
+ case F_FILE_A: /*a*/\r
+ psp_memcpy( &( gl_file.pos ), &( gl_file.dirpos ), sizeof( F_POS ) );\r
+ if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) )\r
+ {\r
+ if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ gl_file.startcluster = _f_getdecluster( de );\r
+ gl_file.filesize = _f_getlong( &de->filesize );\r
+\r
+ if ( gl_file.startcluster )\r
+ {\r
+ _f_clustertopos( gl_file.startcluster, &gl_file.pos );\r
+ gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE); /*forcing seek to read 1st sector! abspos=0;*/\r
+ if ( _f_fseek( (long)gl_file.filesize ) )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ return 0;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );\r
+ _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );\r
+\r
+ if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )\r
+ {\r
+ return 0; /*couldnt be added*/\r
+ }\r
+\r
+ de->attr |= F_ATTR_ARC; /*set as archiv*/\r
+ if ( _f_writeglsector( (unsigned long)-1 ) )\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );\r
+ #endif\r
+ break;\r
+\r
+\r
+ case F_FILE_WR: /*w*/\r
+ case F_FILE_WRP: /*w+*/\r
+ _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos );\r
+ if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.pos, &de, 0 ) )\r
+ {\r
+ unsigned long cluster = _f_getdecluster( de ); /*exist*/\r
+\r
+ if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) );\r
+\r
+ _f_setlong( de->filesize, 0 ); /*reset size;*/\r
+ de->attr |= F_ATTR_ARC; /*set as archiv*/\r
+ _f_setword( de->clusterlo, 0 ); /*no points anywhere*/\r
+ _f_setword( de->clusterhi, 0 );\r
+\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ f_igettimedate( &time, &date );\r
+ _f_setword( &de->crtdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ _f_setword( &de->crttime, time ); /*if there is realtime clock then creation time could be set from*/\r
+ _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ }\r
+\r
+ if ( _f_writeglsector( (unsigned long)-1 ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( _f_removechain( cluster ) )\r
+ {\r
+ return 0; /*remove */\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) )\r
+ {\r
+ return 0; /*couldnt be added*/\r
+ }\r
+\r
+ psp_memset( &gl_file, 0, 21 );\r
+ de->attr |= F_ATTR_ARC; /*set as archiv*/\r
+ if ( _f_writeglsector( (unsigned long)-1 ) )\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext );\r
+ #endif\r
+\r
+ break;\r
+\r
+ default:\r
+ return 0; /*invalid mode*/\r
+ } /* switch */\r
+\r
+ if ( ( m_mode != F_FILE_RD ) && ( gl_file.startcluster == 0 ) )\r
+ {\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ if ( _f_alloccluster( &( gl_file.startcluster ) ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ _f_clustertopos( gl_file.startcluster, &gl_file.pos );\r
+ if ( _f_setclustervalue( gl_file.startcluster, F_CLUSTER_LAST ) )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( _f_writefatsector() )\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+\r
+\r
+ gl_file.mode = m_mode; /* lock it */\r
+ return (F_FILE *)1;\r
+} /* fn_open */\r
+\r
+\r
+/****************************************************************************\r
+ * _f_updatefileentry\r
+ * Updated a file directory entry or removes the entry\r
+ * and the fat chain belonging to it.\r
+ ***************************************************************************/\r
+static unsigned char _f_updatefileentry ( int remove )\r
+{\r
+ F_DIRENTRY * de;\r
+ unsigned short date;\r
+ unsigned short time;\r
+\r
+ de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * gl_file.dirpos.pos );\r
+ if ( _f_readglsector( gl_file.dirpos.sector ) || remove )\r
+ {\r
+ _f_setdecluster( de, 0 );\r
+ _f_setlong( &de->filesize, 0 );\r
+ (void)_f_writeglsector( (unsigned long)-1 );\r
+ (void)_f_removechain( gl_file.startcluster );\r
+ return F_ERR_WRITE;\r
+ }\r
+\r
+ _f_setdecluster( de, gl_file.startcluster );\r
+ _f_setlong( &de->filesize, gl_file.filesize );\r
+ f_igettimedate( &time, &date );\r
+ _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/\r
+ }\r
+\r
+ return _f_writeglsector( (unsigned long)-1 );\r
+} /* _f_updatefileentry */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_close\r
+ *\r
+ * close a previously opened file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - which file needs to be closed\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_close ( F_FILE * f )\r
+{\r
+ unsigned char ret;\r
+\r
+#if F_FILE_CHANGED_EVENT\r
+ unsigned char mode;\r
+#endif\r
+\r
+ if ( !f )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( gl_file.mode == F_FILE_CLOSE )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+\r
+ else if ( gl_file.mode == F_FILE_RD )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ return F_NO_ERROR;\r
+ }\r
+ else\r
+ {\r
+ #if F_FILE_CHANGED_EVENT\r
+ mode = f->mode;\r
+ #endif\r
+ gl_file.mode = F_FILE_CLOSE;\r
+\r
+ if ( gl_file.modified )\r
+ {\r
+ if ( _f_writeglsector( (unsigned long)-1 ) )\r
+ {\r
+ (void)_f_updatefileentry( 1 );\r
+ return F_ERR_WRITE;\r
+ }\r
+ }\r
+\r
+ ret = _f_updatefileentry( 0 );\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ if ( f_filechangedevent && !ret )\r
+ {\r
+ ST_FILE_CHANGED fc;\r
+ if ( ( mode == F_FILE_WR ) || ( mode == F_FILE_WRP ) )\r
+ {\r
+ fc.action = FACTION_ADDED;\r
+ fc.flags = FFLAGS_FILE_NAME;\r
+ }\r
+ else if ( ( mode == F_FILE_A ) || ( mode == F_FILE_RDP ) )\r
+ {\r
+ fc.action = FACTION_MODIFIED;\r
+ fc.flags = FFLAGS_FILE_NAME | FFLAGS_SIZE;\r
+ }\r
+\r
+ strcpy( fc.filename, f->filename );\r
+ if ( f->filename[0] )\r
+ {\r
+ f_filechangedevent( &fc );\r
+ }\r
+\r
+ f->filename[0] = '\0';\r
+ }\r
+\r
+ #endif /* if F_FILE_CHANGED_EVENT */\r
+ return ret;\r
+ }\r
+} /* fn_close */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_flush\r
+ *\r
+ * flush a previously opened file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - which file needs to be closed\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_flush ( F_FILE * f )\r
+{\r
+ unsigned char ret;\r
+\r
+ if ( !f )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( gl_file.mode == F_FILE_CLOSE )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+ else if ( gl_file.mode != F_FILE_RD )\r
+ {\r
+ if ( gl_file.modified )\r
+ {\r
+ if ( _f_writeglsector( (unsigned long)-1 ) )\r
+ {\r
+ (void)_f_updatefileentry( 1 );\r
+ return F_ERR_WRITE;\r
+ }\r
+ }\r
+\r
+ return _f_updatefileentry( 0 );\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* fn_flush */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_read\r
+ *\r
+ * read data from file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * buf - where the store data\r
+ * size - size of items to be read\r
+ * _size_t - number of items need to be read\r
+ * filehandle - file where to read from\r
+ *\r
+ * RETURNS\r
+ *\r
+ * with the number of read bytes\r
+ *\r
+ ***************************************************************************/\r
+long fn_read ( void * buf, long size, long _size_st, F_FILE * f )\r
+{\r
+ char * buffer = (char *)buf;\r
+ long retsize;\r
+\r
+ if ( !f )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ retsize = size;\r
+ size *= _size_st;\r
+ _size_st = retsize;\r
+ retsize = 0;\r
+\r
+ if ( _f_getvolume() )\r
+ {\r
+ return 0; /*cant read any*/\r
+ }\r
+\r
+ if ( size + gl_file.relpos + gl_file.abspos >= gl_file.filesize ) /*read len longer than the file*/\r
+ {\r
+ size = (long)( ( gl_file.filesize ) - ( gl_file.relpos ) - ( gl_file.abspos ) ); /*calculate new size*/\r
+ }\r
+\r
+ if ( size <= 0 )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( _f_getcurrsector() )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/\r
+ return 0;\r
+ }\r
+\r
+ for( ; ; )\r
+ {\r
+ unsigned long rdsize = (unsigned long)size;\r
+\r
+ if ( gl_file.relpos == F_SECTOR_SIZE )\r
+ {\r
+ unsigned char ret;\r
+\r
+ gl_file.abspos += gl_file.relpos;\r
+ gl_file.relpos = 0;\r
+\r
+ if ( gl_file.modified )\r
+ {\r
+ ret = _f_writeglsector( (unsigned long)-1 ); /*empty write buffer */\r
+ if ( ret )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/\r
+ return retsize;\r
+ }\r
+ }\r
+\r
+ gl_file.pos.sector++; /*goto next*/\r
+\r
+ ret = _f_getcurrsector();\r
+ if ( ( ret == F_ERR_EOF ) && ( !size ) )\r
+ {\r
+ return retsize;\r
+ }\r
+\r
+ if ( ret )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/\r
+ return retsize;\r
+ }\r
+ }\r
+\r
+ if ( !size )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( rdsize >= F_SECTOR_SIZE - gl_file.relpos )\r
+ {\r
+ rdsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );\r
+ }\r
+\r
+ psp_memcpy( buffer, gl_sector + gl_file.relpos, rdsize ); /*always less than 512*/\r
+\r
+ buffer += rdsize;\r
+ gl_file.relpos += rdsize;\r
+ size -= rdsize;\r
+ retsize += rdsize;\r
+ }\r
+\r
+ return retsize / _size_st;\r
+} /* fn_read */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_write\r
+ *\r
+ * write data into file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * buf - where the store data\r
+ * size - size of items to be read\r
+ * size_t - number of items need to be read\r
+ * filehandle - file where to read from\r
+ *\r
+ * RETURNS\r
+ *\r
+ * with the number of read bytes\r
+ *\r
+ ***************************************************************************/\r
+\r
+long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )\r
+{\r
+ char * buffer = (char *)buf;\r
+ long retsize;\r
+ long ret = 0;\r
+\r
+ if ( !f )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( ( gl_file.mode & ( F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ retsize = size;\r
+ size *= _size_st;\r
+ _size_st = retsize;\r
+ retsize = 0;\r
+\r
+ if ( _f_getvolume() )\r
+ {\r
+ return 0; /*can't write*/\r
+ }\r
+\r
+ if ( ( gl_file.mode ) & ( F_FILE_A | F_FILE_AP ) )\r
+ {\r
+ if ( _f_fseek( (long)gl_file.filesize ) )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ if ( _f_getcurrsector() )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ return 0;\r
+ }\r
+\r
+ for( ; ; )\r
+ {\r
+ unsigned long wrsize = (unsigned long)size;\r
+\r
+ if ( gl_file.relpos == F_SECTOR_SIZE )\r
+ { /*now full*/\r
+ if ( gl_file.modified )\r
+ {\r
+ if ( _f_emptywritebuffer() )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE;\r
+ if ( _f_updatefileentry( 0 ) == 0 )\r
+ {\r
+ return retsize;\r
+ }\r
+ else\r
+ {\r
+ return 0;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ gl_file.pos.sector++; /*goto next*/\r
+ }\r
+\r
+ gl_file.abspos += gl_file.relpos;\r
+ gl_file.relpos = 0;\r
+\r
+ if ( wrsize && ( wrsize < F_SECTOR_SIZE ) )\r
+ {\r
+ ret = _f_getcurrsector();\r
+\r
+ if ( ret )\r
+ {\r
+ if ( ret != F_ERR_EOF )\r
+ {\r
+ gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/\r
+ return retsize;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( !size )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( wrsize >= F_SECTOR_SIZE - gl_file.relpos )\r
+ {\r
+ wrsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos );\r
+ }\r
+\r
+\r
+ psp_memcpy( gl_sector + gl_file.relpos, buffer, wrsize );\r
+ gl_file.modified = 1; /*sector is modified*/\r
+\r
+ buffer += wrsize;\r
+ gl_file.relpos += wrsize;\r
+ size -= wrsize;\r
+ retsize += wrsize;\r
+\r
+ if ( gl_file.filesize < gl_file.abspos + gl_file.relpos )\r
+ {\r
+ gl_file.filesize = gl_file.abspos + gl_file.relpos;\r
+ }\r
+ }\r
+\r
+ return retsize / _size_st;\r
+} /* fn_write */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_seek\r
+ *\r
+ * moves position into given offset in given file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - F_FILE structure which file position needed to be modified\r
+ * offset - relative position\r
+ * whence - where to calculate position (F_SEEK_SET,F_SEEK_CUR,F_SEEK_END)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if successfully\r
+ * other - if any error\r
+ *\r
+ ***************************************************************************/\r
+\r
+\r
+unsigned char fn_seek ( F_FILE * f, long offset, unsigned char whence )\r
+{\r
+ unsigned char ret;\r
+\r
+ if ( !f )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+\r
+ if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )\r
+ {\r
+ return F_ERR_NOTOPEN;\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( whence == F_SEEK_CUR )\r
+ {\r
+ return _f_fseek( (long)( gl_file.abspos + gl_file.relpos + offset ) );\r
+ }\r
+ else if ( whence == F_SEEK_END )\r
+ {\r
+ return _f_fseek( (long)( gl_file.filesize + offset ) );\r
+ }\r
+ else if ( whence == F_SEEK_SET )\r
+ {\r
+ return _f_fseek( offset );\r
+ }\r
+\r
+ return F_ERR_NOTUSEABLE;\r
+} /* fn_seek */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_tell\r
+ *\r
+ * Tells the current position of opened file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - which file needs the position\r
+ *\r
+ * RETURNS\r
+ *\r
+ * position in the file from start\r
+ *\r
+ ***************************************************************************/\r
+\r
+long fn_tell ( F_FILE * f )\r
+{\r
+ if ( !f )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ return (long)( gl_file.abspos + gl_file.relpos );\r
+}\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_eof\r
+ *\r
+ * Tells if the current position is end of file or not\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - which file needs the checking\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if not EOF\r
+ * other - if EOF or invalid file handle\r
+ *\r
+ ***************************************************************************/\r
+\r
+unsigned char fn_eof ( F_FILE * f )\r
+{\r
+ if ( !f )\r
+ {\r
+ return F_ERR_NOTOPEN; /*if error*/\r
+ }\r
+\r
+ if ( gl_file.abspos + gl_file.relpos < gl_file.filesize )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ return F_ERR_EOF; /*EOF*/\r
+}\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_rewind\r
+ *\r
+ * set the fileposition in the opened file to the begining\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - which file needs to be rewinded\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+\r
+unsigned char fn_rewind ( F_FILE * filehandle )\r
+{\r
+ return fn_seek( filehandle, 0L, F_SEEK_SET );\r
+}\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_putc\r
+ *\r
+ * write a character into file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ch - what to write into file\r
+ * filehandle - file where to write\r
+ *\r
+ * RETURNS\r
+ *\r
+ * with the number of written bytes (1-success, 0-not successfully)\r
+ *\r
+ ***************************************************************************/\r
+\r
+int fn_putc ( int ch, F_FILE * filehandle )\r
+{\r
+ unsigned char tmpch = (unsigned char)ch;\r
+\r
+ if ( fn_write( &tmpch, 1, 1, filehandle ) )\r
+ {\r
+ return ch;\r
+ }\r
+ else\r
+ {\r
+ return -1;\r
+ }\r
+}\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_getc\r
+ *\r
+ * get a character from file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filehandle - file where to read from\r
+ *\r
+ * RETURNS\r
+ *\r
+ * with the read character or -1 if read was not successfully\r
+ *\r
+ ***************************************************************************/\r
+int fn_getc ( F_FILE * filehandle )\r
+{\r
+ unsigned char ch;\r
+\r
+ if ( !fn_read( &ch, 1, 1, filehandle ) )\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ return (int)ch;\r
+}\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_delete\r
+ *\r
+ * delete a file\r
+ *\r
+ * INPUTS\r
+ *\r
+ * filename - file which wanted to be deleted (with or without path)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_delete ( const char * filename )\r
+{\r
+ F_POS pos;\r
+ F_DIRENTRY * de;\r
+ F_NAME fsname;\r
+ unsigned char ret;\r
+\r
+ if ( _f_setfsname( filename, &fsname ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( _f_checknamewc( fsname.filename, fsname.fileext ) )\r
+ {\r
+ return F_ERR_INVALIDNAME; /*invalid name*/\r
+ }\r
+\r
+ if ( fsname.filename[0] == '.' )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !( _f_findpath( &fsname, &pos ) ) )\r
+ {\r
+ return F_ERR_INVALIDDIR;\r
+ }\r
+\r
+ if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )\r
+ {\r
+ return F_ERR_NOTFOUND;\r
+ }\r
+\r
+ if ( de->attr & F_ATTR_DIR )\r
+ {\r
+ return F_ERR_INVALIDDIR; /*directory*/\r
+ }\r
+\r
+ if ( de->attr & F_ATTR_READONLY )\r
+ {\r
+ return F_ERR_ACCESSDENIED; /*readonly*/\r
+ }\r
+\r
+ if ( ( gl_file.mode != F_FILE_CLOSE ) && ( gl_file.dirpos.sector == pos.sector ) && ( gl_file.dirpos.pos == pos.pos ) )\r
+ {\r
+ return F_ERR_LOCKED;\r
+ }\r
+\r
+ de->name[0] = (unsigned char)0xe5; /*removes it*/\r
+ ret = _f_writeglsector( (unsigned long)-1 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_removechain( _f_getdecluster( de ) );\r
+\r
+ #if F_FILE_CHANGED_EVENT\r
+ if ( f_filechangedevent && !ret )\r
+ {\r
+ ST_FILE_CHANGED fc;\r
+ fc.action = FACTION_REMOVED;\r
+ fc.flags = FFLAGS_FILE_NAME;\r
+\r
+ if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )\r
+ {\r
+ f_filechangedevent( &fc );\r
+ }\r
+ }\r
+\r
+ #endif\r
+\r
+ return ret;\r
+} /* fn_delete */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_seteof\r
+ *\r
+ * Set end of file\r
+ *\r
+ * INPUT: f - file pointer\r
+ * filesize - required new size\r
+ * RETURN: F_NO_ERROR - on success\r
+ * other if error\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_seteof ( F_FILE * f, long filesize )\r
+{\r
+ unsigned char rc = F_NO_ERROR;\r
+\r
+ if ( !f )\r
+ {\r
+ return F_ERR_NOTOPEN; /*if error*/\r
+ }\r
+\r
+ if ( ( unsigned long) filesize < gl_file.filesize )\r
+ {\r
+ rc = _f_fseek( filesize );\r
+ if ( rc == F_NO_ERROR )\r
+ {\r
+ unsigned long cluster;\r
+ rc = _f_getclustervalue( gl_file.pos.cluster, &cluster );\r
+ if ( rc == F_NO_ERROR )\r
+ {\r
+ if ( cluster != F_CLUSTER_LAST )\r
+ {\r
+ rc = _f_removechain( cluster );\r
+ if ( rc )\r
+ {\r
+ return rc;\r
+ }\r
+\r
+ rc = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );\r
+ if ( rc )\r
+ {\r
+ return rc;\r
+ }\r
+\r
+ rc = _f_writefatsector();\r
+ if ( rc )\r
+ {\r
+ return rc;\r
+ }\r
+ }\r
+\r
+ gl_file.filesize = (unsigned long)filesize;\r
+ }\r
+ }\r
+ }\r
+ else if ( (unsigned long) filesize > gl_file.filesize )\r
+ {\r
+ rc = _f_fseek( filesize );\r
+ }\r
+\r
+ return rc;\r
+} /* _f_seteof */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_seteof\r
+ *\r
+ * Set end of file\r
+ *\r
+ * INPUT: f - file pointer\r
+ * filesize - required new size\r
+ * RETURN: F_NO_ERROR - on success\r
+ * other if error\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_seteof ( F_FILE * f )\r
+{\r
+ unsigned char rc = F_NO_ERROR;\r
+\r
+ rc = _f_seteof( f, ( gl_file.abspos + gl_file.relpos ) );\r
+\r
+ return rc;\r
+} /* fn_seteof */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_truncate\r
+ *\r
+ * Open a file and set end of file\r
+ *\r
+ * INPUT: filename - name of the file\r
+ * filesize - required new size\r
+ * RETURN: NULL on error, otherwise file pointer\r
+ *\r
+ ***************************************************************************/\r
+F_FILE * fn_truncate ( const char * filename, long filesize )\r
+{\r
+ F_FILE * f = fn_open( filename, "r+" );\r
+ unsigned char rc;\r
+\r
+ if ( f != NULL )\r
+ {\r
+ rc = _f_fseek( (long)gl_file.filesize );\r
+ if ( rc == F_NO_ERROR )\r
+ {\r
+ rc = _f_seteof( f, filesize );\r
+ }\r
+\r
+ if ( rc )\r
+ {\r
+ fn_close( f );\r
+ f = NULL;\r
+ }\r
+ }\r
+\r
+ return f;\r
+} /* fn_truncate */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __FILE_H\r
+#define __FILE_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define F_FILE_CLOSE 0x00\r
+#define F_FILE_RD 0x01\r
+#define F_FILE_WR 0x02\r
+#define F_FILE_A 0x04\r
+#define F_FILE_RDP 0x08\r
+#define F_FILE_WRP 0x10\r
+#define F_FILE_AP 0x20\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __FILE_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/include/psp_rtc.h"\r
+#include "dir.h"\r
+\r
+#include "util.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getword\r
+ *\r
+ * get a word 16bit number from a memory (it uses LITTLE ENDIAN mode always)\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ptr - pointer where data is\r
+ *\r
+ * RETURNS\r
+ *\r
+ * word number\r
+ *\r
+ ***************************************************************************/\r
+unsigned short _f_getword ( void * ptr )\r
+{\r
+ unsigned char * sptr = (unsigned char *)ptr;\r
+ unsigned short ret;\r
+\r
+ ret = (unsigned short)( sptr[1] & 0xff );\r
+ ret <<= 8;\r
+ ret |= ( sptr[0] & 0xff );\r
+ return ret;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setword\r
+ *\r
+ * set a word 16bit number into a memory (it uses LITTLE ENDIAN mode always)\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ptr - where to store data\r
+ * num - 16 bit number to store\r
+ *\r
+ ***************************************************************************/\r
+void _f_setword ( void * ptr, unsigned short num )\r
+{\r
+ unsigned char * sptr = (unsigned char *)ptr;\r
+\r
+ sptr[1] = (unsigned char)( num >> 8 );\r
+ sptr[0] = (unsigned char)( num );\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getlong\r
+ *\r
+ * get a long 32bit number from a memory (it uses LITTLE ENDIAN mode always)\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ptr - pointer where data is\r
+ *\r
+ * RETURNS\r
+ *\r
+ * long number\r
+ *\r
+ ***************************************************************************/\r
+unsigned long _f_getlong ( void * ptr )\r
+{\r
+ unsigned char * sptr = (unsigned char *)ptr;\r
+ unsigned long ret;\r
+\r
+ ret = (unsigned long)( sptr[3] & 0xff );\r
+ ret <<= 8;\r
+ ret |= ( sptr[2] & 0xff );\r
+ ret <<= 8;\r
+ ret |= ( sptr[1] & 0xff );\r
+ ret <<= 8;\r
+ ret |= ( sptr[0] & 0xff );\r
+ return ret;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setlong\r
+ *\r
+ * set a long 32bit number into a memory (it uses LITTLE ENDIAN mode always)\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ptr - where to store data\r
+ * num - 32 bit number to store\r
+ *\r
+ ***************************************************************************/\r
+void _f_setlong ( void * ptr, unsigned long num )\r
+{\r
+ unsigned char * sptr = (unsigned char *)ptr;\r
+\r
+ sptr[3] = (unsigned char)( num >> 24 );\r
+ sptr[2] = (unsigned char)( num >> 16 );\r
+ sptr[1] = (unsigned char)( num >> 8 );\r
+ sptr[0] = (unsigned char)( num );\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _setcharzero\r
+ *\r
+ * fills with zero charater to memory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * num - number of characters\r
+ * ptr - where to store data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * last write position\r
+ *\r
+ ***************************************************************************/\r
+unsigned char * _setcharzero ( int num, unsigned char * ptr )\r
+{\r
+ while ( num-- )\r
+ {\r
+ *ptr++ = 0;\r
+ }\r
+\r
+ return ptr;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _setchar\r
+ *\r
+ * copy a charater string to memory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * array - original code what to copy\r
+ * num - number of characters\r
+ * ptr - where to store data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * last write position\r
+ *\r
+ ***************************************************************************/\r
+unsigned char * _setchar ( const unsigned char * array, int num, unsigned char * ptr )\r
+{\r
+ if ( !array )\r
+ {\r
+ return _setcharzero( num, ptr );\r
+ }\r
+\r
+ while ( num-- )\r
+ {\r
+ *ptr++ = *array++;\r
+ }\r
+\r
+ return ptr;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _setword\r
+ *\r
+ * store a 16bit word into memory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * num - 16bit number to store\r
+ * ptr - where to store data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * last write position\r
+ *\r
+ ***************************************************************************/\r
+unsigned char * _setword ( unsigned short num, unsigned char * ptr )\r
+{\r
+ _f_setword( ptr, num );\r
+ return ptr + 2;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _setlong\r
+ *\r
+ * store a 32bit long number into memory\r
+ *\r
+ * INPUTS\r
+ *\r
+ * num - 32bit number to store\r
+ * ptr - where to store data\r
+ *\r
+ * RETURNS\r
+ *\r
+ * last write position\r
+ *\r
+ ***************************************************************************/\r
+unsigned char * _setlong ( unsigned long num, unsigned char * ptr )\r
+{\r
+ _f_setlong( ptr, num );\r
+ return ptr + 4;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_toupper\r
+ *\r
+ * convert a string into lower case\r
+ *\r
+ * INPUTS\r
+ *\r
+ * s - input string to convert\r
+ *\r
+ ***************************************************************************/\r
+char _f_toupper ( char ch )\r
+{\r
+ if ( ( ch >= 'a' ) && ( ch <= 'z' ) )\r
+ {\r
+ return (char)( ch - 'a' + 'A' );\r
+ }\r
+\r
+ return ch;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * f_igettimedate\r
+ *\r
+ * INPUTS\r
+ * time - pointer to time variable\r
+ * date - pointer to date variable\r
+ * OUTPUTS\r
+ * time - current time\r
+ * date - current date\r
+ *\r
+ * RETURNS\r
+ * none\r
+ *\r
+ ***************************************************************************/\r
+void f_igettimedate ( unsigned short * time, unsigned short * date )\r
+{\r
+ t_psp_timedate s_timedate;\r
+\r
+ psp_getcurrenttimedate( &s_timedate );\r
+\r
+ *time = ( ( (uint16_t)s_timedate.hour << F_CTIME_HOUR_SHIFT ) & F_CTIME_HOUR_MASK )\r
+ | ( ( (uint16_t)s_timedate.min << F_CTIME_MIN_SHIFT ) & F_CTIME_MIN_MASK )\r
+ | ( ( ( (uint16_t)s_timedate.sec >> 1 ) << F_CTIME_SEC_SHIFT ) & F_CTIME_SEC_MASK );\r
+\r
+ *date = ( ( ( s_timedate.year - 1980 ) << F_CDATE_YEAR_SHIFT ) & F_CDATE_YEAR_MASK )\r
+ | ( ( (uint16_t)s_timedate.month << F_CDATE_MONTH_SHIFT ) & F_CDATE_MONTH_MASK )\r
+ | ( ( (uint16_t)s_timedate.day << F_CDATE_DAY_SHIFT ) & F_CDATE_DAY_MASK );\r
+\r
+ return;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __UTIL_H\r
+#define __UTIL_H\r
+\r
+#include "util_sfn.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+void f_igettimedate ( unsigned short * time, unsigned short * date );\r
+\r
+unsigned short _f_getword ( void * );\r
+unsigned long _f_getlong ( void * );\r
+char _f_toupper ( char );\r
+void _f_memset ( void *, unsigned char, int );\r
+void _f_memcpy ( void *, void *, int );\r
+\r
+void _f_setword ( void *, unsigned short );\r
+void _f_setlong ( void *, unsigned long );\r
+unsigned char * _setcharzero ( int, unsigned char * );\r
+unsigned char * _setchar ( const unsigned char *, int, unsigned char * );\r
+unsigned char * _setword ( unsigned short, unsigned char * );\r
+unsigned char * _setlong ( unsigned long, unsigned char * );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __UTIL_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+\r
+#include "util.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_checknameprim\r
+ *\r
+ * checking a string if could be valid\r
+ *\r
+ * INPUTS\r
+ *\r
+ * ptr - pointer to name or extension\r
+ * len - number max char of name or extension\r
+ *\r
+ * RETURNS\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_checknameprim ( char * ptr, unsigned char len )\r
+{\r
+ unsigned char inspace = 0;\r
+\r
+ while ( len-- )\r
+ {\r
+ char ch = *ptr++;\r
+ if ( !inspace )\r
+ {\r
+ if ( ch == ' ' )\r
+ {\r
+ inspace = 1;\r
+ }\r
+\r
+ if ( ( ch == '|' ) || ( ch == '[' ) || ( ch == ']' ) || ( ch == '<' ) || ( ch == '>' ) || ( ch == '/' ) || ( ch == '\\' ) || ( ch == ':' ) )\r
+ {\r
+ return 1;\r
+ }\r
+ }\r
+ else if ( ch != ' ' )\r
+ {\r
+ return 1; /*no inspace allowed*/\r
+ }\r
+ }\r
+\r
+ return 0;\r
+} /* _f_checknameprim */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_checkname\r
+ *\r
+ * checking filename and extension for special characters\r
+ *\r
+ * INPUTS\r
+ *\r
+ * name - filename (e.g.: filename)\r
+ * ext - extension of file (e.g.: txt)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if no contains invalid character\r
+ * other - if contains any invalid character\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_checkname ( char * name, char * ext )\r
+{\r
+ if ( _f_checknameprim( name, F_MAXNAME ) )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ if ( _f_checknameprim( ext, F_MAXEXT ) )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_checknamewc\r
+ *\r
+ * checking filename and extension for wildcard character\r
+ *\r
+ * INPUTS\r
+ *\r
+ * name - filename (e.g.: filename)\r
+ * ext - extension of file (e.g.: txt)\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if no contains wildcard character (? or *)\r
+ * other - if contains any wildcard character\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_checknamewc ( const char * name, const char * ext )\r
+{\r
+ unsigned char a = 0;\r
+\r
+ for ( a = 0 ; a < F_MAXNAME ; a++ )\r
+ {\r
+ char ch = name[a];\r
+ if ( ( ch == '?' ) || ( ch == '*' ) )\r
+ {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ for ( a = 0 ; a < F_MAXEXT ; a++ )\r
+ {\r
+ char ch = ext[a];\r
+ if ( ( ch == '?' ) || ( ch == '*' ) )\r
+ {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return _f_checkname( (char *)name, (char *)ext );\r
+} /* _f_checknamewc */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setnameext\r
+ *\r
+ * convert a string into filename and extension separatelly, the terminator\r
+ * character could be zero char, '/' or '\'\r
+ *\r
+ * INPUTS\r
+ *\r
+ * s - source string (e.g.: hello.txt)\r
+ * name - where to store name (this array size has to be F_MAXNAME (8))\r
+ * ext - where to store extension (this array size has to be F_MAXEXT (3))\r
+ *\r
+ * RETURNS\r
+ *\r
+ * length of the used bytes from source string array\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_setnameext ( char * s, char * name, char * ext )\r
+{\r
+ unsigned char len, extlen = 0;\r
+ unsigned char a;\r
+ unsigned char setext = 1;\r
+\r
+ for ( len = 0 ; ; )\r
+ {\r
+ unsigned char ch = s[len];\r
+ if ( ( ch == 0 ) || ( ch == '\\' ) || ( ch == '/' ) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ len++; /*calculate len*/\r
+ }\r
+\r
+ if ( len && ( s[0] == '.' ) )\r
+ {\r
+/* if (len==1 || (s[1]=='.' && len==2)) goto dots; */\r
+ if ( ( len == 1 ) || ( s[1] == '.' ) )\r
+ {\r
+ goto dots;\r
+ }\r
+ }\r
+\r
+ for ( a = len ; a ; a-- )\r
+ {\r
+ if ( s[a - 1] == '.' )\r
+ {\r
+ unsigned char b;\r
+\r
+ extlen = (unsigned char)( len - a + 1 );\r
+ len = (unsigned char)( a - 1 );\r
+\r
+ for ( b = 0 ; b < F_MAXEXT ; b++ )\r
+ {\r
+ if ( b < extlen - 1 )\r
+ {\r
+ ext[b] = _f_toupper( s[a++] );\r
+ }\r
+ else\r
+ {\r
+ ext[b] = ' ';\r
+ }\r
+ }\r
+\r
+ setext = 0;\r
+ break;\r
+ }\r
+ }\r
+\r
+dots:\r
+ if ( setext )\r
+ {\r
+ for ( a = 0 ; a < F_MAXEXT ; a++ )\r
+ {\r
+ ext[a] = ' ';\r
+ }\r
+ }\r
+\r
+ for ( a = 0 ; a < F_MAXNAME ; a++ )\r
+ {\r
+ if ( a < len )\r
+ {\r
+ name[a] = _f_toupper( s[a] );\r
+ }\r
+ else\r
+ {\r
+ name[a] = ' ';\r
+ }\r
+ }\r
+\r
+ return (unsigned char)( len + extlen );\r
+} /* _f_setnameext */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_setfsname\r
+ *\r
+ * convert a single string into F_NAME structure\r
+ *\r
+ * INPUTS\r
+ *\r
+ * name - combined name with drive,path,filename,extension used for source\r
+ * fsname - where to fill this structure with separated drive,path,name,ext\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 0 - if successfully\r
+ * other - if name contains invalid path or name\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_setfsname ( const char * name, F_NAME * fsname )\r
+{\r
+ char s[F_MAXPATH];\r
+ unsigned char namepos = 0;\r
+\r
+ unsigned char pathpos = 0;\r
+ unsigned char a;\r
+\r
+ s[0] = 0;\r
+\r
+ if ( !name[0] )\r
+ {\r
+ return 1; /*no name*/\r
+ }\r
+\r
+ if ( name[1] == ':' )\r
+ {\r
+ name += 2;\r
+ }\r
+\r
+ if ( ( name[0] != '/' ) && ( name[0] != '\\' ) )\r
+ {\r
+ if ( fn_getcwd( fsname->path, F_MAXPATH, 0 ) )\r
+ {\r
+ return 1; /*error*/\r
+ }\r
+\r
+ for ( pathpos = 0 ; fsname->path[pathpos] ; )\r
+ {\r
+ pathpos++;\r
+ }\r
+ }\r
+\r
+\r
+ for ( ; ; )\r
+ {\r
+ char ch = _f_toupper( *name++ );\r
+\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( ch == ':' )\r
+ {\r
+ return 1; /*not allowed*/\r
+ }\r
+\r
+ if ( ( ch == '/' ) || ( ch == '\\' ) )\r
+ {\r
+ if ( pathpos )\r
+ {\r
+ if ( fsname->path[pathpos - 1] == '/' )\r
+ {\r
+ return 1; /*not allowed double */\r
+ }\r
+\r
+ if ( pathpos >= F_MAXPATH - 2 )\r
+ {\r
+ return 1; /*path too long*/\r
+ }\r
+\r
+ fsname->path[pathpos++] = '/';\r
+ }\r
+\r
+ for ( ; namepos ; )\r
+ {\r
+ if ( s[namepos - 1] != ' ' )\r
+ {\r
+ break;\r
+ }\r
+\r
+ namepos--; /*remove end spaces*/\r
+ }\r
+\r
+ for ( a = 0 ; a < namepos ; a++ )\r
+ {\r
+ if ( pathpos >= F_MAXPATH - 2 )\r
+ {\r
+ return 1; /*path too long*/\r
+ }\r
+\r
+ fsname->path[pathpos++] = s[a];\r
+ }\r
+\r
+ namepos = 0;\r
+ continue;\r
+ }\r
+\r
+ if ( ( ch == ' ' ) && ( !namepos ) )\r
+ {\r
+ continue; /*remove start spaces*/\r
+ }\r
+\r
+ if ( namepos >= ( sizeof( s ) - 2 ) )\r
+ {\r
+ return 1; /*name too long*/\r
+ }\r
+\r
+ s[namepos++] = ch;\r
+ }\r
+\r
+ s[namepos] = 0; /*terminates it*/\r
+ fsname->path[pathpos] = 0; /*terminates it*/\r
+\r
+ for ( ; namepos ; )\r
+ {\r
+ if ( s[namepos - 1] != ' ' )\r
+ {\r
+ break;\r
+ }\r
+\r
+ s[namepos - 1] = 0; /*remove end spaces*/\r
+ namepos--;\r
+ }\r
+\r
+ if ( !_f_setnameext( s, fsname->filename, fsname->fileext ) )\r
+ {\r
+ return 2; /*no name*/\r
+ }\r
+\r
+ if ( fsname->filename[0] == ' ' )\r
+ {\r
+ return 1; /*cannot be*/\r
+ }\r
+\r
+ return 0;\r
+} /* _f_setfsname */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_createfullname\r
+ *\r
+ * create full name\r
+ *\r
+ * INPUTS\r
+ *\r
+ * buffer - where to create\r
+ * buffersize - size of the buffer\r
+ * drivenum - drive number\r
+ * path - path of the file\r
+ * filename - file name\r
+ * fileext - file extension\r
+ *\r
+ * RETURNS\r
+ *\r
+ * 1 - if found and osize is filled\r
+ * 0 - not found\r
+ *\r
+ ***************************************************************************/\r
+int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext )\r
+{\r
+ char * fullname = buffer;\r
+ int a;\r
+\r
+ /* adding drive letter */\r
+ if ( buffersize < 1 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = '/';\r
+ buffersize -= 1;\r
+\r
+ /* adding path */\r
+ if ( path[0] )\r
+ {\r
+ for ( ; ; )\r
+ {\r
+ char ch = *path++;\r
+\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( buffersize <= 0 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = ch;\r
+ buffersize--;\r
+ }\r
+\r
+ /* adding separator */\r
+ if ( buffersize <= 0 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = '/';\r
+ }\r
+\r
+ /* adding name */\r
+ for ( a = 0 ; a < F_MAXNAME ; a++ )\r
+ {\r
+ char ch = *filename++;\r
+\r
+ if ( ( !ch ) || ( ch == 32 ) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( buffersize <= 0 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = ch;\r
+ buffersize--;\r
+ }\r
+\r
+ /* adding ext*/\r
+ if ( fileext[0] && ( fileext[0] != 32 ) )\r
+ {\r
+ /* adding dot */\r
+ if ( !buffersize )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = '.';\r
+\r
+ for ( a = 0 ; a < F_MAXEXT ; a++ )\r
+ {\r
+ char ch = *fileext++;\r
+\r
+ if ( ( !ch ) || ( ch == 32 ) )\r
+ {\r
+ break;\r
+ }\r
+\r
+ if ( buffersize <= 0 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = ch;\r
+ buffersize--;\r
+ }\r
+ }\r
+\r
+ /* adding terminator */\r
+ if ( buffersize <= 0 )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ *fullname++ = 0;\r
+\r
+ return 0;\r
+} /* _f_createfullname */\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __UTIL_SFN_H\r
+#define __UTIL_SFN_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+unsigned char _f_checknamewc ( const char *, const char * );\r
+unsigned char _f_checkname ( char *, char * );\r
+\r
+unsigned char _f_setnameext ( char *, char *, char * );\r
+unsigned char _f_setfsname ( const char *, F_NAME * );\r
+int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __UTIL_SFN_H */\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/include/psp_string.h"\r
+\r
+#include "volume.h"\r
+#include "util.h"\r
+#include "drv.h"\r
+#include "fat.h"\r
+#include "dir.h"\r
+#include "file.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#if F_FS_THREAD_AWARE == 1\r
+ #include "f_lock.h"\r
+#endif\r
+\r
+F_VOLUME gl_volume; /* only one volume */\r
+F_FILE gl_file; /* file */\r
+char gl_sector[F_SECTOR_SIZE]; /* actual sector */\r
+\r
+#if F_FILE_CHANGED_EVENT\r
+F_FILE_CHANGED_EVENTFUNC f_filechangedevent;\r
+#endif\r
+\r
+\r
+/* Defines the number of sectors per cluster on a sector number basis */\r
+typedef struct\r
+{\r
+ unsigned long max_sectors;\r
+ unsigned char sector_per_cluster;\r
+} t_FAT32_CS;\r
+\r
+static const t_FAT32_CS FAT32_CS[] =\r
+{\r
+ { 0x00020000, 1 } /* ->64MB */\r
+ , { 0x00040000, 2 } /* ->128MB */\r
+ , { 0x00080000, 4 } /* ->256MB */\r
+ , { 0x01000000, 8 } /* ->8GB */\r
+ , { 0x02000000, 16 } /* ->16GB */\r
+ , { 0x0ffffff0, 32 } /* -> ... */\r
+};\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_writebootrecord\r
+ *\r
+ * writing boot record onto a volume, it uses number of hidden sector variable\r
+ *\r
+ * INPUTS\r
+ * phy - media physical descriptor\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_writebootrecord ( F_PHY * phy )\r
+{\r
+ unsigned char jump_code[] =\r
+ {\r
+ 0xeb, 0x3c, 0x90\r
+ };\r
+ unsigned char oem_name[] = "MSDOS5.0";\r
+ unsigned char executable_marker[] =\r
+ {\r
+ 0x55, 0xaa\r
+ };\r
+ unsigned char * ptr = (unsigned char *)gl_sector;\r
+ unsigned char rs;\r
+ unsigned short mre;\r
+\r
+ unsigned char ret;\r
+ unsigned char _n = 0;\r
+\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ { /*write FS_INFO*/\r
+ unsigned char a;\r
+\r
+ rs = 32 + 4;\r
+ mre = 0;\r
+\r
+ psp_memset( ptr, 0, F_SECTOR_SIZE );\r
+\r
+ for ( a = 0 ; a < rs ; a++ )\r
+ {\r
+ ret = _f_writeglsector( a ); /*erase reserved area*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+ }\r
+\r
+ ptr = _setlong( 0x41615252, ptr ); /*signature*/\r
+ ptr = _setcharzero( 480, ptr ); /*reserved*/\r
+ ptr = _setlong( 0x61417272, ptr ); /*signature*/\r
+ ptr = _setlong( 0xffffffff, ptr ); /*no last*/\r
+ ptr = _setlong( 0xffffffff, ptr ); /*no hint*/\r
+ ptr = _setcharzero( 12, ptr ); /*reserved*/\r
+ ptr = _setlong( 0xaa550000, ptr ); /*trail*/\r
+\r
+\r
+ ret = _f_writeglsector( 1 ); /*write FSINFO*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ ret = _f_writeglsector( 1 + 6 ); /*write FSINFO*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ rs = 1;\r
+ mre = 512;\r
+ }\r
+\r
+ ptr = (unsigned char *)gl_sector;\r
+ ptr = _setchar( jump_code, sizeof( jump_code ), ptr );\r
+ ptr = _setchar( oem_name, sizeof( oem_name ) - 1, ptr );\r
+ ptr = _setword( F_SECTOR_SIZE, ptr );\r
+ *ptr++ = gl_volume.bootrecord.sector_per_cluster;\r
+ ptr = _setword( rs, ptr ); /* reserved sectors */\r
+ *ptr++ = 2; /* number of FATs */\r
+ ptr = _setword( mre, ptr ); /* max root entry */\r
+ if ( phy->number_of_sectors < 0x10000 )\r
+ {\r
+ ptr = _setword( (unsigned short)phy->number_of_sectors, ptr );\r
+ }\r
+ else\r
+ {\r
+ ptr = _setword( 0, ptr );\r
+ }\r
+\r
+ *ptr++ = 0xf0; /* media descriptor */\r
+ ptr = _setword( (unsigned short)gl_volume.bootrecord.sector_per_FAT, ptr );\r
+ ptr = _setword( phy->sector_per_track, ptr );\r
+ ptr = _setword( phy->number_of_heads, ptr );\r
+ ptr = _setlong( 0, ptr ); /* number of hidden sectors */\r
+ if ( phy->number_of_sectors >= 0x10000 )\r
+ {\r
+ ptr = _setlong( phy->number_of_sectors, ptr );\r
+ }\r
+ else\r
+ {\r
+ ptr = _setlong( 0, ptr ); /* number of sectors */\r
+ }\r
+\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ ptr = _setlong( gl_volume.bootrecord.sector_per_FAT32, ptr );\r
+ ptr = _setword( 0, ptr );\r
+ ptr = _setword( 0, ptr );\r
+ ptr = _setlong( 2, ptr );\r
+ ptr = _setword( 1, ptr );\r
+ ptr = _setword( 6, ptr );\r
+ ptr = _setchar( NULL, 12, ptr );\r
+ _n = 28;\r
+ }\r
+\r
+\r
+ ptr = _setword( 0, ptr ); /* logical drive num */\r
+ *ptr++ = 0x29; /* extended signature */\r
+ ptr = _setlong( 0x11223344, ptr );\r
+ ptr = _setchar( (const unsigned char *)"NO NAME ", 11, ptr ); /* volume name */\r
+\r
+ switch ( gl_volume.mediatype )\r
+ {\r
+ case F_FAT12_MEDIA:\r
+ ptr = _setchar( (const unsigned char *)"FAT12 ", 8, ptr );\r
+ break;\r
+\r
+ case F_FAT16_MEDIA:\r
+ ptr = _setchar( (const unsigned char *)"FAT16 ", 8, ptr );\r
+ break;\r
+\r
+ case F_FAT32_MEDIA:\r
+ ptr = _setchar( (const unsigned char *)"FAT32 ", 8, ptr );\r
+ break;\r
+\r
+ default:\r
+ return F_ERR_INVALIDMEDIA;\r
+ } /* switch */\r
+\r
+ ptr = _setchar( 0, 448 - _n, ptr );\r
+ ptr = _setchar( executable_marker, sizeof( executable_marker ), ptr );\r
+\r
+ if ( _n )\r
+ {\r
+ ret = _f_writeglsector( 6 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+ }\r
+\r
+\r
+ return _f_writeglsector( 0 ); /*write bootrecord*/\r
+} /* _f_writebootrecord */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_buildsectors\r
+ *\r
+ * INPUTS\r
+ * phy - media physical descriptor\r
+ *\r
+ * calculate relative sector position from boot record\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_buildsectors ( F_PHY * phy )\r
+{\r
+ gl_volume.mediatype = F_UNKNOWN_MEDIA;\r
+\r
+\r
+ if ( gl_volume.bootrecord.sector_per_FAT )\r
+ {\r
+ gl_volume.firstfat.sector = 1;\r
+ gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT;\r
+ gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs ) );\r
+ gl_volume.root.num = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE;\r
+\r
+ gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num;\r
+ gl_volume._tdata.num = 0; /*??*/\r
+ }\r
+ else\r
+ {\r
+ gl_volume.firstfat.sector = ( 32 + 4 );\r
+ gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT32;\r
+ gl_volume._tdata.sector = gl_volume.firstfat.sector;\r
+ gl_volume._tdata.sector += gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs );\r
+ gl_volume._tdata.num = 0; /*??*/\r
+\r
+ {\r
+ unsigned long sectorcou = gl_volume.bootrecord.sector_per_cluster;\r
+ gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * sectorcou ) + gl_volume._tdata.sector;\r
+ gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster;\r
+ }\r
+ }\r
+\r
+ {\r
+ unsigned long maxcluster;\r
+ maxcluster = phy->number_of_sectors;\r
+ maxcluster -= gl_volume._tdata.sector;\r
+ maxcluster /= gl_volume.bootrecord.sector_per_cluster;\r
+ gl_volume.maxcluster = maxcluster;\r
+ }\r
+\r
+ if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) )\r
+ {\r
+ gl_volume.mediatype = F_FAT12_MEDIA;\r
+ }\r
+ else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) )\r
+ {\r
+ gl_volume.mediatype = F_FAT16_MEDIA;\r
+ }\r
+ else\r
+ {\r
+ gl_volume.mediatype = F_FAT32_MEDIA;\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_buildsectors */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_prepareformat\r
+ *\r
+ * preparing boot record for formatting, it sets and calculates values\r
+ *\r
+ * INPUTS\r
+ * phy - media physical descriptor\r
+ * f_bootrecord - which bootrecord need to be prepare\r
+ * number_of_hidden_sectors - where boot record starts\r
+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_prepareformat ( F_PHY * phy, unsigned char fattype )\r
+{\r
+ if ( !phy->number_of_sectors )\r
+ {\r
+ return F_ERR_INVALIDSECTOR;\r
+ }\r
+\r
+ gl_volume.bootrecord.number_of_FATs = 2;\r
+ gl_volume.bootrecord.media_descriptor = 0xf0;\r
+\r
+ if ( fattype != F_FAT32_MEDIA )\r
+ {\r
+ unsigned long _n;\r
+ switch ( fattype )\r
+ {\r
+ case F_FAT12_MEDIA:\r
+ _n = F_CLUSTER_RESERVED & 0xfff;\r
+ break;\r
+\r
+ case F_FAT16_MEDIA:\r
+ _n = F_CLUSTER_RESERVED & 0xffff;\r
+ break;\r
+\r
+ default:\r
+ return F_ERR_INVFATTYPE;\r
+ }\r
+\r
+ gl_volume.bootrecord.sector_per_cluster = 1;\r
+ while ( gl_volume.bootrecord.sector_per_cluster )\r
+ {\r
+ if ( phy->number_of_sectors / gl_volume.bootrecord.sector_per_cluster < _n )\r
+ {\r
+ break;\r
+ }\r
+\r
+ gl_volume.bootrecord.sector_per_cluster <<= 1;\r
+ }\r
+\r
+ if ( !gl_volume.bootrecord.sector_per_cluster )\r
+ {\r
+ return F_ERR_MEDIATOOLARGE;\r
+ }\r
+ }\r
+\r
+ else\r
+ {\r
+ unsigned char i;\r
+ for ( i = 0 ; i<( sizeof( FAT32_CS ) / sizeof( t_FAT32_CS ) ) - 1 && phy->number_of_sectors>FAT32_CS[i].max_sectors ; i++ )\r
+ {\r
+ }\r
+\r
+ gl_volume.bootrecord.sector_per_cluster = FAT32_CS[i].sector_per_cluster;\r
+ }\r
+ if ( !gl_volume.bootrecord.sector_per_cluster )\r
+ {\r
+ return F_ERR_INVALIDMEDIA; /*fat16 cannot be there*/\r
+ }\r
+\r
+ {\r
+ long secpercl = gl_volume.bootrecord.sector_per_cluster;\r
+ long nfat = gl_volume.bootrecord.number_of_FATs;\r
+ unsigned long roots;\r
+ unsigned long fatsec;\r
+\r
+ roots = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE;\r
+\r
+ switch ( fattype )\r
+ {\r
+ case F_FAT32_MEDIA:\r
+ {\r
+ unsigned long _n = (unsigned long)( 128 * secpercl + nfat );\r
+ fatsec = ( phy->number_of_sectors - ( 32 + 4 ) + 2 * secpercl );\r
+ fatsec += ( _n - 1 );\r
+ fatsec /= _n;\r
+ gl_volume.bootrecord.sector_per_FAT32 = fatsec;\r
+ gl_volume.bootrecord.sector_per_FAT = 0;\r
+ }\r
+ break;\r
+\r
+ case F_FAT16_MEDIA:\r
+ {\r
+ unsigned long _n = (unsigned long)( 256 * secpercl + nfat );\r
+ fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl );\r
+ fatsec += ( _n - 1 );\r
+ fatsec /= _n;\r
+ gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec );\r
+ }\r
+ break;\r
+\r
+ case F_FAT12_MEDIA:\r
+ {\r
+ unsigned long _n = (unsigned long)( 1024 * secpercl + 3 * nfat );\r
+ fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl );\r
+ fatsec *= 3;\r
+ fatsec += ( _n - 1 );\r
+ fatsec /= _n;\r
+ gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec );\r
+ }\r
+ break;\r
+\r
+ default:\r
+ return F_ERR_INVALIDMEDIA;\r
+ } /* switch */\r
+\r
+ return F_NO_ERROR;\r
+ }\r
+} /* _f_prepareformat */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_postformat\r
+ *\r
+ * erase fats, erase root directory, reset variables after formatting\r
+ *\r
+ * INPUTS\r
+ * phy - media physical descriptor\r
+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_postformat ( F_PHY * phy, unsigned char fattype )\r
+{\r
+ unsigned long a;\r
+ unsigned char ret;\r
+\r
+ _f_buildsectors( phy ); /*get positions*/\r
+ if ( gl_volume.mediatype != fattype )\r
+ {\r
+ return F_ERR_MEDIATOOSMALL;\r
+ }\r
+\r
+ gl_volume.fatsector = (unsigned long)( -1 );\r
+\r
+ {\r
+ unsigned char * ptr = (unsigned char *)gl_sector;\r
+ unsigned char j = 2;\r
+ unsigned long i;\r
+\r
+ psp_memset( ptr, 0, F_SECTOR_SIZE );\r
+\r
+ switch ( gl_volume.mediatype )\r
+ {\r
+ case F_FAT16_MEDIA:\r
+ j = 3;\r
+ break;\r
+\r
+ case F_FAT32_MEDIA:\r
+ j = 11;\r
+ break;\r
+ }\r
+\r
+ *ptr = gl_volume.bootrecord.media_descriptor;\r
+ psp_memset( ptr + 1, 0xff, j );\r
+ if ( gl_volume.mediatype == F_FAT32_MEDIA )\r
+ {\r
+ *( ptr + 8 ) = (unsigned char)( F_CLUSTER_LAST & 0xff );\r
+ }\r
+\r
+ (void)_f_writeglsector( gl_volume.firstfat.sector );\r
+ (void)_f_writeglsector( gl_volume.firstfat.sector + gl_volume.firstfat.num );\r
+ psp_memset( ptr, 0, ( j + 1 ) );\r
+\r
+ for ( i = 1 ; i < gl_volume.firstfat.num ; i++ )\r
+ {\r
+ (void)_f_writeglsector( gl_volume.firstfat.sector + i );\r
+ (void)_f_writeglsector( gl_volume.firstfat.sector + i + gl_volume.firstfat.num );\r
+ }\r
+ }\r
+\r
+ for ( a = 0 ; a < gl_volume.root.num ; a++ ) /*reset root direntries*/\r
+ {\r
+ ret = _f_writeglsector( gl_volume.root.sector + a );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+ }\r
+\r
+ return _f_writebootrecord( phy );\r
+} /* _f_postformat */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_hardformat\r
+ *\r
+ * Making a complete format on media, independently from master boot record,\r
+ * according to media physical\r
+ *\r
+ * INPUTS\r
+ * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA\r
+ *\r
+ * RETURNS\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_hardformat ( unsigned char fattype )\r
+{\r
+ unsigned char ret;\r
+ int mdrv_ret;\r
+ F_PHY phy;\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret && ( ret != F_ERR_NOTFORMATTED ) )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ gl_volume.state = F_STATE_NEEDMOUNT;\r
+\r
+ psp_memset( &phy, 0, sizeof( F_PHY ) );\r
+\r
+ mdrv_ret = mdrv->getphy( mdrv, &phy );\r
+ if ( mdrv_ret )\r
+ {\r
+ return F_ERR_ONDRIVE;\r
+ }\r
+\r
+ ret = _f_prepareformat( &phy, fattype ); /*no partition*/\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ return _f_postformat( &phy, fattype );\r
+} /* fn_hardformat */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_readbootrecord\r
+ *\r
+ * read boot record from a volume, it detects if there is MBR on the media\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static unsigned char _f_readbootrecord ( void )\r
+{\r
+ unsigned char ret;\r
+ unsigned char * ptr = (unsigned char *)gl_sector;\r
+ unsigned long maxcluster, _n;\r
+ unsigned long first_sector = 0;\r
+\r
+ gl_volume.mediatype = F_UNKNOWN_MEDIA;\r
+\r
+\r
+ ret = _f_readglsector( 0 );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+\r
+ if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) )\r
+ {\r
+ return F_ERR_NOTFORMATTED; /*??*/\r
+ }\r
+\r
+ if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) )\r
+ {\r
+ first_sector = _f_getlong( &ptr[0x08 + 0x1be] ); /*start sector for 1st partioon*/\r
+\r
+ ret = _f_readglsector( first_sector );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) )\r
+ {\r
+ return F_ERR_NOTFORMATTED; /*??*/\r
+ }\r
+\r
+ if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) )\r
+ {\r
+ return F_ERR_NOTFORMATTED; /*??*/\r
+ }\r
+ }\r
+\r
+ ptr += 11;\r
+ if ( _f_getword( ptr ) != F_SECTOR_SIZE )\r
+ {\r
+ return F_ERR_NOTSUPPSECTORSIZE;\r
+ }\r
+\r
+ ptr += 2;\r
+ gl_volume.bootrecord.sector_per_cluster = *ptr++;\r
+ gl_volume.firstfat.sector = _f_getword( ptr );\r
+ ptr += 2;\r
+ gl_volume.bootrecord.number_of_FATs = *ptr++;\r
+ gl_volume.root.num = _f_getword( ptr );\r
+ ptr += 2;\r
+ gl_volume.root.num *= sizeof( F_DIRENTRY );\r
+ gl_volume.root.num /= F_SECTOR_SIZE;\r
+ maxcluster = _f_getword( ptr );\r
+ ptr += 2;\r
+ gl_volume.bootrecord.media_descriptor = *ptr++;\r
+ gl_volume.firstfat.num = _f_getword( ptr );\r
+ ptr += 6;\r
+ _n = _f_getlong( ptr );\r
+ ptr += 4;\r
+ if ( _n < first_sector )\r
+ {\r
+ _n = first_sector;\r
+ }\r
+\r
+ gl_volume.firstfat.sector += _n;\r
+ if ( !maxcluster )\r
+ {\r
+ maxcluster = _f_getlong( ptr );\r
+ }\r
+\r
+ ptr += 4;\r
+\r
+\r
+ if ( gl_volume.firstfat.num )\r
+ {\r
+ gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs );\r
+ gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num;\r
+ gl_volume._tdata.num = 0;\r
+ ptr += 3;\r
+ }\r
+ else\r
+ {\r
+ gl_volume.firstfat.num = _f_getlong( ptr );\r
+ ptr += 8;\r
+ gl_volume._tdata.sector = gl_volume.firstfat.sector;\r
+ gl_volume._tdata.sector += gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs;\r
+ gl_volume._tdata.num = 0;\r
+ gl_volume.bootrecord.rootcluster = _f_getlong( ptr );\r
+ ptr += 23;\r
+ gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster;\r
+ gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * gl_volume.root.num ) + gl_volume._tdata.sector;\r
+ }\r
+\r
+ gl_volume.bootrecord.serial_number = _f_getlong( ptr );\r
+\r
+ maxcluster -= gl_volume._tdata.sector;\r
+ maxcluster += _n;\r
+ gl_volume.maxcluster = maxcluster / gl_volume.bootrecord.sector_per_cluster;\r
+\r
+ if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) )\r
+ {\r
+ gl_volume.mediatype = F_FAT12_MEDIA;\r
+ }\r
+ else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) )\r
+ {\r
+ gl_volume.mediatype = F_FAT16_MEDIA;\r
+ }\r
+ else\r
+ {\r
+ gl_volume.mediatype = F_FAT32_MEDIA;\r
+ }\r
+\r
+ if ( gl_volume.bootrecord.media_descriptor != 0xf8 ) /*fixdrive*/\r
+ {\r
+ if ( gl_volume.bootrecord.media_descriptor != 0xf0 ) /*removable*/\r
+ {\r
+ return F_ERR_NOTFORMATTED; /*??*/\r
+ }\r
+ }\r
+\r
+ return F_NO_ERROR;\r
+} /* _f_readbootrecord */\r
+\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * _f_getvolume\r
+ *\r
+ * getting back a volume info structure of a given drive, it try to mounts\r
+ * drive if it was not mounted before\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char _f_getvolume ( void )\r
+{\r
+ switch ( gl_volume.state )\r
+ {\r
+ case F_STATE_NONE:\r
+ return F_ERR_ONDRIVE;\r
+\r
+ case F_STATE_WORKING:\r
+\r
+ if ( !_f_checkstatus() )\r
+ {\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ /* here we don't stop case flow, */\r
+ /* because we have to clean up this volume! */\r
+\r
+ case F_STATE_NEEDMOUNT:\r
+ {\r
+ gl_file.modified = 0;\r
+ gl_volume.modified = 0;\r
+ gl_volume.lastalloccluster = 0;\r
+ gl_volume.actsector = (unsigned long)( -1 );\r
+ gl_volume.fatsector = (unsigned long)( -1 );\r
+\r
+ gl_file.mode = F_FILE_CLOSE;\r
+\r
+ gl_volume.cwd[0] = 0; /*reset cwd*/\r
+ gl_volume.mediatype = F_UNKNOWN_MEDIA;\r
+\r
+ if ( mdrv->getstatus != NULL )\r
+ {\r
+ if ( mdrv->getstatus( mdrv ) & F_ST_MISSING )\r
+ {\r
+ gl_volume.state = F_STATE_NEEDMOUNT; /*card missing*/\r
+ return F_ERR_CARDREMOVED;\r
+ }\r
+ }\r
+\r
+ if ( !_f_readbootrecord() )\r
+ {\r
+ gl_volume.state = F_STATE_WORKING;\r
+ return F_NO_ERROR;\r
+ }\r
+\r
+ gl_volume.mediatype = F_UNKNOWN_MEDIA;\r
+ return F_ERR_NOTFORMATTED;\r
+ }\r
+ } /* switch */\r
+\r
+ return F_ERR_ONDRIVE;\r
+} /* _f_getvolume */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_getfreespace\r
+ *\r
+ * get total/free/used/bad diskspace\r
+ *\r
+ * INPUTS\r
+ * pspace - pointer where to store the information\r
+ *\r
+ * RETURNS\r
+ * error code\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_getfreespace ( F_SPACE * pspace )\r
+{\r
+ unsigned char ret;\r
+ unsigned long a;\r
+ unsigned long clustersize;\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ psp_memset( pspace, 0, sizeof( F_SPACE ) );\r
+ pspace->total = gl_volume.maxcluster;\r
+\r
+ gl_volume.fatsector = (unsigned long)-1;\r
+ for ( a = 2 ; a < gl_volume.maxcluster + 2 ; a++ )\r
+ {\r
+ unsigned long value;\r
+\r
+ ret = _f_getclustervalue( a, &value );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( !value )\r
+ {\r
+ ++( pspace->free );\r
+ }\r
+ else if ( value == F_CLUSTER_BAD )\r
+ {\r
+ ++( pspace->bad );\r
+ }\r
+ else\r
+ {\r
+ ++( pspace->used );\r
+ }\r
+ }\r
+\r
+ clustersize = (unsigned long)( gl_volume.bootrecord.sector_per_cluster * F_SECTOR_SIZE );\r
+ for ( a = 0 ; ( clustersize & 1 ) == 0 ; a++ )\r
+ {\r
+ clustersize >>= 1;\r
+ }\r
+\r
+ pspace->total_high = ( pspace->total ) >> ( 32 - a );\r
+ pspace->total <<= a;\r
+ pspace->free_high = ( pspace->free ) >> ( 32 - a );\r
+ pspace->free <<= a;\r
+ pspace->used_high = ( pspace->used ) >> ( 32 - a );\r
+ pspace->used <<= a;\r
+ pspace->bad_high = ( pspace->bad ) >> ( 32 - a );\r
+ pspace->bad <<= a;\r
+\r
+ return F_NO_ERROR;\r
+} /* fn_getfreespace */\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_getserial\r
+ *\r
+ * get serial number\r
+ *\r
+ * INPUTS\r
+ * serial - pointer where to store the serial number\r
+ *\r
+ * RETURNS\r
+ * error code\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_getserial ( unsigned long * serial )\r
+{\r
+ unsigned char ret;\r
+\r
+ ret = _f_getvolume();\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ *serial = gl_volume.bootrecord.serial_number;\r
+ return 0;\r
+}\r
+\r
+/*\r
+** fn_init\r
+**\r
+** Initialize FAT_SL file system\r
+**\r
+** RETURN: F_NO_ERROR on success, other if error.\r
+*/\r
+unsigned char fn_init ( void )\r
+{\r
+ return F_NO_ERROR;\r
+} /* fn_init */\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_initvolume\r
+ *\r
+ * initiate a volume, this function has to be called 1st to set physical\r
+ * driver function to a given volume\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_initvolume ( F_DRIVERINIT initfunc )\r
+{\r
+#if F_FS_THREAD_AWARE == 1\r
+ {\r
+ if( fs_lock_semaphore == NULL )\r
+ {\r
+ fs_lock_semaphore = xSemaphoreCreateMutex();\r
+ if( fs_lock_semaphore == NULL )\r
+ {\r
+ return F_ERR_OS;\r
+ }\r
+ }\r
+ }\r
+#endif /* F_FS_THREAD_AWARE */\r
+\r
+ gl_volume.state = F_STATE_NONE;\r
+\r
+ mdrv = initfunc( 0 );\r
+ if ( mdrv == NULL )\r
+ {\r
+ return F_ERR_INITFUNC;\r
+ }\r
+\r
+ gl_volume.state = F_STATE_NEEDMOUNT;\r
+\r
+#if F_FILE_CHANGED_EVENT\r
+ f_filechangedevent = 0;\r
+#endif\r
+\r
+ return _f_getvolume();\r
+} /* fn_initvolume */\r
+\r
+/****************************************************************************\r
+ *\r
+ * fn_delvolume\r
+ *\r
+ ***************************************************************************/\r
+unsigned char fn_delvolume ( void )\r
+{\r
+ if ( mdrv->release )\r
+ {\r
+ (void)mdrv->release( mdrv );\r
+ }\r
+\r
+ return 0;\r
+}\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __VOLUME_H\r
+#define __VOLUME_H\r
+\r
+#include "config_fat_sl.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned char sector_per_cluster;\r
+ unsigned char number_of_FATs;\r
+ unsigned char media_descriptor;\r
+ unsigned long rootcluster;\r
+ unsigned long sector_per_FAT;\r
+ unsigned long sector_per_FAT32;\r
+ unsigned long serial_number;\r
+} F_BOOTRECORD;\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned long sector; /*start sector*/\r
+ unsigned long num; /*number of sectors*/\r
+} F_SECTOR;\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned char state;\r
+ F_BOOTRECORD bootrecord;\r
+ F_SECTOR firstfat;\r
+ F_SECTOR root;\r
+ F_SECTOR _tdata;\r
+\r
+ unsigned long actsector;\r
+ unsigned long fatsector;\r
+\r
+ unsigned long lastalloccluster;\r
+ unsigned char modified;\r
+ char cwd[F_MAXPATH]; /*current working folder in this volume*/\r
+ unsigned char mediatype;\r
+ unsigned long maxcluster;\r
+} F_VOLUME;\r
+\r
+\r
+enum\r
+{\r
+/* 0 */\r
+ F_STATE_NONE,\r
+\r
+/* 1 */ F_STATE_NEEDMOUNT,\r
+\r
+/* 2 */ F_STATE_WORKING\r
+};\r
+\r
+\r
+extern F_VOLUME gl_volume;\r
+extern F_FILE gl_file;\r
+extern char gl_sector[F_SECTOR_SIZE]; /* actual sector */\r
+\r
+unsigned char _f_getvolume ( void );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __VOLUME_H */\r
--- /dev/null
+#ifndef _TEST_C_\r
+#define _TEST_C_\r
+\r
+\r
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "test.h"\r
+#include "../../api/fat_sl.h"\r
+#include "../../psp/target/fat_sl/psp_test.h"\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+static char cwd[F_MAXPATH];\r
+\r
+static F_FIND find;\r
+\r
+static void _f_deleteall ( void )\r
+{\r
+ F_FIND f2;\r
+ unsigned char sd = 0, rc, fl = 0;\r
+\r
+ f2 = find;\r
+ do\r
+ {\r
+ rc = f_findfirst( "*.*", &find );\r
+ while ( rc == 0 && find.filename[0] == '.' )\r
+ {\r
+ rc = f_findnext( &find );\r
+ }\r
+\r
+ if ( rc == 0 )\r
+ {\r
+ if ( find.attr & F_ATTR_DIR )\r
+ {\r
+ ++sd;\r
+ fl = 1;\r
+ f2 = find;\r
+ (void)f_chdir( find.filename );\r
+ continue;\r
+ }\r
+ else\r
+ {\r
+ (void)f_delete( find.filename );\r
+ rc = f_findnext( &find );\r
+ }\r
+ }\r
+\r
+ if ( rc && sd && fl )\r
+ {\r
+ (void)f_chdir( ".." );\r
+ --sd;\r
+ fl = 0;\r
+ find = f2;\r
+ (void)f_rmdir( find.filename );\r
+ rc = f_findnext( &find );\r
+ }\r
+\r
+ if ( rc && sd && !fl )\r
+ {\r
+ (void)f_chdir( "/" );\r
+ sd = 0;\r
+ rc = 0;\r
+ }\r
+ }\r
+ while ( rc == 0 );\r
+} /* _f_deleteall */\r
+\r
+char stmp[20];\r
+static char * f_nameconv ( char * s )\r
+{\r
+ char * ss = stmp;\r
+\r
+ for ( ; ; )\r
+ {\r
+ char ch = *s++;\r
+ if ( ( ch >= 'a' ) && ( ch <= 'z' ) )\r
+ {\r
+ ch += 'A' - 'a';\r
+ }\r
+\r
+ *ss++ = ch;\r
+ if ( !ch )\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return stmp;\r
+} /* f_nameconv */\r
+\r
+static unsigned char f_formatting ( void )\r
+{\r
+ unsigned char ret;\r
+\r
+ _f_dump( "f_formatting" );\r
+\r
+/*checking formatting*/\r
+ ret = f_format( F_FAT_TYPE );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 0, ret );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 1, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 2, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_formatting */\r
+\r
+static unsigned char _f_checkcwd ( char * orig )\r
+{\r
+ unsigned char ret;\r
+\r
+ ret = f_getcwd( cwd, F_MAXPATH );\r
+ if ( ret )\r
+ {\r
+ return ret;\r
+ }\r
+\r
+ if ( strcmp( orig, cwd ) )\r
+ {\r
+ return (unsigned char)-1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+static unsigned char f_dirtest ( void )\r
+{\r
+ unsigned char ret;\r
+\r
+ _f_dump( "f_dirtest" );\r
+\r
+ _f_deleteall();\r
+\r
+/*creates a ab abc abcd*/\r
+ ret = f_mkdir( "a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 1, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "ab" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 2, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "abc" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 3, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "abca" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+/*creates directories in /a - a ab abc abcd*/\r
+ ret = f_mkdir( "a/a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 5, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "a/ab" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 6, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "a/abc" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 7, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "a/abcd" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+/*change into a/abcd and check cwd*/\r
+ ret = f_chdir( "a/abcd" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 9, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+/*make directory t change into t and check cwd="a/abcd/t"*/\r
+ ret = f_mkdir( "t" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 11, ret );\r
+ }\r
+\r
+ ret = f_chdir( "t" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 12, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ ret = f_chdir( "." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 15, ret );\r
+ }\r
+\r
+ ret = f_chdir( "../." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 16, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 17, ret );\r
+ }\r
+\r
+/*removing t dir*/\r
+ ret = f_rmdir( "t" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 18, ret );\r
+ }\r
+\r
+ ret = f_chdir( "t" );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 19, ret );\r
+ }\r
+\r
+/*removing /a dir*/\r
+ ret = f_rmdir( "/ab" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 20, ret );\r
+ }\r
+\r
+ ret = f_chdir( "/ab" );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+/*removing /a dir*/\r
+ ret = f_rmdir( "../../a" );\r
+ if ( ret != F_ERR_NOTEMPTY )\r
+ {\r
+ return _f_result( 22, ret );\r
+ }\r
+\r
+/*removing /abca dir*/\r
+ ret = f_rmdir( "a:/abca" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 24, ret );\r
+ }\r
+\r
+/*changing invalid dirs*/\r
+ ret = f_chdir( "" );\r
+ if ( ret != F_ERR_INVALIDNAME )\r
+ {\r
+ return _f_result( 25, ret );\r
+ }\r
+\r
+ ret = f_chdir( " " );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 26, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 27, ret );\r
+ }\r
+\r
+ ret = f_chdir( "?" );\r
+ if ( ret != F_ERR_INVALIDNAME )\r
+ {\r
+ return _f_result( 28, ret );\r
+ }\r
+\r
+ ret = f_chdir( "*.*" );\r
+ if ( ret != F_ERR_INVALIDNAME )\r
+ {\r
+ return _f_result( 29, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/a/abcd" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 30, ret );\r
+ }\r
+\r
+/*changing into /abc and removes subfolder from /a/ */\r
+ ret = f_chdir( "/abc" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 31, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "/a/a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 32, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "A:../a/ab" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 33, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "A:/a/abc" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 34, ret );\r
+ }\r
+\r
+ ret = f_rmdir( ".././abc/.././a/../a/abcd" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 35, ret );\r
+ }\r
+\r
+/*some invalid rmdir*/\r
+ ret = f_rmdir( "." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 36, ret );\r
+ }\r
+\r
+ ret = f_rmdir( ".." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 37, ret );\r
+ }\r
+\r
+/*create again abc remove abc*/\r
+ ret = f_mkdir( ".././abc" );\r
+ if ( ret != F_ERR_DUPLICATED )\r
+ {\r
+ return _f_result( 38, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "../abc" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 39, ret );\r
+ }\r
+\r
+ ret = f_mkdir( ".././abc" );\r
+ if ( ret != F_ERR_INVALIDDIR )\r
+ {\r
+ return _f_result( 40, ret ); /*cwd is not exist*/\r
+ }\r
+\r
+ ret = f_chdir( "/" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 41, ret );\r
+ }\r
+\r
+/*try . and .. in the root*/\r
+ ret = f_chdir( "." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 42, ret );\r
+ }\r
+\r
+ ret = f_chdir( "./././." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 43, ret );\r
+ }\r
+\r
+ ret = f_chdir( ".." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 44, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( "/" ); /*root!*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 45, ret );\r
+ }\r
+\r
+/*test . and .. in a and remove a*/\r
+ ret = f_chdir( "a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 46, ret );\r
+ }\r
+\r
+ ret = f_chdir( ".." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 47, ret );\r
+ }\r
+\r
+ ret = f_chdir( "a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 48, ret );\r
+ }\r
+\r
+ ret = f_chdir( "." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 49, ret );\r
+ }\r
+\r
+ ret = f_chdir( "a" );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 50, ret );\r
+ }\r
+\r
+ ret = f_chdir( "./.." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 51, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "a" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 52, ret );\r
+ }\r
+\r
+/*check if all are removed*/\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 53, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_dirtest */\r
+\r
+\r
+static unsigned char f_findingtest ( void )\r
+{\r
+ unsigned char ret;\r
+\r
+ _f_dump( "f_findingtest" );\r
+\r
+ _f_deleteall();\r
+\r
+/*check empty*/\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 0, ret );\r
+ }\r
+\r
+/*create Hello.dir*/\r
+ ret = f_mkdir( "Hello.dir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 1, ret );\r
+ }\r
+\r
+/*check if it is exist, and only exist*/\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 2, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "Hello.dir" ) ) )\r
+ {\r
+ return _f_result( 3, 0 );\r
+ }\r
+\r
+ if ( find.attr != F_ATTR_DIR )\r
+ {\r
+ return _f_result( 4, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 5, ret );\r
+ }\r
+\r
+/*check some not founds*/\r
+ ret = f_findfirst( "q*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 6, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "Hello.", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 7, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "a/*.*", &find );\r
+ if ( ret != F_ERR_INVALIDDIR )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+ ret = f_findfirst( ".", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 9, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "..", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "?e.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 11, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 12, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.?", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.??", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+\r
+\r
+/*check some founds*/\r
+ ret = f_findfirst( "*.dir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 15, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.d?r", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 16, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.d??", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 17, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.???", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 18, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "?ello.???", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 19, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "he??o.dir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 20, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "he?*.dir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "HELLO.DIR", &find ); /*no capitals sensitivity in find!!*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 22, ret );\r
+ }\r
+\r
+/*change into hello.dir*/\r
+ ret = f_chdir( "hello.dir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 23, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 24, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "..", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 25, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "??", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 26, ret );\r
+ }\r
+\r
+ ret = f_findfirst( ".", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 27, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "k*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 28, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 29, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, "." ) )\r
+ {\r
+ return _f_result( 29, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 29, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, ".." ) )\r
+ {\r
+ return _f_result( 29, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 29, ret );\r
+ }\r
+\r
+\r
+ ret = f_findfirst( "*.a", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 30, ret );\r
+ }\r
+\r
+/*creating testdir and find it*/\r
+ ret = f_mkdir( "testdir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 31, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 32, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, "." ) )\r
+ {\r
+ return _f_result( 32, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 32, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, ".." ) )\r
+ {\r
+ return _f_result( 32, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 32, ret );\r
+ }\r
+\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 33, 0 );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 34, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, "." ) )\r
+ {\r
+ return _f_result( 35, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 35, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, ".." ) )\r
+ {\r
+ return _f_result( 35, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 36, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 37, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 38, ret );\r
+ }\r
+\r
+/*search exact file*/\r
+ ret = f_findfirst( "testDir", &find ); /*no capitals!*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 39, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 40, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 41, ret );\r
+ }\r
+\r
+\r
+/*go back to root and remove dirs*/\r
+ ret = f_chdir( "\\" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 42, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "Hello.dir/testdir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 43, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "Hello.dir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 44, ret );\r
+ }\r
+\r
+/*check if all are removed*/\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 45, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_findingtest */\r
+\r
+static unsigned char f_powerfail ( void )\r
+{\r
+ unsigned char ret;\r
+\r
+ _f_dump( "f_powerfail" );\r
+\r
+/*checking if its power fail system (RAMDRIVE is not powerfail!)*/\r
+ ret = f_mkdir( "testdir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 0, ret );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 1, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "testdir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 2, ret );\r
+ }\r
+\r
+/*checking formatting*/\r
+ ret = f_format( F_FAT_TYPE );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 3, ret );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 5, ret );\r
+ }\r
+\r
+/*checking formatting, 1st creating*/\r
+ ret = f_format( F_FAT_TYPE );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 6, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "testdir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 7, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "testdir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 9, 0 );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 11, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 12, 0 );\r
+ }\r
+\r
+/*checking formatting, 2nd creating*/\r
+ ret = f_format( F_FAT_TYPE );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "testdir" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "testdir", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 15, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 16, 0 );\r
+ }\r
+\r
+ ret = f_mkdir( "testdir2" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 17, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "testdir2", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 18, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) )\r
+ {\r
+ return _f_result( 19, 0 );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 20, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir" ) ) )\r
+ {\r
+ return _f_result( 22, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 23, ret );\r
+ }\r
+\r
+ if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) )\r
+ {\r
+ return _f_result( 24, 0 );\r
+ }\r
+\r
+ ret = f_findnext( &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 25, ret );\r
+ }\r
+\r
+\r
+/*checking empty*/\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 26, ret );\r
+ }\r
+\r
+ ret = f_format( F_FAT_TYPE );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 27, ret );\r
+ }\r
+\r
+ ret = _f_poweron();\r
+ if ( ret )\r
+ {\r
+ return _f_result( 28, ret );\r
+ }\r
+\r
+ ret = f_findfirst( "*.*", &find );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 29, ret );\r
+ }\r
+\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_powerfail */\r
+\r
+\r
+char testbuffer[F_MAX_SEEK_TEST + 16]; /* +16 for f_appending test */\r
+\r
+static unsigned char checkfilecontent ( long nums, unsigned char value, F_FILE * file )\r
+{\r
+ unsigned char ch;\r
+\r
+ while ( nums-- )\r
+ {\r
+ if ( f_eof( file ) )\r
+ {\r
+ return 1; /*eof ?*/\r
+ }\r
+\r
+ if ( 1 != f_read( &ch, 1, 1, file ) )\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ if ( ch != value )\r
+ {\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+} /* checkfilecontent */\r
+\r
+static unsigned char f_seeking ( int sectorsize )\r
+{\r
+ F_FILE * file;\r
+ unsigned char ret;\r
+ unsigned long size;\r
+ unsigned long pos;\r
+\r
+ if ( sectorsize == 128 )\r
+ {\r
+ _f_dump( "f_seeking with 128" );\r
+ }\r
+\r
+ #if ( F_MAX_SEEK_TEST > 128 )\r
+ else if ( sectorsize == 256 )\r
+ {\r
+ _f_dump( "f_seeking with 256" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 256 )\r
+ else if ( sectorsize == 512 )\r
+ {\r
+ _f_dump( "f_seeking with 512" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 512 )\r
+ else if ( sectorsize == 1024 )\r
+ {\r
+ _f_dump( "f_seeking with 1024" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 1024 )\r
+ else if ( sectorsize == 2048 )\r
+ {\r
+ _f_dump( "f_seeking with 2048" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 2048 )\r
+ else if ( sectorsize == 4096 )\r
+ {\r
+ _f_dump( "f_seeking with 4096" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 4096 )\r
+ else if ( sectorsize == 8192 )\r
+ {\r
+ _f_dump( "f_seeking with 8192" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 8192 )\r
+ else if ( sectorsize == 16384 )\r
+ {\r
+ _f_dump( "f_seeking with 16384" );\r
+ }\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 16384 )\r
+ else if ( sectorsize == 32768 )\r
+ {\r
+ _f_dump( "f_seeking with 32768" );\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ _f_dump( "f_seeking with random" );\r
+ }\r
+\r
+/*checking sector boundary seekeng*/\r
+ file = f_open( "test.bin", "w+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 0, 0 );\r
+ }\r
+\r
+/*write sectorsize times 0*/\r
+ psp_memset( testbuffer, 0, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, (long)sectorsize, file );\r
+ if ( size != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 1, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 2, pos );\r
+ }\r
+\r
+/*seek back and read some*/\r
+ ret = f_seek( file, 0, F_SEEK_SET ); /*seek back*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 3, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos )\r
+ {\r
+ return _f_result( 4, pos );\r
+ }\r
+\r
+ size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );\r
+ if ( size != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 5, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 6, pos );\r
+ }\r
+\r
+/*fake read at eof*/\r
+ size = (unsigned long)f_read( testbuffer, 1, 2, file ); /*eof!*/\r
+ if ( size != 0 )\r
+ {\r
+ return _f_result( 7, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 8, pos );\r
+ }\r
+\r
+/*writing sectorsize times 1 at the end*/\r
+ psp_memset( testbuffer, 1, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, sectorsize, file );\r
+ if ( size != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 11, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( sectorsize * 2 ) )\r
+ {\r
+ return _f_result( 12, pos );\r
+ }\r
+\r
+/*seeking back and read 1byte less*/\r
+ ret = f_seek( file, 0, F_SEEK_SET );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos )\r
+ {\r
+ return _f_result( 14, pos );\r
+ }\r
+\r
+ size = (unsigned long)f_read( testbuffer, 1, sectorsize - 1, file );\r
+ if ( size != (unsigned long) ( sectorsize - 1 ) )\r
+ {\r
+ return _f_result( 15, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( sectorsize - 1 ) )\r
+ {\r
+ return _f_result( 16, pos );\r
+ }\r
+\r
+\r
+/*write 2 times 2*/\r
+ psp_memset( testbuffer, 2, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 2, file );\r
+ if ( size != 2 )\r
+ {\r
+ return _f_result( 17, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( sectorsize + 1 ) )\r
+ {\r
+ return _f_result( 18, pos );\r
+ }\r
+\r
+/*read 2 bytes*/\r
+ size = (unsigned long)f_read( testbuffer, 2, 1, file );\r
+ if ( size != 1 )\r
+ {\r
+ return _f_result( 19, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( sectorsize + 3 ) )\r
+ {\r
+ return _f_result( 20, pos );\r
+ }\r
+\r
+\r
+/*write 4 times 3*/\r
+ psp_memset( testbuffer, 3, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 4, file );\r
+ if ( size != 4 )\r
+ {\r
+ return _f_result( 21, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( sectorsize + 3 + 4 ) )\r
+ {\r
+ return _f_result( 22, pos );\r
+ }\r
+\r
+/*seek at 2*/\r
+ ret = f_seek( file, 2, F_SEEK_SET );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 23, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != 2 )\r
+ {\r
+ return _f_result( 24, pos );\r
+ }\r
+\r
+/*write 6 times 4*/\r
+ psp_memset( testbuffer, 4, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 6, file );\r
+ if ( size != 6 )\r
+ {\r
+ return _f_result( 25, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != 8 )\r
+ {\r
+ return _f_result( 26, pos );\r
+ }\r
+\r
+/*seek end -4*/\r
+ ret = f_seek( file, -4, F_SEEK_END );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 27, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize - 4 ) )\r
+ {\r
+ return _f_result( 28, pos );\r
+ }\r
+\r
+/*read 2 bytes*/\r
+ size = (unsigned long)f_read( testbuffer, 1, 2, file );\r
+ if ( size != 2 )\r
+ {\r
+ return _f_result( 29, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize - 2 ) )\r
+ {\r
+ return _f_result( 30, pos );\r
+ }\r
+\r
+/*write 8 times 5*/\r
+ psp_memset( testbuffer, 5, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 8, file );\r
+ if ( size != 8 )\r
+ {\r
+ return _f_result( 31, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) )\r
+ {\r
+ return _f_result( 32, pos );\r
+ }\r
+\r
+/*seek to the begining*/\r
+ ret = f_seek( file, 0, F_SEEK_SET );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 33, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos )\r
+ {\r
+ return _f_result( 34, pos );\r
+ }\r
+\r
+/*seek to the end*/\r
+ ret = f_seek( file, 2 * sectorsize + 6, F_SEEK_SET );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 35, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) )\r
+ {\r
+ return _f_result( 36, pos );\r
+ }\r
+\r
+/*write 2 times 6*/\r
+ psp_memset( testbuffer, 6, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 2, file );\r
+ if ( size != 2 )\r
+ {\r
+ return _f_result( 37, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) )\r
+ {\r
+ return _f_result( 38, pos );\r
+ }\r
+\r
+/*seek to the begining*/\r
+ (void)f_seek( file, -( 2 * sectorsize + 8 ), F_SEEK_CUR );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 39, ret );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos )\r
+ {\r
+ return _f_result( 40, pos );\r
+ }\r
+\r
+/*read 2 times sector*/\r
+ size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );\r
+ if ( size != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 41, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 42, pos );\r
+ }\r
+\r
+ size = (unsigned long)f_read( testbuffer, 1, sectorsize, file );\r
+ if ( size != (unsigned long) sectorsize )\r
+ {\r
+ return _f_result( 43, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize ) )\r
+ {\r
+ return _f_result( 44, pos );\r
+ }\r
+\r
+/*write 1 once 7*/\r
+ psp_memset( testbuffer, 7, sectorsize );\r
+ size = (unsigned long)f_write( testbuffer, 1, 1, file );\r
+ if ( size != 1 )\r
+ {\r
+ return _f_result( 45, size );\r
+ }\r
+\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize + 1 ) )\r
+ {\r
+ return _f_result( 46, pos );\r
+ }\r
+\r
+/*close it*/\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 47, ret );\r
+ }\r
+\r
+\r
+/*check the result*/\r
+ size = (unsigned long)f_filelength( "test.bin" );\r
+ if ( size != (unsigned long) ( 2 * sectorsize + 8 ) )\r
+ {\r
+ return _f_result( 48, size );\r
+ }\r
+\r
+/*opens it*/\r
+ file = f_open( "test.bin", "r" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 49, size );\r
+ }\r
+\r
+ if ( checkfilecontent( 2, 0, file ) )\r
+ {\r
+ return _f_result( 50, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 6, 4, file ) )\r
+ {\r
+ return _f_result( 51, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( sectorsize - 8 - 1, 0, file ) )\r
+ {\r
+ return _f_result( 52, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 2, 2, file ) )\r
+ {\r
+ return _f_result( 53, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 2, 1, file ) )\r
+ {\r
+ return _f_result( 54, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 4, 3, file ) )\r
+ {\r
+ return _f_result( 55, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( sectorsize - 7 - 2, 1, file ) )\r
+ {\r
+ return _f_result( 56, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 2, 5, file ) )\r
+ {\r
+ return _f_result( 57, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 1, 7, file ) )\r
+ {\r
+ return _f_result( 58, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 5, 5, file ) )\r
+ {\r
+ return _f_result( 59, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( 2, 6, file ) )\r
+ {\r
+ return _f_result( 60, 0 );\r
+ }\r
+\r
+/*check pos result*/\r
+ pos = (unsigned long)f_tell( file );\r
+ if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) )\r
+ {\r
+ return _f_result( 61, pos );\r
+ }\r
+\r
+/*this has to be eof*/\r
+ pos = f_eof( file );\r
+ if ( !pos )\r
+ {\r
+ return _f_result( 62, pos );\r
+ }\r
+\r
+/*close it*/\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 63, ret );\r
+ }\r
+\r
+/*deletes it*/\r
+ ret = f_delete( "test.bin" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 64, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_seeking */\r
+\r
+static unsigned char f_opening ( void )\r
+{\r
+ F_FILE * file;\r
+ F_FILE * file2;\r
+ unsigned char ret;\r
+ unsigned short size, pos;\r
+\r
+ _f_dump( "f_opening" );\r
+\r
+/*test non existing file open r, r+*/\r
+ file = f_open( "file.bin", "r" );\r
+ if ( file )\r
+ {\r
+ return _f_result( 0, 0 );\r
+ }\r
+\r
+ file = f_open( "file.bin", "r+" );\r
+ if ( file )\r
+ {\r
+ return _f_result( 1, 0 );\r
+ }\r
+\r
+/*test non existing appends "a" a+*/\r
+ file = f_open( "file.bin", "a" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 2, 0 );\r
+ }\r
+\r
+ file2 = f_open( "file.bin", "a+" ); /*open again*/\r
+ if ( file2 )\r
+ {\r
+ return _f_result( 3, 0 );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 3, 1 );\r
+ }\r
+\r
+ ret = f_close( file2 );\r
+ if ( ret != F_ERR_NOTOPEN )\r
+ {\r
+ return _f_result( 3, 2 );\r
+ }\r
+\r
+\r
+/*try to creates it w*/\r
+ file = f_open( "file.bin", "w" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 4, 0 );\r
+ }\r
+\r
+/*write 512 times 1*/\r
+ psp_memset( testbuffer, 1, 512 ); /*set all 1*/\r
+ size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 5, size );\r
+ }\r
+\r
+/*go back, and read it*/\r
+ ret = f_rewind( file ); /*back to the begining*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 6, ret ); /*it should fail*/\r
+ }\r
+\r
+ size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/\r
+ if ( size )\r
+ {\r
+ return _f_result( 7, size ); /*it should fail*/\r
+ }\r
+\r
+/*close and check size*/\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size )\r
+ {\r
+ return _f_result( 8, size ); /*has to be zero*/\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 9, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 10, size );\r
+ }\r
+\r
+/*try to owerwrites it it*/\r
+ file = f_open( "file.bin", "w+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 11, 0 );\r
+ }\r
+\r
+/*close and check size*/\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size )\r
+ {\r
+ return _f_result( 12, size ); /*has to be zero*/\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size )\r
+ {\r
+ return _f_result( 14, size );\r
+ }\r
+\r
+\r
+\r
+/*test non existing appends "a" */\r
+ file = f_open( "file.bin", "r+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 15, 0 );\r
+ }\r
+\r
+/*write 512 times 1*/\r
+ psp_memset( testbuffer, 1, 512 ); /*set all 1*/\r
+ size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 16, size );\r
+ }\r
+\r
+/*go back, and read it*/\r
+ ret = f_rewind( file ); /*back to the begining*/\r
+ size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 17, size ); /*it should fail*/\r
+ }\r
+\r
+ ret = f_rewind( file ); /*back to the begining*/\r
+\r
+/*write 256 times 2*/\r
+ psp_memset( testbuffer, 2, 512 ); /*set all 2*/\r
+ size = (unsigned short)f_write( testbuffer, 1, 256, file ); /*test write*/\r
+ if ( size != 256 )\r
+ {\r
+ return _f_result( 18, size );\r
+ }\r
+\r
+ pos = (unsigned short)f_tell( file );\r
+ if ( pos != 256 )\r
+ {\r
+ return _f_result( 19, pos ); /*position has to be 512*/\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size )\r
+ {\r
+ return _f_result( 20, size ); /*has to be zero*/\r
+ }\r
+\r
+/*close and check size*/\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 22, size );\r
+ }\r
+\r
+\r
+/*test non existing appends a+*/\r
+ file = f_open( "file.bin", "a+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 23, 0 );\r
+ }\r
+\r
+ pos = (unsigned short)f_tell( file );\r
+ if ( pos != 512 )\r
+ {\r
+ return _f_result( 24, pos ); /*position has to be 512*/\r
+ }\r
+\r
+/*write 512 times 3*/\r
+ psp_memset( testbuffer, 3, 512 ); /*set all 3*/\r
+ size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 25, size );\r
+ }\r
+\r
+/*go back, and read it*/\r
+ ret = f_rewind( file ); /*back to the begining*/\r
+ if ( ret )\r
+ {\r
+ return _f_result( 26, ret ); /*it should fail*/\r
+ }\r
+\r
+ size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 27, size ); /*it should fail*/\r
+ }\r
+\r
+ pos = (unsigned short)f_tell( file );\r
+ if ( pos != 512 )\r
+ {\r
+ return _f_result( 28, pos ); /*position has to be 512*/\r
+ }\r
+\r
+/*close and check size*/\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size != 512 )\r
+ {\r
+ return _f_result( 29, size ); /*has to be zero*/\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 30, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "file.bin" );\r
+ if ( size != 1024 )\r
+ {\r
+ return _f_result( 31, size );\r
+ }\r
+\r
+/*close again!*/\r
+ ret = f_close( file );\r
+ if ( ret != F_ERR_NOTOPEN )\r
+ {\r
+ return _f_result( 32, pos );\r
+ }\r
+\r
+ ret = f_delete( "file.bin" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 33, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_opening */\r
+\r
+static unsigned char f_appending ( void )\r
+{\r
+ F_FILE * file;\r
+ unsigned short size, tsize, pos;\r
+ unsigned char a, b, ret;\r
+\r
+ _f_dump( "f_appending" );\r
+\r
+ _f_deleteall();\r
+\r
+ for ( tsize = 0, a = 0 ; a < 16 ; a++ )\r
+ {\r
+ file = f_open( "ap.bin", "a" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 1, 0 );\r
+ }\r
+\r
+ psp_memset( testbuffer, a, sizeof( testbuffer ) );\r
+ size = (unsigned short)f_write( testbuffer, 1, a + 128, file );\r
+ if ( size != a + 128 )\r
+ {\r
+ return _f_result( 2, size );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "ap.bin" );\r
+ if ( size != tsize )\r
+ {\r
+ return _f_result( 3, size );\r
+ }\r
+\r
+ tsize += a + 128;\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "ap.bin" );\r
+ if ( size != tsize )\r
+ {\r
+ return _f_result( 5, size );\r
+ }\r
+ }\r
+\r
+ file = f_open( "ap.bin", "r" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 6, 0 );\r
+ }\r
+\r
+ for ( tsize = 0, a = 0 ; a < 16 ; a++ )\r
+ {\r
+ if ( checkfilecontent( a + 128, (char)a, file ) )\r
+ {\r
+ return _f_result( 7, a );\r
+ }\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+ for ( tsize = 0, a = 0 ; a < 16 ; a++ )\r
+ {\r
+ file = f_open( "ap.bin", "r" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 9, 0 );\r
+ }\r
+\r
+ ret = f_seek( file, tsize, F_SEEK_SET );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+ pos = (unsigned short)f_tell( file );\r
+ if ( pos != tsize )\r
+ {\r
+ return _f_result( 11, pos );\r
+ }\r
+\r
+ size = (unsigned short)f_read( testbuffer, 1, a + 128, file );\r
+ if ( size != a + 128 )\r
+ {\r
+ return _f_result( 12, size );\r
+ }\r
+\r
+ for ( b = 0 ; b < a + 128 ; b++ )\r
+ {\r
+ if ( testbuffer[b] != (char)a )\r
+ {\r
+ return _f_result( 13, a );\r
+ }\r
+ }\r
+\r
+ tsize += a + 128;\r
+\r
+ pos = (unsigned short)f_tell( file );\r
+ if ( pos != tsize )\r
+ {\r
+ return _f_result( 13, pos );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret != F_ERR_NOTOPEN )\r
+ {\r
+ return _f_result( 9, ret );\r
+ }\r
+\r
+ ret = f_delete( "ap.bin" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_appending */\r
+\r
+static unsigned char f_writing ( void )\r
+{\r
+ F_FILE * file;\r
+ unsigned short size;\r
+ unsigned char a, ret;\r
+ F_SPACE before, after;\r
+\r
+ _f_dump( "f_writing" );\r
+\r
+ ret = f_getfreespace( &before );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 0, ret );\r
+ }\r
+\r
+ for ( a = 0 ; a < 4 ; a++ )\r
+ {\r
+ file = f_open( "wr.bin", "w" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 1, 0 );\r
+ }\r
+\r
+ psp_memset( testbuffer, a, sizeof( testbuffer ) );\r
+ size = (unsigned short)f_write( testbuffer, 1, a * 128, file );\r
+ if ( size != a * 128 )\r
+ {\r
+ return _f_result( 2, size );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 3, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "wr.bin" );\r
+ if ( size != a * 128 )\r
+ {\r
+ return _f_result( 4, size );\r
+ }\r
+\r
+ file = f_open( "wr.bin", "r" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 5, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( a * 128, (char)a, file ) )\r
+ {\r
+ return _f_result( 6, a );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 7, ret );\r
+ }\r
+ }\r
+\r
+\r
+ for ( a = 0 ; a < 4 ; a++ )\r
+ {\r
+ file = f_open( "wr.bin", "w+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 8, 0 );\r
+ }\r
+\r
+ psp_memset( testbuffer, a, sizeof( testbuffer ) );\r
+ size = (unsigned short)f_write( testbuffer, 1, a * 128, file );\r
+ if ( size != a * 128 )\r
+ {\r
+ return _f_result( 9, size );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+ size = (unsigned short)f_filelength( "wr.bin" );\r
+ if ( size != a * 128 )\r
+ {\r
+ return _f_result( 11, size );\r
+ }\r
+\r
+ file = f_open( "wr.bin", "r+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 12, 0 );\r
+ }\r
+\r
+ if ( checkfilecontent( a * 128, (char)a, file ) )\r
+ {\r
+ return _f_result( 13, a );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 14, ret );\r
+ }\r
+ }\r
+\r
+ ret = f_getfreespace( &after );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 15, ret );\r
+ }\r
+\r
+ if ( before.bad != after.bad )\r
+ {\r
+ return _f_result( 16, 0 );\r
+ }\r
+\r
+ if ( before.free == after.free )\r
+ {\r
+ return _f_result( 17, 0 );\r
+ }\r
+\r
+ if ( before.used == after.used )\r
+ {\r
+ return _f_result( 18, 0 );\r
+ }\r
+\r
+ if ( before.total != after.total )\r
+ {\r
+ return _f_result( 19, 0 );\r
+ }\r
+\r
+ if ( before.used + before.free != after.used + after.free )\r
+ {\r
+ return _f_result( 20, 0 );\r
+ }\r
+\r
+ ret = f_delete( "wr.bin" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+ ret = f_getfreespace( &after );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 22, ret );\r
+ }\r
+\r
+ if ( before.bad != after.bad )\r
+ {\r
+ return _f_result( 23, 0 );\r
+ }\r
+\r
+ if ( before.free != after.free )\r
+ {\r
+ return _f_result( 24, 0 );\r
+ }\r
+\r
+ if ( before.used != after.used )\r
+ {\r
+ return _f_result( 25, 0 );\r
+ }\r
+\r
+ if ( before.total != after.total )\r
+ {\r
+ return _f_result( 26, 0 );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_writing */\r
+\r
+static unsigned char f_dots ( void )\r
+{\r
+ unsigned char ret;\r
+ unsigned char a, size;\r
+ F_FILE * file;\r
+\r
+ _f_dump( "f_dots" );\r
+\r
+ ret = f_mkdir( "/tt" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 0, ret );\r
+ }\r
+\r
+ ret = f_chdir( "/tt" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 1, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+ ret = f_rmdir( ".." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 5, ret );\r
+ }\r
+\r
+ ret = f_chdir( "." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 6, ret );\r
+ }\r
+\r
+ ret = _f_checkcwd( f_nameconv( "/tt" ) );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 7, ret );\r
+ }\r
+\r
+ ret = f_delete( "." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+ ret = f_delete( ".." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 9, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 10, ret );\r
+ }\r
+\r
+ ret = f_mkdir( ".." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 11, ret );\r
+ }\r
+\r
+ ret = f_mkdir( "..." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 12, ret );\r
+ }\r
+\r
+ for ( a = 0 ; a < 6 ; a++ )\r
+ {\r
+ char * mode;\r
+ switch ( a )\r
+ {\r
+ case 0:\r
+ mode = "r";\r
+ break;\r
+\r
+ case 1:\r
+ mode = "r+";\r
+ break;\r
+\r
+ case 2:\r
+ mode = "w";\r
+ break;\r
+\r
+ case 3:\r
+ mode = "w+";\r
+ break;\r
+\r
+ case 4:\r
+ mode = "a";\r
+ break;\r
+\r
+ case 5:\r
+ mode = "a+";\r
+ break;\r
+\r
+ default:\r
+ return _f_result( 13, a );\r
+ } /* switch */\r
+\r
+ file = f_open( ".", mode );\r
+ if ( file )\r
+ {\r
+ return _f_result( 14, a );\r
+ }\r
+\r
+ file = f_open( "..", mode );\r
+ if ( file )\r
+ {\r
+ return _f_result( 15, a );\r
+ }\r
+\r
+ file = f_open( "...", mode );\r
+ if ( file )\r
+ {\r
+ return _f_result( 16, a );\r
+ }\r
+ }\r
+\r
+ size = (unsigned char)f_filelength( "." );\r
+ if ( size )\r
+ {\r
+ return _f_result( 17, size );\r
+ }\r
+\r
+ size = (unsigned char)f_filelength( ".." );\r
+ if ( size )\r
+ {\r
+ return _f_result( 18, size );\r
+ }\r
+\r
+ size = (unsigned char)f_filelength( "..." );\r
+ if ( size )\r
+ {\r
+ return _f_result( 19, size );\r
+ }\r
+\r
+\r
+ ret = f_chdir( "..." );\r
+ if ( ret != F_ERR_NOTFOUND )\r
+ {\r
+ return _f_result( 20, ret );\r
+ }\r
+\r
+ ret = f_chdir( ".." );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 21, ret );\r
+ }\r
+\r
+ ret = f_rmdir( "tt" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 27, ret );\r
+ }\r
+\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_dots */\r
+\r
+\r
+typedef struct\r
+{\r
+ unsigned char MagicNum;\r
+ unsigned char Line;\r
+ unsigned char Buf[87];\r
+} struct_TestFileSysEntry;\r
+ #define NUM_OF_RECORDS 10\r
+static unsigned char f_rit ( void )\r
+{\r
+ unsigned char i;\r
+ unsigned char ret;\r
+ F_FILE * File;\r
+ struct_TestFileSysEntry * Entry = (struct_TestFileSysEntry *)( ( ( (long)testbuffer + 3 ) >> 2 ) << 2 );\r
+ unsigned short Pos;\r
+ unsigned char Ch;\r
+ unsigned char Founded;\r
+\r
+ _f_dump( "f_rit" );\r
+\r
+ (void)f_delete( "MyTest" );\r
+ File = f_open( "MyTest", "a+" );\r
+ if ( !File )\r
+ {\r
+ return _f_result( 1, 0 );\r
+ }\r
+\r
+ /* add records */\r
+ for ( i = 0 ; i < NUM_OF_RECORDS ; i++ )\r
+ {\r
+ Ch = (char)( i % 10 );\r
+ Entry->MagicNum = 0xbc;\r
+ Entry->Line = i;\r
+ Entry->Buf[0] = Ch;\r
+ Entry->Buf[10] = (unsigned char)( Ch + 1 );\r
+\r
+ if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_END ) )\r
+ {\r
+ return _f_result( 2, 0 ); /* Fail, could not go to the end of the file */\r
+ }\r
+\r
+ if ( sizeof( struct_TestFileSysEntry ) != f_write( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )\r
+ {\r
+ return _f_result( 3, 0 ); /* Fail, could not write new entry */\r
+ }\r
+\r
+ Pos = (unsigned short)f_tell( File );\r
+ if ( ( ( Pos / sizeof( struct_TestFileSysEntry ) ) - 1 ) != i )\r
+ {\r
+ return _f_result( 4, 0 ); /* Fail, wrong file position */\r
+ }\r
+\r
+ if ( F_NO_ERROR != f_seek( File, (long)( Pos - sizeof( struct_TestFileSysEntry ) ), F_SEEK_SET ) )\r
+ {\r
+ return _f_result( 5, 0 ); /* Fail, could not go to new entry position */\r
+ }\r
+\r
+ if ( sizeof( struct_TestFileSysEntry ) != f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )\r
+ {\r
+ return _f_result( 6, 0 ); /* Fail, could not read the new entry */\r
+ }\r
+\r
+ if ( ( Entry->MagicNum != 0xbc ) || ( Entry->Line != (int)i ) || ( Entry->Buf[0] != Ch ) || ( Entry->Buf[10] != Ch + 1 ) )\r
+ {\r
+ return _f_result( 7, 0 ); /*Fail, the new entry is corrupted"*/\r
+ }\r
+ }\r
+\r
+ ret = f_close( File );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+\r
+ /*Open file again*/\r
+ File = f_open( "MyTest", "a+" );\r
+ if ( !File )\r
+ {\r
+ return _f_result( 9, 0 );\r
+ }\r
+\r
+ /* read records */\r
+ for ( i = 0 ; i < NUM_OF_RECORDS ; i++ )\r
+ {\r
+ Ch = (char)( i % 10 );\r
+\r
+ if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_SET ) )\r
+ {\r
+ return _f_result( 10, 0 ); /* Fail, could not go to the start of the file */\r
+ }\r
+\r
+ Founded = 0;\r
+ while ( sizeof( struct_TestFileSysEntry ) == f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) )\r
+ {\r
+ if ( ( Entry->MagicNum == 0xbc )\r
+ && ( Entry->Line == (int)i )\r
+ && ( Entry->Buf[0] == Ch )\r
+ && ( Entry->Buf[10] == Ch + 1 ) )\r
+ {\r
+ Founded = 1;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( !Founded )\r
+ {\r
+ return _f_result( 11, i ); /* Entry not founded */\r
+ }\r
+ }\r
+\r
+ ret = f_close( File );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 12, ret );\r
+ }\r
+\r
+\r
+ ret = f_delete( "MyTest" );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 13, ret );\r
+ }\r
+\r
+ _f_dump( "passed..." );\r
+\r
+ return 0;\r
+} /* f_rit */\r
+\r
+\r
+\r
+\r
+static unsigned char f_truncating ( void )\r
+{\r
+ F_FILE * file;\r
+ unsigned long size;\r
+ unsigned char ret;\r
+\r
+ _f_dump( "f_truncating" );\r
+\r
+ file = f_open( "test.bin", "w+" );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 0, 0 );\r
+ }\r
+\r
+ (void)psp_memset( testbuffer, 1, F_MAX_SEEK_TEST );\r
+ size = (unsigned long)f_write( testbuffer, 1, F_MAX_SEEK_TEST, file );\r
+ if ( size != F_MAX_SEEK_TEST )\r
+ {\r
+ return _f_result( 1, size );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 2, ret );\r
+ }\r
+\r
+ file = f_truncate( "test.bin", F_MAX_SEEK_TEST - 4 );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 3, 0 );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+ size = (unsigned long)f_filelength( "test.bin" );\r
+ if ( size != F_MAX_SEEK_TEST - 4 )\r
+ {\r
+ return _f_result( 5, size );\r
+ }\r
+\r
+\r
+ file = f_truncate( "test.bin", F_MAX_SEEK_TEST );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 3, 0 );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 4, ret );\r
+ }\r
+\r
+ size = (unsigned long)f_filelength( "test.bin" );\r
+ if ( size != F_MAX_SEEK_TEST )\r
+ {\r
+ return _f_result( 5, size );\r
+ }\r
+\r
+\r
+ file = f_truncate( "test.bin", ( F_MAX_SEEK_TEST / 2 ) - 92 );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 6, 0 );\r
+ }\r
+\r
+ (void)psp_memset( testbuffer, 2, 92 );\r
+ size = (unsigned long)f_write( testbuffer, 1, 92, file );\r
+ if ( size != 92 )\r
+ {\r
+ return _f_result( 7, size );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 8, ret );\r
+ }\r
+\r
+ size = (unsigned long)f_filelength( "test.bin" );\r
+ if ( size != ( F_MAX_SEEK_TEST / 2 ) )\r
+ {\r
+ return _f_result( 9, size );\r
+ }\r
+\r
+\r
+ file = f_truncate( "test.bin", 1 );\r
+ if ( !file )\r
+ {\r
+ return _f_result( 10, 0 );\r
+ }\r
+\r
+ (void)psp_memset( testbuffer, 3, 2 );\r
+ size = (unsigned long)f_write( testbuffer, 1, 2, file );\r
+ if ( size != 2 )\r
+ {\r
+ return _f_result( 11, size );\r
+ }\r
+\r
+ ret = f_close( file );\r
+ if ( ret )\r
+ {\r
+ return _f_result( 12, ret );\r
+ }\r
+\r
+ size = (unsigned long)f_filelength( "test.bin" );\r
+ if ( size != 3 )\r
+ {\r
+ return _f_result( 13, size );\r
+ }\r
+\r
+\r
+\r
+ _f_dump( "passed..." );\r
+ return 0;\r
+} /* f_truncating */\r
+\r
+\r
+void f_dotest ( unsigned char t )\r
+{\r
+ _f_dump( "File system test started..." );\r
+ _f_dump( "WARNING: The contents of your drive will be destroyed!\n" );\r
+\r
+ (void)_f_poweron();\r
+\r
+ switch ( t )\r
+ {\r
+ case 0:\r
+ case 1:\r
+ (void)f_formatting();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 2:\r
+ (void)f_dirtest();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 3:\r
+ (void)f_findingtest();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 4:\r
+ (void)f_powerfail();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 5:\r
+ (void)f_seeking( 128 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #if ( F_MAX_SEEK_TEST > 128 )\r
+\r
+ /* fall through */\r
+ case 6:\r
+ (void)f_seeking( 256 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 256 )\r
+\r
+ /* fall through */\r
+ case 7:\r
+ (void)f_seeking( 512 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 512 )\r
+\r
+ /* fall through */\r
+ case 8:\r
+ (void)f_seeking( 1024 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 1024 )\r
+\r
+ /* fall through */\r
+ case 9:\r
+ (void)f_seeking( 2048 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 2048 )\r
+\r
+ /* fall through */\r
+ case 10:\r
+ (void)f_seeking( 4096 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 4096 )\r
+\r
+ /* fall through */\r
+ case 11:\r
+ (void)f_seeking( 8192 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 8192 )\r
+\r
+ /* fall through */\r
+ case 12:\r
+ (void)f_seeking( 16384 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+ #if ( F_MAX_SEEK_TEST > 16384 )\r
+\r
+ /* fall through */\r
+ case 13:\r
+ (void)f_seeking( 32768 );\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ #endif\r
+\r
+ /* fall through */\r
+ case 14:\r
+ (void)f_opening();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 15:\r
+ (void)f_appending();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 16:\r
+ (void)f_writing();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 17:\r
+ (void)f_dots();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+\r
+ /* fall through */\r
+ case 18:\r
+ (void)f_rit();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ case 19:\r
+ (void)f_truncating();\r
+ if ( t )\r
+ {\r
+ break;\r
+ }\r
+\r
+ break;\r
+ } /* switch */\r
+\r
+ _f_dump( "End of tests..." );\r
+} /* f_dotest */\r
+\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * end of test.c\r
+ *\r
+ ***************************************************************************/\r
+#endif /*_TEST_C_*/\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef __TEST_H\r
+#define __TEST_H\r
+\r
+#include "../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/*\r
+** Maximum size for seek test.\r
+** Options: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768\r
+*/\r
+#define F_MAX_SEEK_TEST 16384\r
+\r
+\r
+/*\r
+** Defines media type for testing.\r
+** Options: F_FAT12_MEDIA, F_FAT16_MEDIA\r
+*/\r
+#define F_FAT_TYPE F_FAT12_MEDIA\r
+\r
+\r
+/*\r
+** Start filesystem test.\r
+** Parameter:\r
+** 0 - run all the tests\r
+**\r
+** 2 - directory\r
+** 3 - find\r
+**\r
+** 5* - seek 128\r
+** 6* - seek 256\r
+** 7* - seek 512\r
+** 8* - seek 1024\r
+** 9* - seek 2048\r
+** 10*- seek 4096\r
+** 11*- seek 8192\r
+** 12*- seek 16384\r
+** 13*- seek 32768\r
+** 14 - open\r
+** 15 - append\r
+** 16 - write\r
+** 17 - dots\r
+** 18 - rit\r
+** *Note that only seek tests allowed by F_MAX_SEEK_TEST are executed.\r
+**\r
+** The following defines are required for the specific test:\r
+** 1 1 1 1 1 1 1 1 1\r
+** 2 3 5 6 7 8 9 0 1 2 3 4 5 6 7 8\r
+** F_CHDIR x x - - - - - - - - - - x - x -\r
+** F_MKDIR x x - - - - - - - - - - - - x -\r
+** F_RMDIR x x - - - - - - - - - - x - x -\r
+** F_DELETE x x x x x x x x x x x x x x x x\r
+** F_FILELENGTH - - x x x x x x x x x x x x - -\r
+** F_FINDING x x - - - - - - - - - - x - - -\r
+** F_TELL - - x x x x x x x x x x x x - x\r
+** F_REWIND - - - - - - - - - - - x - - - -\r
+** F_EOF - - x x x x x x x x x - - x - -\r
+** F_SEEK - - x x x x x x x x x - x x - x\r
+** F_WRITE - - x x x x x x x x x x x x - x\r
+** F_WRITING x x x x x x x x x x x x x x x x\r
+** F_DIRECTORIES x x - - - - - - - - - - x - x -\r
+** F_CHECKNAME x - - - - - - - - - - - - - x -\r
+*/\r
+void f_dotest ( unsigned char );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* ifndef __TEST_H */\r
+\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include "../../api/api_mdriver_ram.h"\r
+#include "config_mdriver_ram.h"\r
+#include "../../psp/include/psp_string.h"\r
+\r
+#include "../../version/ver_mdriver_ram.h"\r
+#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2\r
+ #error Incompatible MDRIVER_RAM version number!\r
+#endif\r
+\r
+\r
+char ramdrv0[MDRIVER_RAM_VOLUME0_SIZE];\r
+\r
+typedef struct\r
+{\r
+ char * ramdrv;\r
+ unsigned long maxsector;\r
+ int use;\r
+ F_DRIVER * driver;\r
+} t_RamDrv;\r
+\r
+static F_DRIVER t_drivers[1];\r
+\r
+static t_RamDrv RamDrv[1] =\r
+{\r
+ { ramdrv0, ( MDRIVER_RAM_VOLUME0_SIZE / MDRIVER_RAM_SECTOR_SIZE ), 0, &t_drivers[0] }\r
+};\r
+\r
+\r
+/****************************************************************************\r
+ * Read one sector\r
+ ***************************************************************************/\r
+static int ram_readsector ( F_DRIVER * driver, void * data, unsigned long sector )\r
+{\r
+ long len;\r
+ char * d = (char *)data;\r
+ char * s;\r
+ t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );\r
+\r
+ if ( sector >= p->maxsector )\r
+ {\r
+ return MDRIVER_RAM_ERR_SECTOR;\r
+ }\r
+\r
+ s = p->ramdrv;\r
+ s += sector * MDRIVER_RAM_SECTOR_SIZE;\r
+ len = MDRIVER_RAM_SECTOR_SIZE;\r
+\r
+#if MDRIVER_MEM_LONG_ACCESS\r
+ if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) )\r
+ {\r
+ long * dd = (long *)d;\r
+ long * ss = (long *)s;\r
+ len >>= 2;\r
+ while ( len-- )\r
+ {\r
+ *dd++ = *ss++;\r
+ }\r
+\r
+ return MDRIVER_RAM_NO_ERROR;\r
+ }\r
+\r
+#endif /* if MDRIVER_MEM_LONG_ACCESS */\r
+\r
+ while ( len-- )\r
+ {\r
+ *d++ = *s++;\r
+ }\r
+\r
+ return MDRIVER_RAM_NO_ERROR;\r
+}\r
+\r
+/****************************************************************************\r
+ * Write one sector\r
+ ***************************************************************************/\r
+static int ram_writesector ( F_DRIVER * driver, void * data, unsigned long sector )\r
+{\r
+ long len;\r
+ char * s = (char *)data;\r
+ char * d;\r
+ t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );\r
+\r
+ if ( sector >= p->maxsector )\r
+ {\r
+ return MDRIVER_RAM_ERR_SECTOR;\r
+ }\r
+\r
+ d = p->ramdrv;\r
+ d += sector * MDRIVER_RAM_SECTOR_SIZE;\r
+ len = MDRIVER_RAM_SECTOR_SIZE;\r
+\r
+#if MDRIVER_MEM_LONG_ACCESS\r
+ if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) )\r
+ {\r
+ long * dd = (long *)d;\r
+ long * ss = (long *)s;\r
+ len >>= 2;\r
+ while ( len-- )\r
+ {\r
+ *dd++ = *ss++;\r
+ }\r
+\r
+ return MDRIVER_RAM_NO_ERROR;\r
+ }\r
+\r
+#endif /* if MDRIVER_MEM_LONG_ACCESS */\r
+\r
+ while ( len-- )\r
+ {\r
+ *d++ = *s++;\r
+ }\r
+\r
+ return MDRIVER_RAM_NO_ERROR;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * ram_getphy\r
+ *\r
+ * determinate ramdrive physicals\r
+ *\r
+ * INPUTS\r
+ *\r
+ * driver - driver structure\r
+ * phy - this structure has to be filled with physical information\r
+ *\r
+ * RETURNS\r
+ *\r
+ * error code or zero if successful\r
+ *\r
+ ***************************************************************************/\r
+static int ram_getphy ( F_DRIVER * driver, F_PHY * phy )\r
+{\r
+ t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );\r
+\r
+ phy->number_of_sectors = p->maxsector;\r
+ phy->bytes_per_sector = MDRIVER_RAM_SECTOR_SIZE;\r
+\r
+ return MDRIVER_RAM_NO_ERROR;\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * ram_release\r
+ *\r
+ * Releases a drive\r
+ *\r
+ * INPUTS\r
+ *\r
+ * driver_param - driver parameter\r
+ *\r
+ ***************************************************************************/\r
+static void ram_release ( F_DRIVER * driver )\r
+{\r
+ t_RamDrv * p = (t_RamDrv *)( driver->user_ptr );\r
+\r
+ if ( p == RamDrv )\r
+ {\r
+ p->use = 0;\r
+ }\r
+}\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * ram_initfunc\r
+ *\r
+ * this init function has to be passed for highlevel to initiate the\r
+ * driver functions\r
+ *\r
+ * INPUTS\r
+ *\r
+ * driver_param - driver parameter\r
+ *\r
+ * RETURNS\r
+ *\r
+ * driver structure pointer\r
+ *\r
+ ***************************************************************************/\r
+F_DRIVER * ram_initfunc ( unsigned long driver_param )\r
+{\r
+ t_RamDrv * p;\r
+\r
+ p = RamDrv + driver_param;\r
+\r
+ if ( p != RamDrv )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ if ( p->use )\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ (void)psp_memset( p->driver, 0, sizeof( F_DRIVER ) );\r
+\r
+ p->driver->readsector = ram_readsector;\r
+ p->driver->writesector = ram_writesector;\r
+ p->driver->getphy = ram_getphy;\r
+ p->driver->release = ram_release;\r
+ p->driver->user_ptr = p;\r
+\r
+ p->use = 1;\r
+\r
+ return p->driver;\r
+} /* ram_initfunc */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _PSP_RTC_H\r
+#define _PSP_RTC_H\r
+\r
+#include <stdint.h>\r
+\r
+#include "../../version/ver_psp_rtc.h"\r
+#if VER_PSP_RTC_MAJOR != 1\r
+ #error "VER_PSP_RTC_MAJOR invalid"\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct\r
+{\r
+ uint8_t sec;\r
+ uint8_t min;\r
+ uint8_t hour;\r
+ uint8_t day;\r
+ uint8_t month;\r
+ uint16_t year;\r
+} t_psp_timedate;\r
+\r
+void psp_getcurrenttimedate ( t_psp_timedate * p_timedate );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* _PSP_RTC_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _PSP_STRING_H_\r
+#define _PSP_STRING_H_\r
+\r
+#include <stddef.h>\r
+#include <string.h>\r
+\r
+#include "../../version/ver_psp_string.h"\r
+#if VER_PSP_STRING_MAJOR != 1 || VER_PSP_STRING_MINOR != 4\r
+ #error Incompatible PSP_STRING version number!\r
+#endif\r
+\r
+#define psp_memcpy( d, s, l ) memcpy( ( d ), ( s ), (size_t)( l ) )\r
+#define psp_memmove( d, s, l ) memmove( ( d ), ( s ), (size_t)( l ) )\r
+#define psp_memset( d, c, l ) memset( ( d ), ( c ), (size_t)( l ) )\r
+#define psp_memcmp( s1, s2, l ) memcmp( ( s1 ), ( s2 ), (size_t)( l ) )\r
+#define psp_strnlen( s, l ) strnlen( ( s ), ( size_t )( l ) )\r
+#define psp_strncat( d, s, l ) strncat( ( d ), ( s ), (size_t)( l ) )\r
+#define psp_strncpy( d, s, l ) strncpy( ( d ), ( s ), (size_t)( l ) )\r
+#define psp_strncmp( s1, s2, l ) strncmp( ( s1 ), ( s2 ), (size_t)( l ) )\r
+\r
+#endif /* ifndef _PSP_STRING_H_ */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "psp_test.h"\r
+#include "config_fat_sl.h"\r
+#include "config_mdriver_ram.h"\r
+#include "../../../api/fat_sl.h"\r
+#include "../../../api/api_mdriver_ram.h"\r
+\r
+#include "../../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+#include "../../../version/ver_psp_fat_sl.h"\r
+#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1\r
+ #error Incompatible PSP_FAT_FAT_SL version number!\r
+#endif\r
+\r
+uint8_t all_tests_passed = 1u;\r
+\r
+/* Use to display text (printf). */\r
+void _f_dump ( char * s )\r
+{\r
+ printf( "%s\r\n", s );\r
+}\r
+\r
+/* Use to display test result (printf). */\r
+uint8_t _f_result ( uint8_t testnum, uint32_t result )\r
+{\r
+ (void)testnum;\r
+ if ( result == 0 )\r
+ {\r
+ printf( "Passed\r\n" );\r
+ }\r
+ else\r
+ {\r
+ printf( "FAILED! Error code: %u\r\n", result );\r
+ all_tests_passed = 0u;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/* Use to build file system (mount). */\r
+uint8_t _f_poweron ( void )\r
+{\r
+ f_delvolume();\r
+ return f_initvolume( ram_initfunc );\r
+}\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _PSP_FAT_FAT_SL_H\r
+#define _PSP_FAT_FAT_SL_H\r
+\r
+#include <stdint.h>\r
+#include "../../../psp/include/psp_string.h"\r
+\r
+#include "../../../version/ver_fat_sl.h"\r
+#if VER_FAT_SL_MAJOR != 3\r
+ #error Incompatible FAT_SL version number!\r
+#endif\r
+#include "../../../version/ver_psp_fat_sl.h"\r
+#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1\r
+ #error Incompatible PSP_FAT_FAT_SL version number!\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern uint8_t all_tests_passed;\r
+\r
+/* Use to display text (printf). */\r
+void _f_dump ( char * s );\r
+\r
+/* Use to display test result (printf). */\r
+uint8_t _f_result ( uint8_t testnum, uint32_t result );\r
+\r
+/* Use to build file system (mount). */\r
+uint8_t _f_poweron ( void );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* _PSP_FAT_FAT_SL_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+#include "../../include/psp_rtc.h"\r
+\r
+#include "../../../version/ver_psp_rtc.h"\r
+#if VER_PSP_RTC_MAJOR != 1\r
+ #error "VER_PSP_RTC_MAJOR invalid"\r
+#endif\r
+#if VER_PSP_RTC_MINOR != 0\r
+ #error "VER_PSP_RTC_MINOR invalid"\r
+#endif\r
+\r
+\r
+/****************************************************************************\r
+ *\r
+ * psp_getcurrenttimedate\r
+ *\r
+ * Need to be ported depending on system, it retreives the\r
+ * current time and date.\r
+ * Please take care of correct roll-over handling.\r
+ * Roll-over problem is to read a date at 23.59.59 and then reading time at\r
+ * 00:00.00.\r
+ *\r
+ * INPUT\r
+ *\r
+ * p_timedate - pointer where to store time and date\r
+ *\r
+ ***************************************************************************/\r
+void psp_getcurrenttimedate ( t_psp_timedate * p_timedate )\r
+{\r
+ if ( p_timedate != NULL )\r
+ {\r
+ p_timedate->sec = 0;\r
+ p_timedate->min = 0;\r
+ p_timedate->hour = 12u;\r
+\r
+ p_timedate->day = 1u;\r
+ p_timedate->month = 1u;\r
+ p_timedate->year = 1980u;\r
+ }\r
+} /* psp_getcurrenttimedate */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_FAT_SL_H\r
+#define _VER_FAT_SL_H\r
+\r
+#define VER_FAT_SL_MAJOR 3\r
+#define VER_FAT_SL_MINOR 2\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_MDRIVER_H\r
+#define _VER_MDRIVER_H\r
+\r
+#define VER_MDRIVER_MAJOR 1\r
+#define VER_MDRIVER_MINOR 0\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_MDRIVER_RAM_H\r
+#define _VER_MDRIVER_RAM_H\r
+\r
+#define VER_MDRIVER_RAM_MAJOR 1\r
+#define VER_MDRIVER_RAM_MINOR 2\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_PSP_FAT_FAT_SL_H\r
+#define _VER_PSP_FAT_FAT_SL_H\r
+\r
+#define VER_PSP_FAT_FAT_SL_MAJOR 1\r
+#define VER_PSP_FAT_FAT_SL_MINOR 1\r
+\r
+#endif /* _VER_PSP_FAT_FAT_SL_H */\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_PSP_RTC_H\r
+#define _VER_PSP_RTC_H\r
+\r
+#define VER_PSP_RTC_MAJOR 1\r
+#define VER_PSP_RTC_MINOR 0\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ *\r
+ * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
+ * terms.\r
+ * \r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
+ * under a pure GPL open source license (as opposed to the modified GPL licence\r
+ * under which FreeRTOS is distributed) or a commercial license. Details of \r
+ * both license options follow:\r
+ * \r
+ * - Open source licensing -\r
+ * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
+ * distributed without charge provided the user adheres to version two of the \r
+ * GNU General Public License (GPL) and does not remove the copyright notice or \r
+ * this text. The GPL V2 text is available on the gnu.org web site, and on the\r
+ * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.\r
+ * \r
+ * - Commercial licensing -\r
+ * Businesses and individuals who for commercial or other reasons cannot comply\r
+ * with the terms of the GPL V2 license must obtain a commercial license before \r
+ * incorporating FreeRTOS+FAT SL into proprietary software for distribution in \r
+ * any form. Commercial licenses can be purchased from \r
+ * http://shop.freertos.org/fat_sl and do not require any source files to be \r
+ * changed.\r
+ *\r
+ * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You\r
+ * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as\r
+ * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the\r
+ * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all\r
+ * conditions and terms, be they implied, expressed, or statutory.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus\r
+ *\r
+ */\r
+\r
+#ifndef _VER_PSP_STRING_H\r
+#define _VER_PSP_STRING_H\r
+\r
+#define VER_PSP_STRING_MAJOR 1\r
+#define VER_PSP_STRING_MINOR 4\r
+\r
+#endif\r
+\r
#define configUSE_QUEUE_SETS 0\r
#endif\r
\r
-#ifndef portTASK_USES_FLOATING_POINT\r
- #defeine portTASK_USES_FLOATING_POINT()\r
-#endif\r
-\r
/* For backward compatability. */\r
#define eTaskStateGet eTaskGetState\r
\r