From: richardbarry Date: Tue, 30 Apr 2013 20:37:52 +0000 (+0000) Subject: Add FAT SL code and demo project. X-Git-Tag: V7.4.2~2 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6bfaa1e9fe6bdfb24fa1cb3b875e9a54bb872bee;p=freertos Add FAT SL code and demo project. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1879 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h new file mode 100644 index 000000000..04793bec6 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h @@ -0,0 +1,171 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * http://www.freertos.org/a00110.html + * + * The bottom of this file contains some constants specific to running the UDP + * stack in this demo. Constants specific to FreeRTOS+UDP itself (rather than + * the demo) are contained in FreeRTOSIPConfig.h. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 7 ) +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32U * 1024U ) ) +#define configMAX_TASK_NAME_LEN ( 7 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 + +/* Hook function related definitions. */ +#define configUSE_TICK_HOOK 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */ + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* Run time stats gathering definitions. */ +unsigned long ulGetRunTimeCounterValue( void ); +void vConfigureTimerForRunTimeStats( void ); +#define configGENERATE_RUN_TIME_STATS 1 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerTaskHandle 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* Assert call defined for debug builds. */ +#ifdef _DEBUG + extern void vAssertCalled( const char *pcFile, unsigned long ulLine ); + #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ ) +#endif /* _DEBUG */ + + + +/* Application specific definitions follow. **********************************/ + +/* The UDP port to use for incoming command inputs. The outgoing port is +set to ( configUDP_CLI_PORT_NUMBER + 1 ). */ +#define configUDP_CLI_PORT_NUMBER 5001 + +/* The size of the global output buffer that is available for use when there +are multiple command interpreters running at once (for example, one on a UART +and one on TCP/IP). This is done to prevent an output buffer being defined by +each implementation - which would waste RAM. In this case, there is only one +command interpreter running, and it has its own local output buffer, so the +global buffer is just set to be one byte long as it is not used and should not +take up unnecessary RAM. */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h new file mode 100644 index 000000000..373d78092 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_fat_sl.h @@ -0,0 +1,67 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers + * Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of + * the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS, + * and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual + * license model, information on which is provided below: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified and distributed + * without charge provided the user adheres to version two of the GNU General + * Public license (GPL) and does not remove the copyright notice or this text. + * The GPL V2 text is available on the gnu.org web site, and on the following + * URL: http://www.FreeRTOS.org/gpl-2.0.txt + * + * - Commercial licensing - + * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into + * proprietary software for redistribution in any form must first obtain a + * commercial license - and in-so-doing support the maintenance, support and + * further development of the FreeRTOS+FAT SL product. Commercial licenses can + * be obtained from http://shop.freertos.org and do not require any source files + * to be changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _CONFIG_FAT_SL_H +#define _CONFIG_FAT_SL_H + +#include "../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#include "../api/api_mdriver.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************** +** +** FAT SL user settings +** +**************************************************************************/ +#define F_SECTOR_SIZE 512u /* Disk sector size. */ +#define F_FS_THREAD_AWARE 1 /* Set to one if the file system will be access from more than one task. */ +#define F_MAXPATH 64 /* Maximum length a file name (including its full path) can be. */ +#define F_MAX_LOCK_WAIT_TICKS 20 /* The maximum number of RTOS ticks to wait when attempting to obtain a lock on the file system when F_FS_THREAD_AWARE is set to 1. */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CONFIG_FAT_SL_H */ + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h new file mode 100644 index 000000000..1c3ce96e5 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/ConfigurationFiles/config_mdriver_ram.h @@ -0,0 +1,52 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers + * Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of + * the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS, + * and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual + * license model, information on which is provided below: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified and distributed + * without charge provided the user adheres to version two of the GNU General + * Public license (GPL) and does not remove the copyright notice or this text. + * The GPL V2 text is available on the gnu.org web site, and on the following + * URL: http://www.FreeRTOS.org/gpl-2.0.txt + * + * - Commercial licensing - + * Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into + * proprietary software for redistribution in any form must first obtain a + * commercial license - and in-so-doing support the maintenance, support and + * further development of the FreeRTOS+FAT SL product. Commercial licenses can + * be obtained from http://shop.freertos.org and do not require any source files + * to be changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _CONFIG_MDRIVER_RAM_H_ +#define _CONFIG_MDRIVER_RAM_H_ + +#include "../version/ver_mdriver_ram.h" +#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2 + #error Incompatible MDRIVER_RAM version number! +#endif + +#define MDRIVER_RAM_SECTOR_SIZE 512 /* Sector size */ + +#define MDRIVER_RAM_VOLUME0_SIZE (128 * 1024) /* defintion for size of ramdrive0 */ + +#define MDRIVER_MEM_LONG_ACCESS 1 /* set this value to 1 if 32bit access available */ + +#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */ + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c new file mode 100644 index 000000000..0e36e7a6b --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-Releated-CLI-commands.c @@ -0,0 +1,618 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* File system includes. */ +#include "fat_sl.h" +#include "api_mdriver_ram.h" +#include "test.h" + +#ifdef _WINDOWS_ + #define snprintf _snprintf +#endif + +#define cliNEW_LINE "\r\n" + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* + * Print out information on a single file. + */ +static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct ); + +/* + * Copies an existing file into a newly created file. + */ +static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile, + int32_t lSourceFileLength, + int8_t *pcDestinationFile, + int8_t *pxWriteBuffer, + size_t xWriteBufferLen ); + +/* + * Implements the DIR command. + */ +static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the CD command. + */ +static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the DEL command. + */ +static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the TYPE command. + */ +static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the COPY command. + */ +static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the TEST command. + */ +static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* Structure that defines the DIR command line command, which lists all the +files in the current directory. */ +static const CLI_Command_Definition_t xDIR = +{ + ( const int8_t * const ) "dir", /* The command string to type. */ + ( const int8_t * const ) "\r\ndir:\r\n Lists the files in the current directory\r\n", + prvDIRCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the CD command line command, which changes the +working directory. */ +static const CLI_Command_Definition_t xCD = +{ + ( const int8_t * const ) "cd", /* The command string to type. */ + ( const int8_t * const ) "\r\ncd :\r\n Changes the working directory\r\n", + prvCDCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the TYPE command line command, which prints the +contents of a file to the console. */ +static const CLI_Command_Definition_t xTYPE = +{ + ( const int8_t * const ) "type", /* The command string to type. */ + ( const int8_t * const ) "\r\ntype :\r\n Prints file contents to the terminal\r\n", + prvTYPECommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the DEL command line command, which deletes a file. */ +static const CLI_Command_Definition_t xDEL = +{ + ( const int8_t * const ) "del", /* The command string to type. */ + ( const int8_t * const ) "\r\ndel :\r\n deletes a file or directory\r\n", + prvDELCommand, /* The function to run. */ + 1 /* One parameter is expected. */ +}; + +/* Structure that defines the COPY command line command, which deletes a file. */ +static const CLI_Command_Definition_t xCOPY = +{ + ( const int8_t * const ) "copy", /* The command string to type. */ + ( const int8_t * const ) "\r\ncopy :\r\n Copies to \r\n", + prvCOPYCommand, /* The function to run. */ + 2 /* Two parameters are expected. */ +}; + +/* Structure that defines the TEST command line command, which executes some +file system driver tests. */ +static const CLI_Command_Definition_t xTEST_FS = +{ + ( const int8_t * const ) "testfs", /* The command string to type. */ + ( const int8_t * const ) "\r\ntest_fs:\r\n Executes some file system test. ALL FILES WILL BE DELETED!!!\r\n", + prvTESTFSCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/*-----------------------------------------------------------*/ + +void vRegisterFileSystemCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xDIR ); + FreeRTOS_CLIRegisterCommand( &xCD ); + FreeRTOS_CLIRegisterCommand( &xTYPE ); + FreeRTOS_CLIRegisterCommand( &xDEL ); + FreeRTOS_CLIRegisterCommand( &xCOPY ); + FreeRTOS_CLIRegisterCommand( &xTEST_FS ); +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcParameter; +portBASE_TYPE xParameterStringLength, xReturn = pdTRUE; +static F_FILE *pxFile = NULL; +int iChar; +size_t xByte; +size_t xColumns = 50U; + + /* Ensure there is always a null terminator after each character written. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( xWriteBufferLen < xColumns ) + { + /* Ensure the loop that uses xColumns as an end condition does not + write off the end of the buffer. */ + xColumns = xWriteBufferLen; + } + + if( pxFile == NULL ) + { + /* The file has not been opened yet. Find the file name. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to open the requested file. */ + pxFile = f_open( ( const char * ) pcParameter, "r" ); + } + + if( pxFile != NULL ) + { + /* Read the next chunk of data from the file. */ + for( xByte = 0; xByte < xColumns; xByte++ ) + { + iChar = f_getc( pxFile ); + + if( iChar == -1 ) + { + /* No more characters to return. */ + f_close( pxFile ); + pxFile = NULL; + break; + } + else + { + pcWriteBuffer[ xByte ] = ( int8_t ) iChar; + } + } + } + + if( pxFile == NULL ) + { + /* Either the file was not opened, or all the data from the file has + been returned and the file is now closed. */ + xReturn = pdFALSE; + } + + strcat( ( char * ) pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcParameter; +portBASE_TYPE xParameterStringLength; +unsigned char ucReturned; +size_t xStringLength; + + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to move to the requested directory. */ + ucReturned = f_chdir( ( char * ) pcParameter ); + + if( ucReturned == F_NO_ERROR ) + { + sprintf( ( char * ) pcWriteBuffer, "In: " ); + xStringLength = strlen( ( const char * ) pcWriteBuffer ); + f_getcwd( ( char * ) &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Error" ); + } + + strcat( ( char * ) pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +static F_FIND *pxFindStruct = NULL; +unsigned char ucReturned; +portBASE_TYPE xReturn = pdFALSE; + + /* This assumes pcWriteBuffer is long enough. */ + ( void ) pcCommandString; + + /* Ensure the buffer leaves space for the \r\n. */ + configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) ); + xWriteBufferLen -= strlen( cliNEW_LINE ); + + if( pxFindStruct == NULL ) + { + /* This is the first time this function has been executed since the Dir + command was run. Create the find structure. */ + pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) ); + + if( pxFindStruct != NULL ) + { + ucReturned = f_findfirst( "*.*", pxFindStruct ); + + if( ucReturned == F_NO_ERROR ) + { + prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); + xReturn = pdPASS; + } + else + { + snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." ); + } + } + else + { + snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." ); + } + } + else + { + /* The find struct has already been created. Find the next file in + the directory. */ + ucReturned = f_findnext( pxFindStruct ); + + if( ucReturned == F_NO_ERROR ) + { + prvCreateFileInfoString( pcWriteBuffer, pxFindStruct ); + xReturn = pdPASS; + } + else + { + /* There are no more files. Free the find structure. */ + vPortFree( pxFindStruct ); + pxFindStruct = NULL; + + /* No string to return. */ + pcWriteBuffer[ 0 ] = 0x00; + } + } + + strcat( ( char * ) pcWriteBuffer, cliNEW_LINE ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcParameter; +portBASE_TYPE xParameterStringLength; +unsigned char ucReturned; + + /* This function assumes xWriteBufferLen is large enough! */ + ( void ) xWriteBufferLen; + + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Attempt to delete the file. */ + ucReturned = f_delete( ( const char * ) pcParameter ); + + if( ucReturned == F_NO_ERROR ) + { + sprintf( ( char * ) pcWriteBuffer, "%s was deleted", pcParameter ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Error" ); + } + + strcat( ( char * ) pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvTESTFSCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +unsigned portBASE_TYPE uxOriginalPriority; + + /* Avoid compiler warnings. */ + ( void ) xWriteBufferLen; + ( void ) pcCommandString; + + /* Limitations in the interaction with the Windows TCP/IP stack require + the command console to run at the idle priority. Raise the priority for + the duration of the tests to ensure there are not multiple switches to the + idle task as in the simulated environment the idle task hook function may + include a (relatively) long delay. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + + f_dotest( 0 ); + + /* Reset back to the original priority. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + sprintf( ( char * ) pcWriteBuffer, "%s", "Test results were sent to Windows console" ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcSourceFile, *pcDestinationFile; +portBASE_TYPE xParameterStringLength; +long lSourceLength, lDestinationLength = 0; + + /* Obtain the name of the destination file. */ + pcDestinationFile = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 2, /* Return the second parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcDestinationFile ); + + /* Obtain the name of the source file. */ + pcSourceFile = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcSourceFile ); + + /* Terminate the string. */ + pcSourceFile[ xParameterStringLength ] = 0x00; + + /* See if the source file exists, obtain its length if it does. */ + lSourceLength = f_filelength( ( const char * ) pcSourceFile ); + + if( lSourceLength == 0 ) + { + sprintf( ( char * ) pcWriteBuffer, "Source file does not exist" ); + } + else + { + /* See if the destination file exists. */ + lDestinationLength = f_filelength( ( const char * ) pcDestinationFile ); + + if( lDestinationLength != 0 ) + { + sprintf( ( char * ) pcWriteBuffer, "Error: Destination file already exists" ); + } + } + + /* Continue only if the source file exists and the destination file does + not exist. */ + if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) ) + { + if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS ) + { + sprintf( ( char * ) pcWriteBuffer, "Copy made" ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Error during copy" ); + } + } + + strcat( ( char * ) pcWriteBuffer, cliNEW_LINE ); + + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile, + int32_t lSourceFileLength, + int8_t *pcDestinationFile, + int8_t *pxWriteBuffer, + size_t xWriteBufferLen ) +{ +int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining; +F_FILE *pxFile; +portBASE_TYPE xReturn = pdPASS; + + /* NOTE: Error handling has been omitted for clarity. */ + + while( lBytesRead < lSourceFileLength ) + { + /* How many bytes are left? */ + lBytesRemaining = lSourceFileLength - lBytesRead; + + /* How many bytes should be read this time around the loop. Can't + read more bytes than will fit into the buffer. */ + if( lBytesRemaining > ( long ) xWriteBufferLen ) + { + lBytesToRead = ( long ) xWriteBufferLen; + } + else + { + lBytesToRead = lBytesRemaining; + } + + /* Open the source file, seek past the data that has already been + read from the file, read the next block of data, then close the + file again so the destination file can be opened. */ + pxFile = f_open( ( const char * ) pcSourceFile, "r" ); + if( pxFile != NULL ) + { + f_seek( pxFile, lBytesRead, F_SEEK_SET ); + f_read( pxWriteBuffer, lBytesToRead, 1, pxFile ); + f_close( pxFile ); + } + else + { + xReturn = pdFAIL; + break; + } + + /* Open the destination file and write the block of data to the end of + the file. */ + pxFile = f_open( ( const char * ) pcDestinationFile, "a" ); + if( pxFile != NULL ) + { + f_write( pxWriteBuffer, lBytesToRead, 1, pxFile ); + f_close( pxFile ); + } + else + { + xReturn = pdFAIL; + break; + } + + lBytesRead += lBytesToRead; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct ) +{ +const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory"; +const char * pcAttrib; + + /* Point pcAttrib to a string that describes the file. */ + if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 ) + { + pcAttrib = pcDirectory; + } + else if( pxFindStruct->attr & F_ATTR_READONLY ) + { + pcAttrib = pcReadOnlyFile; + } + else + { + pcAttrib = pcWritableFile; + } + + /* Create a string that includes the file name, the file size and the + attributes string. */ + sprintf( ( char * ) pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, pxFindStruct->filesize ); +} diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c new file mode 100644 index 000000000..8f3915b3c --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/File-system-demo.c @@ -0,0 +1,381 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +/******************************************************************************* + * See the URL in the comments within main.c for the location of the online + * documentation. + ******************************************************************************/ + +/* Standard includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" + +/* File system includes. */ +#include "fat_sl.h" +#include "api_mdriver_ram.h" + +/* 8.3 format, plus null terminator. */ +#define fsMAX_FILE_NAME_LEN 13 + +/* The number of bytes read/written to the example files at a time. */ +#define fsRAM_BUFFER_SIZE 200 + +/* The number of bytes written to the file that uses f_putc() and f_getc(). */ +#define fsPUTC_FILE_SIZE 100 + +/*-----------------------------------------------------------*/ + +/* + * Creates and verifies different files on the volume, demonstrating the use of + * various different API functions. + */ +void vCreateAndVerifySampleFiles( void ); + +/* + * Create a set of example files in the root directory of the volume using + * f_write(). + */ +static void prvCreateDemoFilesUsing_f_write( void ); + +/* + * Use f_read() to read back and verify the files that were created by + * prvCreateDemoFilesUsing_f_write(). + */ +static void prvVerifyDemoFileUsing_f_read( void ); + +/* + * Create an example file in a sub-directory using f_putc(). + */ +static void prvCreateDemoFileUsing_f_putc( void ); + +/* + * Use f_getc() to read back and verify the file that was created by + * prvCreateDemoFileUsing_f_putc(). + */ +static void prvVerifyDemoFileUsing_f_getc( void ); + +/*-----------------------------------------------------------*/ + +/* A buffer used to both create content to write to disk, and read content back +from a disk. Note there is no mutual exclusion on this buffer. */ +static char cRAMBuffer[ fsRAM_BUFFER_SIZE ]; + +/* Names of directories that are created. */ +static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2"; + +/*-----------------------------------------------------------*/ + +void vCreateAndVerifySampleFiles( void ) +{ +unsigned char ucStatus; + + /* First create the volume. */ + ucStatus = f_initvolume( ram_initfunc ); + + /* It is expected that the volume is not formatted. */ + if( ucStatus == F_ERR_NOTFORMATTED ) + { + /* Format the created volume. */ + ucStatus = f_format( F_FAT12_MEDIA ); + } + + if( ucStatus == F_NO_ERROR ) + { + /* Create a set of files using f_write(). */ + prvCreateDemoFilesUsing_f_write(); + + /* Read back and verify the files that were created using f_write(). */ + prvVerifyDemoFileUsing_f_read(); + + /* Create sub directories two deep then create a file using putc. */ + prvCreateDemoFileUsing_f_putc(); + + /* Read back and verify the file created by + prvCreateDemoFileUsing_f_putc(). */ + prvVerifyDemoFileUsing_f_getc(); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateDemoFilesUsing_f_write( void ) +{ +portBASE_TYPE xFileNumber, xWriteNumber; +char cFileName[ fsMAX_FILE_NAME_LEN ]; +const portBASE_TYPE xMaxFiles = 5; +long lItemsWritten; +F_FILE *pxFile; + + /* Create xMaxFiles files. Each created file will be + ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled + with a different repeating character. */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate a file name. */ + sprintf( cFileName, "root%03d.txt", xFileNumber ); + + /* Obtain the current working directory and print out the file name and + the directory into which the file is being written. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "Creating file %s in %s\r\n", cFileName, cRAMBuffer ); + + /* Open the file, creating the file if it does not already exist. */ + pxFile = f_open( cFileName, "w" ); + configASSERT( pxFile ); + + /* Fill the RAM buffer with data that will be written to the file. This + is just a repeating ascii character that indicates the file number. */ + memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE ); + + /* Write the RAM buffer to the opened file a number of times. The + number of times the RAM buffer is written to the file depends on the + file number, so the length of each created file will be different. */ + for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ ) + { + lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); + configASSERT( lItemsWritten == 1 ); + } + + /* Close the file so another file can be created. */ + f_close( pxFile ); + } +} +/*-----------------------------------------------------------*/ + +static void prvVerifyDemoFileUsing_f_read( void ) +{ +portBASE_TYPE xFileNumber, xReadNumber; +char cFileName[ fsMAX_FILE_NAME_LEN ]; +const portBASE_TYPE xMaxFiles = 5; +long lItemsRead, lChar; +F_FILE *pxFile; + + /* Read back the files that were created by + prvCreateDemoFilesUsing_f_write(). */ + for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ ) + { + /* Generate the file name. */ + sprintf( cFileName, "root%03d.txt", xFileNumber ); + + /* Obtain the current working directory and print out the file name and + the directory from which the file is being read. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "Reading file %s from %s\r\n", cFileName, cRAMBuffer ); + + /* Open the file for reading. */ + pxFile = f_open( cFileName, "r" ); + configASSERT( pxFile ); + + /* Read the file into the RAM buffer, checking the file contents are as + expected. The size of the file depends on the file number. */ + for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ ) + { + /* Start with the RAM buffer clear. */ + memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE ); + + lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile ); + configASSERT( lItemsRead == 1 ); + + /* Check the RAM buffer is filled with the expected data. Each + file contains a different repeating ascii character that indicates + the number of the file. */ + for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ ) + { + configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) ); + } + } + + /* Close the file. */ + f_close( pxFile ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateDemoFileUsing_f_putc( void ) +{ +unsigned char ucReturn; +int iByte, iReturned; +F_FILE *pxFile; +char cFileName[ fsMAX_FILE_NAME_LEN ]; + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "In directory %s\r\n", cRAMBuffer ); + + /* Create a sub directory. */ + ucReturn = f_mkdir( pcDirectory1 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Move into the created sub-directory. */ + ucReturn = f_chdir( pcDirectory1 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "In directory %s\r\n", cRAMBuffer ); + + /* Create a subdirectory in the new directory. */ + ucReturn = f_mkdir( pcDirectory2 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Move into the directory just created - now two directories down from + the root. */ + ucReturn = f_chdir( pcDirectory2 ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "In directory %s\r\n", cRAMBuffer ); + configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 ); + + /* Generate the file name. */ + sprintf( cFileName, "%s.txt", pcDirectory2 ); + + /* Print out the file name and the directory into which the file is being + written. */ + printf( "Writing file %s in %s\r\n", cFileName, cRAMBuffer ); + + pxFile = f_open( cFileName, "w" ); + + /* Create a file 1 byte at a time. The file is filled with incrementing + ascii characters starting from '0'. */ + for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) + { + iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile ); + configASSERT( iReturned == ( ( int ) '0' + iByte ) ); + } + + /* Finished so close the file. */ + f_close( pxFile ); + + /* Move back to the root directory. */ + ucReturn = f_chdir( "../.." ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "Back in root directory %s\r\n", cRAMBuffer ); + configASSERT( strcmp( ( const char * ) cRAMBuffer, pcRoot ) == 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvVerifyDemoFileUsing_f_getc( void ) +{ +unsigned char ucReturn; +int iByte, iReturned; +F_FILE *pxFile; +char cFileName[ fsMAX_FILE_NAME_LEN ]; + + /* Move into the directory in which the file was created. */ + ucReturn = f_chdir( pcFullPath ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "Back in directory %s\r\n", cRAMBuffer ); + configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 ); + + /* Generate the file name. */ + sprintf( cFileName, "%s.txt", pcDirectory2 ); + + /* Print out the file name and the directory from which the file is being + read. */ + printf( "Reading file %s in %s\r\n", cFileName, cRAMBuffer ); + + /* This time the file is opened for reading. */ + pxFile = f_open( cFileName, "r" ); + + /* Read the file 1 byte at a time. */ + for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ ) + { + iReturned = f_getc( pxFile ); + configASSERT( iReturned == ( ( int ) '0' + iByte ) ); + } + + /* Finished so close the file. */ + f_close( pxFile ); + + /* Move back to the root directory. */ + ucReturn = f_chdir( "../.." ); + configASSERT( ucReturn == F_NO_ERROR ); + + /* Obtain and print out the working directory. */ + f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE ); + printf( "Back in root directory %s\r\n", cRAMBuffer ); +} + + + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln new file mode 100644 index 000000000..3f819af17 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/FreeRTOS_Plus_FAT_SL_with_CLI.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WIN32", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32 + {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url new file mode 100644 index 000000000..9c6b614f1 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/READ_ME.url @@ -0,0 +1,5 @@ +[InternetShortcut] +URL=http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c new file mode 100644 index 000000000..40dca76d1 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Run-time-stats-utils.c @@ -0,0 +1,137 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +/* + * Utility functions required to gather run time statistics. See: + * http://www.freertos.org/rtos-run-time-stats.html + * + * Note that this is a simulated port, where simulated time is a lot slower than + * real time, therefore the run time counter values have no real meaningful + * units. + * + * Also note that it is assumed this demo is going to be used for short periods + * of time only, and therefore timer overflows are not handled. +*/ + +/* FreeRTOS includes. */ +#include + +/* Variables used in the creation of the run time stats time base. Run time +stats record how much time each task spends in the Running state. */ +static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL; + +/*-----------------------------------------------------------*/ + +void vConfigureTimerForRunTimeStats( void ) +{ +LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue; + + /* Initialise the variables used to create the run time stats time base. + Run time stats record how much time each task spends in the Running + state. */ + + if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 ) + { + llTicksPerHundedthMillisecond = 1; + } + else + { + /* How many times does the performance counter increment in 1/100th + millisecond. */ + llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL; + + /* What is the performance counter value now, this will be subtracted + from readings taken at run time. */ + QueryPerformanceCounter( &liInitialRunTimeValue ); + llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart; + } +} +/*-----------------------------------------------------------*/ + +unsigned long ulGetRunTimeCounterValue( void ) +{ +LARGE_INTEGER liCurrentCount; +unsigned long ulReturn; + + /* What is the performance counter value now? */ + QueryPerformanceCounter( &liCurrentCount ); + + /* Subtract the performance counter value reading taken when the + application started to get a count from that reference point, then + scale to (simulated) 1/100ths of a millisecond. */ + ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond ); + + return ulReturn; +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c new file mode 100644 index 000000000..1fccb84f6 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/Sample-CLI-commands.c @@ -0,0 +1,426 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + + /****************************************************************************** + * + * See the following URL for information on the commands defined in this file: + * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml + * + ******************************************************************************/ + + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS + #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0 +#endif + + +/* + * Implements the run-time-stats command. + */ +static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the task-stats command. + */ +static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the echo-three-parameters command. + */ +static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the echo-parameters command. + */ +static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); + +/* + * Implements the "trace start" and "trace stop" commands; + */ +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ); +#endif + +/* Structure that defines the "run-time-stats" command line command. This +generates a table that shows how much run time each task has */ +static const CLI_Command_Definition_t xRunTimeStats = +{ + ( const int8_t * const ) "run-time-stats", /* The command string to type. */ + ( const int8_t * const ) "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n", + prvRunTimeStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "task-stats" command line command. This generates +a table that gives information on each task in the system. */ +static const CLI_Command_Definition_t xTaskStats = +{ + ( const int8_t * const ) "task-stats", /* The command string to type. */ + ( const int8_t * const ) "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n", + prvTaskStatsCommand, /* The function to run. */ + 0 /* No parameters are expected. */ +}; + +/* Structure that defines the "echo_3_parameters" command line command. This +takes exactly three parameters that the command simply echos back one at a +time. */ +static const CLI_Command_Definition_t xThreeParameterEcho = +{ + ( const int8_t * const ) "echo-3-parameters", + ( const int8_t * const ) "\r\necho-3-parameters :\r\n Expects three parameters, echos each in turn\r\n", + prvThreeParameterEchoCommand, /* The function to run. */ + 3 /* Three parameters are expected, which can take any value. */ +}; + +/* Structure that defines the "echo_parameters" command line command. This +takes a variable number of parameters that the command simply echos back one at +a time. */ +static const CLI_Command_Definition_t xParameterEcho = +{ + ( const int8_t * const ) "echo-parameters", + ( const int8_t * const ) "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n", + prvParameterEchoCommand, /* The function to run. */ + -1 /* The user can enter any number of commands. */ +}; + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + /* Structure that defines the "trace" command line command. This takes a single + parameter, which can be either "start" or "stop". */ + static const CLI_Command_Definition_t xStartStopTrace = + { + ( const int8_t * const ) "trace", + ( const int8_t * const ) "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n", + prvStartStopTraceCommand, /* The function to run. */ + 1 /* One parameter is expected. Valid values are "start" and "stop". */ + }; +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ + +/*-----------------------------------------------------------*/ + +void vRegisterSampleCLICommands( void ) +{ + /* Register all the command line commands defined immediately above. */ + FreeRTOS_CLIRegisterCommand( &xTaskStats ); + FreeRTOS_CLIRegisterCommand( &xRunTimeStats ); + FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho ); + FreeRTOS_CLIRegisterCommand( &xParameterEcho ); + + #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 ) + { + FreeRTOS_CLIRegisterCommand( & xStartStopTrace ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +const int8_t *const pcHeader = ( int8_t * ) "Task State Priority Stack #\r\n************************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + write buffer is not NULL. NOTE - for simplicity, this example assumes the + write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); + vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); + + /* There is no more data to return after this single string, so return + pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +const int8_t * const pcHeader = ( int8_t * ) "Task Abs Time % Time\r\n****************************************\r\n"; + + /* Remove compile time warnings about unused parameters, and check the + write buffer is not NULL. NOTE - for simplicity, this example assumes the + write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Generate a table of task stats. */ + strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader ); + vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) ); + + /* There is no more data to return after this single string, so return + pdFALSE. */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcParameter; +portBASE_TYPE xParameterStringLength, xReturn; +static portBASE_TYPE lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + write buffer is not NULL. NOTE - for simplicity, this example assumes the + write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + entered just a header string is returned. */ + sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); + strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* If this is the last of the three parameters then there are no more + strings to return after this one. */ + if( lParameterNumber == 3L ) + { + /* If this is the last of the three parameters then there are no more + strings to return after this one. */ + xReturn = pdFALSE; + lParameterNumber = 0L; + } + else + { + /* There are more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) +{ +int8_t *pcParameter; +portBASE_TYPE xParameterStringLength, xReturn; +static portBASE_TYPE lParameterNumber = 0; + + /* Remove compile time warnings about unused parameters, and check the + write buffer is not NULL. NOTE - for simplicity, this example assumes the + write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + if( lParameterNumber == 0 ) + { + /* The first time the function is called after the command has been + entered just a header string is returned. */ + sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" ); + + /* Next time the function is called the first parameter will be echoed + back. */ + lParameterNumber = 1L; + + /* There is more data to be returned as no parameters have been echoed + back yet. */ + xReturn = pdPASS; + } + else + { + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + lParameterNumber, /* Return the next parameter. */ + &xParameterStringLength /* Store the parameter string length. */ + ); + + if( pcParameter != NULL ) + { + /* Return the parameter string. */ + memset( pcWriteBuffer, 0x00, xWriteBufferLen ); + sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber ); + strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength ); + strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) ); + + /* There might be more parameters to return after this one. */ + xReturn = pdTRUE; + lParameterNumber++; + } + else + { + /* No more parameters were found. Make sure the write buffer does + not contain a valid string. */ + pcWriteBuffer[ 0 ] = 0x00; + + /* No more data to return. */ + xReturn = pdFALSE; + + /* Start over the next time this command is executed. */ + lParameterNumber = 0; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 + + static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString ) + { + int8_t *pcParameter; + portBASE_TYPE lParameterStringLength; + + /* Remove compile time warnings about unused parameters, and check the + write buffer is not NULL. NOTE - for simplicity, this example assumes the + write buffer length is adequate, so does not check for buffer overflows. */ + ( void ) pcCommandString; + ( void ) xWriteBufferLen; + configASSERT( pcWriteBuffer ); + + /* Obtain the parameter string. */ + pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter + ( + pcCommandString, /* The command string itself. */ + 1, /* Return the first parameter. */ + &lParameterStringLength /* Store the parameter string length. */ + ); + + /* Sanity check something was returned. */ + configASSERT( pcParameter ); + + /* There are only two valid parameter values. */ + if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 ) + { + /* Start or restart the trace. */ + vTraceStop(); + vTraceClear(); + vTraceStart(); + + sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" ); + } + else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 ) + { + /* End the trace, if one is running. */ + vTraceStop(); + sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" ); + } + else + { + sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" ); + } + + /* There is no more data to return after this single string, so return + pdFALSE. */ + return pdFALSE; + } + +#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */ diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c new file mode 100644 index 000000000..f5f65cfb0 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/UDPCommandServer.c @@ -0,0 +1,276 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + + +#pragma comment( lib, "ws2_32.lib" ) + +/* Win32 includes. */ +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Standard includes. */ +#include +#include + +/* FreeRTOS+CLI includes. */ +#include "FreeRTOS_CLI.h" + +/* Dimensions the buffer into which input characters are placed. */ +#define cmdMAX_INPUT_SIZE 60 + +/* Dimensions the buffer into which string outputs can be placed. */ +#define cmdMAX_OUTPUT_SIZE 1024 + +/* Dimensions the buffer passed to the recvfrom() call. */ +#define cmdSOCKET_INPUT_BUFFER_SIZE 60 + +/* DEL acts as a backspace. */ +#define cmdASCII_DEL ( 0x7F ) + +/* + * Open and configure the UDP socket. + */ +static SOCKET prvOpenUDPSocket( void ); + +/*-----------------------------------------------------------*/ + +/* + * Task that provides the input and output for the FreeRTOS+CLI command + * interpreter. In this case a WinSock UDP port is used for convenience as this + * demo runs in a simulated environment on a Windows PC. See the URL in the + * comments within main.c for the location of the online documentation. + */ +void vUDPCommandInterpreterTask( void *pvParameters ) +{ +long lBytes, lByte; +signed char cInChar, cInputIndex = 0; +static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ]; +portBASE_TYPE xMoreDataToFollow; +volatile int iErrorCode = 0; +struct sockaddr_in xClient; +int xClientAddressLength = sizeof( struct sockaddr_in ); +SOCKET xSocket; + + /* Just to prevent compiler warnings. */ + ( void ) pvParameters; + + /* Attempt to open the socket. */ + xSocket = prvOpenUDPSocket(); + + if( xSocket != INVALID_SOCKET ) + { + for( ;; ) + { + /* Wait for incoming data on the opened socket. */ + lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength ); + + if( lBytes == SOCKET_ERROR ) + { + /* Something went wrong, but it is not handled by this simple + example. */ + iErrorCode = WSAGetLastError(); + } + else + { + /* Process each received byte in turn. */ + lByte = 0; + while( lByte < lBytes ) + { + /* The next character in the input buffer. */ + cInChar = cLocalBuffer[ lByte ]; + lByte++; + + /* Newline characters are taken as the end of the command + string. */ + if( cInChar == '\n' ) + { + /* Process the input string received prior to the + newline. */ + do + { + /* Pass the string to FreeRTOS+CLI. */ + xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE ); + + /* Send the output generated by the command's + implementation. */ + sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + + } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */ + + /* All the strings generated by the command processing + have been sent. Clear the input string ready to receive + the next command. */ + cInputIndex = 0; + memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); + + /* Transmit a spacer, just to make the command console + easier to read. */ + sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength ); + } + else + { + if( cInChar == '\r' ) + { + /* Ignore the character. Newlines are used to + detect the end of the input string. */ + } + else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) ) + { + /* Backspace was pressed. Erase the last character + in the string - if any. */ + if( cInputIndex > 0 ) + { + cInputIndex--; + cInputString[ cInputIndex ] = '\0'; + } + } + else + { + /* A character was entered. Add it to the string + entered so far. When a \n is entered the complete + string will be passed to the command interpreter. */ + if( cInputIndex < cmdMAX_INPUT_SIZE ) + { + cInputString[ cInputIndex ] = cInChar; + cInputIndex++; + } + } + } + } + } + } + } + else + { + /* The socket could not be opened. */ + vTaskDelete( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static SOCKET prvOpenUDPSocket( void ) +{ +WSADATA xWSAData; +WORD wVersionRequested; +struct sockaddr_in xServer; +SOCKET xSocket = INVALID_SOCKET; + + wVersionRequested = MAKEWORD( 2, 2 ); + + /* Prepare to use WinSock. */ + if( WSAStartup( wVersionRequested, &xWSAData ) != 0 ) + { + fprintf( stderr, "Could not open Windows connection.\n" ); + } + else + { + xSocket = socket( AF_INET, SOCK_DGRAM, 0 ); + if( xSocket == INVALID_SOCKET) + { + fprintf( stderr, "Could not create socket.\n" ); + WSACleanup(); + } + else + { + /* Zero out the server structure. */ + memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) ); + + /* Set family and port. */ + xServer.sin_family = AF_INET; + xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER ); + + /* Assign the loopback address */ + xServer.sin_addr.S_un.S_un_b.s_b1 = 127; + xServer.sin_addr.S_un.S_un_b.s_b2 = 0; + xServer.sin_addr.S_un.S_un_b.s_b3 = 0; + xServer.sin_addr.S_un.S_un_b.s_b4 = 1; + + /* Bind the address to the socket. */ + if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 ) + { + fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER ); + closesocket( xSocket ); + xSocket = INVALID_SOCKET; + WSACleanup(); + } + } + } + + return xSocket; +} + + diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj new file mode 100644 index 000000000..294c69b3c --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {C686325E-3261-42F7-AEB1-DDE5280E1CEB} + RTOSDemo + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\ + .\Debug\ + true + .\Release\ + .\Release\ + false + + + + .\Debug/WIN32.tlb + + + + + Disabled + ..\..\..\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) + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/WIN32.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level4 + true + false + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Debug/RTOSDemo.exe + true + true + .\Debug/WIN32.pdb + Console + MachineX86 + %(AdditionalDependencies) + .\WinPCap + + + true + .\Debug/WIN32.bsc + + + + + .\Release/WIN32.tlb + + + + + MaxSpeed + OnlyExplicitInline + _WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/WIN32.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + ..\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) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c09 + + + .\Release/RTOSDemo.exe + true + .\Release/WIN32.pdb + Console + MachineX86 + ..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap + wpcap.lib;%(AdditionalDependencies) + + + true + .\Release/WIN32.bsc + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters new file mode 100644 index 000000000..e230fae6d --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.filters @@ -0,0 +1,177 @@ + + + + + {38712199-cebf-4124-bf15-398f7c3419ea} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {af3445a1-4908-4170-89ed-39345d90d30c} + + + {f32be356-4763-4cae-9020-974a2638cb08} + *.c + + + {88f409e6-d396-4ac5-94bd-7a99c914be46} + + + {e5ad4ec7-23dc-4295-8add-2acaee488f5a} + + + {fd43c0ed-fdbc-437f-a5a3-c50399690bd7} + + + {c5889fe2-af0f-4cea-927f-6a6935ec5e14} + + + {d261611a-5416-4455-bb33-3bd84381ea40} + + + {17c1a794-a4a6-4358-850f-2a88bfe3bd33} + + + {fb7ccc1d-c4ad-475a-98d9-2e8ae2301c99} + + + {34bb4a98-fb88-41fc-81f2-4e3f1c50c528} + + + {286bf65c-93cd-4480-8363-0fb2c2bc7ce1} + + + {19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4} + h;hpp;hxx;hm;inl + + + {e4105d81-802a-4210-b40b-d5dd3cf6e643} + + + {ab23827c-126c-4e5a-bc99-8efa44d8a8bd} + + + {9e1c9cf5-c2c7-4f8d-b09d-0b7f329eac57} + + + + + FreeRTOS\Source\Portable + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source + + + FreeRTOS\Source\Portable + + + FreeRTOS+\FreeRTOS+CLI + + + FreeRTOS+\FreeRTOS+FAT SL\Media_Driver + + + FreeRTOS+\FreeRTOS+FAT SL\psp\target\rtc + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + + + + + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL\tests + + + FreeRTOS+\FreeRTOS+FAT SL + + + + + Configuration Files + + + FreeRTOS+\FreeRTOS+CLI\include + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + FreeRTOS+\FreeRTOS+FAT SL + + + Configuration Files + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS\Source\include + + + FreeRTOS+\FreeRTOS+FAT SL\api + + + FreeRTOS+\FreeRTOS+FAT SL + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/WIN32.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c new file mode 100644 index 000000000..392507267 --- /dev/null +++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_FAT_SL_and_CLI_Windows_Simulator/main.c @@ -0,0 +1,237 @@ +/* + FreeRTOS V7.4.0 - Copyright (C) 2013 Real Time Engineers Ltd. + + FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT + http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + + >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. You should have received a copy of the GNU General Public License + and the FreeRTOS license exception along with FreeRTOS; if not itcan be + viewed here: http://www.freertos.org/a00114.html and also obtained by + writing to Real Time Engineers Ltd., contact details for whom are available + on the FreeRTOS WEB site. + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, and our new + fully thread aware and reentrant UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems, who sell the code with commercial support, + indemnification and middleware, under the OpenRTOS brand. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. +*/ + +/****************************************************************************** + * + * This demo is described on the following web page: + * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml + * + ******************************************************************************/ + +/* Standard includes. */ +#include +#include + +/* FreeRTOS includes. */ +#include +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* File system includes. */ +#include "config_fat_sl.h" + +/* Priorities at which the tasks are created. */ +#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/*-----------------------------------------------------------*/ + +/* + * Register the generic commands that can be used with FreeRTOS+CLI. + */ +extern void vRegisterSampleCLICommands( void ); + +/* + * Register the file system commands that can be used with FreeRTOS+CLI. + */ +extern void vRegisterFileSystemCLICommands( void ); + +/* + * The task that implements the UDP command interpreter using FreeRTOS+CLI. + */ +extern void vUDPCommandInterpreterTask( void *pvParameters ); + +/* + * Creates and verifies different files on the volume, demonstrating the use of + * various different API functions. + */ +extern void vCreateAndVerifySampleFiles( void ); + +/*-----------------------------------------------------------*/ + +/****************************************************************************** + * + * This demo is described on the following web page: + * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/Demos/File_System_Win32_Simulator_demo.shtml + * + ******************************************************************************/ + +int main( void ) +{ +const uint32_t ulLongTime_ms = 250UL; + + /* If the file system is only going to be accessed from one task then + F_FS_THREAD_AWARE can be set to 0 and the set of example files are created + before the RTOS scheduler is started. If the file system is going to be + access from more than one task then F_FS_THREAD_AWARE must be set to 1 and + the set of sample files are created from the idle task hook function + vApplicationIdleHook() - which is defined in this file. */ + #if F_FS_THREAD_AWARE == 0 + { + /* Initialise the drive and file system, then create a few example + files. The output from this function just goes to the stdout window, + allowing the output to be viewed when the UDP command console is not + connected. */ + vCreateAndVerifySampleFiles(); + } + #endif + + /* Register generic commands with the FreeRTOS+CLI command interpreter. */ + vRegisterSampleCLICommands(); + + /* Register file system related commands with the FreeRTOS+CLI command + interpreter. */ + vRegisterFileSystemCLICommands(); + + /* Create the task that handles the CLI on a UDP port. The port number + is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ + xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */ + ( signed char * ) "CLI", /* The name of the task - just to assist debugging. */ + configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */ + mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */ + NULL ); /* A handle to the task is not required, so NULL is passed. */ + + /* Start the RTOS scheduler. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details (this is standard text that is not not + really applicable to the Win32 simulator port). */ + for( ;; ) + { + Sleep( ulLongTime_ms ); + } +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ +const unsigned long ulMSToSleep = 5; + + /* If the file system is only going to be accessed from one task then + F_FS_THREAD_AWARE can be set to 0 and the set of example files is created + before the RTOS scheduler is started. If the file system is going to be + access from more than one task then F_FS_THREAD_AWARE must be set to 1 and + the set of sample files are created from the idle task hook function. */ + #if F_FS_THREAD_AWARE == 1 + { + static portBASE_TYPE xCreatedSampleFiles = pdFALSE; + + /* Initialise the drive and file system, then create a few example + files. The output from this function just goes to the stdout window, + allowing the output to be viewed when the UDP command console is not + connected. */ + if( xCreatedSampleFiles == pdFALSE ) + { + vCreateAndVerifySampleFiles(); + xCreatedSampleFiles = pdTRUE; + } + } + #endif + + /* This function is called on each cycle of the idle task if + configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU + load. */ + Sleep( ulMSToSleep ); +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( const char *pcFile, unsigned long ulLine ) +{ + printf( "ASSERT FAILED: File %s, line %u\r\n", pcFile, ulLine ); +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the + size of the heap available to pvPortMalloc() is defined by + configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize() + API function can be used to query the size of free heap space that remains + (although it does not provide information on how the remaining heap might + be fragmented). */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} + + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url new file mode 100644 index 000000000..c0924c38f --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/ReadMe.url @@ -0,0 +1,5 @@ +[InternetShortcut] +URL=http://www.freertos.org/fat +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h new file mode 100644 index 000000000..c10ffec07 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver.h @@ -0,0 +1,102 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _API_MDRIVER_H_ +#define _API_MDRIVER_H_ + +#include "../version/ver_mdriver.h" +#if VER_MDRIVER_MAJOR != 1 || VER_MDRIVER_MINOR != 0 + #error Incompatible MDRIVER version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct +{ + unsigned short number_of_cylinders; + unsigned short sector_per_track; + unsigned short number_of_heads; + unsigned long number_of_sectors; + unsigned char media_descriptor; + + unsigned short bytes_per_sector; +} F_PHY; + +/* media descriptor to be set in getphy function */ +#define F_MEDIADESC_REMOVABLE 0xf0 +#define F_MEDIADESC_FIX 0xf8 + +/* return bitpattern for driver getphy function */ +#define F_ST_MISSING 0x00000001 +#define F_ST_CHANGED 0x00000002 +#define F_ST_WRPROTECT 0x00000004 + +/* Driver definitions */ +typedef struct F_DRIVER F_DRIVER; + +typedef int ( *F_WRITESECTOR )( F_DRIVER * driver, void * data, unsigned long sector ); +typedef int ( *F_READSECTOR )( F_DRIVER * driver, void * data, unsigned long sector ); +typedef int ( *F_GETPHY )( F_DRIVER * driver, F_PHY * phy ); +typedef long ( *F_GETSTATUS )( F_DRIVER * driver ); +typedef void ( *F_RELEASE )( F_DRIVER * driver ); + +typedef struct F_DRIVER +{ + unsigned long user_data; /* user defined data */ + void * user_ptr; /* user define pointer */ + + /* driver functions */ + F_WRITESECTOR writesector; + F_READSECTOR readsector; + F_GETPHY getphy; + F_GETSTATUS getstatus; + F_RELEASE release; +} _F_DRIVER; + +typedef F_DRIVER *( *F_DRIVERINIT )( unsigned long driver_param ); + +#ifdef __cplusplus +} +#endif + +#endif /* _API_MDRIVER_H_ */ + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h new file mode 100644 index 000000000..46dd1c61e --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/api_mdriver_ram.h @@ -0,0 +1,70 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _API_MDRIVER_RAM_H_ +#define _API_MDRIVER_RAM_H_ + +#include "api_mdriver.h" + +#include "../version/ver_mdriver_ram.h" +#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2 + #error Incompatible MDRIVER_RAM version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define F_RAM_DRIVE0 0 + +enum +{ + MDRIVER_RAM_NO_ERROR + , MDRIVER_RAM_ERR_SECTOR = 101 + , MDRIVER_RAM_ERR_NOTAVAILABLE +}; + +F_DRIVER * ram_initfunc ( unsigned long driver_param ); + +#ifdef __cplusplus +} +#endif + + +#endif /* _API_MDRIVER_RAM_H_ */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h new file mode 100644 index 000000000..f80ef2784 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/api/fat_sl.h @@ -0,0 +1,479 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _API_FAT_SL_H_ +#define _API_FAT_SL_H_ + +#include "config_fat_sl.h" + +#include "../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define F_MAXNAME 8 /* 8 byte name */ +#define F_MAXEXT 3 /* 3 byte extension */ + +typedef struct +{ + char path[F_MAXPATH]; /* /directory1/dir2/ */ + char filename[F_MAXNAME]; /* filename */ + char fileext[F_MAXEXT]; /* extension */ +} F_NAME; + +typedef struct +{ + unsigned long cluster; + unsigned long sector; + unsigned long sectorend; + unsigned long pos; +} F_POS; + +typedef struct +{ + char filename[F_MAXPATH]; /*file name+ext*/ + char name[F_MAXNAME]; /*file name*/ + char ext[F_MAXEXT]; /*file extension*/ + unsigned char attr; /*attribute of the file*/ + + unsigned short ctime; /*creation time*/ + unsigned short cdate; /*creation date*/ + unsigned long cluster; + + long filesize; /*length of file*/ + + F_NAME findfsname; /*find properties*/ + F_POS pos; +} F_FIND; + +/* definitions for ctime */ +#define F_CTIME_SEC_SHIFT 0 +#define F_CTIME_SEC_MASK 0x001f /*0-30 in 2seconds*/ +#define F_CTIME_MIN_SHIFT 5 +#define F_CTIME_MIN_MASK 0x07e0 /*0-59 */ +#define F_CTIME_HOUR_SHIFT 11 +#define F_CTIME_HOUR_MASK 0xf800 /*0-23*/ + + +/* definitions for cdate */ +#define F_CDATE_DAY_SHIFT 0 +#define F_CDATE_DAY_MASK 0x001f /*0-31*/ +#define F_CDATE_MONTH_SHIFT 5 +#define F_CDATE_MONTH_MASK 0x01e0 /*1-12*/ +#define F_CDATE_YEAR_SHIFT 9 +#define F_CDATE_YEAR_MASK 0xfe00 /*0-119 (1980+value)*/ + +#define F_ATTR_ARC 0x20 +#define F_ATTR_DIR 0x10 +#define F_ATTR_VOLUME 0x08 +#define F_ATTR_SYSTEM 0x04 +#define F_ATTR_HIDDEN 0x02 +#define F_ATTR_READONLY 0x01 + +#define F_CLUSTER_FREE ( (unsigned long)0x00000000 ) +#define F_CLUSTER_RESERVED ( (unsigned long)0x0ffffff0 ) +#define F_CLUSTER_BAD ( (unsigned long)0x0ffffff7 ) +#define F_CLUSTER_LAST ( (unsigned long)0x0ffffff8 ) +#define F_CLUSTER_LASTF32R ( (unsigned long)0x0fffffff ) + +#define F_ST_MISSING 0x00000001 +#define F_ST_CHANGED 0x00000002 +#define F_ST_WRPROTECT 0x00000004 + +typedef struct +{ + unsigned long abspos; + unsigned long filesize; + unsigned long startcluster; + unsigned long prevcluster; + unsigned long relpos; + unsigned char modified; + unsigned char mode; + unsigned char _tdata[F_SECTOR_SIZE]; + F_POS pos; + F_POS dirpos; +#if F_FILE_CHANGED_EVENT + char filename[F_MAXPATH]; /* filename with full path */ +#endif +} F_FILE; + +enum +{ + F_UNKNOWN_MEDIA + , F_FAT12_MEDIA + , F_FAT16_MEDIA + , F_FAT32_MEDIA +}; + +enum +{ +/* 0 */ + F_NO_ERROR, + +/* 1 */ F_ERR_RESERVED_1, + +/* 2 */ F_ERR_NOTFORMATTED, + +/* 3 */ F_ERR_INVALIDDIR, + +/* 4 */ F_ERR_INVALIDNAME, + +/* 5 */ F_ERR_NOTFOUND, + +/* 6 */ F_ERR_DUPLICATED, + +/* 7 */ F_ERR_NOMOREENTRY, + +/* 8 */ F_ERR_NOTOPEN, + +/* 9 */ F_ERR_EOF, + +/* 10 */ F_ERR_RESERVED_2, + +/* 11 */ F_ERR_NOTUSEABLE, + +/* 12 */ F_ERR_LOCKED, + +/* 13 */ F_ERR_ACCESSDENIED, + +/* 14 */ F_ERR_NOTEMPTY, + +/* 15 */ F_ERR_INITFUNC, + +/* 16 */ F_ERR_CARDREMOVED, + +/* 17 */ F_ERR_ONDRIVE, + +/* 18 */ F_ERR_INVALIDSECTOR, + +/* 19 */ F_ERR_READ, + +/* 20 */ F_ERR_WRITE, + +/* 21 */ F_ERR_INVALIDMEDIA, + +/* 22 */ F_ERR_BUSY, + +/* 23 */ F_ERR_WRITEPROTECT, + +/* 24 */ F_ERR_INVFATTYPE, + +/* 25 */ F_ERR_MEDIATOOSMALL, + +/* 26 */ F_ERR_MEDIATOOLARGE, + +/* 27 */ F_ERR_NOTSUPPSECTORSIZE + +/* 28 */, F_ERR_ALLOCATION + +#if F_FS_THREAD_AWARE == 1 +/* 29 */, F_ERR_OS = 29 +#endif /* F_FS_THREAD_AWARE */ +}; + +typedef struct +{ + unsigned long total; + unsigned long free; + unsigned long used; + unsigned long bad; + + unsigned long total_high; + unsigned long free_high; + unsigned long used_high; + unsigned long bad_high; +} F_SPACE; + +enum +{ + F_SEEK_SET /*Beginning of file*/ + , F_SEEK_CUR /*Current position of file pointer*/ + , F_SEEK_END /*End of file*/ +}; + + +/**************************************************************************** + * + * for file changed events + * + ***************************************************************************/ +#ifndef F_FILE_CHANGED_EVENT + #define F_FILE_CHANGED_EVENT 0 +#endif + +#if F_FILE_CHANGED_EVENT + +typedef struct +{ + unsigned char action; + unsigned char flags; + unsigned char attr; + unsigned short ctime; + unsigned short cdate; + unsigned long filesize; + char filename[F_MAXPATH]; +} ST_FILE_CHANGED; + +typedef void ( *F_FILE_CHANGED_EVENTFUNC )( ST_FILE_CHANGED * fc ); + +extern F_FILE_CHANGED_EVENTFUNC f_filechangedevent; + + #define f_setfilechangedevent( filechangeevent ) f_filechangedevent = filechangeevent + +/* flags */ + + #define FFLAGS_NONE 0x00000000 + + #define FFLAGS_FILE_NAME 0x00000001 + #define FFLAGS_DIR_NAME 0x00000002 + #define FFLAGS_NAME 0x00000003 + #define FFLAGS_ATTRIBUTES 0x00000004 + #define FFLAGS_SIZE 0x00000008 + #define FFLAGS_LAST_WRITE 0x00000010 + +/* actions */ + + #define FACTION_ADDED 0x00000001 + #define FACTION_REMOVED 0x00000002 + #define FACTION_MODIFIED 0x00000003 + +#endif /* if F_FILE_CHANGED_EVENT */ + +unsigned char fn_initvolume ( F_DRIVERINIT initfunc ); +unsigned char fn_delvolume ( void ); + +unsigned char fn_getfreespace ( F_SPACE * pspace ); + +unsigned char fn_chdir ( const char * dirname ); +unsigned char fn_mkdir ( const char * dirname ); +unsigned char fn_rmdir ( const char * dirname ); + +unsigned char fn_findfirst ( const char * filename, F_FIND * find ); +unsigned char fn_findnext ( F_FIND * find ); + +long fn_filelength ( const char * filename ); + +unsigned char fn_close ( F_FILE * filehandle ); +F_FILE * fn_open ( const char * filename, const char * mode ); + +long fn_read ( void * buf, long size, long _size_t, F_FILE * filehandle ); + +long fn_write ( const void * buf, long size, long _size_t, F_FILE * filehandle ); + +unsigned char fn_seek ( F_FILE * filehandle, long offset, unsigned char whence ); + +long fn_tell ( F_FILE * filehandle ); +int fn_getc ( F_FILE * filehandle ); +int fn_putc ( int ch, F_FILE * filehandle ); +unsigned char fn_rewind ( F_FILE * filehandle ); +unsigned char fn_eof ( F_FILE * filehandle ); + +unsigned char fn_delete ( const char * filename ); + +unsigned char fn_seteof ( F_FILE * ); + +F_FILE * fn_truncate ( const char *, long ); + +unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root ); + +unsigned char fn_hardformat ( unsigned char fattype ); +unsigned char fn_format ( unsigned char fattype ); + +unsigned char fn_getserial ( unsigned long * ); + + +#if F_FS_THREAD_AWARE == 1 + +#include "FreeRTOS.h" +#include "semphr.h" +#ifndef FS_MUTEX_DEFINED + extern xSemaphoreHandle fs_lock_semaphore; +#endif /* FS_MUTEX_DEFINED */ + +unsigned char fn_init ( void ); +#define f_init fn_init +#define f_initvolume fn_initvolume +#define f_delvolume fn_delvolume + +unsigned char fr_hardformat ( unsigned char fattype ); +#define f_hardformat( fattype ) fr_hardformat( fattype ) +#define f_format( fattype ) fr_hardformat( fattype ) + +unsigned char fr_getcwd ( char * buffer, unsigned char maxlen, char root ); +#define f_getcwd( buffer, maxlen ) fr_getcwd( buffer, maxlen, 1 ) + +unsigned char fr_getfreespace ( F_SPACE * pspace ); +#define f_getfreespace fr_getfreespace + + +unsigned char fr_chdir ( const char * dirname ); +#define f_chdir( dirname ) fr_chdir( dirname ) +unsigned char fr_mkdir ( const char * dirname ); +#define f_mkdir( dirname ) fr_mkdir( dirname ) +unsigned char fr_rmdir ( const char * dirname ); +#define f_rmdir( dirname ) fr_rmdir( dirname ) + +unsigned char fr_findfirst ( const char * filename, F_FIND * find ); +unsigned char fr_findnext ( F_FIND * find ); +#define f_findfirst( filename, find ) fr_findfirst( filename, find ) +#define f_findnext( find ) fr_findnext( find ) + +long fr_filelength ( const char * filename ); +#define f_filelength( filename ) fr_filelength( filename ) + +unsigned char fr_close ( F_FILE * filehandle ); +F_FILE * fr_open ( const char * filename, const char * mode ); + +long fr_read ( void * buf, long size, long _size_t, F_FILE * filehandle ); + +unsigned char fr_getserial ( unsigned long * ); +#define f_getserial( serial ) fr_getserial( serial ) + +unsigned char fr_flush ( F_FILE * f ); +#define f_flush( filehandle ) fr_flush( filehandle ) + +long fr_write ( const void * buf, long size, long _size_t, F_FILE * filehandle ); +#define f_write( buf, size, _size_t, filehandle ) fr_write( buf, size, _size_t, filehandle ) + +unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence ); +#define f_seek( filehandle, offset, whence ) fr_seek( filehandle, offset, whence ) + +long fr_tell ( F_FILE * filehandle ); +#define f_tell( filehandle ) fr_tell( filehandle ) +int fr_getc ( F_FILE * filehandle ); +#define f_getc( filehandle ) fr_getc( filehandle ) +int fr_putc ( int ch, F_FILE * filehandle ); +#define f_putc( ch, filehandle ) fr_putc( ch, filehandle ) +unsigned char fr_rewind ( F_FILE * filehandle ); +#define f_rewind( filehandle ) fr_rewind( filehandle ) +unsigned char fr_eof ( F_FILE * filehandle ); +#define f_eof( filehandle ) fr_eof( filehandle ) + +unsigned char fr_delete ( const char * filename ); +#define f_delete( filename ) fr_delete( filename ) + +unsigned char fr_seteof ( F_FILE * ); +#define f_seteof( file ) fr_seteof( file ) + +F_FILE * fr_truncate ( const char *, long ); +#define f_truncate( filename, filesize ) fr_truncate( filename, filesize ) + +#define f_close( filehandle ) fr_close( filehandle ) +#define f_open( filename, mode ) fr_open( filename, mode ) +#define f_read( buf, size, _size_t, filehandle ) fr_read( buf, size, _size_t, filehandle ) + +#else /* F_FS_THREAD_AWARE */ + +unsigned char fn_init ( void ); +#define f_init fn_init +#define f_initvolume fn_initvolume +#define f_delvolume fn_delvolume + +#define f_hardformat( fattype ) fn_hardformat( fattype ) +#define f_format( fattype ) fn_hardformat( fattype ) + +#define f_getcwd( buffer, maxlen ) fn_getcwd( buffer, maxlen, 1 ) + +unsigned char fn_getfreespace ( F_SPACE * pspace ); +#define f_getfreespace fn_getfreespace + + +unsigned char fn_chdir ( const char * dirname ); +#define f_chdir( dirname ) fn_chdir( dirname ) +unsigned char fn_mkdir ( const char * dirname ); +#define f_mkdir( dirname ) fn_mkdir( dirname ) +unsigned char fn_rmdir ( const char * dirname ); +#define f_rmdir( dirname ) fn_rmdir( dirname ) + +unsigned char fn_findfirst ( const char * filename, F_FIND * find ); +unsigned char fn_findnext ( F_FIND * find ); +#define f_findfirst( filename, find ) fn_findfirst( filename, find ) +#define f_findnext( find ) fn_findnext( find ) + +#define f_filelength( filename ) fn_filelength( filename ) + +#define f_getserial( serial ) fn_getserial( serial ) + +unsigned char fn_flush ( F_FILE * f ); +#define f_flush( filehandle ) fn_flush( filehandle ) + +#define f_write( buf, size, _size_t, filehandle ) fn_write( buf, size, _size_t, filehandle ) + +#define f_seek( filehandle, offset, whence ) fn_seek( filehandle, offset, whence ) + +long fn_tell ( F_FILE * filehandle ); +#define f_tell( filehandle ) fn_tell( filehandle ) +int fn_getc ( F_FILE * filehandle ); +#define f_getc( filehandle ) fn_getc( filehandle ) +int fn_putc ( int ch, F_FILE * filehandle ); +#define f_putc( ch, filehandle ) fn_putc( ch, filehandle ) +unsigned char fn_rewind ( F_FILE * filehandle ); +#define f_rewind( filehandle ) fn_rewind( filehandle ) +unsigned char fn_eof ( F_FILE * filehandle ); +#define f_eof( filehandle ) fn_eof( filehandle ) + +unsigned char fn_delete ( const char * filename ); +#define f_delete( filename ) fn_delete( filename ) + +unsigned char fn_seteof ( F_FILE * ); +#define f_seteof( file ) fn_seteof( file ) + +F_FILE * fn_truncate ( const char *, long ); +#define f_truncate( filename, filesize ) fn_truncate( filename, filesize ) + +#define f_close( filehandle ) fn_close( filehandle ) +#define f_open( filename, mode ) fn_open( filename, mode ) +#define f_read( buf, size, _size_t, filehandle ) fn_read( buf, size, _size_t, filehandle ) + +#endif /* F_FS_THREAD_AWARE */ + +/**************************************************************************** + * + * end of fat_sl.h + * + ***************************************************************************/ +#ifdef __cplusplus +} +#endif + +#endif /*_API_FAT_SL_H_*/ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h new file mode 100644 index 000000000..2ecf56966 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_fat_sl_template.h @@ -0,0 +1,69 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _CONFIG_FAT_SL_H +#define _CONFIG_FAT_SL_H + +#include "../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#include "../api/api_mdriver.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************** +** +** FAT SL user settings +** +**************************************************************************/ +#define F_SECTOR_SIZE 512u /* Disk sector size. */ +#define F_FS_THREAD_AWARE 1 /* Set to one if the file system will be access from more than one task. */ +#define F_MAXPATH 64 /* Maximum length a file name (including its full path) can be. */ +#define F_MAX_LOCK_WAIT_TICKS 20 /* The maximum number of RTOS ticks to wait when attempting to obtain a lock on the file system when F_FS_THREAD_AWARE is set to 1. */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CONFIG_FAT_SL_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h new file mode 100644 index 000000000..5912ed04d --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/config/config_mdriver_ram_template.h @@ -0,0 +1,54 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _CONFIG_MDRIVER_RAM_H_ +#define _CONFIG_MDRIVER_RAM_H_ + +#include "../version/ver_mdriver_ram.h" +#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2 + #error Incompatible MDRIVER_RAM version number! +#endif + +#define MDRIVER_RAM_SECTOR_SIZE 512 /* Sector size */ + +#define MDRIVER_RAM_VOLUME0_SIZE (128 * 1024) /* defintion for size of ramdrive0 */ + +#define MDRIVER_MEM_LONG_ACCESS 1 /* set this value to 1 if 32bit access available */ + +#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c new file mode 100644 index 000000000..815db86a9 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.c @@ -0,0 +1,1219 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" +#include "../../psp/include/psp_string.h" + +#include "dir.h" +#include "util.h" +#include "volume.h" +#include "drv.h" +#include "fat.h" +#include "file.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + + +/**************************************************************************** + * + * _f_findfilewc + * + * internal function to finding file in directory entry with or without + * wildcard + * + * INPUTS + * + * name - filename + * ext - fileextension + * pos - where to start searching, and contains current position + * pde - store back the directory entry pointer + * wc - wildcard checking? + * + * RETURNS + * + * 0 - if file was not found + * 1 - if file was found + * + ***************************************************************************/ +unsigned char _f_findfilewc ( char * name, char * ext, F_POS * pos, F_DIRENTRY * * pde, unsigned char wc ) +{ + while ( pos->cluster < F_CLUSTER_RESERVED ) + { + for ( ; pos->sector < pos->sectorend ; pos->sector++ ) + { + F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos ); + + if ( _f_readglsector( pos->sector ) ) + { + return 0; /*not found*/ + } + + for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ ) + { + unsigned char b, ok; + + if ( !de->name[0] ) + { + return 0; /*empty*/ + } + + if ( (unsigned char)( de->name[0] ) == 0xe5 ) + { + continue; /*deleted*/ + } + + if ( de->attr & F_ATTR_VOLUME ) + { + continue; + } + + if ( wc ) + { + for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ ) + { + if ( name[b] == '*' ) + { + break; + } + + if ( name[b] != '?' ) + { + if ( de->name[b] != name[b] ) + { + ok = 0; + break; + } + } + } + + if ( ok ) + { + for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ ) + { + if ( ext[b] == '*' ) + { + if ( pde ) + { + *pde = de; + } + + return 1; + } + + if ( ext[b] != '?' ) + { + if ( de->ext[b] != ext[b] ) + { + ok = 0; + break; + } + } + } + + if ( ok ) + { + if ( pde ) + { + *pde = de; + } + + return 1; + } + } + } + else + { + for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ ) + { + if ( de->name[b] != name[b] ) + { + ok = 0; + break; + } + } + + if ( ok ) + { + for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ ) + { + if ( de->ext[b] != ext[b] ) + { + ok = 0; + break; + } + } + + if ( ok ) + { + if ( pde ) + { + *pde = de; + } + + return 1; + } + } + } + } + + pos->pos = 0; + } + + if ( !pos->cluster ) + { + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + pos->cluster = gl_volume.bootrecord.rootcluster; + } + else + return 0; + } + + { + unsigned long nextcluster; + gl_volume.fatsector = (unsigned long)-1; + if ( _f_getclustervalue( pos->cluster, &nextcluster ) ) + { + return 0; /*not found*/ + } + + if ( nextcluster >= F_CLUSTER_RESERVED ) + { + return 0; /*eof*/ + } + + _f_clustertopos( nextcluster, pos ); + } + } /* _f_findfilewc */ + + return 0; +} + + +/**************************************************************************** + * + * _f_getfilename + * + * create a complete filename from name and extension + * + * INPUTS + * + * dest - where to store filename + * name - name of the file + * ext - extension of the file + * + ***************************************************************************/ +static void _f_getfilename ( char * dest, char * name, char * ext ) +{ + unsigned char a, len; + + for ( len = a = F_MAXNAME ; a ; a--, len-- ) + { + if ( name[a - 1] != ' ' ) + { + break; + } + } + + for ( a = 0 ; a < len ; a++ ) + { + *dest++ = *name++; + } + + + for ( len = a = F_MAXEXT ; a ; a--, len-- ) + { + if ( ext[a - 1] != ' ' ) + { + break; + } + } + + if ( len ) + { + *dest++ = '.'; + } + + for ( a = 0 ; a < len ; a++ ) + { + *dest++ = *ext++; + } + + *dest = 0; /*terminateit*/ +} /* _f_getfilename */ + + + + +/**************************************************************************** + * + * _f_getdecluster + * + * get a directory entry structure start cluster value + * + * INPUTS + * + * de - directory entry + * + * RETURNS + * + * directory entry cluster value + * + ***************************************************************************/ +unsigned long _f_getdecluster ( F_DIRENTRY * de ) +{ + unsigned long cluster; + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + cluster = _f_getword( &de->clusterhi ); + cluster <<= 16; + cluster |= _f_getword( &de->clusterlo ); + return cluster; + } + + return _f_getword( &de->clusterlo ); +} + + +/**************************************************************************** + * + * _f_setdecluster + * + * set a directory entry structure start cluster value + * + * INPUTS + * + * de - directory entry + * cluster - value of the start cluster + * + ***************************************************************************/ +void _f_setdecluster ( F_DIRENTRY * de, unsigned long cluster ) +{ + _f_setword( &de->clusterlo, (unsigned short)( cluster & 0xffff ) ); + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + _f_setword( &de->clusterhi, (unsigned short)( cluster >> 16 ) ); + } + else + { + _f_setword( &de->clusterhi, (unsigned short)0 ); + } +} + + +/**************************************************************************** + * + * _f_findpath + * + * finding out if path is valid in F_NAME and + * correct path info with absolute path (removes relatives) + * + * INPUTS + * + * fsname - filled structure with path,drive + * pos - where to start searching, and contains current position + * + * RETURNS + * + * 0 - if path was not found or invalid + * 1 - if path was found + * + ***************************************************************************/ +unsigned char _f_findpath ( F_NAME * fsname, F_POS * pos ) +{ + char * path = fsname->path; + char * mpath = path; + F_DIRENTRY * de; + + _f_clustertopos( 0, pos ); + + for ( ; *path ; ) + { + char name[F_MAXNAME]; + char ext[F_MAXEXT]; + + unsigned char len = _f_setnameext( path, name, ext ); + + if ( ( pos->cluster == 0 ) && ( len == 1 ) && ( name[0] == '.' ) ) + { + _f_clustertopos( 0, pos ); + } + else + { + if ( !_f_findfilewc( name, ext, pos, &de, 0 ) ) + { + return 0; + } + if ( !( de->attr & F_ATTR_DIR ) ) + { + return 0; + } + + _f_clustertopos( _f_getdecluster( de ), pos ); + } + + + if ( name[0] == '.' ) + { + if ( len == 1 ) + { + path += len; + + if ( !( *path ) ) + { + if ( mpath != fsname->path ) + { + mpath--; /*if we are now at the top*/ + } + + break; + } + + path++; + continue; + } + + if ( name[1] != '.' ) + { + return 0; /*invalid name*/ + } + + if ( len != 2 ) + { + return 0; /*invalid name !*/ + } + + path += len; + + if ( mpath == fsname->path ) + { + return 0; /*we are in the top*/ + } + + mpath--; /*no on separator*/ + for ( ; ; ) + { + if ( mpath == fsname->path ) + { + break; /*we are now at the top*/ + } + + mpath--; + if ( *mpath == '/' ) + { + mpath++; + break; + } + } + + if ( !( *path ) ) + { + if ( mpath != fsname->path ) + { + mpath--; /*if we are now at the top*/ + } + + break; + } + + path++; + continue; + } + else + { + if ( path == mpath ) /*if no was dots just step*/ + { + path += len; + mpath += len; + } + else + { + unsigned char a; + for ( a = 0 ; a < len ; a++ ) + { + *mpath++ = *path++; /*copy if in different pos*/ + } + } + } + + if ( !( *path ) ) + { + break; + } + + path++; + *mpath++ = '/'; /*add separator*/ + } + + *mpath = 0; /*terminate it*/ + return 1; +} /* _f_findpath */ + + +/**************************************************************************** + * + * fn_getcwd + * + * getting a current working directory of current drive + * + * INPUTS + * + * buffer - where to store current working folder + * maxlen - buffer length (possible size is F_MAXPATH) + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + + +unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root ) +{ + unsigned char a; + + if ( !maxlen ) + { + return F_NO_ERROR; + } + + maxlen--; /*need for termination*/ + if ( root && maxlen ) + { + *buffer++ = '/'; + maxlen--; + } + + for ( a = 0 ; a < maxlen ; a++ ) + { + char ch = gl_volume.cwd[a]; + buffer[a] = ch; + if ( !ch ) + { + break; + } + } + + buffer[a] = 0; /*add terminator at the end*/ + + return F_NO_ERROR; +} /* fn_getcwd */ + + + +/**************************************************************************** + * + * fn_findfirst + * + * find a file(s) or directory(s) in directory + * + * INPUTS + * + * filename - filename (with or without wildcards) + * find - where to store found file information + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + + +unsigned char fn_findfirst ( const char * filename, F_FIND * find ) +{ + unsigned char ret; + + if ( _f_setfsname( filename, &find->findfsname ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( _f_checkname( find->findfsname.filename, find->findfsname.fileext ) ) + { + return F_ERR_INVALIDNAME; /*invalid name, wildcard is ok*/ + } + + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( !_f_findpath( &find->findfsname, &find->pos ) ) + { + return F_ERR_INVALIDDIR; /*search for path*/ + } + + return fn_findnext( find ); +} /* fn_findfirst */ + + + +/**************************************************************************** + * + * fn_findnext + * + * find further file(s) or directory(s) in directory + * + * INPUTS + * + * find - where to store found file information (findfirst should call 1st) + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + + +unsigned char fn_findnext ( F_FIND * find ) +{ + F_DIRENTRY * de; + unsigned char a; + unsigned char ret; + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( !_f_findfilewc( find->findfsname.filename, find->findfsname.fileext, &find->pos, &de, 1 ) ) + { + return F_ERR_NOTFOUND; + } + + for ( a = 0 ; a < F_MAXNAME ; a++ ) + { + find->name[a] = de->name[a]; + } + + for ( a = 0 ; a < F_MAXEXT ; a++ ) + { + find->ext[a] = de->ext[a]; + } + + _f_getfilename( find->filename, (char *)de->name, (char *)de->ext ); + + find->attr = de->attr; + find->cdate = _f_getword( &de->cdate ); + find->ctime = _f_getword( &de->ctime ); + find->filesize = (long)_f_getlong( &de->filesize ); + find->cluster = _f_getdecluster( de ); + find->pos.pos++; /*goto next position*/ + + return 0; +} /* fn_findnext */ + + + +/**************************************************************************** + * + * fn_chdir + * + * change current working directory + * + * INPUTS + * + * dirname - new working directory name + * + * RETURNS + * + * 0 - if successfully + * other - if any error + * + ***************************************************************************/ +unsigned char fn_chdir ( const char * dirname ) +{ + F_POS pos; + F_NAME fsname; + unsigned char len; + unsigned char a; + unsigned char ret; + + ret = _f_setfsname( dirname, &fsname ); + + if ( ret == 1 ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + for ( len = 0 ; fsname.path[len] ; ) + { + len++; + } + + if ( len && ( ( fsname.filename[0] != 32 ) || ( fsname.fileext[0] != 32 ) ) ) + { + fsname.path[len++] = '/'; + } + + _f_getfilename( fsname.path + len, fsname.filename, fsname.fileext ); + + if ( !( _f_findpath( &fsname, &pos ) ) ) + { + return F_ERR_NOTFOUND; + } + + for ( a = 0 ; a < F_MAXPATH ; a++ ) + { + gl_volume.cwd[a] = fsname.path[a]; + } + + return F_NO_ERROR; +} /* fn_chdir */ + + + +/**************************************************************************** + * + * _f_initentry + * + * init directory entry, this function is called if a new entry is coming + * + * INPUTS + * + * de - directory entry which needs to be initialized + * name - fil ename (8) + * ext - file extension (3) + * + ***************************************************************************/ +static void _f_initentry ( F_DIRENTRY * de, char * name, char * ext ) +{ + unsigned short date; + unsigned short time; + + psp_memset( de, 0, sizeof( F_DIRENTRY ) ); /*reset all entries*/ + + psp_memcpy( de->name, name, sizeof( de->name ) ); + psp_memcpy( de->ext, ext, sizeof( de->ext ) ); + + f_igettimedate( &time, &date ); + _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/ + _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/ +} + + + + + +/**************************************************************************** + * + * _f_addentry + * + * Add a new directory entry into driectory list + * + * INPUTS + * + * fs_name - filled structure what to add into directory list + * pos - where directory cluster chains starts + * pde - F_DIRENTRY pointer where to store the entry where it was added + * + * RETURNS + * + * 0 - if successfully added + * other - if any error (see FS_xxx errorcodes) + * + ***************************************************************************/ +unsigned char _f_addentry ( F_NAME * fsname, F_POS * pos, F_DIRENTRY * * pde ) +{ + unsigned char ret; + unsigned short date; + unsigned short time; + + if ( !fsname->filename[0] ) + { + return F_ERR_INVALIDNAME; + } + + if ( fsname->filename[0] == '.' ) + { + return F_ERR_INVALIDNAME; + } + + while ( pos->cluster < F_CLUSTER_RESERVED ) + { + for ( ; pos->sector < pos->sectorend ; pos->sector++ ) + { + F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos ); + + ret = _f_readglsector( pos->sector ); + if ( ret ) + { + return ret; + } + + for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ ) + { + if ( ( !de->name[0] ) || ( (unsigned char)( de->name[0] ) == 0xe5 ) ) + { + _f_initentry( de, fsname->filename, fsname->fileext ); + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + f_igettimedate( &time, &date ); + _f_setword( &de->crtdate, date ); /*if there is realtime clock then creation date could be set from*/ + _f_setword( &de->crttime, time ); /*if there is realtime clock then creation time could be set from*/ + _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/ + } + + if ( pde ) + { + *pde = de; + } + + return F_NO_ERROR; + } + } + + pos->pos = 0; + } + + if ( !pos->cluster ) + { + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + pos->cluster = gl_volume.bootrecord.rootcluster; + } + else + return F_ERR_NOMOREENTRY; + } + + { + unsigned long cluster; + + gl_volume.fatsector = (unsigned long)-1; + ret = _f_getclustervalue( pos->cluster, &cluster ); /*try to get next cluster*/ + if ( ret ) + { + return ret; + } + + if ( cluster < F_CLUSTER_RESERVED ) + { + _f_clustertopos( cluster, pos ); + } + else + { + ret = _f_alloccluster( &cluster ); /*get a new one*/ + if ( ret ) + { + return ret; + } + + if ( cluster < F_CLUSTER_RESERVED ) + { + if ( gl_file.mode != F_FILE_CLOSE ) + { + return F_ERR_NOMOREENTRY; + } + + _f_clustertopos( cluster, &gl_file.pos ); + + ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST ); + if ( ret ) + { + return ret; + } + + ret = _f_setclustervalue( pos->cluster, gl_file.pos.cluster ); + if ( ret ) + { + return ret; + } + + ret = _f_writefatsector(); + if ( ret ) + { + return ret; + } + + gl_volume.fatsector = (unsigned long)-1; + psp_memset( gl_sector, 0, F_SECTOR_SIZE ); + while ( gl_file.pos.sector < gl_file.pos.sectorend ) + { + ret = _f_writeglsector( gl_file.pos.sector ); + if ( ret ) + { + return ret; + } + + gl_file.pos.sector++; + } + + _f_clustertopos( gl_file.pos.cluster, pos ); + } + else + { + return F_ERR_NOMOREENTRY; + } + } + } + } /* _f_addentry */ + + return F_ERR_NOMOREENTRY; +} + + + +/**************************************************************************** + * + * fn_mkdir + * + * making a new directory + * + * INPUTS + * + * dirname - new directory name + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_mkdir ( const char * dirname ) +{ + F_POS posdir; + F_POS pos; + F_DIRENTRY * de; + F_NAME fsname; + unsigned long cluster; + unsigned char ret; + + #if F_FILE_CHANGED_EVENT + ST_FILE_CHANGED fc; + #endif + + if ( _f_setfsname( dirname, &fsname ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( !_f_findpath( &fsname, &posdir ) ) + { + return F_ERR_INVALIDDIR; + } + + pos = posdir; + + if ( fsname.filename[0] == '.' ) + { + return F_ERR_NOTFOUND; + } + + if ( _f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) ) + { + return F_ERR_DUPLICATED; + } + + pos = posdir; + + gl_volume.fatsector = (unsigned long)-1; + ret = _f_alloccluster( &cluster ); + if ( ret ) + { + return ret; + } + + ret = _f_addentry( &fsname, &pos, &de ); + if ( ret ) + { + return ret; + } + + de->attr |= F_ATTR_DIR; /*set as directory*/ + + #if F_FILE_CHANGED_EVENT + if ( f_filechangedevent ) + { + fc.action = FACTION_ADDED; + fc.flags = FFLAGS_DIR_NAME | FFLAGS_ATTRIBUTES | FFLAGS_SIZE | FFLAGS_LAST_WRITE; + fc.attr = de->attr; + fc.ctime = _f_getword( de->ctime ); + fc.cdate = _f_getword( de->cdate ); + fc.filesize = _f_getlong( de->filesize ); + } + + #endif + + if ( gl_file.mode != F_FILE_CLOSE ) + { + return F_ERR_LOCKED; + } + + _f_clustertopos( cluster, &gl_file.pos ); + _f_setdecluster( de, cluster ); /*new dir*/ + + (void)_f_writeglsector( (unsigned long)-1 ); /*write actual directory sector*/ + + + de = (F_DIRENTRY *)gl_sector; + + _f_initentry( de, ". ", " " ); + de->attr = F_ATTR_DIR; /*set as directory*/ + _f_setdecluster( de, cluster ); /*current*/ + de++; + + _f_initentry( de, ".. ", " " ); + de->attr = F_ATTR_DIR; /*set as directory*/ + _f_setdecluster( de, posdir.cluster ); /*parent*/ + de++; + + psp_memset( de, 0, ( F_SECTOR_SIZE - 2 * sizeof( F_DIRENTRY ) ) ); + + + ret = _f_writeglsector( gl_file.pos.sector ); + if ( ret ) + { + return ret; + } + + gl_file.pos.sector++; + psp_memset( gl_sector, 0, ( 2 * sizeof( F_DIRENTRY ) ) ); + while ( gl_file.pos.sector < gl_file.pos.sectorend ) + { + ret = _f_writeglsector( gl_file.pos.sector ); + if ( ret ) + { + return ret; + } + + gl_file.pos.sector++; + } + + gl_volume.fatsector = (unsigned long)-1; + ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST ); + if ( ret ) + { + return ret; + } + + ret = _f_writefatsector(); + #if F_FILE_CHANGED_EVENT + if ( f_filechangedevent && !ret ) + { + fc.action = FACTION_ADDED; + fc.flags = FFLAGS_DIR_NAME; + + if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) ) + { + f_filechangedevent( &fc ); + } + } + + #endif + + return ret; +} /* fn_mkdir */ + + + +/**************************************************************************** + * + * fn_rmdir + * + * Remove directory, only could be removed if empty + * + * INPUTS + * + * dirname - which directory needed to be removed + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_rmdir ( const char * dirname ) +{ + unsigned char ret; + F_POS pos; + F_DIRENTRY * de; + F_NAME fsname; + unsigned long dirsector; + unsigned char a; + + if ( _f_setfsname( dirname, &fsname ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( fsname.filename[0] == '.' ) + { + return F_ERR_NOTFOUND; + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( !( _f_findpath( &fsname, &pos ) ) ) + { + return F_ERR_INVALIDDIR; + } + + if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) ) + { + return F_ERR_NOTFOUND; + } + + if ( !( de->attr & F_ATTR_DIR ) ) + { + return F_ERR_INVALIDDIR; /*not a directory*/ + } + + dirsector = gl_volume.actsector; + + if ( gl_file.mode != F_FILE_CLOSE ) + { + return F_ERR_LOCKED; + } + + _f_clustertopos( _f_getdecluster( de ), &gl_file.pos ); + + for ( ; ; ) + { + F_DIRENTRY * de2; + char ch = 0; + + ret = _f_getcurrsector(); + if ( ret == F_ERR_EOF ) + { + break; + } + + if ( ret ) + { + return ret; + } + + de2 = (F_DIRENTRY *)gl_sector; + for ( a = 0 ; a < ( F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ) ; a++, de2++ ) + { + ch = de2->name[0]; + if ( !ch ) + { + break; + } + + if ( (unsigned char)ch == 0xe5 ) + { + continue; + } + + if ( ch == '.' ) + { + continue; + } + + return F_ERR_NOTEMPTY; /*something is there*/ + } + + if ( !ch ) + { + break; + } + + gl_file.pos.sector++; + } + + ret = _f_readglsector( dirsector ); + if ( ret ) + { + return ret; + } + + de->name[0] = (unsigned char)0xe5; + + ret = _f_writeglsector( dirsector ); + if ( ret ) + { + return ret; + } + + gl_volume.fatsector = (unsigned long)-1; + ret = _f_removechain( _f_getdecluster( de ) ); + #if F_FILE_CHANGED_EVENT + if ( f_filechangedevent && !ret ) + { + ST_FILE_CHANGED fc; + fc.action = FACTION_REMOVED; + fc.flags = FFLAGS_DIR_NAME; + + if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) ) + { + f_filechangedevent( &fc ); + } + } + + #endif + return ret; +} /* fn_rmdir */ + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h new file mode 100644 index 000000000..467973cc0 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/dir.h @@ -0,0 +1,90 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __DIR_H +#define __DIR_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + + +#define NTRES_LOW 0x08 /*lower case name*/ + + +typedef struct +{ + unsigned char name[F_MAXNAME]; /* 8+3 */ + unsigned char ext[F_MAXEXT]; + unsigned char attr; /* 00ADVSHR */ + + unsigned char ntres; /* FAT32 only */ + unsigned char crttimetenth; /* FAT32 only */ + unsigned char crttime[2]; /* FAT32 only */ + unsigned char crtdate[2]; /* FAT32 only */ + unsigned char lastaccessdate[2]; /* FAT32 only */ + + unsigned char clusterhi[2]; /* FAT32 only */ + unsigned char ctime[2]; + unsigned char cdate[2]; + unsigned char clusterlo[2]; /* fat12,fat16,fat32 */ + unsigned char filesize[4]; +} F_DIRENTRY; + + +unsigned char _f_getdirsector ( unsigned long ); +unsigned char _f_findfilewc ( char *, char *, F_POS *, F_DIRENTRY * *, unsigned char ); +unsigned char _f_findpath ( F_NAME *, F_POS * ); +unsigned long _f_getdecluster ( F_DIRENTRY * ); + +unsigned char _f_writedirsector ( void ); +void _f_setdecluster ( F_DIRENTRY *, unsigned long ); +unsigned char _f_addentry ( F_NAME *, F_POS *, F_DIRENTRY * * ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __DIR_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c new file mode 100644 index 000000000..82f19bd33 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.c @@ -0,0 +1,216 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" +#include "../../psp/include/psp_string.h" + +#include "drv.h" +#include "util.h" +#include "volume.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +F_DRIVER * mdrv = NULL; /* driver structure */ + + +/**************************************************************************** + * + * _f_checkstatus + * + * checking a volume driver status, if media is removed or has been changed + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_checkstatus ( void ) +{ + if ( mdrv->getstatus != NULL ) + { + if ( mdrv->getstatus( mdrv ) & ( F_ST_MISSING | F_ST_CHANGED ) ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/ + return F_ERR_CARDREMOVED; + } + } + + return F_NO_ERROR; +} + + +/**************************************************************************** + * + * _f_writesector + * + * write sector data on a volume, it calls low level driver function, it + * writes a complete sector + * + * INPUTS + * sector - which physical sector + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_writeglsector ( unsigned long sector ) +{ + unsigned char retry; + + if ( mdrv->writesector == NULL ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*no write function*/ + return F_ERR_ACCESSDENIED; + } + + if ( sector == (unsigned long)-1 ) + { + if ( gl_file.modified ) + { + sector = gl_file.pos.sector; + } + else + { + sector = gl_volume.actsector; + } + } + + if ( sector != (unsigned long)-1 ) + { + if ( mdrv->getstatus != NULL ) + { + unsigned int status; + + status = mdrv->getstatus( mdrv ); + + if ( status & ( F_ST_MISSING | F_ST_CHANGED ) ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/ + return F_ERR_CARDREMOVED; + } + + if ( status & ( F_ST_WRPROTECT ) ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/ + return F_ERR_WRITEPROTECT; + } + } + + gl_volume.modified = 0; + gl_file.modified = 0; + gl_volume.actsector = sector; + for ( retry = 3 ; retry ; retry-- ) + { + int mdrv_ret; + mdrv_ret = mdrv->writesector( mdrv, (unsigned char *)gl_sector, sector ); + if ( !mdrv_ret ) + { + return F_NO_ERROR; + } + + if ( mdrv_ret == -1 ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/ + return F_ERR_CARDREMOVED; + } + } + } + + + return F_ERR_ONDRIVE; +} /* _f_writeglsector */ + + +/**************************************************************************** + * + * _f_readsector + * + * read sector data from a volume, it calls low level driver function, it + * reads a complete sector + * + * INPUTS + * sector - which physical sector is read + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_readglsector ( unsigned long sector ) +{ + unsigned char retry; + unsigned char ret; + + if ( sector == gl_volume.actsector ) + { + return F_NO_ERROR; + } + + if ( gl_volume.modified || gl_file.modified ) + { + ret = _f_writeglsector( (unsigned long)-1 ); + if ( ret ) + { + return ret; + } + } + + + for ( retry = 3 ; retry ; retry-- ) + { + int mdrv_ret; + mdrv_ret = mdrv->readsector( mdrv, (unsigned char *)gl_sector, sector ); + if ( !mdrv_ret ) + { + gl_volume.actsector = sector; + return F_NO_ERROR; + } + + if ( mdrv_ret == -1 ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card has been removed;*/ + return F_ERR_CARDREMOVED; + } + } + + gl_volume.actsector = (unsigned long)-1; + return F_ERR_ONDRIVE; +} /* _f_readglsector */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h new file mode 100644 index 000000000..10827a21a --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/drv.h @@ -0,0 +1,61 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __DRV_H +#define __DRV_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern F_DRIVER * mdrv; /* driver structure */ + +unsigned char _f_checkstatus ( void ); +unsigned char _f_readglsector ( unsigned long ); +unsigned char _f_writeglsector ( unsigned long ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __DRV_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c new file mode 100644 index 000000000..23ebbf20b --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.c @@ -0,0 +1,642 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#define FS_MUTEX_DEFINED + +#include "../../api/fat_sl.h" +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#if F_FS_THREAD_AWARE == 1 + +xSemaphoreHandle fs_lock_semaphore; + + +/* +** fr_findfirst +** +** find first time a file using wildcards +** +** INPUT : filename - name of the file +** *find - pointer to a pre-define F_FIND structure +** RETURN: F_NOERR - on success +** F_ERR_NOTFOUND - if not found +*/ +unsigned char fr_findfirst ( const char * filename, F_FIND * find ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_findfirst( filename, find ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_findnext +** +** find next time a file using wildcards +** +** INPUT : *find - pointer to a pre-define F_FIND structure +** RETURN: F_NOERR - on success +** F_ERR_NOTFOUND - if not found +*/ +unsigned char fr_findnext ( F_FIND * find ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_findnext( find ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_filelength +** +** Get the length of a file +** +** INPUT : filename - name of the file +** RETURN: size of the file or F_ERR_INVALID if not exists or volume not working +*/ +long fr_filelength ( const char * filename ) +{ + unsigned long rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_filelength( filename ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = 0; + } + + return rc; +} + + +/* +** fr_open +** +** open a file +** +** INPUT : filename - file to be opened +** mode - open method (r,w,a,r+,w+,a+) +** RETURN: pointer to a file descriptor or 0 on error +*/ +F_FILE * fr_open ( const char * filename, const char * mode ) +{ + F_FILE * rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_open( filename, mode ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = NULL; + } + + return rc; +} + + +/* +** fr_close +** +** Close a previously opened file. +** +** INPUT : *filehandle - pointer to the file descriptor +** RETURN: F_NOERR on success, other if error +*/ +unsigned char fr_close ( F_FILE * filehandle ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_close( filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_read +** +** Read from a file. +** +** INPUT : buf - buffer to read data +** size - number of unique +** size_st - size of unique +** *filehandle - pointer to file descriptor +** OUTPUT: number of read bytes +*/ +long fr_read ( void * bbuf, long size, long size_st, F_FILE * filehandle ) +{ + long rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_read( bbuf, size, size_st, filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = 0; + } + + return rc; +} + + +/* +** fr_write +** +** INPUT : bbuf - buffer to write from +** size - number of unique +** size_st - size of unique +** *filehandle - pointer to the file descriptor +** RETURN: number of written bytes +*/ +long fr_write ( const void * bbuf, long size, long size_st, F_FILE * filehandle ) +{ + long rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_write( bbuf, size, size_st, filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = 0; + } + + return rc; +} + +/* +** fr_seek +** +** Seek in a file. +** +** INPUT : *filehandle - pointer to a file descriptor +** offset - offset +** whence - F_SEEK_SET: position = offset +** F_SEEK_CUR: position = position + offset +** F_SEEK_END: position = end of file (offset=0) +** RETURN: F_NOERR on succes, other if error. +*/ +unsigned char fr_seek ( F_FILE * filehandle, long offset, unsigned char whence ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_seek( filehandle, offset, whence ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + +/* +** fr_tell +** +** get current position in the file +** +** INPUT : *filehandle - pointer to a file descriptor +** RETURN: -1 on error or current position. +*/ +long fr_tell ( F_FILE * filehandle ) +{ + long rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_tell( filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = -1; + } + + return rc; +} + +/* +** fr_getc +** +** read one byte from a file +** +** INPUT : *filehandle - pointer to a file descriptor +** RETURN: -1 if error, otherwise the read character. +*/ +int fr_getc ( F_FILE * filehandle ) +{ + int rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_getc( filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = -1; + } + + return rc; +} + +/* +** fr_putc +** +** write one byte to a file +** +** INPUT : ch - character to write +** *filehandle - pointer to a file handler +** RETURN: ch on success, -1 on error +*/ +int fr_putc ( int ch, F_FILE * filehandle ) +{ + int rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_putc( ch, filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = -1; + } + + return rc; +} + +/* +** fr_rewind +** +** set current position in the file to the beginning +** +** INPUT : *filehandle - pointer to a file descriptor +** RETURN: F_NOERR on succes, other if error. +*/ +unsigned char fr_rewind ( F_FILE * filehandle ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_rewind( filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + +/* +** fr_eof +** +** check if current position is at the end of the file. +** +** INPUT : *filehandle - pointer to a file descriptor +** RETURN: F_ERR_EOF - at the end of the file +** F_NOERR - no error, end of the file not reached +** other - on error +*/ +unsigned char fr_eof ( F_FILE * filehandle ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_eof( filehandle ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + +/* +** Format the device +*/ +unsigned char fr_hardformat ( unsigned char fattype ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_hardformat( fattype ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + +/* +** fr_get_serial +** +** Get serial number +** +** OUTPUT: serial - where to write the serial number +** RETURN: error code +*/ +unsigned char fr_getserial ( unsigned long * serial ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_getserial( serial ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_delete +** +** Delete a file. Removes the chain that belongs to the file and inserts a new descriptor +** to the directory with first_cluster set to 0. +** +** INPUT : filename - name of the file to delete +** RETURN: F_NOERR on success, other if error. +*/ +unsigned char fr_delete ( const char * filename ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_delete( filename ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + +/* +** fr_truncate +** +** Open a file and set end of file +** +** INPUT: filename - name of the file +** filesize - required new size +** RETURN: NULL on error, otherwise file pointer +*/ +F_FILE * fr_truncate ( const char * filename, long filesize ) +{ + F_FILE * f; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + f = fn_truncate( filename, filesize ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + f = NULL; + } + + return f; +} + + +/* +** fr_getfreespace +** +** Get free space on the volume +** +** OUTPUT: *sp - pre-defined F_SPACE structure, where information will be stored +** RETURN: F_NOERR - on success +** F_ERR_NOTFORMATTED - if volume is not formatted +*/ +unsigned char fr_getfreespace ( F_SPACE * sp ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_getfreespace( sp ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_chdir +** +** Change to a directory +** +** INPUT: path - path to the dircetory +** RETURN: 0 - on success, other if error +*/ +unsigned char fr_chdir ( const char * path ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_chdir( path ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_mkdir +** +** Create a directory +** +** INPUT: path - new directory path +** RETURN: 0 - on success, other if error +*/ +unsigned char fr_mkdir ( const char * path ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_mkdir( path ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_rmdir +** +** Removes a directory +** +** INPUT: path - path to remove +** RETURN: 0 - on success, other if error +*/ +unsigned char fr_rmdir ( const char * path ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_rmdir( path ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_getcwd +** +** Get current working directory +** +** INPUT: maxlen - maximum length allowed +** OUTPUT: path - current working directory +** RETURN: 0 - on success, other if error +*/ +unsigned char fr_getcwd ( char * path, unsigned char maxlen, char root ) +{ + unsigned char rc; + + if( xSemaphoreTake( fs_lock_semaphore, F_MAX_LOCK_WAIT_TICKS ) == pdPASS ) + { + rc = fn_getcwd( path, maxlen, root ); + xSemaphoreGive( fs_lock_semaphore ); + } + else + { + rc = F_ERR_OS; + } + + return rc; +} + + +/* +** fr_init +** +** Initialize FAT_SL OS module +** +** RETURN: F_NO_ERROR or F_ERR_OS +*/ +unsigned char fr_init ( void ) +{ + return F_NO_ERROR; +} + +#endif /* F_FS_THREAD_AWARE */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h new file mode 100644 index 000000000..c0505590c --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/f_lock.h @@ -0,0 +1,59 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _F_RTOS_H +#define _F_RTOS_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char fr_init ( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef _F_RTOS_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c new file mode 100644 index 000000000..771d1ffcd --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.c @@ -0,0 +1,598 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ +#include "../../api/fat_sl.h" + +#include "fat.h" +#include "util.h" +#include "volume.h" +#include "drv.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +/**************************************************************************** + * + * _f_writefatsector + * + * writing fat sector into volume, this function check if fat was modified + * and writes data + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_writefatsector ( void ) +{ + unsigned char a; + + if ( gl_volume.modified ) + { + unsigned long fatsector = gl_volume.firstfat.sector + gl_volume.fatsector; + + if ( gl_volume.fatsector >= gl_volume.firstfat.num ) + { + return F_ERR_INVALIDSECTOR; + } + + for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ ) + { + unsigned char ret; + ret = _f_writeglsector( fatsector ); + if ( ret ) + { + return ret; + } + + fatsector += gl_volume.firstfat.num; + } + + gl_volume.modified = 0; + } + + return F_NO_ERROR; +} /* _f_writefatsector */ + + + +/**************************************************************************** + * + * _f_getfatsector + * + * read a fat sector from media + * + * INPUTS + * + * sector - which fat sector is needed, this sector number is zero based + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_getfatsector ( unsigned long sector ) +{ + unsigned char a; + + if ( gl_volume.fatsector != sector ) + { + unsigned long fatsector; + + gl_volume.fatsector = sector; + + if ( gl_volume.fatsector >= gl_volume.firstfat.num ) + { + return F_ERR_INVALIDSECTOR; + } + + fatsector = gl_volume.firstfat.sector + gl_volume.fatsector; + + for ( a = 0 ; a < gl_volume.bootrecord.number_of_FATs ; a++ ) + { + if ( !_f_readglsector( fatsector ) ) + { + return F_NO_ERROR; + } + + fatsector += gl_volume.firstfat.num; + } + + return F_ERR_READ; + } + + return F_NO_ERROR; +} /* _f_getfatsector */ + + + +/**************************************************************************** + * + * _f_setclustervalue + * + * set a cluster value in the FAT + * + * INPUTS + * + * cluster - which cluster's value need to be modified + * data - new value of the cluster + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_setclustervalue ( unsigned long cluster, unsigned long _tdata ) +{ + unsigned char ret; + + switch ( gl_volume.mediatype ) + { + case F_FAT16_MEDIA: + { + unsigned long sector = cluster; + unsigned short s_data = (unsigned short)( _tdata & 0xffff ); /*keep 16 bit only*/ + + sector /= ( F_SECTOR_SIZE / 2 ); + cluster -= sector * ( F_SECTOR_SIZE / 2 ); + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + if ( _f_getword( &gl_sector[cluster << 1] ) != s_data ) + { + _f_setword( &gl_sector[cluster << 1], s_data ); + gl_volume.modified = 1; + } + } + break; + + case F_FAT12_MEDIA: + { + unsigned char f12new[2]; + unsigned long sector = cluster; + unsigned short pos; + unsigned short s_data = (unsigned short)( _tdata & 0x0fff ); /*keep 12 bit only*/ + + if ( cluster & 1 ) + { + s_data <<= 4; + } + + _f_setword( f12new, s_data ); /*create new data*/ + + sector += sector / 2; /*1.5 bytes*/ + pos = (unsigned short)( sector % F_SECTOR_SIZE ); + sector /= F_SECTOR_SIZE; + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + if ( cluster & 1 ) + { + f12new[0] |= gl_sector[pos] & 0x0f; + } + + if ( gl_sector[pos] != f12new[0] ) + { + gl_sector[pos] = f12new[0]; + gl_volume.modified = 1; + } + + pos++; + if ( pos >= 512 ) + { + ret = _f_getfatsector( sector + 1 ); + if ( ret ) + { + return ret; + } + + pos = 0; + } + + if ( !( cluster & 1 ) ) + { + f12new[1] |= gl_sector[pos] & 0xf0; + } + + if ( gl_sector[pos] != f12new[1] ) + { + gl_sector[pos] = f12new[1]; + gl_volume.modified = 1; + } + } + break; + + case F_FAT32_MEDIA: + { + unsigned long sector = cluster; + unsigned long oldv; + + sector /= ( F_SECTOR_SIZE / 4 ); + cluster -= sector * ( F_SECTOR_SIZE / 4 ); + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + oldv = _f_getlong( &gl_sector[cluster << 2] ); + + _tdata &= 0x0fffffff; + _tdata |= oldv & 0xf0000000; /*keep 4 top bits*/ + + if ( _tdata != oldv ) + { + _f_setlong( &gl_sector[cluster << 2], _tdata ); + gl_volume.modified = 1; + } + } + break; + + default: + return F_ERR_INVALIDMEDIA; + } /* switch */ + + return F_NO_ERROR; +} /* _f_setclustervalue */ + + +/**************************************************************************** + * + * _f_getclustervalue + * + * get a cluster value from FAT + * + * INPUTS + * + * cluster - which cluster value is requested + * pvalue - where to store data + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_getclustervalue ( unsigned long cluster, unsigned long * pvalue ) +{ + unsigned long val; + unsigned char ret; + + switch ( gl_volume.mediatype ) + { + case F_FAT16_MEDIA: + { + unsigned long sector = cluster; + sector /= ( F_SECTOR_SIZE / 2 ); + cluster -= sector * ( F_SECTOR_SIZE / 2 ); + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + val = _f_getword( &gl_sector[cluster << 1] ); + if ( val >= ( F_CLUSTER_RESERVED & 0xffff ) ) + { + val |= 0x0ffff000; /*extends it*/ + } + + if ( pvalue ) + { + *pvalue = val; + } + } + break; + + case F_FAT12_MEDIA: + { + unsigned char dataf12[2]; + unsigned long sector = cluster; + unsigned short pos; + + sector += sector / 2; /*1.5 bytes*/ + pos = (unsigned short)( sector % F_SECTOR_SIZE ); + sector /= F_SECTOR_SIZE; + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + dataf12[0] = gl_sector[pos++]; + + if ( pos >= 512 ) + { + ret = _f_getfatsector( sector + 1 ); + if ( ret ) + { + return ret; + } + + pos = 0; + } + + dataf12[1] = gl_sector[pos]; + + val = _f_getword( dataf12 ); + + if ( cluster & 1 ) + { + val = val >> 4; + } + else + { + val = val & 0xfff; + } + + if ( val >= ( F_CLUSTER_RESERVED & 0xfff ) ) + { + val |= 0x0ffff000; /*extends it*/ + } + + if ( pvalue ) + { + *pvalue = val; + } + } + break; + + case F_FAT32_MEDIA: + { + unsigned long sector = cluster; + sector /= ( F_SECTOR_SIZE / 4 ); + cluster -= sector * ( F_SECTOR_SIZE / 4 ); + + ret = _f_getfatsector( sector ); + if ( ret ) + { + return ret; + } + + if ( pvalue ) + { + *pvalue = _f_getlong( &gl_sector[cluster << 2] ) & 0x0fffffff; /*28bit*/ + } + } + break; + + default: + return F_ERR_INVALIDMEDIA; + } /* switch */ + + return F_NO_ERROR; +} /* _f_getclustervalue */ + + + + + + +/**************************************************************************** + * + * _f_clustertopos + * + * convert a cluster position into physical sector position + * + * INPUTS + * + * cluster - original cluster position + * pos - position structure to fills the position + * + ***************************************************************************/ +void _f_clustertopos ( unsigned long cluster, F_POS * pos ) +{ + pos->cluster = cluster; + + if ( !cluster ) + { + pos->sector = gl_volume.root.sector; + pos->sectorend = pos->sector + gl_volume.root.num; + } + else + { + unsigned long sectorcou = gl_volume.bootrecord.sector_per_cluster; + pos->sector = ( pos->cluster - 2 ) * sectorcou + gl_volume._tdata.sector; + pos->sectorend = pos->sector + sectorcou; + } + + if ( cluster >= F_CLUSTER_RESERVED ) + { + pos->sectorend = 0; + } + + pos->pos = 0; +} /* _f_clustertopos */ + + + + +/**************************************************************************** + * + * _f_getcurrsector + * + * read current sector according in file structure + * + * INPUTS + * f - internal file pointer + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_getcurrsector ( void ) +{ + unsigned char ret; + unsigned long cluster; + + if ( gl_file.pos.sector == gl_file.pos.sectorend ) + { + gl_volume.fatsector = (unsigned long)-1; + ret = _f_getclustervalue( gl_file.pos.cluster, &cluster ); + if ( ret ) + { + return ret; + } + + if ( cluster >= F_CLUSTER_RESERVED ) + { + return F_ERR_EOF; + } + + gl_file.prevcluster = gl_file.pos.cluster; + _f_clustertopos( cluster, &gl_file.pos ); + } + + return _f_readglsector( gl_file.pos.sector ); +} /* _f_getcurrsector */ + + + +/**************************************************************************** + * + * _f_alloccluster + * + * allocate cluster from FAT + * + * INPUTS + * pcluster - where to store the allocated cluster number + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + +unsigned char _f_alloccluster ( unsigned long * pcluster ) +{ + unsigned long maxcluster = gl_volume.maxcluster; + unsigned long cou; + unsigned long cluster = gl_volume.lastalloccluster; + unsigned long value; + unsigned char ret; + + for ( cou = 0 ; cou < maxcluster ; cou++ ) + { + if ( cluster >= maxcluster ) + { + cluster = 0; + } + + ret = _f_getclustervalue( cluster, &value ); + if ( ret ) + { + return ret; + } + + if ( !value ) + { + gl_volume.lastalloccluster = cluster + 1; /*set next one*/ + *pcluster = cluster; + + return F_NO_ERROR; + } + + cluster++; + } + + return F_ERR_NOMOREENTRY; +} /* _f_alloccluster */ + + + + +/**************************************************************************** + * + * _f_removechain + * + * remove cluster chain from fat + * + * INPUTS + * cluster - first cluster in the cluster chain + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + +unsigned char _f_removechain ( unsigned long cluster ) +{ + gl_volume.fatsector = (unsigned long)-1; + + if ( cluster < gl_volume.lastalloccluster ) /*this could be the begining of alloc*/ + { + gl_volume.lastalloccluster = cluster; + } + + while ( cluster < F_CLUSTER_RESERVED && cluster >= 2 ) + { + unsigned long nextcluster; + + unsigned char ret = _f_getclustervalue( cluster, &nextcluster ); + if ( ret ) + { + return ret; + } + + ret = _f_setclustervalue( cluster, F_CLUSTER_FREE ); + if ( ret ) + { + return ret; + } + + cluster = nextcluster; + } + + return _f_writefatsector(); +} /* _f_removechain */ + + + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h new file mode 100644 index 000000000..bb8c727c3 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/fat.h @@ -0,0 +1,65 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __FAT_H +#define __FAT_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char _f_getfatsector ( unsigned long ); +unsigned char _f_getclustervalue ( unsigned long, unsigned long * ); +void _f_clustertopos ( unsigned long, F_POS * ); +unsigned char _f_getcurrsector ( void ); + +unsigned char _f_writefatsector ( void ); +unsigned char _f_setclustervalue ( unsigned long, unsigned long ); +unsigned char _f_alloccluster ( unsigned long * ); +unsigned char _f_removechain ( unsigned long ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __FAT_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c new file mode 100644 index 000000000..ae08990b2 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c @@ -0,0 +1,1492 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" +#include "../../psp/include/psp_string.h" + +#include "util.h" +#include "volume.h" +#include "drv.h" +#include "fat.h" +#include "dir.h" +#include "file.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +static unsigned char _f_emptywritebuffer ( void ); + + +/**************************************************************************** + * + * fn_filelength + * + * Get a file length + * + * INPUTS + * + * filename - file whose length is needed + * + * RETURNS + * + * length of the file + * + ***************************************************************************/ + +long fn_filelength ( const char * filename ) +{ + F_POS pos; + F_DIRENTRY * de; + F_NAME fsname; + + if ( _f_setfsname( filename, &fsname ) ) + { + return 0; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return 0; /*invalid name*/ + } + + if ( _f_getvolume() ) + { + return 0; /*can't get the size*/ + } + + if ( !_f_findpath( &fsname, &pos ) ) + { + return 0; + } + + if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) ) + { + return 0; + } + + if ( de->attr & F_ATTR_DIR ) + { + return 0; /*directory*/ + } + + return (long)_f_getlong( &de->filesize ); +} /* fn_filelength */ + + + + + +/**************************************************************************** + * + * _f_emptywritebuffer + * + * empty write buffer if it contains unwritten data + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ + + +static unsigned char _f_emptywritebuffer ( void ) +{ + unsigned char ret; + + ret = _f_writeglsector( gl_file.pos.sector ); + if ( ret ) + { + return ret; + } + + gl_file.modified = 0; + + gl_file.pos.sector++; + + if ( gl_file.pos.sector >= gl_file.pos.sectorend ) + { + unsigned long value; + + gl_volume.fatsector = (unsigned long)-1; + ret = _f_getclustervalue( gl_file.pos.cluster, &value ); + if ( ret ) + { + return ret; + } + + if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/ + { + gl_file.prevcluster = gl_file.pos.cluster; + _f_clustertopos( value, &gl_file.pos ); /*go to next cluster*/ + } + else + { + unsigned long nextcluster; + + ret = _f_alloccluster( &nextcluster ); + if ( ret ) + { + return ret; + } + + ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST ); + if ( ret ) + { + return ret; + } + + ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster ); + if ( ret ) + { + return ret; + } + + gl_file.prevcluster = gl_file.pos.cluster; + + _f_clustertopos( nextcluster, &gl_file.pos ); + + return _f_writefatsector(); + } + } + + + return F_NO_ERROR; +} /* _f_emptywritebuffer */ + + + + +/**************************************************************************** + * + * _f_extend + * + * Extend file to a certain size + * + ***************************************************************************/ +static unsigned char _f_extend ( long size ) +{ + unsigned long _size; + unsigned char rc; + + size -= gl_file.filesize; + _size = (unsigned long)size; + + rc = _f_getcurrsector(); + if ( rc ) + { + return rc; + } + + psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) ); + + if ( gl_file.relpos + _size > F_SECTOR_SIZE ) + { + _size -= ( F_SECTOR_SIZE - gl_file.relpos ); + while ( _size ) + { + if ( _f_emptywritebuffer() ) + { + return F_ERR_WRITE; + } + + psp_memset( gl_sector, 0, F_SECTOR_SIZE ); + _size -= ( _size > F_SECTOR_SIZE ? F_SECTOR_SIZE : _size ); + } + } + else + { + _size += gl_file.relpos; + } + + gl_file.modified = 1; + gl_file.filesize += size; + gl_file.abspos = gl_file.filesize & ( ~( F_SECTOR_SIZE - 1 ) ); + gl_file.relpos = _size; + + return F_NO_ERROR; +} /* _f_extend */ + + + +/**************************************************************************** + * + * _f_fseek + * + * subfunction for f_seek it moves position into given offset and read + * the current sector + * + * INPUTS + * offset - position from start + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +static unsigned char _f_fseek ( long offset ) +{ + unsigned long cluster; + unsigned long tmp; + unsigned char ret = F_NO_ERROR; + long remain; + + if ( offset < 0 ) + { + offset = 0; + } + + if ( ( (unsigned long) offset <= gl_file.filesize ) + && ( (unsigned long) offset >= gl_file.abspos ) + && ( (unsigned long) offset < gl_file.abspos + F_SECTOR_SIZE ) ) + { + gl_file.relpos = (unsigned short)( offset - gl_file.abspos ); + } + else + { + if ( gl_file.modified ) + { + ret = _f_writeglsector( (unsigned long)-1 ); + if ( ret ) + { + gl_file.mode = F_FILE_CLOSE; /*cant accessed any more*/ + return ret; + } + } + + if ( gl_file.startcluster ) + { + gl_file.abspos = 0; + gl_file.relpos = 0; + gl_file.prevcluster = 0; + gl_file.pos.cluster = gl_file.startcluster; + remain = gl_file.filesize; + + tmp = gl_volume.bootrecord.sector_per_cluster; + tmp *= F_SECTOR_SIZE; /* set to cluster size */ + + /*calc cluster*/ + gl_volume.fatsector = (unsigned long)-1; + while ( (unsigned long)offset >= tmp ) + { + ret = _f_getclustervalue( gl_file.pos.cluster, &cluster ); + if ( ret ) + { + gl_file.mode = F_FILE_CLOSE; + return ret; + } + + if ( (long) tmp >= remain ) + { + break; + } + + remain -= tmp; + offset -= tmp; + gl_file.abspos += tmp; + if ( cluster >= F_CLUSTER_RESERVED ) + { + break; + } + + gl_file.prevcluster = gl_file.pos.cluster; + gl_file.pos.cluster = cluster; + } + + _f_clustertopos( gl_file.pos.cluster, &gl_file.pos ); + if ( remain && offset ) + { + while ( ( offset > (long) F_SECTOR_SIZE ) + && ( remain > (long) F_SECTOR_SIZE ) ) + { + gl_file.pos.sector++; + offset -= F_SECTOR_SIZE; + remain -= F_SECTOR_SIZE; + gl_file.abspos += F_SECTOR_SIZE; + } + } + + if ( remain < offset ) + { + gl_file.relpos = (unsigned short)remain; + ret = _f_extend( gl_file.filesize + offset - remain ); + } + else + { + gl_file.relpos = (unsigned short)offset; + } + } + } + + return ret; +} /* _f_fseek */ + + + +/**************************************************************************** + * + * fn_open + * + * open a file for reading/writing/appending + * + * INPUTS + * + * filename - which file need to be opened + * mode - string how to open ("r"-read, "w"-write, "w+"-overwrite, "a"-append + * + * RETURNS + * + * F_FILE pointer if successfully + * 0 - if any error + * + ***************************************************************************/ +F_FILE * fn_open ( const char * filename, const char * mode ) +{ + F_DIRENTRY * de; + F_NAME fsname; + unsigned short date; + unsigned short time; + unsigned char m_mode = F_FILE_CLOSE; + + if ( mode[1] == 0 ) + { + if ( mode[0] == 'r' ) + { + m_mode = F_FILE_RD; + } + + if ( mode[0] == 'w' ) + { + m_mode = F_FILE_WR; + } + + if ( mode[0] == 'a' ) + { + m_mode = F_FILE_A; + } + } + + if ( ( mode[1] == '+' ) && ( mode[2] == 0 ) ) + { + if ( mode[0] == 'r' ) + { + m_mode = F_FILE_RDP; + } + + if ( mode[0] == 'w' ) + { + m_mode = F_FILE_WRP; + } + + if ( mode[0] == 'a' ) + { + m_mode = F_FILE_AP; + } + + } + + if ( m_mode == F_FILE_CLOSE ) + { + return 0; /*invalid mode*/ + } + + if ( _f_setfsname( filename, &fsname ) ) + { + return 0; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return 0; /*invalid name*/ + } + + if ( fsname.filename[0] == '.' ) + { + return 0; + } + + if ( _f_getvolume() ) + { + return 0; /*cant open any*/ + } + + if ( gl_file.mode != F_FILE_CLOSE ) + { + return 0; + } + + psp_memset( &gl_file, 0, 21 ); + + if ( !_f_findpath( &fsname, &gl_file.dirpos ) ) + { + return 0; + } + + switch ( m_mode ) + { + case F_FILE_RDP: /*r*/ + case F_FILE_RD: /*r*/ + if ( !_f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) ) + { + return 0; + } + + if ( de->attr & F_ATTR_DIR ) + { + return 0; /*directory*/ + } + + gl_file.startcluster = _f_getdecluster( de ); + + if ( gl_file.startcluster ) + { + _f_clustertopos( gl_file.startcluster, &gl_file.pos ); + gl_file.filesize = _f_getlong( &de->filesize ); + gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE); + if ( _f_fseek( 0 ) ) + { + return 0; + } + } + +#if F_FILE_CHANGED_EVENT + if ( m_mode == F_FILE_RDP ) + { + _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); + } + +#endif + + break; + + case F_FILE_AP: + case F_FILE_A: /*a*/ + psp_memcpy( &( gl_file.pos ), &( gl_file.dirpos ), sizeof( F_POS ) ); + if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) ) + { + if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) ) + { + return 0; + } + + gl_file.startcluster = _f_getdecluster( de ); + gl_file.filesize = _f_getlong( &de->filesize ); + + if ( gl_file.startcluster ) + { + _f_clustertopos( gl_file.startcluster, &gl_file.pos ); + gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE); /*forcing seek to read 1st sector! abspos=0;*/ + if ( _f_fseek( (long)gl_file.filesize ) ) + { + gl_file.mode = F_FILE_CLOSE; + return 0; + } + } + } + else + { + psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) ); + _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos ); + + if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) ) + { + return 0; /*couldnt be added*/ + } + + de->attr |= F_ATTR_ARC; /*set as archiv*/ + if ( _f_writeglsector( (unsigned long)-1 ) ) + { + return 0; + } + } + + #if F_FILE_CHANGED_EVENT + _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); + #endif + break; + + + case F_FILE_WR: /*w*/ + case F_FILE_WRP: /*w+*/ + _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos ); + if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.pos, &de, 0 ) ) + { + unsigned long cluster = _f_getdecluster( de ); /*exist*/ + + if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) ) + { + return 0; + } + + psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) ); + + _f_setlong( de->filesize, 0 ); /*reset size;*/ + de->attr |= F_ATTR_ARC; /*set as archiv*/ + _f_setword( de->clusterlo, 0 ); /*no points anywhere*/ + _f_setword( de->clusterhi, 0 ); + + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + f_igettimedate( &time, &date ); + _f_setword( &de->crtdate, date ); /*if there is realtime clock then creation date could be set from*/ + _f_setword( &de->crttime, time ); /*if there is realtime clock then creation time could be set from*/ + _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/ + } + + if ( _f_writeglsector( (unsigned long)-1 ) ) + { + return 0; + } + + if ( _f_removechain( cluster ) ) + { + return 0; /*remove */ + } + } + else + { + if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) ) + { + return 0; /*couldnt be added*/ + } + + psp_memset( &gl_file, 0, 21 ); + de->attr |= F_ATTR_ARC; /*set as archiv*/ + if ( _f_writeglsector( (unsigned long)-1 ) ) + { + return 0; + } + } + + #if F_FILE_CHANGED_EVENT + _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); + #endif + + break; + + default: + return 0; /*invalid mode*/ + } /* switch */ + + if ( ( m_mode != F_FILE_RD ) && ( gl_file.startcluster == 0 ) ) + { + gl_volume.fatsector = (unsigned long)-1; + if ( _f_alloccluster( &( gl_file.startcluster ) ) ) + { + return 0; + } + + _f_clustertopos( gl_file.startcluster, &gl_file.pos ); + if ( _f_setclustervalue( gl_file.startcluster, F_CLUSTER_LAST ) ) + { + return 0; + } + + if ( _f_writefatsector() ) + { + return 0; + } + } + + + gl_file.mode = m_mode; /* lock it */ + return (F_FILE *)1; +} /* fn_open */ + + +/**************************************************************************** + * _f_updatefileentry + * Updated a file directory entry or removes the entry + * and the fat chain belonging to it. + ***************************************************************************/ +static unsigned char _f_updatefileentry ( int remove ) +{ + F_DIRENTRY * de; + unsigned short date; + unsigned short time; + + de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * gl_file.dirpos.pos ); + if ( _f_readglsector( gl_file.dirpos.sector ) || remove ) + { + _f_setdecluster( de, 0 ); + _f_setlong( &de->filesize, 0 ); + (void)_f_writeglsector( (unsigned long)-1 ); + (void)_f_removechain( gl_file.startcluster ); + return F_ERR_WRITE; + } + + _f_setdecluster( de, gl_file.startcluster ); + _f_setlong( &de->filesize, gl_file.filesize ); + f_igettimedate( &time, &date ); + _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/ + _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/ + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/ + } + + return _f_writeglsector( (unsigned long)-1 ); +} /* _f_updatefileentry */ + + +/**************************************************************************** + * + * fn_close + * + * close a previously opened file + * + * INPUTS + * + * filehandle - which file needs to be closed + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_close ( F_FILE * f ) +{ + unsigned char ret; + +#if F_FILE_CHANGED_EVENT + unsigned char mode; +#endif + + if ( !f ) + { + return F_ERR_NOTOPEN; + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( gl_file.mode == F_FILE_CLOSE ) + { + return F_ERR_NOTOPEN; + } + + else if ( gl_file.mode == F_FILE_RD ) + { + gl_file.mode = F_FILE_CLOSE; + return F_NO_ERROR; + } + else + { + #if F_FILE_CHANGED_EVENT + mode = f->mode; + #endif + gl_file.mode = F_FILE_CLOSE; + + if ( gl_file.modified ) + { + if ( _f_writeglsector( (unsigned long)-1 ) ) + { + (void)_f_updatefileentry( 1 ); + return F_ERR_WRITE; + } + } + + ret = _f_updatefileentry( 0 ); + + #if F_FILE_CHANGED_EVENT + if ( f_filechangedevent && !ret ) + { + ST_FILE_CHANGED fc; + if ( ( mode == F_FILE_WR ) || ( mode == F_FILE_WRP ) ) + { + fc.action = FACTION_ADDED; + fc.flags = FFLAGS_FILE_NAME; + } + else if ( ( mode == F_FILE_A ) || ( mode == F_FILE_RDP ) ) + { + fc.action = FACTION_MODIFIED; + fc.flags = FFLAGS_FILE_NAME | FFLAGS_SIZE; + } + + strcpy( fc.filename, f->filename ); + if ( f->filename[0] ) + { + f_filechangedevent( &fc ); + } + + f->filename[0] = '\0'; + } + + #endif /* if F_FILE_CHANGED_EVENT */ + return ret; + } +} /* fn_close */ + + +/**************************************************************************** + * + * fn_flush + * + * flush a previously opened file + * + * INPUTS + * + * filehandle - which file needs to be closed + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_flush ( F_FILE * f ) +{ + unsigned char ret; + + if ( !f ) + { + return F_ERR_NOTOPEN; + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( gl_file.mode == F_FILE_CLOSE ) + { + return F_ERR_NOTOPEN; + } + else if ( gl_file.mode != F_FILE_RD ) + { + if ( gl_file.modified ) + { + if ( _f_writeglsector( (unsigned long)-1 ) ) + { + (void)_f_updatefileentry( 1 ); + return F_ERR_WRITE; + } + } + + return _f_updatefileentry( 0 ); + } + + return F_NO_ERROR; +} /* fn_flush */ + + +/**************************************************************************** + * + * fn_read + * + * read data from file + * + * INPUTS + * + * buf - where the store data + * size - size of items to be read + * _size_t - number of items need to be read + * filehandle - file where to read from + * + * RETURNS + * + * with the number of read bytes + * + ***************************************************************************/ +long fn_read ( void * buf, long size, long _size_st, F_FILE * f ) +{ + char * buffer = (char *)buf; + long retsize; + + if ( !f ) + { + return 0; + } + + if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 ) + { + return 0; + } + + retsize = size; + size *= _size_st; + _size_st = retsize; + retsize = 0; + + if ( _f_getvolume() ) + { + return 0; /*cant read any*/ + } + + if ( size + gl_file.relpos + gl_file.abspos >= gl_file.filesize ) /*read len longer than the file*/ + { + size = (long)( ( gl_file.filesize ) - ( gl_file.relpos ) - ( gl_file.abspos ) ); /*calculate new size*/ + } + + if ( size <= 0 ) + { + return 0; + } + + if ( _f_getcurrsector() ) + { + gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/ + return 0; + } + + for( ; ; ) + { + unsigned long rdsize = (unsigned long)size; + + if ( gl_file.relpos == F_SECTOR_SIZE ) + { + unsigned char ret; + + gl_file.abspos += gl_file.relpos; + gl_file.relpos = 0; + + if ( gl_file.modified ) + { + ret = _f_writeglsector( (unsigned long)-1 ); /*empty write buffer */ + if ( ret ) + { + gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/ + return retsize; + } + } + + gl_file.pos.sector++; /*goto next*/ + + ret = _f_getcurrsector(); + if ( ( ret == F_ERR_EOF ) && ( !size ) ) + { + return retsize; + } + + if ( ret ) + { + gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/ + return retsize; + } + } + + if ( !size ) + { + break; + } + + if ( rdsize >= F_SECTOR_SIZE - gl_file.relpos ) + { + rdsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos ); + } + + psp_memcpy( buffer, gl_sector + gl_file.relpos, rdsize ); /*always less than 512*/ + + buffer += rdsize; + gl_file.relpos += rdsize; + size -= rdsize; + retsize += rdsize; + } + + return retsize / _size_st; +} /* fn_read */ + + +/**************************************************************************** + * + * fn_write + * + * write data into file + * + * INPUTS + * + * buf - where the store data + * size - size of items to be read + * size_t - number of items need to be read + * filehandle - file where to read from + * + * RETURNS + * + * with the number of read bytes + * + ***************************************************************************/ + +long fn_write ( const void * buf, long size, long _size_st, F_FILE * f ) +{ + char * buffer = (char *)buf; + long retsize; + long ret = 0; + + if ( !f ) + { + return 0; + } + + if ( ( gl_file.mode & ( F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 ) + { + return 0; + } + + retsize = size; + size *= _size_st; + _size_st = retsize; + retsize = 0; + + if ( _f_getvolume() ) + { + return 0; /*can't write*/ + } + + if ( ( gl_file.mode ) & ( F_FILE_A | F_FILE_AP ) ) + { + if ( _f_fseek( (long)gl_file.filesize ) ) + { + gl_file.mode = F_FILE_CLOSE; + return 0; + } + } + + if ( _f_getcurrsector() ) + { + gl_file.mode = F_FILE_CLOSE; + return 0; + } + + for( ; ; ) + { + unsigned long wrsize = (unsigned long)size; + + if ( gl_file.relpos == F_SECTOR_SIZE ) + { /*now full*/ + if ( gl_file.modified ) + { + if ( _f_emptywritebuffer() ) + { + gl_file.mode = F_FILE_CLOSE; + if ( _f_updatefileentry( 0 ) == 0 ) + { + return retsize; + } + else + { + return 0; + } + } + } + else + { + gl_file.pos.sector++; /*goto next*/ + } + + gl_file.abspos += gl_file.relpos; + gl_file.relpos = 0; + + if ( wrsize && ( wrsize < F_SECTOR_SIZE ) ) + { + ret = _f_getcurrsector(); + + if ( ret ) + { + if ( ret != F_ERR_EOF ) + { + gl_file.mode = F_FILE_CLOSE; /*no more read allowed*/ + return retsize; + } + } + } + } + + if ( !size ) + { + break; + } + + if ( wrsize >= F_SECTOR_SIZE - gl_file.relpos ) + { + wrsize = (unsigned long)( F_SECTOR_SIZE - gl_file.relpos ); + } + + + psp_memcpy( gl_sector + gl_file.relpos, buffer, wrsize ); + gl_file.modified = 1; /*sector is modified*/ + + buffer += wrsize; + gl_file.relpos += wrsize; + size -= wrsize; + retsize += wrsize; + + if ( gl_file.filesize < gl_file.abspos + gl_file.relpos ) + { + gl_file.filesize = gl_file.abspos + gl_file.relpos; + } + } + + return retsize / _size_st; +} /* fn_write */ + + + +/**************************************************************************** + * + * fn_seek + * + * moves position into given offset in given file + * + * INPUTS + * + * filehandle - F_FILE structure which file position needed to be modified + * offset - relative position + * whence - where to calculate position (F_SEEK_SET,F_SEEK_CUR,F_SEEK_END) + * + * RETURNS + * + * 0 - if successfully + * other - if any error + * + ***************************************************************************/ + + +unsigned char fn_seek ( F_FILE * f, long offset, unsigned char whence ) +{ + unsigned char ret; + + if ( !f ) + { + return F_ERR_NOTOPEN; + } + + if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 ) + { + return F_ERR_NOTOPEN; + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( whence == F_SEEK_CUR ) + { + return _f_fseek( (long)( gl_file.abspos + gl_file.relpos + offset ) ); + } + else if ( whence == F_SEEK_END ) + { + return _f_fseek( (long)( gl_file.filesize + offset ) ); + } + else if ( whence == F_SEEK_SET ) + { + return _f_fseek( offset ); + } + + return F_ERR_NOTUSEABLE; +} /* fn_seek */ + + + +/**************************************************************************** + * + * fn_tell + * + * Tells the current position of opened file + * + * INPUTS + * + * filehandle - which file needs the position + * + * RETURNS + * + * position in the file from start + * + ***************************************************************************/ + +long fn_tell ( F_FILE * f ) +{ + if ( !f ) + { + return 0; + } + + if ( ( gl_file.mode & ( F_FILE_RD | F_FILE_WR | F_FILE_A | F_FILE_RDP | F_FILE_WRP | F_FILE_AP ) ) == 0 ) + { + return 0; + } + + return (long)( gl_file.abspos + gl_file.relpos ); +} + + + +/**************************************************************************** + * + * fn_eof + * + * Tells if the current position is end of file or not + * + * INPUTS + * + * filehandle - which file needs the checking + * + * RETURNS + * + * 0 - if not EOF + * other - if EOF or invalid file handle + * + ***************************************************************************/ + +unsigned char fn_eof ( F_FILE * f ) +{ + if ( !f ) + { + return F_ERR_NOTOPEN; /*if error*/ + } + + if ( gl_file.abspos + gl_file.relpos < gl_file.filesize ) + { + return 0; + } + + return F_ERR_EOF; /*EOF*/ +} + + + + +/**************************************************************************** + * + * fn_rewind + * + * set the fileposition in the opened file to the begining + * + * INPUTS + * + * filehandle - which file needs to be rewinded + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ + +unsigned char fn_rewind ( F_FILE * filehandle ) +{ + return fn_seek( filehandle, 0L, F_SEEK_SET ); +} + + + +/**************************************************************************** + * + * fn_putc + * + * write a character into file + * + * INPUTS + * + * ch - what to write into file + * filehandle - file where to write + * + * RETURNS + * + * with the number of written bytes (1-success, 0-not successfully) + * + ***************************************************************************/ + +int fn_putc ( int ch, F_FILE * filehandle ) +{ + unsigned char tmpch = (unsigned char)ch; + + if ( fn_write( &tmpch, 1, 1, filehandle ) ) + { + return ch; + } + else + { + return -1; + } +} + + + +/**************************************************************************** + * + * fn_getc + * + * get a character from file + * + * INPUTS + * + * filehandle - file where to read from + * + * RETURNS + * + * with the read character or -1 if read was not successfully + * + ***************************************************************************/ +int fn_getc ( F_FILE * filehandle ) +{ + unsigned char ch; + + if ( !fn_read( &ch, 1, 1, filehandle ) ) + { + return -1; + } + + return (int)ch; +} + + + +/**************************************************************************** + * + * fn_delete + * + * delete a file + * + * INPUTS + * + * filename - file which wanted to be deleted (with or without path) + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_delete ( const char * filename ) +{ + F_POS pos; + F_DIRENTRY * de; + F_NAME fsname; + unsigned char ret; + + if ( _f_setfsname( filename, &fsname ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) + { + return F_ERR_INVALIDNAME; /*invalid name*/ + } + + if ( fsname.filename[0] == '.' ) + { + return F_ERR_NOTFOUND; + } + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + if ( !( _f_findpath( &fsname, &pos ) ) ) + { + return F_ERR_INVALIDDIR; + } + + if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) ) + { + return F_ERR_NOTFOUND; + } + + if ( de->attr & F_ATTR_DIR ) + { + return F_ERR_INVALIDDIR; /*directory*/ + } + + if ( de->attr & F_ATTR_READONLY ) + { + return F_ERR_ACCESSDENIED; /*readonly*/ + } + + if ( ( gl_file.mode != F_FILE_CLOSE ) && ( gl_file.dirpos.sector == pos.sector ) && ( gl_file.dirpos.pos == pos.pos ) ) + { + return F_ERR_LOCKED; + } + + de->name[0] = (unsigned char)0xe5; /*removes it*/ + ret = _f_writeglsector( (unsigned long)-1 ); + if ( ret ) + { + return ret; + } + + ret = _f_removechain( _f_getdecluster( de ) ); + + #if F_FILE_CHANGED_EVENT + if ( f_filechangedevent && !ret ) + { + ST_FILE_CHANGED fc; + fc.action = FACTION_REMOVED; + fc.flags = FFLAGS_FILE_NAME; + + if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) ) + { + f_filechangedevent( &fc ); + } + } + + #endif + + return ret; +} /* fn_delete */ + + + + +/**************************************************************************** + * + * _f_seteof + * + * Set end of file + * + * INPUT: f - file pointer + * filesize - required new size + * RETURN: F_NO_ERROR - on success + * other if error + * + ***************************************************************************/ +unsigned char _f_seteof ( F_FILE * f, long filesize ) +{ + unsigned char rc = F_NO_ERROR; + + if ( !f ) + { + return F_ERR_NOTOPEN; /*if error*/ + } + + if ( ( unsigned long) filesize < gl_file.filesize ) + { + rc = _f_fseek( filesize ); + if ( rc == F_NO_ERROR ) + { + unsigned long cluster; + rc = _f_getclustervalue( gl_file.pos.cluster, &cluster ); + if ( rc == F_NO_ERROR ) + { + if ( cluster != F_CLUSTER_LAST ) + { + rc = _f_removechain( cluster ); + if ( rc ) + { + return rc; + } + + rc = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST ); + if ( rc ) + { + return rc; + } + + rc = _f_writefatsector(); + if ( rc ) + { + return rc; + } + } + + gl_file.filesize = (unsigned long)filesize; + } + } + } + else if ( (unsigned long) filesize > gl_file.filesize ) + { + rc = _f_fseek( filesize ); + } + + return rc; +} /* _f_seteof */ + + +/**************************************************************************** + * + * fn_seteof + * + * Set end of file + * + * INPUT: f - file pointer + * filesize - required new size + * RETURN: F_NO_ERROR - on success + * other if error + * + ***************************************************************************/ +unsigned char fn_seteof ( F_FILE * f ) +{ + unsigned char rc = F_NO_ERROR; + + rc = _f_seteof( f, ( gl_file.abspos + gl_file.relpos ) ); + + return rc; +} /* fn_seteof */ + + + + +/**************************************************************************** + * + * fn_truncate + * + * Open a file and set end of file + * + * INPUT: filename - name of the file + * filesize - required new size + * RETURN: NULL on error, otherwise file pointer + * + ***************************************************************************/ +F_FILE * fn_truncate ( const char * filename, long filesize ) +{ + F_FILE * f = fn_open( filename, "r+" ); + unsigned char rc; + + if ( f != NULL ) + { + rc = _f_fseek( (long)gl_file.filesize ); + if ( rc == F_NO_ERROR ) + { + rc = _f_seteof( f, filesize ); + } + + if ( rc ) + { + fn_close( f ); + f = NULL; + } + } + + return f; +} /* fn_truncate */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h new file mode 100644 index 000000000..a124d0700 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.h @@ -0,0 +1,63 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __FILE_H +#define __FILE_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define F_FILE_CLOSE 0x00 +#define F_FILE_RD 0x01 +#define F_FILE_WR 0x02 +#define F_FILE_A 0x04 +#define F_FILE_RDP 0x08 +#define F_FILE_WRP 0x10 +#define F_FILE_AP 0x20 + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __FILE_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c new file mode 100644 index 000000000..590aecf01 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.c @@ -0,0 +1,320 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" +#include "../../psp/include/psp_rtc.h" +#include "dir.h" + +#include "util.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + + +/**************************************************************************** + * + * _f_getword + * + * get a word 16bit number from a memory (it uses LITTLE ENDIAN mode always) + * + * INPUTS + * + * ptr - pointer where data is + * + * RETURNS + * + * word number + * + ***************************************************************************/ +unsigned short _f_getword ( void * ptr ) +{ + unsigned char * sptr = (unsigned char *)ptr; + unsigned short ret; + + ret = (unsigned short)( sptr[1] & 0xff ); + ret <<= 8; + ret |= ( sptr[0] & 0xff ); + return ret; +} + + +/**************************************************************************** + * + * _f_setword + * + * set a word 16bit number into a memory (it uses LITTLE ENDIAN mode always) + * + * INPUTS + * + * ptr - where to store data + * num - 16 bit number to store + * + ***************************************************************************/ +void _f_setword ( void * ptr, unsigned short num ) +{ + unsigned char * sptr = (unsigned char *)ptr; + + sptr[1] = (unsigned char)( num >> 8 ); + sptr[0] = (unsigned char)( num ); +} + + +/**************************************************************************** + * + * _f_getlong + * + * get a long 32bit number from a memory (it uses LITTLE ENDIAN mode always) + * + * INPUTS + * + * ptr - pointer where data is + * + * RETURNS + * + * long number + * + ***************************************************************************/ +unsigned long _f_getlong ( void * ptr ) +{ + unsigned char * sptr = (unsigned char *)ptr; + unsigned long ret; + + ret = (unsigned long)( sptr[3] & 0xff ); + ret <<= 8; + ret |= ( sptr[2] & 0xff ); + ret <<= 8; + ret |= ( sptr[1] & 0xff ); + ret <<= 8; + ret |= ( sptr[0] & 0xff ); + return ret; +} + + +/**************************************************************************** + * + * _f_setlong + * + * set a long 32bit number into a memory (it uses LITTLE ENDIAN mode always) + * + * INPUTS + * + * ptr - where to store data + * num - 32 bit number to store + * + ***************************************************************************/ +void _f_setlong ( void * ptr, unsigned long num ) +{ + unsigned char * sptr = (unsigned char *)ptr; + + sptr[3] = (unsigned char)( num >> 24 ); + sptr[2] = (unsigned char)( num >> 16 ); + sptr[1] = (unsigned char)( num >> 8 ); + sptr[0] = (unsigned char)( num ); +} + + +/**************************************************************************** + * + * _setcharzero + * + * fills with zero charater to memory + * + * INPUTS + * + * num - number of characters + * ptr - where to store data + * + * RETURNS + * + * last write position + * + ***************************************************************************/ +unsigned char * _setcharzero ( int num, unsigned char * ptr ) +{ + while ( num-- ) + { + *ptr++ = 0; + } + + return ptr; +} + + +/**************************************************************************** + * + * _setchar + * + * copy a charater string to memory + * + * INPUTS + * + * array - original code what to copy + * num - number of characters + * ptr - where to store data + * + * RETURNS + * + * last write position + * + ***************************************************************************/ +unsigned char * _setchar ( const unsigned char * array, int num, unsigned char * ptr ) +{ + if ( !array ) + { + return _setcharzero( num, ptr ); + } + + while ( num-- ) + { + *ptr++ = *array++; + } + + return ptr; +} + + +/**************************************************************************** + * + * _setword + * + * store a 16bit word into memory + * + * INPUTS + * + * num - 16bit number to store + * ptr - where to store data + * + * RETURNS + * + * last write position + * + ***************************************************************************/ +unsigned char * _setword ( unsigned short num, unsigned char * ptr ) +{ + _f_setword( ptr, num ); + return ptr + 2; +} + + +/**************************************************************************** + * + * _setlong + * + * store a 32bit long number into memory + * + * INPUTS + * + * num - 32bit number to store + * ptr - where to store data + * + * RETURNS + * + * last write position + * + ***************************************************************************/ +unsigned char * _setlong ( unsigned long num, unsigned char * ptr ) +{ + _f_setlong( ptr, num ); + return ptr + 4; +} + + +/**************************************************************************** + * + * _f_toupper + * + * convert a string into lower case + * + * INPUTS + * + * s - input string to convert + * + ***************************************************************************/ +char _f_toupper ( char ch ) +{ + if ( ( ch >= 'a' ) && ( ch <= 'z' ) ) + { + return (char)( ch - 'a' + 'A' ); + } + + return ch; +} + + +/**************************************************************************** + * + * f_igettimedate + * + * INPUTS + * time - pointer to time variable + * date - pointer to date variable + * OUTPUTS + * time - current time + * date - current date + * + * RETURNS + * none + * + ***************************************************************************/ +void f_igettimedate ( unsigned short * time, unsigned short * date ) +{ + t_psp_timedate s_timedate; + + psp_getcurrenttimedate( &s_timedate ); + + *time = ( ( (uint16_t)s_timedate.hour << F_CTIME_HOUR_SHIFT ) & F_CTIME_HOUR_MASK ) + | ( ( (uint16_t)s_timedate.min << F_CTIME_MIN_SHIFT ) & F_CTIME_MIN_MASK ) + | ( ( ( (uint16_t)s_timedate.sec >> 1 ) << F_CTIME_SEC_SHIFT ) & F_CTIME_SEC_MASK ); + + *date = ( ( ( s_timedate.year - 1980 ) << F_CDATE_YEAR_SHIFT ) & F_CDATE_YEAR_MASK ) + | ( ( (uint16_t)s_timedate.month << F_CDATE_MONTH_SHIFT ) & F_CDATE_MONTH_MASK ) + | ( ( (uint16_t)s_timedate.day << F_CDATE_DAY_SHIFT ) & F_CDATE_DAY_MASK ); + + return; +} + + + + + + + + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h new file mode 100644 index 000000000..9d2366569 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util.h @@ -0,0 +1,73 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __UTIL_H +#define __UTIL_H + +#include "util_sfn.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void f_igettimedate ( unsigned short * time, unsigned short * date ); + +unsigned short _f_getword ( void * ); +unsigned long _f_getlong ( void * ); +char _f_toupper ( char ); +void _f_memset ( void *, unsigned char, int ); +void _f_memcpy ( void *, void *, int ); + +void _f_setword ( void *, unsigned short ); +void _f_setlong ( void *, unsigned long ); +unsigned char * _setcharzero ( int, unsigned char * ); +unsigned char * _setchar ( const unsigned char *, int, unsigned char * ); +unsigned char * _setword ( unsigned short, unsigned char * ); +unsigned char * _setlong ( unsigned long, unsigned char * ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __UTIL_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c new file mode 100644 index 000000000..1ddbee162 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.c @@ -0,0 +1,540 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" + +#include "util.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + + + +/**************************************************************************** + * + * _f_checknameprim + * + * checking a string if could be valid + * + * INPUTS + * + * ptr - pointer to name or extension + * len - number max char of name or extension + * + * RETURNS + * + ***************************************************************************/ +static unsigned char _f_checknameprim ( char * ptr, unsigned char len ) +{ + unsigned char inspace = 0; + + while ( len-- ) + { + char ch = *ptr++; + if ( !inspace ) + { + if ( ch == ' ' ) + { + inspace = 1; + } + + if ( ( ch == '|' ) || ( ch == '[' ) || ( ch == ']' ) || ( ch == '<' ) || ( ch == '>' ) || ( ch == '/' ) || ( ch == '\\' ) || ( ch == ':' ) ) + { + return 1; + } + } + else if ( ch != ' ' ) + { + return 1; /*no inspace allowed*/ + } + } + + return 0; +} /* _f_checknameprim */ + + +/**************************************************************************** + * + * _f_checkname + * + * checking filename and extension for special characters + * + * INPUTS + * + * name - filename (e.g.: filename) + * ext - extension of file (e.g.: txt) + * + * RETURNS + * + * 0 - if no contains invalid character + * other - if contains any invalid character + * + ***************************************************************************/ +unsigned char _f_checkname ( char * name, char * ext ) +{ + if ( _f_checknameprim( name, F_MAXNAME ) ) + { + return 1; + } + + if ( _f_checknameprim( ext, F_MAXEXT ) ) + { + return 1; + } + + return 0; +} + + +/**************************************************************************** + * + * _f_checknamewc + * + * checking filename and extension for wildcard character + * + * INPUTS + * + * name - filename (e.g.: filename) + * ext - extension of file (e.g.: txt) + * + * RETURNS + * + * 0 - if no contains wildcard character (? or *) + * other - if contains any wildcard character + * + ***************************************************************************/ +unsigned char _f_checknamewc ( const char * name, const char * ext ) +{ + unsigned char a = 0; + + for ( a = 0 ; a < F_MAXNAME ; a++ ) + { + char ch = name[a]; + if ( ( ch == '?' ) || ( ch == '*' ) ) + { + return 1; + } + } + + for ( a = 0 ; a < F_MAXEXT ; a++ ) + { + char ch = ext[a]; + if ( ( ch == '?' ) || ( ch == '*' ) ) + { + return 1; + } + } + + return _f_checkname( (char *)name, (char *)ext ); +} /* _f_checknamewc */ + + + + +/**************************************************************************** + * + * _f_setnameext + * + * convert a string into filename and extension separatelly, the terminator + * character could be zero char, '/' or '\' + * + * INPUTS + * + * s - source string (e.g.: hello.txt) + * name - where to store name (this array size has to be F_MAXNAME (8)) + * ext - where to store extension (this array size has to be F_MAXEXT (3)) + * + * RETURNS + * + * length of the used bytes from source string array + * + ***************************************************************************/ +unsigned char _f_setnameext ( char * s, char * name, char * ext ) +{ + unsigned char len, extlen = 0; + unsigned char a; + unsigned char setext = 1; + + for ( len = 0 ; ; ) + { + unsigned char ch = s[len]; + if ( ( ch == 0 ) || ( ch == '\\' ) || ( ch == '/' ) ) + { + break; + } + + len++; /*calculate len*/ + } + + if ( len && ( s[0] == '.' ) ) + { +/* if (len==1 || (s[1]=='.' && len==2)) goto dots; */ + if ( ( len == 1 ) || ( s[1] == '.' ) ) + { + goto dots; + } + } + + for ( a = len ; a ; a-- ) + { + if ( s[a - 1] == '.' ) + { + unsigned char b; + + extlen = (unsigned char)( len - a + 1 ); + len = (unsigned char)( a - 1 ); + + for ( b = 0 ; b < F_MAXEXT ; b++ ) + { + if ( b < extlen - 1 ) + { + ext[b] = _f_toupper( s[a++] ); + } + else + { + ext[b] = ' '; + } + } + + setext = 0; + break; + } + } + +dots: + if ( setext ) + { + for ( a = 0 ; a < F_MAXEXT ; a++ ) + { + ext[a] = ' '; + } + } + + for ( a = 0 ; a < F_MAXNAME ; a++ ) + { + if ( a < len ) + { + name[a] = _f_toupper( s[a] ); + } + else + { + name[a] = ' '; + } + } + + return (unsigned char)( len + extlen ); +} /* _f_setnameext */ + + + +/**************************************************************************** + * + * _f_setfsname + * + * convert a single string into F_NAME structure + * + * INPUTS + * + * name - combined name with drive,path,filename,extension used for source + * fsname - where to fill this structure with separated drive,path,name,ext + * + * RETURNS + * + * 0 - if successfully + * other - if name contains invalid path or name + * + ***************************************************************************/ +unsigned char _f_setfsname ( const char * name, F_NAME * fsname ) +{ + char s[F_MAXPATH]; + unsigned char namepos = 0; + + unsigned char pathpos = 0; + unsigned char a; + + s[0] = 0; + + if ( !name[0] ) + { + return 1; /*no name*/ + } + + if ( name[1] == ':' ) + { + name += 2; + } + + if ( ( name[0] != '/' ) && ( name[0] != '\\' ) ) + { + if ( fn_getcwd( fsname->path, F_MAXPATH, 0 ) ) + { + return 1; /*error*/ + } + + for ( pathpos = 0 ; fsname->path[pathpos] ; ) + { + pathpos++; + } + } + + + for ( ; ; ) + { + char ch = _f_toupper( *name++ ); + + if ( !ch ) + { + break; + } + + if ( ch == ':' ) + { + return 1; /*not allowed*/ + } + + if ( ( ch == '/' ) || ( ch == '\\' ) ) + { + if ( pathpos ) + { + if ( fsname->path[pathpos - 1] == '/' ) + { + return 1; /*not allowed double */ + } + + if ( pathpos >= F_MAXPATH - 2 ) + { + return 1; /*path too long*/ + } + + fsname->path[pathpos++] = '/'; + } + + for ( ; namepos ; ) + { + if ( s[namepos - 1] != ' ' ) + { + break; + } + + namepos--; /*remove end spaces*/ + } + + for ( a = 0 ; a < namepos ; a++ ) + { + if ( pathpos >= F_MAXPATH - 2 ) + { + return 1; /*path too long*/ + } + + fsname->path[pathpos++] = s[a]; + } + + namepos = 0; + continue; + } + + if ( ( ch == ' ' ) && ( !namepos ) ) + { + continue; /*remove start spaces*/ + } + + if ( namepos >= ( sizeof( s ) - 2 ) ) + { + return 1; /*name too long*/ + } + + s[namepos++] = ch; + } + + s[namepos] = 0; /*terminates it*/ + fsname->path[pathpos] = 0; /*terminates it*/ + + for ( ; namepos ; ) + { + if ( s[namepos - 1] != ' ' ) + { + break; + } + + s[namepos - 1] = 0; /*remove end spaces*/ + namepos--; + } + + if ( !_f_setnameext( s, fsname->filename, fsname->fileext ) ) + { + return 2; /*no name*/ + } + + if ( fsname->filename[0] == ' ' ) + { + return 1; /*cannot be*/ + } + + return 0; +} /* _f_setfsname */ + + +/**************************************************************************** + * + * _f_createfullname + * + * create full name + * + * INPUTS + * + * buffer - where to create + * buffersize - size of the buffer + * drivenum - drive number + * path - path of the file + * filename - file name + * fileext - file extension + * + * RETURNS + * + * 1 - if found and osize is filled + * 0 - not found + * + ***************************************************************************/ +int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext ) +{ + char * fullname = buffer; + int a; + + /* adding drive letter */ + if ( buffersize < 1 ) + { + return 1; + } + + *fullname++ = '/'; + buffersize -= 1; + + /* adding path */ + if ( path[0] ) + { + for ( ; ; ) + { + char ch = *path++; + + if ( !ch ) + { + break; + } + + if ( buffersize <= 0 ) + { + return 1; + } + + *fullname++ = ch; + buffersize--; + } + + /* adding separator */ + if ( buffersize <= 0 ) + { + return 1; + } + + *fullname++ = '/'; + } + + /* adding name */ + for ( a = 0 ; a < F_MAXNAME ; a++ ) + { + char ch = *filename++; + + if ( ( !ch ) || ( ch == 32 ) ) + { + break; + } + + if ( buffersize <= 0 ) + { + return 1; + } + + *fullname++ = ch; + buffersize--; + } + + /* adding ext*/ + if ( fileext[0] && ( fileext[0] != 32 ) ) + { + /* adding dot */ + if ( !buffersize ) + { + return 1; + } + + *fullname++ = '.'; + + for ( a = 0 ; a < F_MAXEXT ; a++ ) + { + char ch = *fileext++; + + if ( ( !ch ) || ( ch == 32 ) ) + { + break; + } + + if ( buffersize <= 0 ) + { + return 1; + } + + *fullname++ = ch; + buffersize--; + } + } + + /* adding terminator */ + if ( buffersize <= 0 ) + { + return 1; + } + + *fullname++ = 0; + + return 0; +} /* _f_createfullname */ + + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h new file mode 100644 index 000000000..8e9751a15 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/util_sfn.h @@ -0,0 +1,62 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __UTIL_SFN_H +#define __UTIL_SFN_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned char _f_checknamewc ( const char *, const char * ); +unsigned char _f_checkname ( char *, char * ); + +unsigned char _f_setnameext ( char *, char *, char * ); +unsigned char _f_setfsname ( const char *, F_NAME * ); +int _f_createfullname ( char * buffer, int buffersize, char * path, char * filename, char * fileext ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __UTIL_SFN_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c new file mode 100644 index 000000000..22609831d --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.c @@ -0,0 +1,939 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/fat_sl.h" +#include "../../psp/include/psp_string.h" + +#include "volume.h" +#include "util.h" +#include "drv.h" +#include "fat.h" +#include "dir.h" +#include "file.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#if F_FS_THREAD_AWARE == 1 + #include "f_lock.h" +#endif + +F_VOLUME gl_volume; /* only one volume */ +F_FILE gl_file; /* file */ +char gl_sector[F_SECTOR_SIZE]; /* actual sector */ + +#if F_FILE_CHANGED_EVENT +F_FILE_CHANGED_EVENTFUNC f_filechangedevent; +#endif + + +/* Defines the number of sectors per cluster on a sector number basis */ +typedef struct +{ + unsigned long max_sectors; + unsigned char sector_per_cluster; +} t_FAT32_CS; + +static const t_FAT32_CS FAT32_CS[] = +{ + { 0x00020000, 1 } /* ->64MB */ + , { 0x00040000, 2 } /* ->128MB */ + , { 0x00080000, 4 } /* ->256MB */ + , { 0x01000000, 8 } /* ->8GB */ + , { 0x02000000, 16 } /* ->16GB */ + , { 0x0ffffff0, 32 } /* -> ... */ +}; + + +/**************************************************************************** + * + * _f_writebootrecord + * + * writing boot record onto a volume, it uses number of hidden sector variable + * + * INPUTS + * phy - media physical descriptor + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +static unsigned char _f_writebootrecord ( F_PHY * phy ) +{ + unsigned char jump_code[] = + { + 0xeb, 0x3c, 0x90 + }; + unsigned char oem_name[] = "MSDOS5.0"; + unsigned char executable_marker[] = + { + 0x55, 0xaa + }; + unsigned char * ptr = (unsigned char *)gl_sector; + unsigned char rs; + unsigned short mre; + + unsigned char ret; + unsigned char _n = 0; + + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { /*write FS_INFO*/ + unsigned char a; + + rs = 32 + 4; + mre = 0; + + psp_memset( ptr, 0, F_SECTOR_SIZE ); + + for ( a = 0 ; a < rs ; a++ ) + { + ret = _f_writeglsector( a ); /*erase reserved area*/ + if ( ret ) + { + return ret; + } + } + + ptr = _setlong( 0x41615252, ptr ); /*signature*/ + ptr = _setcharzero( 480, ptr ); /*reserved*/ + ptr = _setlong( 0x61417272, ptr ); /*signature*/ + ptr = _setlong( 0xffffffff, ptr ); /*no last*/ + ptr = _setlong( 0xffffffff, ptr ); /*no hint*/ + ptr = _setcharzero( 12, ptr ); /*reserved*/ + ptr = _setlong( 0xaa550000, ptr ); /*trail*/ + + + ret = _f_writeglsector( 1 ); /*write FSINFO*/ + if ( ret ) + { + return ret; + } + + ret = _f_writeglsector( 1 + 6 ); /*write FSINFO*/ + if ( ret ) + { + return ret; + } + } + else + { + rs = 1; + mre = 512; + } + + ptr = (unsigned char *)gl_sector; + ptr = _setchar( jump_code, sizeof( jump_code ), ptr ); + ptr = _setchar( oem_name, sizeof( oem_name ) - 1, ptr ); + ptr = _setword( F_SECTOR_SIZE, ptr ); + *ptr++ = gl_volume.bootrecord.sector_per_cluster; + ptr = _setword( rs, ptr ); /* reserved sectors */ + *ptr++ = 2; /* number of FATs */ + ptr = _setword( mre, ptr ); /* max root entry */ + if ( phy->number_of_sectors < 0x10000 ) + { + ptr = _setword( (unsigned short)phy->number_of_sectors, ptr ); + } + else + { + ptr = _setword( 0, ptr ); + } + + *ptr++ = 0xf0; /* media descriptor */ + ptr = _setword( (unsigned short)gl_volume.bootrecord.sector_per_FAT, ptr ); + ptr = _setword( phy->sector_per_track, ptr ); + ptr = _setword( phy->number_of_heads, ptr ); + ptr = _setlong( 0, ptr ); /* number of hidden sectors */ + if ( phy->number_of_sectors >= 0x10000 ) + { + ptr = _setlong( phy->number_of_sectors, ptr ); + } + else + { + ptr = _setlong( 0, ptr ); /* number of sectors */ + } + + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + ptr = _setlong( gl_volume.bootrecord.sector_per_FAT32, ptr ); + ptr = _setword( 0, ptr ); + ptr = _setword( 0, ptr ); + ptr = _setlong( 2, ptr ); + ptr = _setword( 1, ptr ); + ptr = _setword( 6, ptr ); + ptr = _setchar( NULL, 12, ptr ); + _n = 28; + } + + + ptr = _setword( 0, ptr ); /* logical drive num */ + *ptr++ = 0x29; /* extended signature */ + ptr = _setlong( 0x11223344, ptr ); + ptr = _setchar( (const unsigned char *)"NO NAME ", 11, ptr ); /* volume name */ + + switch ( gl_volume.mediatype ) + { + case F_FAT12_MEDIA: + ptr = _setchar( (const unsigned char *)"FAT12 ", 8, ptr ); + break; + + case F_FAT16_MEDIA: + ptr = _setchar( (const unsigned char *)"FAT16 ", 8, ptr ); + break; + + case F_FAT32_MEDIA: + ptr = _setchar( (const unsigned char *)"FAT32 ", 8, ptr ); + break; + + default: + return F_ERR_INVALIDMEDIA; + } /* switch */ + + ptr = _setchar( 0, 448 - _n, ptr ); + ptr = _setchar( executable_marker, sizeof( executable_marker ), ptr ); + + if ( _n ) + { + ret = _f_writeglsector( 6 ); + if ( ret ) + { + return ret; + } + } + + + return _f_writeglsector( 0 ); /*write bootrecord*/ +} /* _f_writebootrecord */ + + +/**************************************************************************** + * + * _f_buildsectors + * + * INPUTS + * phy - media physical descriptor + * + * calculate relative sector position from boot record + * + ***************************************************************************/ +static unsigned char _f_buildsectors ( F_PHY * phy ) +{ + gl_volume.mediatype = F_UNKNOWN_MEDIA; + + + if ( gl_volume.bootrecord.sector_per_FAT ) + { + gl_volume.firstfat.sector = 1; + gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT; + gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs ) ); + gl_volume.root.num = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE; + + gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num; + gl_volume._tdata.num = 0; /*??*/ + } + else + { + gl_volume.firstfat.sector = ( 32 + 4 ); + gl_volume.firstfat.num = gl_volume.bootrecord.sector_per_FAT32; + gl_volume._tdata.sector = gl_volume.firstfat.sector; + gl_volume._tdata.sector += gl_volume.firstfat.num * (unsigned long)( gl_volume.bootrecord.number_of_FATs ); + gl_volume._tdata.num = 0; /*??*/ + + { + unsigned long sectorcou = gl_volume.bootrecord.sector_per_cluster; + gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * sectorcou ) + gl_volume._tdata.sector; + gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster; + } + } + + { + unsigned long maxcluster; + maxcluster = phy->number_of_sectors; + maxcluster -= gl_volume._tdata.sector; + maxcluster /= gl_volume.bootrecord.sector_per_cluster; + gl_volume.maxcluster = maxcluster; + } + + if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) ) + { + gl_volume.mediatype = F_FAT12_MEDIA; + } + else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) ) + { + gl_volume.mediatype = F_FAT16_MEDIA; + } + else + { + gl_volume.mediatype = F_FAT32_MEDIA; + } + + return F_NO_ERROR; +} /* _f_buildsectors */ + + + +/**************************************************************************** + * + * _f_prepareformat + * + * preparing boot record for formatting, it sets and calculates values + * + * INPUTS + * phy - media physical descriptor + * f_bootrecord - which bootrecord need to be prepare + * number_of_hidden_sectors - where boot record starts + * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +static unsigned char _f_prepareformat ( F_PHY * phy, unsigned char fattype ) +{ + if ( !phy->number_of_sectors ) + { + return F_ERR_INVALIDSECTOR; + } + + gl_volume.bootrecord.number_of_FATs = 2; + gl_volume.bootrecord.media_descriptor = 0xf0; + + if ( fattype != F_FAT32_MEDIA ) + { + unsigned long _n; + switch ( fattype ) + { + case F_FAT12_MEDIA: + _n = F_CLUSTER_RESERVED & 0xfff; + break; + + case F_FAT16_MEDIA: + _n = F_CLUSTER_RESERVED & 0xffff; + break; + + default: + return F_ERR_INVFATTYPE; + } + + gl_volume.bootrecord.sector_per_cluster = 1; + while ( gl_volume.bootrecord.sector_per_cluster ) + { + if ( phy->number_of_sectors / gl_volume.bootrecord.sector_per_cluster < _n ) + { + break; + } + + gl_volume.bootrecord.sector_per_cluster <<= 1; + } + + if ( !gl_volume.bootrecord.sector_per_cluster ) + { + return F_ERR_MEDIATOOLARGE; + } + } + + else + { + unsigned char i; + for ( i = 0 ; i<( sizeof( FAT32_CS ) / sizeof( t_FAT32_CS ) ) - 1 && phy->number_of_sectors>FAT32_CS[i].max_sectors ; i++ ) + { + } + + gl_volume.bootrecord.sector_per_cluster = FAT32_CS[i].sector_per_cluster; + } + if ( !gl_volume.bootrecord.sector_per_cluster ) + { + return F_ERR_INVALIDMEDIA; /*fat16 cannot be there*/ + } + + { + long secpercl = gl_volume.bootrecord.sector_per_cluster; + long nfat = gl_volume.bootrecord.number_of_FATs; + unsigned long roots; + unsigned long fatsec; + + roots = ( 512 * sizeof( F_DIRENTRY ) ) / F_SECTOR_SIZE; + + switch ( fattype ) + { + case F_FAT32_MEDIA: + { + unsigned long _n = (unsigned long)( 128 * secpercl + nfat ); + fatsec = ( phy->number_of_sectors - ( 32 + 4 ) + 2 * secpercl ); + fatsec += ( _n - 1 ); + fatsec /= _n; + gl_volume.bootrecord.sector_per_FAT32 = fatsec; + gl_volume.bootrecord.sector_per_FAT = 0; + } + break; + + case F_FAT16_MEDIA: + { + unsigned long _n = (unsigned long)( 256 * secpercl + nfat ); + fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl ); + fatsec += ( _n - 1 ); + fatsec /= _n; + gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec ); + } + break; + + case F_FAT12_MEDIA: + { + unsigned long _n = (unsigned long)( 1024 * secpercl + 3 * nfat ); + fatsec = ( phy->number_of_sectors - 1 - roots + 2 * secpercl ); + fatsec *= 3; + fatsec += ( _n - 1 ); + fatsec /= _n; + gl_volume.bootrecord.sector_per_FAT = (unsigned short)( fatsec ); + } + break; + + default: + return F_ERR_INVALIDMEDIA; + } /* switch */ + + return F_NO_ERROR; + } +} /* _f_prepareformat */ + + + +/**************************************************************************** + * + * _f_postformat + * + * erase fats, erase root directory, reset variables after formatting + * + * INPUTS + * phy - media physical descriptor + * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +static unsigned char _f_postformat ( F_PHY * phy, unsigned char fattype ) +{ + unsigned long a; + unsigned char ret; + + _f_buildsectors( phy ); /*get positions*/ + if ( gl_volume.mediatype != fattype ) + { + return F_ERR_MEDIATOOSMALL; + } + + gl_volume.fatsector = (unsigned long)( -1 ); + + { + unsigned char * ptr = (unsigned char *)gl_sector; + unsigned char j = 2; + unsigned long i; + + psp_memset( ptr, 0, F_SECTOR_SIZE ); + + switch ( gl_volume.mediatype ) + { + case F_FAT16_MEDIA: + j = 3; + break; + + case F_FAT32_MEDIA: + j = 11; + break; + } + + *ptr = gl_volume.bootrecord.media_descriptor; + psp_memset( ptr + 1, 0xff, j ); + if ( gl_volume.mediatype == F_FAT32_MEDIA ) + { + *( ptr + 8 ) = (unsigned char)( F_CLUSTER_LAST & 0xff ); + } + + (void)_f_writeglsector( gl_volume.firstfat.sector ); + (void)_f_writeglsector( gl_volume.firstfat.sector + gl_volume.firstfat.num ); + psp_memset( ptr, 0, ( j + 1 ) ); + + for ( i = 1 ; i < gl_volume.firstfat.num ; i++ ) + { + (void)_f_writeglsector( gl_volume.firstfat.sector + i ); + (void)_f_writeglsector( gl_volume.firstfat.sector + i + gl_volume.firstfat.num ); + } + } + + for ( a = 0 ; a < gl_volume.root.num ; a++ ) /*reset root direntries*/ + { + ret = _f_writeglsector( gl_volume.root.sector + a ); + if ( ret ) + { + return ret; + } + } + + return _f_writebootrecord( phy ); +} /* _f_postformat */ + + +/**************************************************************************** + * + * fn_hardformat + * + * Making a complete format on media, independently from master boot record, + * according to media physical + * + * INPUTS + * fattype - one of this definitions F_FAT12_MEDIA,F_FAT16_MEDIA,F_FAT32_MEDIA + * + * RETURNS + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_hardformat ( unsigned char fattype ) +{ + unsigned char ret; + int mdrv_ret; + F_PHY phy; + + ret = _f_getvolume(); + if ( ret && ( ret != F_ERR_NOTFORMATTED ) ) + { + return ret; + } + + gl_volume.state = F_STATE_NEEDMOUNT; + + psp_memset( &phy, 0, sizeof( F_PHY ) ); + + mdrv_ret = mdrv->getphy( mdrv, &phy ); + if ( mdrv_ret ) + { + return F_ERR_ONDRIVE; + } + + ret = _f_prepareformat( &phy, fattype ); /*no partition*/ + if ( ret ) + { + return ret; + } + + return _f_postformat( &phy, fattype ); +} /* fn_hardformat */ + + + + +/**************************************************************************** + * + * _f_readbootrecord + * + * read boot record from a volume, it detects if there is MBR on the media + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +static unsigned char _f_readbootrecord ( void ) +{ + unsigned char ret; + unsigned char * ptr = (unsigned char *)gl_sector; + unsigned long maxcluster, _n; + unsigned long first_sector = 0; + + gl_volume.mediatype = F_UNKNOWN_MEDIA; + + + ret = _f_readglsector( 0 ); + if ( ret ) + { + return ret; + } + + + if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) ) + { + return F_ERR_NOTFORMATTED; /*??*/ + } + + if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) ) + { + first_sector = _f_getlong( &ptr[0x08 + 0x1be] ); /*start sector for 1st partioon*/ + + ret = _f_readglsector( first_sector ); + if ( ret ) + { + return ret; + } + + if ( ( ptr[0x1fe] != 0x55 ) || ( ptr[0x1ff] != 0xaa ) ) + { + return F_ERR_NOTFORMATTED; /*??*/ + } + + if ( ( ptr[0] != 0xeb ) && ( ptr[0] != 0xe9 ) ) + { + return F_ERR_NOTFORMATTED; /*??*/ + } + } + + ptr += 11; + if ( _f_getword( ptr ) != F_SECTOR_SIZE ) + { + return F_ERR_NOTSUPPSECTORSIZE; + } + + ptr += 2; + gl_volume.bootrecord.sector_per_cluster = *ptr++; + gl_volume.firstfat.sector = _f_getword( ptr ); + ptr += 2; + gl_volume.bootrecord.number_of_FATs = *ptr++; + gl_volume.root.num = _f_getword( ptr ); + ptr += 2; + gl_volume.root.num *= sizeof( F_DIRENTRY ); + gl_volume.root.num /= F_SECTOR_SIZE; + maxcluster = _f_getword( ptr ); + ptr += 2; + gl_volume.bootrecord.media_descriptor = *ptr++; + gl_volume.firstfat.num = _f_getword( ptr ); + ptr += 6; + _n = _f_getlong( ptr ); + ptr += 4; + if ( _n < first_sector ) + { + _n = first_sector; + } + + gl_volume.firstfat.sector += _n; + if ( !maxcluster ) + { + maxcluster = _f_getlong( ptr ); + } + + ptr += 4; + + + if ( gl_volume.firstfat.num ) + { + gl_volume.root.sector = gl_volume.firstfat.sector + ( gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs ); + gl_volume._tdata.sector = gl_volume.root.sector + gl_volume.root.num; + gl_volume._tdata.num = 0; + ptr += 3; + } + else + { + gl_volume.firstfat.num = _f_getlong( ptr ); + ptr += 8; + gl_volume._tdata.sector = gl_volume.firstfat.sector; + gl_volume._tdata.sector += gl_volume.firstfat.num * gl_volume.bootrecord.number_of_FATs; + gl_volume._tdata.num = 0; + gl_volume.bootrecord.rootcluster = _f_getlong( ptr ); + ptr += 23; + gl_volume.root.num = gl_volume.bootrecord.sector_per_cluster; + gl_volume.root.sector = ( ( gl_volume.bootrecord.rootcluster - 2 ) * gl_volume.root.num ) + gl_volume._tdata.sector; + } + + gl_volume.bootrecord.serial_number = _f_getlong( ptr ); + + maxcluster -= gl_volume._tdata.sector; + maxcluster += _n; + gl_volume.maxcluster = maxcluster / gl_volume.bootrecord.sector_per_cluster; + + if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xfff ) ) + { + gl_volume.mediatype = F_FAT12_MEDIA; + } + else if ( gl_volume.maxcluster < ( F_CLUSTER_RESERVED & 0xffff ) ) + { + gl_volume.mediatype = F_FAT16_MEDIA; + } + else + { + gl_volume.mediatype = F_FAT32_MEDIA; + } + + if ( gl_volume.bootrecord.media_descriptor != 0xf8 ) /*fixdrive*/ + { + if ( gl_volume.bootrecord.media_descriptor != 0xf0 ) /*removable*/ + { + return F_ERR_NOTFORMATTED; /*??*/ + } + } + + return F_NO_ERROR; +} /* _f_readbootrecord */ + + + + +/**************************************************************************** + * + * _f_getvolume + * + * getting back a volume info structure of a given drive, it try to mounts + * drive if it was not mounted before + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char _f_getvolume ( void ) +{ + switch ( gl_volume.state ) + { + case F_STATE_NONE: + return F_ERR_ONDRIVE; + + case F_STATE_WORKING: + + if ( !_f_checkstatus() ) + { + return F_NO_ERROR; + } + + /* here we don't stop case flow, */ + /* because we have to clean up this volume! */ + + case F_STATE_NEEDMOUNT: + { + gl_file.modified = 0; + gl_volume.modified = 0; + gl_volume.lastalloccluster = 0; + gl_volume.actsector = (unsigned long)( -1 ); + gl_volume.fatsector = (unsigned long)( -1 ); + + gl_file.mode = F_FILE_CLOSE; + + gl_volume.cwd[0] = 0; /*reset cwd*/ + gl_volume.mediatype = F_UNKNOWN_MEDIA; + + if ( mdrv->getstatus != NULL ) + { + if ( mdrv->getstatus( mdrv ) & F_ST_MISSING ) + { + gl_volume.state = F_STATE_NEEDMOUNT; /*card missing*/ + return F_ERR_CARDREMOVED; + } + } + + if ( !_f_readbootrecord() ) + { + gl_volume.state = F_STATE_WORKING; + return F_NO_ERROR; + } + + gl_volume.mediatype = F_UNKNOWN_MEDIA; + return F_ERR_NOTFORMATTED; + } + } /* switch */ + + return F_ERR_ONDRIVE; +} /* _f_getvolume */ + + + +/**************************************************************************** + * + * fn_getfreespace + * + * get total/free/used/bad diskspace + * + * INPUTS + * pspace - pointer where to store the information + * + * RETURNS + * error code + * + ***************************************************************************/ +unsigned char fn_getfreespace ( F_SPACE * pspace ) +{ + unsigned char ret; + unsigned long a; + unsigned long clustersize; + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + psp_memset( pspace, 0, sizeof( F_SPACE ) ); + pspace->total = gl_volume.maxcluster; + + gl_volume.fatsector = (unsigned long)-1; + for ( a = 2 ; a < gl_volume.maxcluster + 2 ; a++ ) + { + unsigned long value; + + ret = _f_getclustervalue( a, &value ); + if ( ret ) + { + return ret; + } + + if ( !value ) + { + ++( pspace->free ); + } + else if ( value == F_CLUSTER_BAD ) + { + ++( pspace->bad ); + } + else + { + ++( pspace->used ); + } + } + + clustersize = (unsigned long)( gl_volume.bootrecord.sector_per_cluster * F_SECTOR_SIZE ); + for ( a = 0 ; ( clustersize & 1 ) == 0 ; a++ ) + { + clustersize >>= 1; + } + + pspace->total_high = ( pspace->total ) >> ( 32 - a ); + pspace->total <<= a; + pspace->free_high = ( pspace->free ) >> ( 32 - a ); + pspace->free <<= a; + pspace->used_high = ( pspace->used ) >> ( 32 - a ); + pspace->used <<= a; + pspace->bad_high = ( pspace->bad ) >> ( 32 - a ); + pspace->bad <<= a; + + return F_NO_ERROR; +} /* fn_getfreespace */ + + +/**************************************************************************** + * + * fn_getserial + * + * get serial number + * + * INPUTS + * serial - pointer where to store the serial number + * + * RETURNS + * error code + * + ***************************************************************************/ +unsigned char fn_getserial ( unsigned long * serial ) +{ + unsigned char ret; + + ret = _f_getvolume(); + if ( ret ) + { + return ret; + } + + *serial = gl_volume.bootrecord.serial_number; + return 0; +} + +/* +** fn_init +** +** Initialize FAT_SL file system +** +** RETURN: F_NO_ERROR on success, other if error. +*/ +unsigned char fn_init ( void ) +{ + return F_NO_ERROR; +} /* fn_init */ + +/**************************************************************************** + * + * fn_initvolume + * + * initiate a volume, this function has to be called 1st to set physical + * driver function to a given volume + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +unsigned char fn_initvolume ( F_DRIVERINIT initfunc ) +{ +#if F_FS_THREAD_AWARE == 1 + { + if( fs_lock_semaphore == NULL ) + { + fs_lock_semaphore = xSemaphoreCreateMutex(); + if( fs_lock_semaphore == NULL ) + { + return F_ERR_OS; + } + } + } +#endif /* F_FS_THREAD_AWARE */ + + gl_volume.state = F_STATE_NONE; + + mdrv = initfunc( 0 ); + if ( mdrv == NULL ) + { + return F_ERR_INITFUNC; + } + + gl_volume.state = F_STATE_NEEDMOUNT; + +#if F_FILE_CHANGED_EVENT + f_filechangedevent = 0; +#endif + + return _f_getvolume(); +} /* fn_initvolume */ + +/**************************************************************************** + * + * fn_delvolume + * + ***************************************************************************/ +unsigned char fn_delvolume ( void ) +{ + if ( mdrv->release ) + { + (void)mdrv->release( mdrv ); + } + + return 0; +} diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h new file mode 100644 index 000000000..e65a44f8d --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/volume.h @@ -0,0 +1,113 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __VOLUME_H +#define __VOLUME_H + +#include "config_fat_sl.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct +{ + unsigned char sector_per_cluster; + unsigned char number_of_FATs; + unsigned char media_descriptor; + unsigned long rootcluster; + unsigned long sector_per_FAT; + unsigned long sector_per_FAT32; + unsigned long serial_number; +} F_BOOTRECORD; + + +typedef struct +{ + unsigned long sector; /*start sector*/ + unsigned long num; /*number of sectors*/ +} F_SECTOR; + + +typedef struct +{ + unsigned char state; + F_BOOTRECORD bootrecord; + F_SECTOR firstfat; + F_SECTOR root; + F_SECTOR _tdata; + + unsigned long actsector; + unsigned long fatsector; + + unsigned long lastalloccluster; + unsigned char modified; + char cwd[F_MAXPATH]; /*current working folder in this volume*/ + unsigned char mediatype; + unsigned long maxcluster; +} F_VOLUME; + + +enum +{ +/* 0 */ + F_STATE_NONE, + +/* 1 */ F_STATE_NEEDMOUNT, + +/* 2 */ F_STATE_WORKING +}; + + +extern F_VOLUME gl_volume; +extern F_FILE gl_file; +extern char gl_sector[F_SECTOR_SIZE]; /* actual sector */ + +unsigned char _f_getvolume ( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __VOLUME_H */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c new file mode 100644 index 000000000..ef67ad094 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.c @@ -0,0 +1,2752 @@ +#ifndef _TEST_C_ +#define _TEST_C_ + + +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "test.h" +#include "../../api/fat_sl.h" +#include "../../psp/target/fat_sl/psp_test.h" + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +static char cwd[F_MAXPATH]; + +static F_FIND find; + +static void _f_deleteall ( void ) +{ + F_FIND f2; + unsigned char sd = 0, rc, fl = 0; + + f2 = find; + do + { + rc = f_findfirst( "*.*", &find ); + while ( rc == 0 && find.filename[0] == '.' ) + { + rc = f_findnext( &find ); + } + + if ( rc == 0 ) + { + if ( find.attr & F_ATTR_DIR ) + { + ++sd; + fl = 1; + f2 = find; + (void)f_chdir( find.filename ); + continue; + } + else + { + (void)f_delete( find.filename ); + rc = f_findnext( &find ); + } + } + + if ( rc && sd && fl ) + { + (void)f_chdir( ".." ); + --sd; + fl = 0; + find = f2; + (void)f_rmdir( find.filename ); + rc = f_findnext( &find ); + } + + if ( rc && sd && !fl ) + { + (void)f_chdir( "/" ); + sd = 0; + rc = 0; + } + } + while ( rc == 0 ); +} /* _f_deleteall */ + +char stmp[20]; +static char * f_nameconv ( char * s ) +{ + char * ss = stmp; + + for ( ; ; ) + { + char ch = *s++; + if ( ( ch >= 'a' ) && ( ch <= 'z' ) ) + { + ch += 'A' - 'a'; + } + + *ss++ = ch; + if ( !ch ) + { + break; + } + } + + return stmp; +} /* f_nameconv */ + +static unsigned char f_formatting ( void ) +{ + unsigned char ret; + + _f_dump( "f_formatting" ); + +/*checking formatting*/ + ret = f_format( F_FAT_TYPE ); + if ( ret ) + { + return _f_result( 0, ret ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 1, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 2, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_formatting */ + +static unsigned char _f_checkcwd ( char * orig ) +{ + unsigned char ret; + + ret = f_getcwd( cwd, F_MAXPATH ); + if ( ret ) + { + return ret; + } + + if ( strcmp( orig, cwd ) ) + { + return (unsigned char)-1; + } + + return 0; +} + +static unsigned char f_dirtest ( void ) +{ + unsigned char ret; + + _f_dump( "f_dirtest" ); + + _f_deleteall(); + +/*creates a ab abc abcd*/ + ret = f_mkdir( "a" ); + if ( ret ) + { + return _f_result( 1, ret ); + } + + ret = f_mkdir( "ab" ); + if ( ret ) + { + return _f_result( 2, ret ); + } + + ret = f_mkdir( "abc" ); + if ( ret ) + { + return _f_result( 3, ret ); + } + + ret = f_mkdir( "abca" ); + if ( ret ) + { + return _f_result( 4, ret ); + } + +/*creates directories in /a - a ab abc abcd*/ + ret = f_mkdir( "a/a" ); + if ( ret ) + { + return _f_result( 5, ret ); + } + + ret = f_mkdir( "a/ab" ); + if ( ret ) + { + return _f_result( 6, ret ); + } + + ret = f_mkdir( "a/abc" ); + if ( ret ) + { + return _f_result( 7, ret ); + } + + ret = f_mkdir( "a/abcd" ); + if ( ret ) + { + return _f_result( 8, ret ); + } + +/*change into a/abcd and check cwd*/ + ret = f_chdir( "a/abcd" ); + if ( ret ) + { + return _f_result( 9, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd" ) ); + if ( ret ) + { + return _f_result( 10, ret ); + } + +/*make directory t change into t and check cwd="a/abcd/t"*/ + ret = f_mkdir( "t" ); + if ( ret ) + { + return _f_result( 11, ret ); + } + + ret = f_chdir( "t" ); + if ( ret ) + { + return _f_result( 12, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) ); + if ( ret ) + { + return _f_result( 13, ret ); + } + + ret = f_chdir( "." ); + if ( ret ) + { + return _f_result( 14, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd/t" ) ); + if ( ret ) + { + return _f_result( 15, ret ); + } + + ret = f_chdir( "../." ); + if ( ret ) + { + return _f_result( 16, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd" ) ); + if ( ret ) + { + return _f_result( 17, ret ); + } + +/*removing t dir*/ + ret = f_rmdir( "t" ); + if ( ret ) + { + return _f_result( 18, ret ); + } + + ret = f_chdir( "t" ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 19, ret ); + } + +/*removing /a dir*/ + ret = f_rmdir( "/ab" ); + if ( ret ) + { + return _f_result( 20, ret ); + } + + ret = f_chdir( "/ab" ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 21, ret ); + } + +/*removing /a dir*/ + ret = f_rmdir( "../../a" ); + if ( ret != F_ERR_NOTEMPTY ) + { + return _f_result( 22, ret ); + } + +/*removing /abca dir*/ + ret = f_rmdir( "a:/abca" ); + if ( ret ) + { + return _f_result( 24, ret ); + } + +/*changing invalid dirs*/ + ret = f_chdir( "" ); + if ( ret != F_ERR_INVALIDNAME ) + { + return _f_result( 25, ret ); + } + + ret = f_chdir( " " ); + if ( ret ) + { + return _f_result( 26, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd" ) ); + if ( ret ) + { + return _f_result( 27, ret ); + } + + ret = f_chdir( "?" ); + if ( ret != F_ERR_INVALIDNAME ) + { + return _f_result( 28, ret ); + } + + ret = f_chdir( "*.*" ); + if ( ret != F_ERR_INVALIDNAME ) + { + return _f_result( 29, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/a/abcd" ) ); + if ( ret ) + { + return _f_result( 30, ret ); + } + +/*changing into /abc and removes subfolder from /a/ */ + ret = f_chdir( "/abc" ); + if ( ret ) + { + return _f_result( 31, ret ); + } + + ret = f_rmdir( "/a/a" ); + if ( ret ) + { + return _f_result( 32, ret ); + } + + ret = f_rmdir( "A:../a/ab" ); + if ( ret ) + { + return _f_result( 33, ret ); + } + + ret = f_rmdir( "A:/a/abc" ); + if ( ret ) + { + return _f_result( 34, ret ); + } + + ret = f_rmdir( ".././abc/.././a/../a/abcd" ); + if ( ret ) + { + return _f_result( 35, ret ); + } + +/*some invalid rmdir*/ + ret = f_rmdir( "." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 36, ret ); + } + + ret = f_rmdir( ".." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 37, ret ); + } + +/*create again abc remove abc*/ + ret = f_mkdir( ".././abc" ); + if ( ret != F_ERR_DUPLICATED ) + { + return _f_result( 38, ret ); + } + + ret = f_rmdir( "../abc" ); + if ( ret ) + { + return _f_result( 39, ret ); + } + + ret = f_mkdir( ".././abc" ); + if ( ret != F_ERR_INVALIDDIR ) + { + return _f_result( 40, ret ); /*cwd is not exist*/ + } + + ret = f_chdir( "/" ); + if ( ret ) + { + return _f_result( 41, ret ); + } + +/*try . and .. in the root*/ + ret = f_chdir( "." ); + if ( ret ) + { + return _f_result( 42, ret ); + } + + ret = f_chdir( "./././." ); + if ( ret ) + { + return _f_result( 43, ret ); + } + + ret = f_chdir( ".." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 44, ret ); + } + + ret = _f_checkcwd( "/" ); /*root!*/ + if ( ret ) + { + return _f_result( 45, ret ); + } + +/*test . and .. in a and remove a*/ + ret = f_chdir( "a" ); + if ( ret ) + { + return _f_result( 46, ret ); + } + + ret = f_chdir( ".." ); + if ( ret ) + { + return _f_result( 47, ret ); + } + + ret = f_chdir( "a" ); + if ( ret ) + { + return _f_result( 48, ret ); + } + + ret = f_chdir( "." ); + if ( ret ) + { + return _f_result( 49, ret ); + } + + ret = f_chdir( "a" ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 50, ret ); + } + + ret = f_chdir( "./.." ); + if ( ret ) + { + return _f_result( 51, ret ); + } + + ret = f_rmdir( "a" ); + if ( ret ) + { + return _f_result( 52, ret ); + } + +/*check if all are removed*/ + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 53, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_dirtest */ + + +static unsigned char f_findingtest ( void ) +{ + unsigned char ret; + + _f_dump( "f_findingtest" ); + + _f_deleteall(); + +/*check empty*/ + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 0, ret ); + } + +/*create Hello.dir*/ + ret = f_mkdir( "Hello.dir" ); + if ( ret ) + { + return _f_result( 1, ret ); + } + +/*check if it is exist, and only exist*/ + ret = f_findfirst( "*.*", &find ); + if ( ret ) + { + return _f_result( 2, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "Hello.dir" ) ) ) + { + return _f_result( 3, 0 ); + } + + if ( find.attr != F_ATTR_DIR ) + { + return _f_result( 4, 0 ); + } + + ret = f_findnext( &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 5, ret ); + } + +/*check some not founds*/ + ret = f_findfirst( "q*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 6, ret ); + } + + ret = f_findfirst( "Hello.", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 7, ret ); + } + + ret = f_findfirst( "a/*.*", &find ); + if ( ret != F_ERR_INVALIDDIR ) + { + return _f_result( 8, ret ); + } + + ret = f_findfirst( ".", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 9, ret ); + } + + ret = f_findfirst( "..", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 10, ret ); + } + + ret = f_findfirst( "?e.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 11, ret ); + } + + ret = f_findfirst( "*.", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 12, ret ); + } + + ret = f_findfirst( "*.?", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 13, ret ); + } + + ret = f_findfirst( "*.??", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 14, ret ); + } + + +/*check some founds*/ + ret = f_findfirst( "*.dir", &find ); + if ( ret ) + { + return _f_result( 15, ret ); + } + + ret = f_findfirst( "*.d?r", &find ); + if ( ret ) + { + return _f_result( 16, ret ); + } + + ret = f_findfirst( "*.d??", &find ); + if ( ret ) + { + return _f_result( 17, ret ); + } + + ret = f_findfirst( "*.???", &find ); + if ( ret ) + { + return _f_result( 18, ret ); + } + + ret = f_findfirst( "?ello.???", &find ); + if ( ret ) + { + return _f_result( 19, ret ); + } + + ret = f_findfirst( "he??o.dir", &find ); + if ( ret ) + { + return _f_result( 20, ret ); + } + + ret = f_findfirst( "he?*.dir", &find ); + if ( ret ) + { + return _f_result( 21, ret ); + } + + ret = f_findfirst( "HELLO.DIR", &find ); /*no capitals sensitivity in find!!*/ + if ( ret ) + { + return _f_result( 22, ret ); + } + +/*change into hello.dir*/ + ret = f_chdir( "hello.dir" ); + if ( ret ) + { + return _f_result( 23, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret ) + { + return _f_result( 24, ret ); + } + + ret = f_findfirst( "..", &find ); + if ( ret ) + { + return _f_result( 25, ret ); + } + + ret = f_findfirst( "??", &find ); + if ( ret ) + { + return _f_result( 26, ret ); + } + + ret = f_findfirst( ".", &find ); + if ( ret ) + { + return _f_result( 27, ret ); + } + + ret = f_findfirst( "k*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 28, ret ); + } + + ret = f_findfirst( "*.", &find ); + if ( ret ) + { + return _f_result( 29, ret ); + } + + if ( strcmp( find.filename, "." ) ) + { + return _f_result( 29, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 29, ret ); + } + + if ( strcmp( find.filename, ".." ) ) + { + return _f_result( 29, 0 ); + } + + ret = f_findnext( &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 29, ret ); + } + + + ret = f_findfirst( "*.a", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 30, ret ); + } + +/*creating testdir and find it*/ + ret = f_mkdir( "testdir" ); + if ( ret ) + { + return _f_result( 31, ret ); + } + + ret = f_findfirst( "*.", &find ); + if ( ret ) + { + return _f_result( 32, ret ); + } + + if ( strcmp( find.filename, "." ) ) + { + return _f_result( 32, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 32, ret ); + } + + if ( strcmp( find.filename, ".." ) ) + { + return _f_result( 32, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 32, ret ); + } + + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 33, 0 ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret ) + { + return _f_result( 34, ret ); + } + + if ( strcmp( find.filename, "." ) ) + { + return _f_result( 35, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 35, ret ); + } + + if ( strcmp( find.filename, ".." ) ) + { + return _f_result( 35, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 36, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 37, 0 ); + } + + ret = f_findnext( &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 38, ret ); + } + +/*search exact file*/ + ret = f_findfirst( "testDir", &find ); /*no capitals!*/ + if ( ret ) + { + return _f_result( 39, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 40, 0 ); + } + + ret = f_findnext( &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 41, ret ); + } + + +/*go back to root and remove dirs*/ + ret = f_chdir( "\\" ); + if ( ret ) + { + return _f_result( 42, ret ); + } + + ret = f_rmdir( "Hello.dir/testdir" ); + if ( ret ) + { + return _f_result( 43, ret ); + } + + ret = f_rmdir( "Hello.dir" ); + if ( ret ) + { + return _f_result( 44, ret ); + } + +/*check if all are removed*/ + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 45, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_findingtest */ + +static unsigned char f_powerfail ( void ) +{ + unsigned char ret; + + _f_dump( "f_powerfail" ); + +/*checking if its power fail system (RAMDRIVE is not powerfail!)*/ + ret = f_mkdir( "testdir" ); + if ( ret ) + { + return _f_result( 0, ret ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 1, ret ); + } + + ret = f_findfirst( "testdir", &find ); + if ( ret ) + { + return _f_result( 2, ret ); + } + +/*checking formatting*/ + ret = f_format( F_FAT_TYPE ); + if ( ret ) + { + return _f_result( 3, ret ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 4, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 5, ret ); + } + +/*checking formatting, 1st creating*/ + ret = f_format( F_FAT_TYPE ); + if ( ret ) + { + return _f_result( 6, ret ); + } + + ret = f_mkdir( "testdir" ); + if ( ret ) + { + return _f_result( 7, ret ); + } + + ret = f_findfirst( "testdir", &find ); + if ( ret ) + { + return _f_result( 8, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 9, 0 ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 10, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret ) + { + return _f_result( 11, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 12, 0 ); + } + +/*checking formatting, 2nd creating*/ + ret = f_format( F_FAT_TYPE ); + if ( ret ) + { + return _f_result( 13, ret ); + } + + ret = f_mkdir( "testdir" ); + if ( ret ) + { + return _f_result( 14, ret ); + } + + ret = f_findfirst( "testdir", &find ); + if ( ret ) + { + return _f_result( 15, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 16, 0 ); + } + + ret = f_mkdir( "testdir2" ); + if ( ret ) + { + return _f_result( 17, ret ); + } + + ret = f_findfirst( "testdir2", &find ); + if ( ret ) + { + return _f_result( 18, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) ) + { + return _f_result( 19, 0 ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 20, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret ) + { + return _f_result( 21, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir" ) ) ) + { + return _f_result( 22, 0 ); + } + + ret = f_findnext( &find ); + if ( ret ) + { + return _f_result( 23, ret ); + } + + if ( strcmp( find.filename, f_nameconv( "testdir2" ) ) ) + { + return _f_result( 24, 0 ); + } + + ret = f_findnext( &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 25, ret ); + } + + +/*checking empty*/ + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 26, ret ); + } + + ret = f_format( F_FAT_TYPE ); + if ( ret ) + { + return _f_result( 27, ret ); + } + + ret = _f_poweron(); + if ( ret ) + { + return _f_result( 28, ret ); + } + + ret = f_findfirst( "*.*", &find ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 29, ret ); + } + + + _f_dump( "passed..." ); + return 0; +} /* f_powerfail */ + + +char testbuffer[F_MAX_SEEK_TEST + 16]; /* +16 for f_appending test */ + +static unsigned char checkfilecontent ( long nums, unsigned char value, F_FILE * file ) +{ + unsigned char ch; + + while ( nums-- ) + { + if ( f_eof( file ) ) + { + return 1; /*eof ?*/ + } + + if ( 1 != f_read( &ch, 1, 1, file ) ) + { + return 1; + } + + if ( ch != value ) + { + return 1; + } + } + + return 0; +} /* checkfilecontent */ + +static unsigned char f_seeking ( int sectorsize ) +{ + F_FILE * file; + unsigned char ret; + unsigned long size; + unsigned long pos; + + if ( sectorsize == 128 ) + { + _f_dump( "f_seeking with 128" ); + } + + #if ( F_MAX_SEEK_TEST > 128 ) + else if ( sectorsize == 256 ) + { + _f_dump( "f_seeking with 256" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 256 ) + else if ( sectorsize == 512 ) + { + _f_dump( "f_seeking with 512" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 512 ) + else if ( sectorsize == 1024 ) + { + _f_dump( "f_seeking with 1024" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 1024 ) + else if ( sectorsize == 2048 ) + { + _f_dump( "f_seeking with 2048" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 2048 ) + else if ( sectorsize == 4096 ) + { + _f_dump( "f_seeking with 4096" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 4096 ) + else if ( sectorsize == 8192 ) + { + _f_dump( "f_seeking with 8192" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 8192 ) + else if ( sectorsize == 16384 ) + { + _f_dump( "f_seeking with 16384" ); + } + #endif + #if ( F_MAX_SEEK_TEST > 16384 ) + else if ( sectorsize == 32768 ) + { + _f_dump( "f_seeking with 32768" ); + } + #endif + else + { + _f_dump( "f_seeking with random" ); + } + +/*checking sector boundary seekeng*/ + file = f_open( "test.bin", "w+" ); + if ( !file ) + { + return _f_result( 0, 0 ); + } + +/*write sectorsize times 0*/ + psp_memset( testbuffer, 0, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, (long)sectorsize, file ); + if ( size != (unsigned long) sectorsize ) + { + return _f_result( 1, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) sectorsize ) + { + return _f_result( 2, pos ); + } + +/*seek back and read some*/ + ret = f_seek( file, 0, F_SEEK_SET ); /*seek back*/ + if ( ret ) + { + return _f_result( 3, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos ) + { + return _f_result( 4, pos ); + } + + size = (unsigned long)f_read( testbuffer, 1, sectorsize, file ); + if ( size != (unsigned long) sectorsize ) + { + return _f_result( 5, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) sectorsize ) + { + return _f_result( 6, pos ); + } + +/*fake read at eof*/ + size = (unsigned long)f_read( testbuffer, 1, 2, file ); /*eof!*/ + if ( size != 0 ) + { + return _f_result( 7, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) sectorsize ) + { + return _f_result( 8, pos ); + } + +/*writing sectorsize times 1 at the end*/ + psp_memset( testbuffer, 1, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, sectorsize, file ); + if ( size != (unsigned long) sectorsize ) + { + return _f_result( 11, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( sectorsize * 2 ) ) + { + return _f_result( 12, pos ); + } + +/*seeking back and read 1byte less*/ + ret = f_seek( file, 0, F_SEEK_SET ); + if ( ret ) + { + return _f_result( 13, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos ) + { + return _f_result( 14, pos ); + } + + size = (unsigned long)f_read( testbuffer, 1, sectorsize - 1, file ); + if ( size != (unsigned long) ( sectorsize - 1 ) ) + { + return _f_result( 15, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( sectorsize - 1 ) ) + { + return _f_result( 16, pos ); + } + + +/*write 2 times 2*/ + psp_memset( testbuffer, 2, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 2, file ); + if ( size != 2 ) + { + return _f_result( 17, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( sectorsize + 1 ) ) + { + return _f_result( 18, pos ); + } + +/*read 2 bytes*/ + size = (unsigned long)f_read( testbuffer, 2, 1, file ); + if ( size != 1 ) + { + return _f_result( 19, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( sectorsize + 3 ) ) + { + return _f_result( 20, pos ); + } + + +/*write 4 times 3*/ + psp_memset( testbuffer, 3, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 4, file ); + if ( size != 4 ) + { + return _f_result( 21, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( sectorsize + 3 + 4 ) ) + { + return _f_result( 22, pos ); + } + +/*seek at 2*/ + ret = f_seek( file, 2, F_SEEK_SET ); + if ( ret ) + { + return _f_result( 23, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != 2 ) + { + return _f_result( 24, pos ); + } + +/*write 6 times 4*/ + psp_memset( testbuffer, 4, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 6, file ); + if ( size != 6 ) + { + return _f_result( 25, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != 8 ) + { + return _f_result( 26, pos ); + } + +/*seek end -4*/ + ret = f_seek( file, -4, F_SEEK_END ); + if ( ret ) + { + return _f_result( 27, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize - 4 ) ) + { + return _f_result( 28, pos ); + } + +/*read 2 bytes*/ + size = (unsigned long)f_read( testbuffer, 1, 2, file ); + if ( size != 2 ) + { + return _f_result( 29, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize - 2 ) ) + { + return _f_result( 30, pos ); + } + +/*write 8 times 5*/ + psp_memset( testbuffer, 5, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 8, file ); + if ( size != 8 ) + { + return _f_result( 31, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) ) + { + return _f_result( 32, pos ); + } + +/*seek to the begining*/ + ret = f_seek( file, 0, F_SEEK_SET ); + if ( ret ) + { + return _f_result( 33, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos ) + { + return _f_result( 34, pos ); + } + +/*seek to the end*/ + ret = f_seek( file, 2 * sectorsize + 6, F_SEEK_SET ); + if ( ret ) + { + return _f_result( 35, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize + 6 ) ) + { + return _f_result( 36, pos ); + } + +/*write 2 times 6*/ + psp_memset( testbuffer, 6, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 2, file ); + if ( size != 2 ) + { + return _f_result( 37, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) ) + { + return _f_result( 38, pos ); + } + +/*seek to the begining*/ + (void)f_seek( file, -( 2 * sectorsize + 8 ), F_SEEK_CUR ); + if ( ret ) + { + return _f_result( 39, ret ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos ) + { + return _f_result( 40, pos ); + } + +/*read 2 times sector*/ + size = (unsigned long)f_read( testbuffer, 1, sectorsize, file ); + if ( size != (unsigned long) sectorsize ) + { + return _f_result( 41, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) sectorsize ) + { + return _f_result( 42, pos ); + } + + size = (unsigned long)f_read( testbuffer, 1, sectorsize, file ); + if ( size != (unsigned long) sectorsize ) + { + return _f_result( 43, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize ) ) + { + return _f_result( 44, pos ); + } + +/*write 1 once 7*/ + psp_memset( testbuffer, 7, sectorsize ); + size = (unsigned long)f_write( testbuffer, 1, 1, file ); + if ( size != 1 ) + { + return _f_result( 45, size ); + } + + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize + 1 ) ) + { + return _f_result( 46, pos ); + } + +/*close it*/ + ret = f_close( file ); + if ( ret ) + { + return _f_result( 47, ret ); + } + + +/*check the result*/ + size = (unsigned long)f_filelength( "test.bin" ); + if ( size != (unsigned long) ( 2 * sectorsize + 8 ) ) + { + return _f_result( 48, size ); + } + +/*opens it*/ + file = f_open( "test.bin", "r" ); + if ( !file ) + { + return _f_result( 49, size ); + } + + if ( checkfilecontent( 2, 0, file ) ) + { + return _f_result( 50, 0 ); + } + + if ( checkfilecontent( 6, 4, file ) ) + { + return _f_result( 51, 0 ); + } + + if ( checkfilecontent( sectorsize - 8 - 1, 0, file ) ) + { + return _f_result( 52, 0 ); + } + + if ( checkfilecontent( 2, 2, file ) ) + { + return _f_result( 53, 0 ); + } + + if ( checkfilecontent( 2, 1, file ) ) + { + return _f_result( 54, 0 ); + } + + if ( checkfilecontent( 4, 3, file ) ) + { + return _f_result( 55, 0 ); + } + + if ( checkfilecontent( sectorsize - 7 - 2, 1, file ) ) + { + return _f_result( 56, 0 ); + } + + if ( checkfilecontent( 2, 5, file ) ) + { + return _f_result( 57, 0 ); + } + + if ( checkfilecontent( 1, 7, file ) ) + { + return _f_result( 58, 0 ); + } + + if ( checkfilecontent( 5, 5, file ) ) + { + return _f_result( 59, 0 ); + } + + if ( checkfilecontent( 2, 6, file ) ) + { + return _f_result( 60, 0 ); + } + +/*check pos result*/ + pos = (unsigned long)f_tell( file ); + if ( pos != (unsigned long) ( 2 * sectorsize + 8 ) ) + { + return _f_result( 61, pos ); + } + +/*this has to be eof*/ + pos = f_eof( file ); + if ( !pos ) + { + return _f_result( 62, pos ); + } + +/*close it*/ + ret = f_close( file ); + if ( ret ) + { + return _f_result( 63, ret ); + } + +/*deletes it*/ + ret = f_delete( "test.bin" ); + if ( ret ) + { + return _f_result( 64, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_seeking */ + +static unsigned char f_opening ( void ) +{ + F_FILE * file; + F_FILE * file2; + unsigned char ret; + unsigned short size, pos; + + _f_dump( "f_opening" ); + +/*test non existing file open r, r+*/ + file = f_open( "file.bin", "r" ); + if ( file ) + { + return _f_result( 0, 0 ); + } + + file = f_open( "file.bin", "r+" ); + if ( file ) + { + return _f_result( 1, 0 ); + } + +/*test non existing appends "a" a+*/ + file = f_open( "file.bin", "a" ); + if ( !file ) + { + return _f_result( 2, 0 ); + } + + file2 = f_open( "file.bin", "a+" ); /*open again*/ + if ( file2 ) + { + return _f_result( 3, 0 ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 3, 1 ); + } + + ret = f_close( file2 ); + if ( ret != F_ERR_NOTOPEN ) + { + return _f_result( 3, 2 ); + } + + +/*try to creates it w*/ + file = f_open( "file.bin", "w" ); + if ( !file ) + { + return _f_result( 4, 0 ); + } + +/*write 512 times 1*/ + psp_memset( testbuffer, 1, 512 ); /*set all 1*/ + size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/ + if ( size != 512 ) + { + return _f_result( 5, size ); + } + +/*go back, and read it*/ + ret = f_rewind( file ); /*back to the begining*/ + if ( ret ) + { + return _f_result( 6, ret ); /*it should fail*/ + } + + size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/ + if ( size ) + { + return _f_result( 7, size ); /*it should fail*/ + } + +/*close and check size*/ + size = (unsigned short)f_filelength( "file.bin" ); + if ( size ) + { + return _f_result( 8, size ); /*has to be zero*/ + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 9, ret ); + } + + size = (unsigned short)f_filelength( "file.bin" ); + if ( size != 512 ) + { + return _f_result( 10, size ); + } + +/*try to owerwrites it it*/ + file = f_open( "file.bin", "w+" ); + if ( !file ) + { + return _f_result( 11, 0 ); + } + +/*close and check size*/ + size = (unsigned short)f_filelength( "file.bin" ); + if ( size ) + { + return _f_result( 12, size ); /*has to be zero*/ + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 13, ret ); + } + + size = (unsigned short)f_filelength( "file.bin" ); + if ( size ) + { + return _f_result( 14, size ); + } + + + +/*test non existing appends "a" */ + file = f_open( "file.bin", "r+" ); + if ( !file ) + { + return _f_result( 15, 0 ); + } + +/*write 512 times 1*/ + psp_memset( testbuffer, 1, 512 ); /*set all 1*/ + size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/ + if ( size != 512 ) + { + return _f_result( 16, size ); + } + +/*go back, and read it*/ + ret = f_rewind( file ); /*back to the begining*/ + size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/ + if ( size != 512 ) + { + return _f_result( 17, size ); /*it should fail*/ + } + + ret = f_rewind( file ); /*back to the begining*/ + +/*write 256 times 2*/ + psp_memset( testbuffer, 2, 512 ); /*set all 2*/ + size = (unsigned short)f_write( testbuffer, 1, 256, file ); /*test write*/ + if ( size != 256 ) + { + return _f_result( 18, size ); + } + + pos = (unsigned short)f_tell( file ); + if ( pos != 256 ) + { + return _f_result( 19, pos ); /*position has to be 512*/ + } + + size = (unsigned short)f_filelength( "file.bin" ); + if ( size ) + { + return _f_result( 20, size ); /*has to be zero*/ + } + +/*close and check size*/ + ret = f_close( file ); + if ( ret ) + { + return _f_result( 21, ret ); + } + + size = (unsigned short)f_filelength( "file.bin" ); + if ( size != 512 ) + { + return _f_result( 22, size ); + } + + +/*test non existing appends a+*/ + file = f_open( "file.bin", "a+" ); + if ( !file ) + { + return _f_result( 23, 0 ); + } + + pos = (unsigned short)f_tell( file ); + if ( pos != 512 ) + { + return _f_result( 24, pos ); /*position has to be 512*/ + } + +/*write 512 times 3*/ + psp_memset( testbuffer, 3, 512 ); /*set all 3*/ + size = (unsigned short)f_write( testbuffer, 1, 512, file ); /*test write*/ + if ( size != 512 ) + { + return _f_result( 25, size ); + } + +/*go back, and read it*/ + ret = f_rewind( file ); /*back to the begining*/ + if ( ret ) + { + return _f_result( 26, ret ); /*it should fail*/ + } + + size = (unsigned short)f_read( testbuffer, 1, 512, file ); /*test read*/ + if ( size != 512 ) + { + return _f_result( 27, size ); /*it should fail*/ + } + + pos = (unsigned short)f_tell( file ); + if ( pos != 512 ) + { + return _f_result( 28, pos ); /*position has to be 512*/ + } + +/*close and check size*/ + size = (unsigned short)f_filelength( "file.bin" ); + if ( size != 512 ) + { + return _f_result( 29, size ); /*has to be zero*/ + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 30, ret ); + } + + size = (unsigned short)f_filelength( "file.bin" ); + if ( size != 1024 ) + { + return _f_result( 31, size ); + } + +/*close again!*/ + ret = f_close( file ); + if ( ret != F_ERR_NOTOPEN ) + { + return _f_result( 32, pos ); + } + + ret = f_delete( "file.bin" ); + if ( ret ) + { + return _f_result( 33, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_opening */ + +static unsigned char f_appending ( void ) +{ + F_FILE * file; + unsigned short size, tsize, pos; + unsigned char a, b, ret; + + _f_dump( "f_appending" ); + + _f_deleteall(); + + for ( tsize = 0, a = 0 ; a < 16 ; a++ ) + { + file = f_open( "ap.bin", "a" ); + if ( !file ) + { + return _f_result( 1, 0 ); + } + + psp_memset( testbuffer, a, sizeof( testbuffer ) ); + size = (unsigned short)f_write( testbuffer, 1, a + 128, file ); + if ( size != a + 128 ) + { + return _f_result( 2, size ); + } + + size = (unsigned short)f_filelength( "ap.bin" ); + if ( size != tsize ) + { + return _f_result( 3, size ); + } + + tsize += a + 128; + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 4, ret ); + } + + size = (unsigned short)f_filelength( "ap.bin" ); + if ( size != tsize ) + { + return _f_result( 5, size ); + } + } + + file = f_open( "ap.bin", "r" ); + if ( !file ) + { + return _f_result( 6, 0 ); + } + + for ( tsize = 0, a = 0 ; a < 16 ; a++ ) + { + if ( checkfilecontent( a + 128, (char)a, file ) ) + { + return _f_result( 7, a ); + } + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 8, ret ); + } + + for ( tsize = 0, a = 0 ; a < 16 ; a++ ) + { + file = f_open( "ap.bin", "r" ); + if ( !file ) + { + return _f_result( 9, 0 ); + } + + ret = f_seek( file, tsize, F_SEEK_SET ); + if ( ret ) + { + return _f_result( 10, ret ); + } + + pos = (unsigned short)f_tell( file ); + if ( pos != tsize ) + { + return _f_result( 11, pos ); + } + + size = (unsigned short)f_read( testbuffer, 1, a + 128, file ); + if ( size != a + 128 ) + { + return _f_result( 12, size ); + } + + for ( b = 0 ; b < a + 128 ; b++ ) + { + if ( testbuffer[b] != (char)a ) + { + return _f_result( 13, a ); + } + } + + tsize += a + 128; + + pos = (unsigned short)f_tell( file ); + if ( pos != tsize ) + { + return _f_result( 13, pos ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 14, ret ); + } + } + + ret = f_close( file ); + if ( ret != F_ERR_NOTOPEN ) + { + return _f_result( 9, ret ); + } + + ret = f_delete( "ap.bin" ); + if ( ret ) + { + return _f_result( 14, ret ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_appending */ + +static unsigned char f_writing ( void ) +{ + F_FILE * file; + unsigned short size; + unsigned char a, ret; + F_SPACE before, after; + + _f_dump( "f_writing" ); + + ret = f_getfreespace( &before ); + if ( ret ) + { + return _f_result( 0, ret ); + } + + for ( a = 0 ; a < 4 ; a++ ) + { + file = f_open( "wr.bin", "w" ); + if ( !file ) + { + return _f_result( 1, 0 ); + } + + psp_memset( testbuffer, a, sizeof( testbuffer ) ); + size = (unsigned short)f_write( testbuffer, 1, a * 128, file ); + if ( size != a * 128 ) + { + return _f_result( 2, size ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 3, ret ); + } + + size = (unsigned short)f_filelength( "wr.bin" ); + if ( size != a * 128 ) + { + return _f_result( 4, size ); + } + + file = f_open( "wr.bin", "r" ); + if ( !file ) + { + return _f_result( 5, 0 ); + } + + if ( checkfilecontent( a * 128, (char)a, file ) ) + { + return _f_result( 6, a ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 7, ret ); + } + } + + + for ( a = 0 ; a < 4 ; a++ ) + { + file = f_open( "wr.bin", "w+" ); + if ( !file ) + { + return _f_result( 8, 0 ); + } + + psp_memset( testbuffer, a, sizeof( testbuffer ) ); + size = (unsigned short)f_write( testbuffer, 1, a * 128, file ); + if ( size != a * 128 ) + { + return _f_result( 9, size ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 10, ret ); + } + + size = (unsigned short)f_filelength( "wr.bin" ); + if ( size != a * 128 ) + { + return _f_result( 11, size ); + } + + file = f_open( "wr.bin", "r+" ); + if ( !file ) + { + return _f_result( 12, 0 ); + } + + if ( checkfilecontent( a * 128, (char)a, file ) ) + { + return _f_result( 13, a ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 14, ret ); + } + } + + ret = f_getfreespace( &after ); + if ( ret ) + { + return _f_result( 15, ret ); + } + + if ( before.bad != after.bad ) + { + return _f_result( 16, 0 ); + } + + if ( before.free == after.free ) + { + return _f_result( 17, 0 ); + } + + if ( before.used == after.used ) + { + return _f_result( 18, 0 ); + } + + if ( before.total != after.total ) + { + return _f_result( 19, 0 ); + } + + if ( before.used + before.free != after.used + after.free ) + { + return _f_result( 20, 0 ); + } + + ret = f_delete( "wr.bin" ); + if ( ret ) + { + return _f_result( 21, ret ); + } + + ret = f_getfreespace( &after ); + if ( ret ) + { + return _f_result( 22, ret ); + } + + if ( before.bad != after.bad ) + { + return _f_result( 23, 0 ); + } + + if ( before.free != after.free ) + { + return _f_result( 24, 0 ); + } + + if ( before.used != after.used ) + { + return _f_result( 25, 0 ); + } + + if ( before.total != after.total ) + { + return _f_result( 26, 0 ); + } + + _f_dump( "passed..." ); + return 0; +} /* f_writing */ + +static unsigned char f_dots ( void ) +{ + unsigned char ret; + unsigned char a, size; + F_FILE * file; + + _f_dump( "f_dots" ); + + ret = f_mkdir( "/tt" ); + if ( ret ) + { + return _f_result( 0, ret ); + } + + ret = f_chdir( "/tt" ); + if ( ret ) + { + return _f_result( 1, ret ); + } + + ret = f_rmdir( "." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 4, ret ); + } + + ret = f_rmdir( ".." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 5, ret ); + } + + ret = f_chdir( "." ); + if ( ret ) + { + return _f_result( 6, ret ); + } + + ret = _f_checkcwd( f_nameconv( "/tt" ) ); + if ( ret ) + { + return _f_result( 7, ret ); + } + + ret = f_delete( "." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 8, ret ); + } + + ret = f_delete( ".." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 9, ret ); + } + + ret = f_mkdir( "." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 10, ret ); + } + + ret = f_mkdir( ".." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 11, ret ); + } + + ret = f_mkdir( "..." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 12, ret ); + } + + for ( a = 0 ; a < 6 ; a++ ) + { + char * mode; + switch ( a ) + { + case 0: + mode = "r"; + break; + + case 1: + mode = "r+"; + break; + + case 2: + mode = "w"; + break; + + case 3: + mode = "w+"; + break; + + case 4: + mode = "a"; + break; + + case 5: + mode = "a+"; + break; + + default: + return _f_result( 13, a ); + } /* switch */ + + file = f_open( ".", mode ); + if ( file ) + { + return _f_result( 14, a ); + } + + file = f_open( "..", mode ); + if ( file ) + { + return _f_result( 15, a ); + } + + file = f_open( "...", mode ); + if ( file ) + { + return _f_result( 16, a ); + } + } + + size = (unsigned char)f_filelength( "." ); + if ( size ) + { + return _f_result( 17, size ); + } + + size = (unsigned char)f_filelength( ".." ); + if ( size ) + { + return _f_result( 18, size ); + } + + size = (unsigned char)f_filelength( "..." ); + if ( size ) + { + return _f_result( 19, size ); + } + + + ret = f_chdir( "..." ); + if ( ret != F_ERR_NOTFOUND ) + { + return _f_result( 20, ret ); + } + + ret = f_chdir( ".." ); + if ( ret ) + { + return _f_result( 21, ret ); + } + + ret = f_rmdir( "tt" ); + if ( ret ) + { + return _f_result( 27, ret ); + } + + + _f_dump( "passed..." ); + return 0; +} /* f_dots */ + + +typedef struct +{ + unsigned char MagicNum; + unsigned char Line; + unsigned char Buf[87]; +} struct_TestFileSysEntry; + #define NUM_OF_RECORDS 10 +static unsigned char f_rit ( void ) +{ + unsigned char i; + unsigned char ret; + F_FILE * File; + struct_TestFileSysEntry * Entry = (struct_TestFileSysEntry *)( ( ( (long)testbuffer + 3 ) >> 2 ) << 2 ); + unsigned short Pos; + unsigned char Ch; + unsigned char Founded; + + _f_dump( "f_rit" ); + + (void)f_delete( "MyTest" ); + File = f_open( "MyTest", "a+" ); + if ( !File ) + { + return _f_result( 1, 0 ); + } + + /* add records */ + for ( i = 0 ; i < NUM_OF_RECORDS ; i++ ) + { + Ch = (char)( i % 10 ); + Entry->MagicNum = 0xbc; + Entry->Line = i; + Entry->Buf[0] = Ch; + Entry->Buf[10] = (unsigned char)( Ch + 1 ); + + if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_END ) ) + { + return _f_result( 2, 0 ); /* Fail, could not go to the end of the file */ + } + + if ( sizeof( struct_TestFileSysEntry ) != f_write( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) ) + { + return _f_result( 3, 0 ); /* Fail, could not write new entry */ + } + + Pos = (unsigned short)f_tell( File ); + if ( ( ( Pos / sizeof( struct_TestFileSysEntry ) ) - 1 ) != i ) + { + return _f_result( 4, 0 ); /* Fail, wrong file position */ + } + + if ( F_NO_ERROR != f_seek( File, (long)( Pos - sizeof( struct_TestFileSysEntry ) ), F_SEEK_SET ) ) + { + return _f_result( 5, 0 ); /* Fail, could not go to new entry position */ + } + + if ( sizeof( struct_TestFileSysEntry ) != f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) ) + { + return _f_result( 6, 0 ); /* Fail, could not read the new entry */ + } + + if ( ( Entry->MagicNum != 0xbc ) || ( Entry->Line != (int)i ) || ( Entry->Buf[0] != Ch ) || ( Entry->Buf[10] != Ch + 1 ) ) + { + return _f_result( 7, 0 ); /*Fail, the new entry is corrupted"*/ + } + } + + ret = f_close( File ); + if ( ret ) + { + return _f_result( 8, ret ); + } + + + /*Open file again*/ + File = f_open( "MyTest", "a+" ); + if ( !File ) + { + return _f_result( 9, 0 ); + } + + /* read records */ + for ( i = 0 ; i < NUM_OF_RECORDS ; i++ ) + { + Ch = (char)( i % 10 ); + + if ( F_NO_ERROR != f_seek( File, 0, F_SEEK_SET ) ) + { + return _f_result( 10, 0 ); /* Fail, could not go to the start of the file */ + } + + Founded = 0; + while ( sizeof( struct_TestFileSysEntry ) == f_read( (void *)Entry, 1, sizeof( struct_TestFileSysEntry ), File ) ) + { + if ( ( Entry->MagicNum == 0xbc ) + && ( Entry->Line == (int)i ) + && ( Entry->Buf[0] == Ch ) + && ( Entry->Buf[10] == Ch + 1 ) ) + { + Founded = 1; + break; + } + } + + if ( !Founded ) + { + return _f_result( 11, i ); /* Entry not founded */ + } + } + + ret = f_close( File ); + if ( ret ) + { + return _f_result( 12, ret ); + } + + + ret = f_delete( "MyTest" ); + if ( ret ) + { + return _f_result( 13, ret ); + } + + _f_dump( "passed..." ); + + return 0; +} /* f_rit */ + + + + +static unsigned char f_truncating ( void ) +{ + F_FILE * file; + unsigned long size; + unsigned char ret; + + _f_dump( "f_truncating" ); + + file = f_open( "test.bin", "w+" ); + if ( !file ) + { + return _f_result( 0, 0 ); + } + + (void)psp_memset( testbuffer, 1, F_MAX_SEEK_TEST ); + size = (unsigned long)f_write( testbuffer, 1, F_MAX_SEEK_TEST, file ); + if ( size != F_MAX_SEEK_TEST ) + { + return _f_result( 1, size ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 2, ret ); + } + + file = f_truncate( "test.bin", F_MAX_SEEK_TEST - 4 ); + if ( !file ) + { + return _f_result( 3, 0 ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 4, ret ); + } + + size = (unsigned long)f_filelength( "test.bin" ); + if ( size != F_MAX_SEEK_TEST - 4 ) + { + return _f_result( 5, size ); + } + + + file = f_truncate( "test.bin", F_MAX_SEEK_TEST ); + if ( !file ) + { + return _f_result( 3, 0 ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 4, ret ); + } + + size = (unsigned long)f_filelength( "test.bin" ); + if ( size != F_MAX_SEEK_TEST ) + { + return _f_result( 5, size ); + } + + + file = f_truncate( "test.bin", ( F_MAX_SEEK_TEST / 2 ) - 92 ); + if ( !file ) + { + return _f_result( 6, 0 ); + } + + (void)psp_memset( testbuffer, 2, 92 ); + size = (unsigned long)f_write( testbuffer, 1, 92, file ); + if ( size != 92 ) + { + return _f_result( 7, size ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 8, ret ); + } + + size = (unsigned long)f_filelength( "test.bin" ); + if ( size != ( F_MAX_SEEK_TEST / 2 ) ) + { + return _f_result( 9, size ); + } + + + file = f_truncate( "test.bin", 1 ); + if ( !file ) + { + return _f_result( 10, 0 ); + } + + (void)psp_memset( testbuffer, 3, 2 ); + size = (unsigned long)f_write( testbuffer, 1, 2, file ); + if ( size != 2 ) + { + return _f_result( 11, size ); + } + + ret = f_close( file ); + if ( ret ) + { + return _f_result( 12, ret ); + } + + size = (unsigned long)f_filelength( "test.bin" ); + if ( size != 3 ) + { + return _f_result( 13, size ); + } + + + + _f_dump( "passed..." ); + return 0; +} /* f_truncating */ + + +void f_dotest ( unsigned char t ) +{ + _f_dump( "File system test started..." ); + _f_dump( "WARNING: The contents of your drive will be destroyed!\n" ); + + (void)_f_poweron(); + + switch ( t ) + { + case 0: + case 1: + (void)f_formatting(); + if ( t ) + { + break; + } + + + /* fall through */ + case 2: + (void)f_dirtest(); + if ( t ) + { + break; + } + + + /* fall through */ + case 3: + (void)f_findingtest(); + if ( t ) + { + break; + } + + + /* fall through */ + case 4: + (void)f_powerfail(); + if ( t ) + { + break; + } + + + /* fall through */ + case 5: + (void)f_seeking( 128 ); + if ( t ) + { + break; + } + + #if ( F_MAX_SEEK_TEST > 128 ) + + /* fall through */ + case 6: + (void)f_seeking( 256 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 256 ) + + /* fall through */ + case 7: + (void)f_seeking( 512 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 512 ) + + /* fall through */ + case 8: + (void)f_seeking( 1024 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 1024 ) + + /* fall through */ + case 9: + (void)f_seeking( 2048 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 2048 ) + + /* fall through */ + case 10: + (void)f_seeking( 4096 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 4096 ) + + /* fall through */ + case 11: + (void)f_seeking( 8192 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 8192 ) + + /* fall through */ + case 12: + (void)f_seeking( 16384 ); + if ( t ) + { + break; + } + + #endif + #if ( F_MAX_SEEK_TEST > 16384 ) + + /* fall through */ + case 13: + (void)f_seeking( 32768 ); + if ( t ) + { + break; + } + + #endif + + /* fall through */ + case 14: + (void)f_opening(); + if ( t ) + { + break; + } + + + /* fall through */ + case 15: + (void)f_appending(); + if ( t ) + { + break; + } + + + /* fall through */ + case 16: + (void)f_writing(); + if ( t ) + { + break; + } + + + /* fall through */ + case 17: + (void)f_dots(); + if ( t ) + { + break; + } + + + /* fall through */ + case 18: + (void)f_rit(); + if ( t ) + { + break; + } + + case 19: + (void)f_truncating(); + if ( t ) + { + break; + } + + break; + } /* switch */ + + _f_dump( "End of tests..." ); +} /* f_dotest */ + + + +/**************************************************************************** + * + * end of test.c + * + ***************************************************************************/ +#endif /*_TEST_C_*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h new file mode 100644 index 000000000..cc6274992 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/test/test.h @@ -0,0 +1,116 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef __TEST_H +#define __TEST_H + +#include "../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2 + #error Incompatible FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +** Maximum size for seek test. +** Options: 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 +*/ +#define F_MAX_SEEK_TEST 16384 + + +/* +** Defines media type for testing. +** Options: F_FAT12_MEDIA, F_FAT16_MEDIA +*/ +#define F_FAT_TYPE F_FAT12_MEDIA + + +/* +** Start filesystem test. +** Parameter: +** 0 - run all the tests +** +** 2 - directory +** 3 - find +** +** 5* - seek 128 +** 6* - seek 256 +** 7* - seek 512 +** 8* - seek 1024 +** 9* - seek 2048 +** 10*- seek 4096 +** 11*- seek 8192 +** 12*- seek 16384 +** 13*- seek 32768 +** 14 - open +** 15 - append +** 16 - write +** 17 - dots +** 18 - rit +** *Note that only seek tests allowed by F_MAX_SEEK_TEST are executed. +** +** The following defines are required for the specific test: +** 1 1 1 1 1 1 1 1 1 +** 2 3 5 6 7 8 9 0 1 2 3 4 5 6 7 8 +** F_CHDIR x x - - - - - - - - - - x - x - +** F_MKDIR x x - - - - - - - - - - - - x - +** F_RMDIR x x - - - - - - - - - - x - x - +** F_DELETE x x x x x x x x x x x x x x x x +** F_FILELENGTH - - x x x x x x x x x x x x - - +** F_FINDING x x - - - - - - - - - - x - - - +** F_TELL - - x x x x x x x x x x x x - x +** F_REWIND - - - - - - - - - - - x - - - - +** F_EOF - - x x x x x x x x x - - x - - +** F_SEEK - - x x x x x x x x x - x x - x +** F_WRITE - - x x x x x x x x x x x x - x +** F_WRITING x x x x x x x x x x x x x x x x +** F_DIRECTORIES x x - - - - - - - - - - x - x - +** F_CHECKNAME x - - - - - - - - - - - - - x - +*/ +void f_dotest ( unsigned char ); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef __TEST_H */ + + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c new file mode 100644 index 000000000..5d1d49fa1 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/media-drv/ram/ramdrv_f.c @@ -0,0 +1,247 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include "../../api/api_mdriver_ram.h" +#include "config_mdriver_ram.h" +#include "../../psp/include/psp_string.h" + +#include "../../version/ver_mdriver_ram.h" +#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2 + #error Incompatible MDRIVER_RAM version number! +#endif + + +char ramdrv0[MDRIVER_RAM_VOLUME0_SIZE]; + +typedef struct +{ + char * ramdrv; + unsigned long maxsector; + int use; + F_DRIVER * driver; +} t_RamDrv; + +static F_DRIVER t_drivers[1]; + +static t_RamDrv RamDrv[1] = +{ + { ramdrv0, ( MDRIVER_RAM_VOLUME0_SIZE / MDRIVER_RAM_SECTOR_SIZE ), 0, &t_drivers[0] } +}; + + +/**************************************************************************** + * Read one sector + ***************************************************************************/ +static int ram_readsector ( F_DRIVER * driver, void * data, unsigned long sector ) +{ + long len; + char * d = (char *)data; + char * s; + t_RamDrv * p = (t_RamDrv *)( driver->user_ptr ); + + if ( sector >= p->maxsector ) + { + return MDRIVER_RAM_ERR_SECTOR; + } + + s = p->ramdrv; + s += sector * MDRIVER_RAM_SECTOR_SIZE; + len = MDRIVER_RAM_SECTOR_SIZE; + +#if MDRIVER_MEM_LONG_ACCESS + if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) ) + { + long * dd = (long *)d; + long * ss = (long *)s; + len >>= 2; + while ( len-- ) + { + *dd++ = *ss++; + } + + return MDRIVER_RAM_NO_ERROR; + } + +#endif /* if MDRIVER_MEM_LONG_ACCESS */ + + while ( len-- ) + { + *d++ = *s++; + } + + return MDRIVER_RAM_NO_ERROR; +} + +/**************************************************************************** + * Write one sector + ***************************************************************************/ +static int ram_writesector ( F_DRIVER * driver, void * data, unsigned long sector ) +{ + long len; + char * s = (char *)data; + char * d; + t_RamDrv * p = (t_RamDrv *)( driver->user_ptr ); + + if ( sector >= p->maxsector ) + { + return MDRIVER_RAM_ERR_SECTOR; + } + + d = p->ramdrv; + d += sector * MDRIVER_RAM_SECTOR_SIZE; + len = MDRIVER_RAM_SECTOR_SIZE; + +#if MDRIVER_MEM_LONG_ACCESS + if ( ( !( len & 3 ) ) && ( !( ( (long)d ) & 3 ) ) && ( !( ( (long)s ) & 3 ) ) ) + { + long * dd = (long *)d; + long * ss = (long *)s; + len >>= 2; + while ( len-- ) + { + *dd++ = *ss++; + } + + return MDRIVER_RAM_NO_ERROR; + } + +#endif /* if MDRIVER_MEM_LONG_ACCESS */ + + while ( len-- ) + { + *d++ = *s++; + } + + return MDRIVER_RAM_NO_ERROR; +} + + +/**************************************************************************** + * + * ram_getphy + * + * determinate ramdrive physicals + * + * INPUTS + * + * driver - driver structure + * phy - this structure has to be filled with physical information + * + * RETURNS + * + * error code or zero if successful + * + ***************************************************************************/ +static int ram_getphy ( F_DRIVER * driver, F_PHY * phy ) +{ + t_RamDrv * p = (t_RamDrv *)( driver->user_ptr ); + + phy->number_of_sectors = p->maxsector; + phy->bytes_per_sector = MDRIVER_RAM_SECTOR_SIZE; + + return MDRIVER_RAM_NO_ERROR; +} + + +/**************************************************************************** + * + * ram_release + * + * Releases a drive + * + * INPUTS + * + * driver_param - driver parameter + * + ***************************************************************************/ +static void ram_release ( F_DRIVER * driver ) +{ + t_RamDrv * p = (t_RamDrv *)( driver->user_ptr ); + + if ( p == RamDrv ) + { + p->use = 0; + } +} + + +/**************************************************************************** + * + * ram_initfunc + * + * this init function has to be passed for highlevel to initiate the + * driver functions + * + * INPUTS + * + * driver_param - driver parameter + * + * RETURNS + * + * driver structure pointer + * + ***************************************************************************/ +F_DRIVER * ram_initfunc ( unsigned long driver_param ) +{ + t_RamDrv * p; + + p = RamDrv + driver_param; + + if ( p != RamDrv ) + { + return 0; + } + + if ( p->use ) + { + return 0; + } + + (void)psp_memset( p->driver, 0, sizeof( F_DRIVER ) ); + + p->driver->readsector = ram_readsector; + p->driver->writesector = ram_writesector; + p->driver->getphy = ram_getphy; + p->driver->release = ram_release; + p->driver->user_ptr = p; + + p->use = 1; + + return p->driver; +} /* ram_initfunc */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h new file mode 100644 index 000000000..7f1d560e8 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_rtc.h @@ -0,0 +1,71 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _PSP_RTC_H +#define _PSP_RTC_H + +#include + +#include "../../version/ver_psp_rtc.h" +#if VER_PSP_RTC_MAJOR != 1 + #error "VER_PSP_RTC_MAJOR invalid" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint8_t sec; + uint8_t min; + uint8_t hour; + uint8_t day; + uint8_t month; + uint16_t year; +} t_psp_timedate; + +void psp_getcurrenttimedate ( t_psp_timedate * p_timedate ); + +#ifdef __cplusplus +} +#endif + + +#endif /* _PSP_RTC_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h new file mode 100644 index 000000000..310e439ab --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/include/psp_string.h @@ -0,0 +1,60 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _PSP_STRING_H_ +#define _PSP_STRING_H_ + +#include +#include + +#include "../../version/ver_psp_string.h" +#if VER_PSP_STRING_MAJOR != 1 || VER_PSP_STRING_MINOR != 4 + #error Incompatible PSP_STRING version number! +#endif + +#define psp_memcpy( d, s, l ) memcpy( ( d ), ( s ), (size_t)( l ) ) +#define psp_memmove( d, s, l ) memmove( ( d ), ( s ), (size_t)( l ) ) +#define psp_memset( d, c, l ) memset( ( d ), ( c ), (size_t)( l ) ) +#define psp_memcmp( s1, s2, l ) memcmp( ( s1 ), ( s2 ), (size_t)( l ) ) +#define psp_strnlen( s, l ) strnlen( ( s ), ( size_t )( l ) ) +#define psp_strncat( d, s, l ) strncat( ( d ), ( s ), (size_t)( l ) ) +#define psp_strncpy( d, s, l ) strncpy( ( d ), ( s ), (size_t)( l ) ) +#define psp_strncmp( s1, s2, l ) strncmp( ( s1 ), ( s2 ), (size_t)( l ) ) + +#endif /* ifndef _PSP_STRING_H_ */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c new file mode 100644 index 000000000..62446fe44 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.c @@ -0,0 +1,86 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include +#include "psp_test.h" +#include "config_fat_sl.h" +#include "config_mdriver_ram.h" +#include "../../../api/fat_sl.h" +#include "../../../api/api_mdriver_ram.h" + +#include "../../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 + #error Incompatible FAT_SL version number! +#endif +#include "../../../version/ver_psp_fat_sl.h" +#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1 + #error Incompatible PSP_FAT_FAT_SL version number! +#endif + +uint8_t all_tests_passed = 1u; + +/* Use to display text (printf). */ +void _f_dump ( char * s ) +{ + printf( "%s\r\n", s ); +} + +/* Use to display test result (printf). */ +uint8_t _f_result ( uint8_t testnum, uint32_t result ) +{ + (void)testnum; + if ( result == 0 ) + { + printf( "Passed\r\n" ); + } + else + { + printf( "FAILED! Error code: %u\r\n", result ); + all_tests_passed = 0u; + } + + return 0; +} + +/* Use to build file system (mount). */ +uint8_t _f_poweron ( void ) +{ + f_delvolume(); + return f_initvolume( ram_initfunc ); +} + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h new file mode 100644 index 000000000..630c60f41 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/fat_sl/psp_test.h @@ -0,0 +1,75 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _PSP_FAT_FAT_SL_H +#define _PSP_FAT_FAT_SL_H + +#include +#include "../../../psp/include/psp_string.h" + +#include "../../../version/ver_fat_sl.h" +#if VER_FAT_SL_MAJOR != 3 + #error Incompatible FAT_SL version number! +#endif +#include "../../../version/ver_psp_fat_sl.h" +#if VER_PSP_FAT_FAT_SL_MAJOR != 1 || VER_PSP_FAT_FAT_SL_MINOR != 1 + #error Incompatible PSP_FAT_FAT_SL version number! +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint8_t all_tests_passed; + +/* Use to display text (printf). */ +void _f_dump ( char * s ); + +/* Use to display test result (printf). */ +uint8_t _f_result ( uint8_t testnum, uint32_t result ); + +/* Use to build file system (mount). */ +uint8_t _f_poweron ( void ); + +#ifdef __cplusplus +} +#endif + + +#endif /* _PSP_FAT_FAT_SL_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c new file mode 100644 index 000000000..45b3a99df --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/psp/target/rtc/psp_rtc.c @@ -0,0 +1,80 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#include +#include +#include "../../include/psp_rtc.h" + +#include "../../../version/ver_psp_rtc.h" +#if VER_PSP_RTC_MAJOR != 1 + #error "VER_PSP_RTC_MAJOR invalid" +#endif +#if VER_PSP_RTC_MINOR != 0 + #error "VER_PSP_RTC_MINOR invalid" +#endif + + +/**************************************************************************** + * + * psp_getcurrenttimedate + * + * Need to be ported depending on system, it retreives the + * current time and date. + * Please take care of correct roll-over handling. + * Roll-over problem is to read a date at 23.59.59 and then reading time at + * 00:00.00. + * + * INPUT + * + * p_timedate - pointer where to store time and date + * + ***************************************************************************/ +void psp_getcurrenttimedate ( t_psp_timedate * p_timedate ) +{ + if ( p_timedate != NULL ) + { + p_timedate->sec = 0; + p_timedate->min = 0; + p_timedate->hour = 12u; + + p_timedate->day = 1u; + p_timedate->month = 1u; + p_timedate->year = 1980u; + } +} /* psp_getcurrenttimedate */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h new file mode 100644 index 000000000..f521ffb83 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_fat_sl.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_FAT_SL_H +#define _VER_FAT_SL_H + +#define VER_FAT_SL_MAJOR 3 +#define VER_FAT_SL_MINOR 2 + +#endif + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h new file mode 100644 index 000000000..4a9468d98 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_MDRIVER_H +#define _VER_MDRIVER_H + +#define VER_MDRIVER_MAJOR 1 +#define VER_MDRIVER_MINOR 0 + +#endif + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h new file mode 100644 index 000000000..384a0916c --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_mdriver_ram.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_MDRIVER_RAM_H +#define _VER_MDRIVER_RAM_H + +#define VER_MDRIVER_RAM_MAJOR 1 +#define VER_MDRIVER_RAM_MINOR 2 + +#endif + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h new file mode 100644 index 000000000..98a22e1da --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_fat_sl.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_PSP_FAT_FAT_SL_H +#define _VER_PSP_FAT_FAT_SL_H + +#define VER_PSP_FAT_FAT_SL_MAJOR 1 +#define VER_PSP_FAT_FAT_SL_MINOR 1 + +#endif /* _VER_PSP_FAT_FAT_SL_H */ + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h new file mode 100644 index 000000000..8a65db0fb --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_rtc.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_PSP_RTC_H +#define _VER_PSP_RTC_H + +#define VER_PSP_RTC_MAJOR 1 +#define VER_PSP_RTC_MINOR 0 + +#endif + diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h new file mode 100644 index 000000000..2ed0415e7 --- /dev/null +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/version/ver_psp_string.h @@ -0,0 +1,46 @@ +/* + * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded + * + * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license + * terms. + * + * FreeRTOS+FAT SL uses a dual license model that allows the software to be used + * under a pure GPL open source license (as opposed to the modified GPL licence + * under which FreeRTOS is distributed) or a commercial license. Details of + * both license options follow: + * + * - Open source licensing - + * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and + * distributed without charge provided the user adheres to version two of the + * GNU General Public License (GPL) and does not remove the copyright notice or + * this text. The GPL V2 text is available on the gnu.org web site, and on the + * following URL: http://www.FreeRTOS.org/gpl-2.0.txt. + * + * - Commercial licensing - + * Businesses and individuals who for commercial or other reasons cannot comply + * with the terms of the GPL V2 license must obtain a commercial license before + * incorporating FreeRTOS+FAT SL into proprietary software for distribution in + * any form. Commercial licenses can be purchased from + * http://shop.freertos.org/fat_sl and do not require any source files to be + * changed. + * + * FreeRTOS+FAT SL is distributed in the hope that it will be useful. You + * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as + * is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the + * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all + * conditions and terms, be they implied, expressed, or statutory. + * + * http://www.FreeRTOS.org + * http://www.FreeRTOS.org/FreeRTOS-Plus + * + */ + +#ifndef _VER_PSP_STRING_H +#define _VER_PSP_STRING_H + +#define VER_PSP_STRING_MAJOR 1 +#define VER_PSP_STRING_MINOR 4 + +#endif + diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index 64cb0bbfa..e6aabb8d4 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -568,10 +568,6 @@ typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); #define configUSE_QUEUE_SETS 0 #endif -#ifndef portTASK_USES_FLOATING_POINT - #defeine portTASK_USES_FLOATING_POINT() -#endif - /* For backward compatability. */ #define eTaskStateGet eTaskGetState