/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
+ * http://www.freertos.org/a00110.html\r
+ *\r
+ * The bottom of this file contains some constants specific to running the UDP\r
+ * stack in this demo. Constants specific to FreeRTOS+UDP itself (rather than\r
+ * the demo) are contained in FreeRTOSIPConfig.h.\r
+ *----------------------------------------------------------*/\r
+\r
+#define configUSE_PREEMPTION 1\r
+#define configMAX_PRIORITIES ( 7 )\r
+#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */\r
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32U * 1024U ) )\r
+#define configMAX_TASK_NAME_LEN ( 7 )\r
+#define configUSE_TRACE_FACILITY 1\r
+#define configUSE_16_BIT_TICKS 0\r
+#define configIDLE_SHOULD_YIELD 1\r
+#define configUSE_CO_ROUTINES 0\r
+#define configUSE_MUTEXES 1\r
+#define configUSE_RECURSIVE_MUTEXES 1\r
+#define configQUEUE_REGISTRY_SIZE 0\r
+#define configUSE_APPLICATION_TASK_TAG 0\r
+#define configUSE_COUNTING_SEMAPHORES 1\r
+#define configUSE_ALTERNATIVE_API 0\r
+\r
+/* Hook function related definitions. */\r
+#define configUSE_TICK_HOOK 0\r
+#define configUSE_IDLE_HOOK 1\r
+#define configUSE_MALLOC_FAILED_HOOK 1\r
+#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */\r
+\r
+/* Software timer related definitions. */\r
+#define configUSE_TIMERS 1\r
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )\r
+#define configTIMER_QUEUE_LENGTH 5\r
+#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )\r
+\r
+/* Run time stats gathering definitions. */\r
+unsigned long ulGetRunTimeCounterValue( void );\r
+void vConfigureTimerForRunTimeStats( void );\r
+#define configGENERATE_RUN_TIME_STATS 1\r
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()\r
+#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()\r
+\r
+/* Co-routine definitions. */\r
+#define configUSE_CO_ROUTINES 0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero\r
+to exclude the API function. */\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 1\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+#define INCLUDE_xTaskGetSchedulerState 1\r
+#define INCLUDE_xTimerGetTimerTaskHandle 0\r
+#define INCLUDE_xTaskGetIdleTaskHandle 0\r
+#define INCLUDE_xQueueGetMutexHolder 1\r
+#define INCLUDE_xTaskGetCurrentTaskHandle 1\r
+\r
+/* This demo makes use of one or more example stats formatting functions. These\r
+format the raw data provided by the uxTaskGetSystemState() function in to human\r
+readable ASCII form. See the notes in the implementation of vTaskList() within \r
+FreeRTOS/Source/tasks.c for limitations. */\r
+#define configUSE_STATS_FORMATTING_FUNCTIONS 1\r
+\r
+/* Assert call defined for debug builds. */\r
+#ifdef _DEBUG\r
+ extern void vAssertCalled( const char *pcFile, unsigned long ulLine );\r
+ #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )\r
+#endif /* _DEBUG */\r
+\r
+\r
+\r
+/* Application specific definitions follow. **********************************/\r
+\r
+/* The UDP port to use for incoming command inputs. The outgoing port is\r
+set to ( configUDP_CLI_PORT_NUMBER + 1 ). */\r
+#define configUDP_CLI_PORT_NUMBER 5001\r
+\r
+/* The size of the global output buffer that is available for use when there\r
+are multiple command interpreters running at once (for example, one on a UART\r
+and one on TCP/IP). This is done to prevent an output buffer being defined by\r
+each implementation - which would waste RAM. In this case, there is only one\r
+command interpreter running, and it has its own local output buffer, so the\r
+global buffer is just set to be one byte long as it is not used and should not\r
+take up unnecessary RAM. */\r
+#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1\r
+\r
+#endif /* FREERTOS_CONFIG_H */\r
--- /dev/null
+/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION\r
+ UTILITY. DO NOT MODIFY.\r
+*/\r
+/** @file\r
+*/\r
+#include <redconf.h>\r
+#include <redtypes.h>\r
+#include <redmacs.h>\r
+#include <redvolume.h>\r
+\r
+\r
+const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] =\r
+{\r
+ { 512U, 65536U, false, 256U, "" }\r
+};\r
--- /dev/null
+/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION\r
+ UTILITY. DO NOT MODIFY.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDCONF_H\r
+#define REDCONF_H\r
+\r
+\r
+#include <string.h>\r
+\r
+#define REDCONF_READ_ONLY 0\r
+\r
+#define REDCONF_API_POSIX 1\r
+\r
+#define REDCONF_API_FSE 0\r
+\r
+#define REDCONF_API_POSIX_FORMAT 1\r
+\r
+#define REDCONF_API_POSIX_LINK 1\r
+\r
+#define REDCONF_API_POSIX_UNLINK 1\r
+\r
+#define REDCONF_API_POSIX_MKDIR 1\r
+\r
+#define REDCONF_API_POSIX_RMDIR 1\r
+\r
+#define REDCONF_API_POSIX_RENAME 1\r
+\r
+#define REDCONF_RENAME_ATOMIC 1\r
+\r
+#define REDCONF_API_POSIX_FTRUNCATE 1\r
+\r
+#define REDCONF_API_POSIX_READDIR 1\r
+\r
+#define REDCONF_NAME_MAX 28U\r
+\r
+#define REDCONF_PATH_SEPARATOR '/'\r
+\r
+#define REDCONF_TASK_COUNT 10U\r
+\r
+#define REDCONF_HANDLE_COUNT 10U\r
+\r
+#define REDCONF_API_FSE_FORMAT 0\r
+\r
+#define REDCONF_API_FSE_TRUNCATE 0\r
+\r
+#define REDCONF_API_FSE_TRANSMASKGET 0\r
+\r
+#define REDCONF_API_FSE_TRANSMASKSET 0\r
+\r
+#define REDCONF_OUTPUT 1\r
+\r
+#define REDCONF_ASSERTS 1\r
+\r
+#define REDCONF_BLOCK_SIZE 512U\r
+\r
+#define REDCONF_VOLUME_COUNT 1U\r
+\r
+#define REDCONF_ENDIAN_BIG 0\r
+\r
+#define REDCONF_ALIGNMENT_SIZE 4U\r
+\r
+#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8\r
+\r
+#define REDCONF_INODE_BLOCKS 1\r
+\r
+#define REDCONF_INODE_TIMESTAMPS 1\r
+\r
+#define REDCONF_ATIME 0\r
+\r
+#define REDCONF_DIRECT_POINTERS 4U\r
+\r
+#define REDCONF_INDIRECT_POINTERS 32U\r
+\r
+#define REDCONF_BUFFER_COUNT 12U\r
+\r
+#define RedMemCpyUnchecked memcpy\r
+\r
+#define RedMemMoveUnchecked memmove\r
+\r
+#define RedMemSetUnchecked memset\r
+\r
+#define RedMemCmpUnchecked memcmp\r
+\r
+#define RedStrLenUnchecked strlen\r
+\r
+#define RedStrCmpUnchecked strcmp\r
+\r
+#define RedStrNCmpUnchecked strncmp\r
+\r
+#define RedStrNCpyUnchecked strncpy\r
+\r
+#define REDCONF_TRANSACT_DEFAULT (( RED_TRANSACT_CREAT | RED_TRANSACT_MKDIR | RED_TRANSACT_RENAME | RED_TRANSACT_LINK | RED_TRANSACT_UNLINK | RED_TRANSACT_FSYNC | RED_TRANSACT_CLOSE | RED_TRANSACT_VOLFULL | RED_TRANSACT_UMOUNT ) & RED_TRANSACT_MASK)\r
+\r
+#define REDCONF_IMAP_INLINE 0\r
+\r
+#define REDCONF_IMAP_EXTERNAL 1\r
+\r
+#define REDCONF_IMAGE_BUILDER 0\r
+\r
+#define REDCONF_CHECKER 0\r
+\r
+#endif\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Defines basic types used by Reliance Edge.\r
+\r
+ The following types *must* be defined by this header, either directly (using\r
+ typedef) or indirectly (by including other headers, such as the C99 headers\r
+ stdint.h and stdbool.h):\r
+\r
+ - bool: Boolean type, capable of storing true (1) or false (0)\r
+ - uint8_t: Unsigned 8-bit integer\r
+ - int8_t: Signed 8-bit integer\r
+ - uint16_t: Unsigned 16-bit integer\r
+ - int16_t: Signed 16-bit integer\r
+ - uint32_t: Unsigned 32-bit integer\r
+ - int32_t: Signed 32-bit integer\r
+ - uint64_t: Unsigned 64-bit integer\r
+ - int64_t: Signed 64-bit integer\r
+ - uintptr_t: Unsigned integer capable of storing a pointer, preferably the\r
+ same size as pointers themselves.\r
+\r
+ These types deliberately use the same names as the standard C99 types, so\r
+ that if the C99 headers stdint.h and stdbool.h are available, they may be\r
+ included here.\r
+\r
+ If the user application defines similar types, those may be reused. For\r
+ example, suppose there is an application header apptypes.h which defines\r
+ types with a similar purpose but different names. That header could be\r
+ reused to define the types Reliance Edge needs:\r
+\r
+ ~~~{.c}\r
+ #include <apptypes.h>\r
+\r
+ typedef BOOL bool;\r
+ typedef BYTE uint8_t;\r
+ typedef INT8 int8_t;\r
+ // And so on...\r
+ ~~~\r
+\r
+ If there are neither C99 headers nor suitable types in application headers,\r
+ this header should be populated with typedefs that define the required types\r
+ in terms of the standard C types. This requires knowledge of the size of\r
+ the C types on the target hardware (e.g., how big is an "int" or a pointer).\r
+ Below is an example which assumes the target has 8-bit chars, 16-bit shorts,\r
+ 32-bit ints, 32-bit pointers, and 64-bit long longs:\r
+\r
+ ~~~{.c}\r
+ typedef int bool;\r
+ typedef unsigned char uint8_t;\r
+ typedef signed char int8_t;\r
+ typedef unsigned short uint16_t;\r
+ typedef short int16_t;\r
+ typedef unsigned int uint32_t;\r
+ typedef int int32_t;\r
+ typedef unsigned long long uint64_t;\r
+ typedef long long int64_t;\r
+ typedef uint32_t uintptr_t;\r
+ ~~~\r
+*/\r
+#ifndef REDTYPES_H\r
+#define REDTYPES_H\r
+\r
+\r
+typedef int bool; /**< @brief Boolean type; either true or false. */\r
+\r
+typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */\r
+typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */\r
+\r
+typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */\r
+typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */\r
+\r
+typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */\r
+typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */\r
+\r
+typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */\r
+typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */\r
+\r
+/** @brief Unsigned integer capable of storing a pointer.\r
+*/\r
+#ifdef _WIN64\r
+typedef uint64_t uintptr_t;\r
+#else\r
+typedef uint32_t uintptr_t;\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+/* File system includes. */\r
+#include <redposix.h>\r
+#include <redtests.h>\r
+\r
+#ifdef _WINDOWS_\r
+ #define snprintf _snprintf\r
+#endif\r
+\r
+#define cliNEW_LINE "\r\n"\r
+\r
+/*******************************************************************************\r
+ * See the URL in the comments within main.c for the location of the online\r
+ * documentation.\r
+ ******************************************************************************/\r
+\r
+/*\r
+ * Print out information on a single file.\r
+ */\r
+static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent );\r
+\r
+/*\r
+ * Copies an existing file into a newly created file.\r
+ */\r
+static BaseType_t prvPerformCopy( int32_t lSourceFildes,\r
+ int32_t lDestinationFiledes,\r
+ char *pxWriteBuffer,\r
+ size_t xWriteBufferLen );\r
+\r
+/*\r
+ * Implements the DIR command.\r
+ */\r
+static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the DEL command.\r
+ */\r
+static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the TYPE command.\r
+ */\r
+static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the APPEND command.\r
+ */\r
+static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the COPY command.\r
+ */\r
+static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the CREATE command.\r
+ */\r
+static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the MKDIR command.\r
+ */\r
+static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the RENAME command.\r
+ */\r
+static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the LINK command.\r
+ */\r
+static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the STAT command.\r
+ */\r
+static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the STATFS command.\r
+ */\r
+static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the FORMAT command.\r
+ */\r
+static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the TRANSACT command.\r
+ */\r
+static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the TRANSMASKGET command.\r
+ */\r
+static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the TRANSMASKSET command.\r
+ */\r
+static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the ABORT command.\r
+ */\r
+static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the TEST command.\r
+ */\r
+static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+\r
+/* Structure that defines the DIR command line command, which lists all the\r
+files in the current directory. */\r
+static const CLI_Command_Definition_t xDIR =\r
+{\r
+ "dir", /* The command string to type. */\r
+ "\r\ndir <filename>:\r\n Lists the files in the named directory\r\n",\r
+ prvDIRCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the TYPE command line command, which prints the\r
+contents of a file to the console. */\r
+static const CLI_Command_Definition_t xTYPE =\r
+{\r
+ "type", /* The command string to type. */\r
+ "\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",\r
+ prvTYPECommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the APPEND command line command, which appends data\r
+to a file. */\r
+static const CLI_Command_Definition_t xAPPEND =\r
+{\r
+ "append", /* The command string to type. */\r
+ "\r\nappend <filename> <character> <length>:\r\n Appends data to a file (created if it does not exist)\r\n",\r
+ prvAPPENDCommand, /* The function to run. */\r
+ 3 /* Three parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the DEL command line command, which deletes a file. */\r
+static const CLI_Command_Definition_t xDEL =\r
+{\r
+ "del", /* The command string to type. */\r
+ "\r\ndel <filename>:\r\n deletes a file or directory\r\n",\r
+ prvDELCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the COPY command line command, which copies a file. */\r
+static const CLI_Command_Definition_t xCOPY =\r
+{\r
+ "copy", /* The command string to type. */\r
+ "\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",\r
+ prvCOPYCommand, /* The function to run. */\r
+ 2 /* Two parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the CREATE command line command, which creates an\r
+empty file. */\r
+static const CLI_Command_Definition_t xCREATE =\r
+{\r
+ "create", /* The command string to type. */\r
+ "\r\ncreate <filename>:\r\n Creates an empty file\r\n",\r
+ prvCREATECommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the MKDIR command line command, which creates an\r
+empty directory. */\r
+static const CLI_Command_Definition_t xMKDIR =\r
+{\r
+ "mkdir", /* The command string to type. */\r
+ "\r\nmkdir <filename>:\r\n Creates an empty directory\r\n",\r
+ prvMKDIRCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the RENAME command line command, which renames a file. */\r
+static const CLI_Command_Definition_t xRENAME =\r
+{\r
+ "rename", /* The command string to type. */\r
+ "\r\nrename <source file> <dest file>:\r\n Rename <source file> to <dest file>\r\n",\r
+ prvRENAMECommand, /* The function to run. */\r
+ 2 /* Two parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the LINK command line command, which creates a hard\r
+link. */\r
+static const CLI_Command_Definition_t xLINK =\r
+{\r
+ "link", /* The command string to type. */\r
+ "\r\nlink <source file> <dest file>:\r\n Create hard link <dest file> pointing at <source file>\r\n",\r
+ prvLINKCommand, /* The function to run. */\r
+ 2 /* Two parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the STAT command line command, which shows various\r
+information about a file. */\r
+static const CLI_Command_Definition_t xSTAT =\r
+{\r
+ "stat", /* The command string to type. */\r
+ "\r\nstat <filename>:\r\n Show file information\r\n",\r
+ prvSTATCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the STATFS command line command, which shows various\r
+file system information. */\r
+static const CLI_Command_Definition_t xSTATFS =\r
+{\r
+ "statfs", /* The command string to type. */\r
+ "\r\nstatfs:\r\n Show file system information.\r\n",\r
+ prvSTATFSCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the FORMAT command line command, which re-formats the\r
+file system. */\r
+static const CLI_Command_Definition_t xFORMAT =\r
+{\r
+ "format", /* The command string to type. */\r
+ "\r\nformat:\r\n Re-formats the file system volume. ALL FILES WILL BE DELETED!\r\n",\r
+ prvFORMATCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the TRANSACT command line command, which commits a\r
+transaction point. */\r
+static const CLI_Command_Definition_t xTRANSACT =\r
+{\r
+ "transact", /* The command string to type. */\r
+ "\r\ntransact:\r\n Commit a Reliance Edge transaction point\r\n",\r
+ prvTRANSACTCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the TRANSMASKGET command line command, which retrieves\r
+the current automatic transaction event mask. */\r
+static const CLI_Command_Definition_t xTRANSMASKGET =\r
+{\r
+ "transmaskget", /* The command string to type. */\r
+ "\r\ntransmaskget:\r\n Retrieve the Reliance Edge automatic transaction mask\r\n",\r
+ prvTRANSMASKGETCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the TRANSMASKSET command line command, which sets the\r
+automatic transaction event mask. */\r
+static const CLI_Command_Definition_t xTRANSMASKSET =\r
+{\r
+ "transmaskset", /* The command string to type. */\r
+ "\r\ntransmaskset <hex mask>:\r\n Set the Reliance Edge automatic transaction mask\r\n",\r
+ prvTRANSMASKSETCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. */\r
+};\r
+\r
+/* Structure that defines the ABORT command line command, which rolls back\r
+changes which have not been transacted. */\r
+static const CLI_Command_Definition_t xABORT =\r
+{\r
+ "abort", /* The command string to type. */\r
+ "\r\nabort:\r\n Roll back all changes not part of the last transaction point\r\n",\r
+ prvABORTCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the TEST-FS command line command, which executes some\r
+file system driver tests. */\r
+static const CLI_Command_Definition_t xTEST_FS =\r
+{\r
+ "test-fs", /* The command string to type. */\r
+ "\r\ntest-fs:\r\n Executes file system tests. ALL FILES WILL BE DELETED!\r\n",\r
+ prvTESTFSCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vRegisterFileSystemCLICommands( void )\r
+{\r
+ /* Register all the command line commands defined immediately above. */\r
+ FreeRTOS_CLIRegisterCommand( &xDIR );\r
+ FreeRTOS_CLIRegisterCommand( &xTYPE );\r
+ FreeRTOS_CLIRegisterCommand( &xAPPEND );\r
+ FreeRTOS_CLIRegisterCommand( &xDEL );\r
+ FreeRTOS_CLIRegisterCommand( &xCOPY );\r
+ FreeRTOS_CLIRegisterCommand( &xCREATE );\r
+ FreeRTOS_CLIRegisterCommand( &xMKDIR );\r
+ FreeRTOS_CLIRegisterCommand( &xRENAME );\r
+ FreeRTOS_CLIRegisterCommand( &xLINK );\r
+ FreeRTOS_CLIRegisterCommand( &xSTAT );\r
+ FreeRTOS_CLIRegisterCommand( &xSTATFS );\r
+ FreeRTOS_CLIRegisterCommand( &xFORMAT );\r
+ FreeRTOS_CLIRegisterCommand( &xTRANSACT );\r
+ FreeRTOS_CLIRegisterCommand( &xTRANSMASKGET );\r
+ FreeRTOS_CLIRegisterCommand( &xTRANSMASKSET );\r
+ FreeRTOS_CLIRegisterCommand( &xABORT );\r
+ FreeRTOS_CLIRegisterCommand( &xTEST_FS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+static REDDIR *pxDir = NULL;\r
+REDDIRENT *pxDirent;\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength, xReturn = pdFALSE;\r
+\r
+ /* This assumes pcWriteBuffer is long enough. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ if( pxDir == NULL )\r
+ {\r
+ /* Retrieve the directory to DIR. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* This is the first time this function has been executed since the Dir\r
+ command was run. Open the directory. */\r
+ pxDir = red_opendir( pcParameter );\r
+ }\r
+\r
+ if( pxDir )\r
+ {\r
+ /* red_readdir() returns NULL either on error or upon reaching the\r
+ end of the directory. Clear errno so these conditions can be\r
+ distinguished. */\r
+ red_errno = 0;\r
+ pxDirent = red_readdir( pxDir );\r
+\r
+ if( pxDirent )\r
+ {\r
+ prvCreateFileInfoString( pcWriteBuffer, pxDirent );\r
+ xReturn = pdPASS;\r
+ }\r
+ else if( red_errno == 0 )\r
+ {\r
+ /* There are no more files. Close the directory. */\r
+ red_closedir( pxDir );\r
+ pxDir = NULL;\r
+\r
+ /* No string to return. */\r
+ pcWriteBuffer[ 0 ] = 0x00;\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d reading directory.", ( int ) red_errno );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOENT :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found." );\r
+ break;\r
+\r
+ case RED_ENOTDIR :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Directory not found or not a directory." );\r
+ break;\r
+\r
+ default :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening directory.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTYPECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength, xReturn = pdTRUE;\r
+static int32_t lFildes = -1;\r
+REDSTAT finfo;\r
+int32_t lStatus, lBytesRead;\r
+size_t xColumns = 50U;\r
+\r
+ /* Ensure there is always a null terminator after each character written. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ if( xWriteBufferLen < xColumns )\r
+ {\r
+ /* Ensure the loop that uses xColumns as an end condition does not\r
+ write off the end of the buffer. */\r
+ xColumns = xWriteBufferLen;\r
+ }\r
+\r
+ if( lFildes == -1 )\r
+ {\r
+ /* The file has not been opened yet. Find the file name. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to open the requested file. */\r
+ lFildes = red_open( pcParameter, RED_O_RDONLY );\r
+ if( lFildes == -1 )\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOENT :\r
+ case RED_ENOTDIR :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." );\r
+ break;\r
+\r
+ default :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Make sure this is a file, not a directory. */\r
+ lStatus = red_fstat( lFildes, &finfo );\r
+ if( lStatus == 0 )\r
+ {\r
+ if( RED_S_ISDIR( finfo.st_mode ) )\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Cannot TYPE a directory." );\r
+ red_close( lFildes );\r
+ lFildes = -1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno );\r
+ red_close( lFildes );\r
+ lFildes = -1;\r
+ }\r
+ }\r
+ }\r
+\r
+ if( lFildes != -1 )\r
+ {\r
+ /* Read the next chunk of data from the file. */\r
+ lBytesRead = red_read( lFildes, pcWriteBuffer, xColumns );\r
+\r
+ if( lBytesRead < ( int32_t ) xColumns )\r
+ {\r
+ /* Error or no more characters to return. */\r
+ red_close( lFildes );\r
+ lFildes = -1;\r
+ }\r
+ }\r
+\r
+ if( lFildes == -1 )\r
+ {\r
+ /* Either the file was not opened, or all the data from the file has\r
+ been returned and the file is now closed. */\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvAPPENDCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+char *pcFileName = NULL;\r
+const char *pcCharacter = NULL, *pcLength;\r
+BaseType_t xParameterStringLength, xGoodParameters = pdTRUE;\r
+int32_t lFildes, lAppendLength = -1, lThisWrite, lTotalWritten, lBytesWritten;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Find the length to write. */\r
+ pcLength = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 3, /* Return the third parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+ configASSERT( pcLength );\r
+\r
+ /* Convert the string into a number. */\r
+ lAppendLength = RedAtoI( pcLength );\r
+ if( lAppendLength < 0 )\r
+ {\r
+ strcpy( pcWriteBuffer, "Third parameter cannot be a negative number." );\r
+ xGoodParameters = pdFALSE;\r
+ }\r
+\r
+ if( xGoodParameters )\r
+ {\r
+ /* Find the character to write. */\r
+ pcCharacter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 2, /* Return the second parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+ configASSERT( pcCharacter );\r
+\r
+ if( xParameterStringLength != 1 )\r
+ {\r
+ strcpy( pcWriteBuffer, "Second parameter must be a single character." );\r
+ xGoodParameters = pdFALSE;\r
+ }\r
+ }\r
+\r
+ if( xGoodParameters )\r
+ {\r
+ /* Find the file name. */\r
+ pcFileName = ( char * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+ configASSERT( pcFileName );\r
+\r
+ /* Terminate the string. */\r
+ pcFileName[ xParameterStringLength ] = 0x00;\r
+ }\r
+\r
+ if( xGoodParameters )\r
+ {\r
+ /* Attempt to open the requested file. */\r
+ lFildes = red_open( pcFileName, RED_O_WRONLY|RED_O_APPEND|RED_O_CREAT );\r
+\r
+ if( lFildes == -1 )\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOENT :\r
+ case RED_ENOTDIR :\r
+ strcpy( pcWriteBuffer, "Bad file path." );\r
+ break;\r
+\r
+ case RED_EISDIR :\r
+ strcpy( pcWriteBuffer, "Cannot append to a directory." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d opening file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Put the requested character into the buffer. */\r
+ memset( pcWriteBuffer, pcCharacter[0], xWriteBufferLen );\r
+\r
+ /* Append the data. */\r
+ for( lTotalWritten = 0; lTotalWritten < lAppendLength; lTotalWritten += lThisWrite )\r
+ {\r
+ lThisWrite = lAppendLength - lTotalWritten;\r
+ if( lThisWrite > ( int32_t ) xWriteBufferLen )\r
+ {\r
+ lThisWrite = ( int32_t ) xWriteBufferLen;\r
+ }\r
+\r
+ lBytesWritten = red_write( lFildes, pcWriteBuffer, lThisWrite );\r
+ if( lBytesWritten == -1 )\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOSPC :\r
+ strcpy( pcWriteBuffer, "Out of disk space." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d writing to file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+\r
+ break;\r
+ }\r
+ else if( lBytesWritten != lThisWrite )\r
+ {\r
+ /* Some data was written, but not all of it. This only\r
+ happens when the disk is full or the file reached its\r
+ maximum size. That latter is unlikely in this demo. */\r
+ strcpy( pcWriteBuffer, "Out of disk space." );\r
+ break;\r
+ }\r
+ }\r
+\r
+ if( lTotalWritten == lAppendLength )\r
+ {\r
+ strcpy( pcWriteBuffer, "Append successful." );\r
+ }\r
+\r
+ red_close( lFildes );\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvDELCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength;\r
+int32_t lStatus;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to delete the file or directory. */\r
+ lStatus = red_unlink( pcParameter );\r
+\r
+ if( lStatus == 0 )\r
+ {\r
+ sprintf( pcWriteBuffer, "%s was deleted", pcParameter );\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOTDIR :\r
+ case RED_ENOENT :\r
+ sprintf( pcWriteBuffer, "File not found." );\r
+ break;\r
+\r
+ case RED_ENOTEMPTY :\r
+ sprintf( pcWriteBuffer, "Cannot remove directory: not empty." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d deleting file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvCOPYCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+char *pcSourceFile;\r
+const char *pcDestinationFile;\r
+BaseType_t xParameterStringLength;\r
+int32_t lSourceFildes, lDestinationFildes;\r
+\r
+ /* Obtain the name of the destination file. */\r
+ pcDestinationFile = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 2, /* Return the second parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcDestinationFile );\r
+\r
+ /* Obtain the name of the source file. */\r
+ pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcSourceFile );\r
+\r
+ /* Terminate the string. */\r
+ pcSourceFile[ xParameterStringLength ] = 0x00;\r
+\r
+ /* See if the source file exists, openm it if it does. */\r
+ lSourceFildes = red_open( pcSourceFile, RED_O_RDONLY );\r
+\r
+ if( lSourceFildes == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Source file does not exist" );\r
+ }\r
+ else\r
+ {\r
+ /* Create the destination file, error if it already exists. */\r
+ lDestinationFildes = red_open( pcDestinationFile, RED_O_CREAT|RED_O_EXCL|RED_O_WRONLY );\r
+\r
+ if( lDestinationFildes == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error: Destination file already exists" );\r
+ }\r
+ else\r
+ {\r
+ if( prvPerformCopy( lSourceFildes, lDestinationFildes, pcWriteBuffer, xWriteBufferLen ) == pdPASS )\r
+ {\r
+ sprintf( pcWriteBuffer, "Copy made" );\r
+ }\r
+ else\r
+ {\r
+ sprintf( pcWriteBuffer, "Error during copy" );\r
+ }\r
+\r
+ red_close( lDestinationFildes );\r
+ }\r
+\r
+ red_close( lSourceFildes );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvCREATECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength;\r
+int32_t lFildes;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to create the file. */\r
+ lFildes = red_open( pcParameter, RED_O_CREAT|RED_O_EXCL|RED_O_RDWR );\r
+\r
+ if( lFildes != -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "%s was created", pcParameter );\r
+ red_close( lFildes );\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOTDIR :\r
+ case RED_ENOENT :\r
+ sprintf( pcWriteBuffer, "Bad file path." );\r
+ break;\r
+\r
+ case RED_EEXIST :\r
+ sprintf( pcWriteBuffer, "File already exists." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d creating file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvMKDIRCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength;\r
+int32_t lStatus;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to create the file. */\r
+ lStatus = red_mkdir( pcParameter );\r
+\r
+ if( lStatus == 0 )\r
+ {\r
+ sprintf( pcWriteBuffer, "%s was created", pcParameter );\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOTDIR :\r
+ case RED_ENOENT :\r
+ sprintf( pcWriteBuffer, "Bad file path." );\r
+ break;\r
+\r
+ case RED_EEXIST :\r
+ sprintf( pcWriteBuffer, "Directory already exists." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d creating directory.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvRENAMECommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcDestinationFile;\r
+char *pcSourceFile;\r
+BaseType_t xParameterStringLength;\r
+int32_t lStatus;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the name of the destination file. */\r
+ pcDestinationFile = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 2, /* Return the second parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcDestinationFile );\r
+\r
+ /* Obtain the name of the source file. */\r
+ pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcSourceFile );\r
+\r
+ /* Terminate the string. */\r
+ pcSourceFile[ xParameterStringLength ] = 0x00;\r
+\r
+ /* Attempt to rename the file. */\r
+ lStatus = red_rename( pcSourceFile, pcDestinationFile );\r
+\r
+ if( lStatus == 0 )\r
+ {\r
+ sprintf( pcWriteBuffer, "%s was renamed to %s", pcSourceFile, pcDestinationFile );\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOTDIR :\r
+ case RED_ENOENT :\r
+ case RED_EISDIR :\r
+ sprintf( pcWriteBuffer, "Bad file path." );\r
+ break;\r
+\r
+ /* This will only be seen if POSIX rename is disabled. */\r
+ case RED_EEXIST :\r
+ sprintf( pcWriteBuffer, "Destination already exists." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d renaming file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvLINKCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcDestinationFile;\r
+char *pcSourceFile;\r
+BaseType_t xParameterStringLength;\r
+int32_t lStatus;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Obtain the name of the destination file. */\r
+ pcDestinationFile = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 2, /* Return the second parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcDestinationFile );\r
+\r
+ /* Obtain the name of the source file. */\r
+ pcSourceFile = ( char * ) FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcSourceFile );\r
+\r
+ /* Terminate the string. */\r
+ pcSourceFile[ xParameterStringLength ] = 0x00;\r
+\r
+ /* Attempt to create the hard link. */\r
+ lStatus = red_link( pcSourceFile, pcDestinationFile );\r
+\r
+ if( lStatus == 0 )\r
+ {\r
+ sprintf( pcWriteBuffer, "%s was linked to %s", pcDestinationFile, pcSourceFile );\r
+ }\r
+ else\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOTDIR :\r
+ case RED_ENOENT :\r
+ sprintf( pcWriteBuffer, "Bad file path." );\r
+ break;\r
+\r
+ case RED_EPERM :\r
+ sprintf( pcWriteBuffer, "Cannot link a directory." );\r
+ break;\r
+\r
+ case RED_EMLINK :\r
+ sprintf( pcWriteBuffer, "Too many hard links." );\r
+ break;\r
+\r
+ default :\r
+ sprintf( pcWriteBuffer, "Error %d linking file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvSTATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter, *pcModeString;\r
+BaseType_t xParameterStringLength;\r
+REDSTAT finfo;\r
+int32_t lFildes, lStatus;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ /* Find the file name. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Attempt to open the requested file. */\r
+ lFildes = red_open( pcParameter, RED_O_RDONLY );\r
+ if( lFildes == -1 )\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_ENOENT :\r
+ case RED_ENOTDIR :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "File not found." );\r
+ break;\r
+\r
+ default :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d opening file.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ lStatus = red_fstat( lFildes, &finfo );\r
+ if( lStatus == 0 )\r
+ {\r
+ if( RED_S_ISDIR( finfo.st_mode ) )\r
+ {\r
+ pcModeString = "dir";\r
+ }\r
+ else\r
+ {\r
+ pcModeString = "file";\r
+ }\r
+\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "ino=%lu mode=0x%04x(%s) nlink=%x size=%lu blocks=%lu",\r
+ ( unsigned long ) finfo.st_ino, ( unsigned ) finfo.st_mode, pcModeString,\r
+ ( unsigned ) finfo.st_nlink, (unsigned long) finfo.st_size, (unsigned long) finfo.st_blocks );\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file.", ( int ) red_errno );\r
+ }\r
+\r
+ red_close( lFildes );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvSTATFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+REDSTATFS fsinfo;\r
+int32_t lStatus;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ lStatus = red_statvfs( "", &fsinfo );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d querying file system.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen,\r
+ "Block size: %lu\r\n"\r
+ "Block count: %lu\r\n"\r
+ "Free blocks: %lu\r\n"\r
+ "Inode count: %lu\r\n"\r
+ "Free inodes: %lu\r\n",\r
+ ( unsigned long ) fsinfo.f_bsize, ( unsigned long ) fsinfo.f_blocks,\r
+ ( unsigned long ) fsinfo.f_bfree, ( unsigned long ) fsinfo.f_files,\r
+ ( unsigned long ) fsinfo.f_ffree );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvFORMATCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+int32_t lStatus;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* File system volumes cannot be formatted while mounted. */\r
+ lStatus = red_umount( "" );\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ /* Re-format the file system volume. */\r
+ lStatus = red_format( "" );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during format.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ /* Mount again so that other commands will work properly. */\r
+ lStatus = red_mount( "" );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ strcpy( pcWriteBuffer, "Format successful." );\r
+ }\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTRANSACTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+int32_t lStatus;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Save the original transaction mask settings. */\r
+ lStatus = red_transact( "" );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during transaction point.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ strcpy( pcWriteBuffer, "Transaction point successful." );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTRANSMASKGETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+uint32_t ulEventMask;\r
+int32_t lStatus;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ lStatus = red_gettransmask( "", &ulEventMask );\r
+ if( lStatus == -1 )\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d retrieving automatic transaction event mask.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen,\r
+ "Current automatic transaction event mask: 0x%04lx\r\n"\r
+ "RED_TRANSACT_UMOUNT (0x0001): %s\r\n"\r
+ "RED_TRANSACT_CREAT (0x0002): %s\r\n"\r
+ "RED_TRANSACT_UNLINK (0x0004): %s\r\n"\r
+ "RED_TRANSACT_MKDIR (0x0008): %s\r\n"\r
+ "RED_TRANSACT_RENAME (0x0010): %s\r\n"\r
+ "RED_TRANSACT_LINK (0x0020): %s\r\n"\r
+ "RED_TRANSACT_CLOSE (0x0040): %s\r\n"\r
+ "RED_TRANSACT_WRITE (0x0080): %s\r\n"\r
+ "RED_TRANSACT_FSYNC (0x0100): %s\r\n"\r
+ "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n"\r
+ "RED_TRANSACT_VOLFULL (0x0400): %s\r\n",\r
+ ( unsigned long ) ulEventMask,\r
+ ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTRANSMASKSETCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength;\r
+uint32_t ulEventMask;\r
+int32_t lStatus;\r
+\r
+ /* Ensure the buffer leaves space for the \r\n. */\r
+ configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );\r
+ xWriteBufferLen -= strlen( cliNEW_LINE );\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ if( ( pcParameter[0] == '0' ) && ( ( pcParameter[1] == 'x' ) || ( pcParameter[1] == 'X' ) ) )\r
+ {\r
+ pcParameter += 2;\r
+ }\r
+\r
+ /* Convert the argument into a value. */\r
+ RedHtoUL( pcParameter, &ulEventMask );\r
+\r
+ /* Set the new transaction mask. */\r
+ lStatus = red_settransmask( "", ulEventMask );\r
+ if( lStatus == -1 )\r
+ {\r
+ /* User-friendly messages for common errors. */\r
+ switch( red_errno )\r
+ {\r
+ case RED_EINVAL:\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Invalid bits in transaction mask." );\r
+ break;\r
+\r
+ default :\r
+ snprintf( pcWriteBuffer, xWriteBufferLen, "Error %d setting transaction mask.", ( int ) red_errno );\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ snprintf( pcWriteBuffer, xWriteBufferLen,\r
+ "Successfully set automatic transaction mask. Enabled events:\r\n"\r
+ "RED_TRANSACT_UMOUNT (0x0001): %s\r\n"\r
+ "RED_TRANSACT_CREAT (0x0002): %s\r\n"\r
+ "RED_TRANSACT_UNLINK (0x0004): %s\r\n"\r
+ "RED_TRANSACT_MKDIR (0x0008): %s\r\n"\r
+ "RED_TRANSACT_RENAME (0x0010): %s\r\n"\r
+ "RED_TRANSACT_LINK (0x0020): %s\r\n"\r
+ "RED_TRANSACT_CLOSE (0x0040): %s\r\n"\r
+ "RED_TRANSACT_WRITE (0x0080): %s\r\n"\r
+ "RED_TRANSACT_FSYNC (0x0100): %s\r\n"\r
+ "RED_TRANSACT_TRUNCATE (0x0200): %s\r\n"\r
+ "RED_TRANSACT_VOLFULL (0x0400): %s\r\n",\r
+ ( ulEventMask & RED_TRANSACT_UMOUNT ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_CREAT ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_UNLINK ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_MKDIR ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_RENAME ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_LINK ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_CLOSE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_WRITE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_FSYNC ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_TRUNCATE ) ? "Enabled" : "Disabled",\r
+ ( ulEventMask & RED_TRANSACT_VOLFULL ) ? "Enabled" : "Disabled" );\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvABORTCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+uint32_t ulEventMask;\r
+int32_t lStatus;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) pcCommandString;\r
+\r
+ /* This function assumes xWriteBufferLen is large enough! */\r
+ ( void ) xWriteBufferLen;\r
+\r
+ /* Save the original transaction mask settings. */\r
+ lStatus = red_gettransmask( "", &ulEventMask );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d querying transaction mask.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ /* Make it so that red_umount() will not automatically commit a new\r
+ transaction point. */\r
+ lStatus = red_settransmask( "", ulEventMask & ~( ( uint32_t ) RED_TRANSACT_UMOUNT ) );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d setting transaction mask.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ /* Unmount. Since red_umount() will not transact, all changes which\r
+ were not already transacted are rolled back. */\r
+ lStatus = red_umount( "" );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during unmount.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ /* Mount. Mount always starts from the last transaction point. */\r
+ lStatus = red_mount( "" );\r
+\r
+ if( lStatus == -1 )\r
+ {\r
+ sprintf( pcWriteBuffer, "Error %d during mount.", ( int ) red_errno );\r
+ }\r
+ else\r
+ {\r
+ strcpy( pcWriteBuffer, "Working state changes succesfully aborted." );\r
+ }\r
+ }\r
+\r
+ /* Restore the original transaction mask settings. */\r
+ red_settransmask( "", ulEventMask );\r
+ }\r
+ }\r
+\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTESTFSCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+UBaseType_t uxOriginalPriority;\r
+FSSTRESSPARAM param;\r
+\r
+ /* Avoid compiler warnings. */\r
+ ( void ) xWriteBufferLen;\r
+ ( void ) pcCommandString;\r
+\r
+ /* Limitations in the interaction with the Windows TCP/IP stack require\r
+ the command console to run at the idle priority. Raise the priority for\r
+ the duration of the tests to ensure there are not multiple switches to the\r
+ idle task as in the simulated environment the idle task hook function may\r
+ include a (relatively) long delay. */\r
+ uxOriginalPriority = uxTaskPriorityGet( NULL );\r
+ vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 );\r
+\r
+ /* Delete all files to avoid inteferring with the test. */\r
+ red_umount( "" );\r
+ red_format( "" );\r
+ red_mount( "" );\r
+\r
+ FsstressDefaultParams(¶m);\r
+ param.fVerbose = pdTRUE;\r
+ param.ulNops = 10000;\r
+ param.ulSeed = 1;\r
+ FsstressStart(¶m);\r
+\r
+ /* Clean up after the test. */\r
+ red_umount( "" );\r
+ red_format( "" );\r
+ red_mount( "" );\r
+\r
+ /* Reset back to the original priority. */\r
+ vTaskPrioritySet( NULL, uxOriginalPriority );\r
+\r
+ sprintf( pcWriteBuffer, "%s", "Test results were sent to Windows console" );\r
+ strcat( pcWriteBuffer, cliNEW_LINE );\r
+\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvPerformCopy( int32_t lSourceFildes,\r
+ int32_t lDestinationFiledes,\r
+ char *pxWriteBuffer,\r
+ size_t xWriteBufferLen )\r
+{\r
+int32_t lBytesRead;\r
+BaseType_t xReturn = pdPASS;\r
+\r
+ /* Assuming both files are at offset zero. */\r
+\r
+ for( ;; )\r
+ {\r
+ /* Read the next block of data. */\r
+ lBytesRead = red_read( lSourceFildes, pxWriteBuffer, xWriteBufferLen );\r
+ if( lBytesRead <= 0 )\r
+ {\r
+ if( lBytesRead == -1)\r
+ {\r
+ /* Error reading from file. */\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ /* No error: reached end of file, time to stop. */\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ /* Write the block of data to the end of the file. */\r
+ if( red_write( lDestinationFiledes, pxWriteBuffer, lBytesRead ) != lBytesRead )\r
+ {\r
+ xReturn = pdFAIL;\r
+ break;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateFileInfoString( char *pcBuffer, REDDIRENT *pxDirent )\r
+{\r
+const char *pcFile = "file", *pcDirectory = "directory";\r
+const char *pcAttrib;\r
+\r
+ /* Point pcAttrib to a string that describes the file. */\r
+ if( RED_S_ISDIR(pxDirent->d_stat.st_mode) )\r
+ {\r
+ pcAttrib = pcDirectory;\r
+ }\r
+ else\r
+ {\r
+ pcAttrib = pcFile;\r
+ }\r
+\r
+ /* Create a string that includes the file name, the file size and the\r
+ attributes string. */\r
+ sprintf( pcBuffer, "%s [%s] [size=%d]", pxDirent->d_name, pcAttrib, pxDirent->d_stat.st_size );\r
+}\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+/*******************************************************************************\r
+ * See the URL in the comments within main.c for the location of the online\r
+ * documentation.\r
+ ******************************************************************************/\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* File system includes. */\r
+#include <redposix.h>\r
+\r
+/* The number of bytes read/written to the example files at a time. */\r
+#define fsRAM_BUFFER_SIZE 200\r
+\r
+/* The volume prefix is an empty string, for convenience since there is only one\r
+volume in this demo.\r
+*/\r
+#define fsVOLUME_NAME ""\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Creates and verifies different files on the volume, demonstrating the use of\r
+ * various different API functions.\r
+ */\r
+void vCreateAndVerifySampleFiles( void );\r
+\r
+/*\r
+ * Create a set of example files in the root directory of the volume using\r
+ * f_write().\r
+ */\r
+static void prvCreateDemoFiles( void );\r
+\r
+/*\r
+ * Use f_read() to read back and verify the files that were created by\r
+ * prvCreateDemoFiles().\r
+ */\r
+static void prvVerifyDemoFiles( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* A buffer used to both create content to write to disk, and read content back\r
+from a disk. Note there is no mutual exclusion on this buffer. */\r
+static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];\r
+\r
+/* Names of directories that are created. */\r
+static const char *pcDirectory1 = "/SUB1", *pcDirectory2 = "/SUB1/SUB2";\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCreateAndVerifySampleFiles( void )\r
+{\r
+int32_t lStatus;\r
+\r
+ /* First initialize the Reliance Edge driver. */\r
+ lStatus = red_init();\r
+\r
+ /* Format the volume. */\r
+ if( lStatus == 0 )\r
+ {\r
+ lStatus = red_format( fsVOLUME_NAME );\r
+ }\r
+\r
+ /* Mount the volume. */\r
+ if( lStatus == 0 )\r
+ {\r
+ lStatus = red_mount( fsVOLUME_NAME );\r
+ }\r
+\r
+ if( lStatus == 0 )\r
+ {\r
+ /* Create a set of files using red_write(). */\r
+ prvCreateDemoFiles();\r
+\r
+ /* Read back and verify the files that were created using red_write(). */\r
+ prvVerifyDemoFiles();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateDemoFiles( void )\r
+{\r
+BaseType_t xFileNumber, xWriteNumber;\r
+char cFilePath[ 64 ];\r
+const BaseType_t xMaxFiles = 5;\r
+uint32_t ulEventMask;\r
+int32_t lBytesWritten, lFildes, lStatus;\r
+int iByte;\r
+\r
+ /* Save the current transaction point settings. */\r
+ lStatus = red_gettransmask( fsVOLUME_NAME, &ulEventMask );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Disable automatic transaction points so that all of the files can be\r
+ created in one atomic operation. */\r
+ lStatus = red_settransmask( fsVOLUME_NAME, RED_TRANSACT_MANUAL );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Create xMaxFiles files. Each created file will be\r
+ ( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled\r
+ with a different repeating character. */\r
+ for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
+ {\r
+ /* Generate a file name. */\r
+ sprintf( cFilePath, "/root%03d.txt", xFileNumber );\r
+\r
+ /* Print out the file name and the directory into which the file is\r
+ being written. */\r
+ printf( "Creating file %s\r\n", cFilePath );\r
+\r
+ /* Open the file, creating the file if it does not already exist. */\r
+ lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY );\r
+ configASSERT( lFildes != -1 );\r
+\r
+ /* Fill the RAM buffer with data that will be written to the file. This\r
+ is just a repeating ascii character that indicates the file number. */\r
+ memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );\r
+\r
+ /* Write the RAM buffer to the opened file a number of times. The\r
+ number of times the RAM buffer is written to the file depends on the\r
+ file number, so the length of each created file will be different. */\r
+ for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )\r
+ {\r
+ lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE );\r
+ }\r
+\r
+ /* Close the file so another file can be created. */\r
+ lStatus = red_close( lFildes );\r
+ configASSERT( lStatus == 0 );\r
+ }\r
+\r
+ /* Commit a transaction point, atomically adding the set of files to the\r
+ transacted state. */\r
+ lStatus = red_transact( fsVOLUME_NAME );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Create a sub directory. */\r
+ printf( "Creating directory %s\r\n", pcDirectory1 );\r
+\r
+ lStatus = red_mkdir( pcDirectory1 );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Create a subdirectory in the new directory. */\r
+ printf( "Creating directory %s\r\n", pcDirectory2 );\r
+\r
+ lStatus = red_mkdir( pcDirectory2 );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Generate the file name. */\r
+ sprintf( cFilePath, "%s/file.txt", pcDirectory2 );\r
+\r
+ /* Print out the file name and the directory into which the file is being\r
+ written. */\r
+ printf( "Writing file %s\r\n", cFilePath );\r
+\r
+ lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY );\r
+\r
+ /* Write the file. It is filled with incrementing ascii characters starting\r
+ from '0'. */\r
+ for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ )\r
+ {\r
+ cRAMBuffer[ iByte ] = ( char ) ( ( int ) '0' + iByte );\r
+ }\r
+\r
+ lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE );\r
+\r
+ /* Finished so close the file. */\r
+ lStatus = red_close( lFildes );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Commit a transaction point, atomically adding the set of files and\r
+ directories to the transacted state. */\r
+ lStatus = red_transact( fsVOLUME_NAME );\r
+ configASSERT( lStatus == 0 );\r
+\r
+ /* Restore previous transaction point settings. */\r
+ lStatus = red_settransmask( fsVOLUME_NAME, ulEventMask );\r
+ configASSERT( lStatus == 0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvVerifyDemoFiles( void )\r
+{\r
+BaseType_t xFileNumber, xReadNumber;\r
+char cFilePath[ 64 ];\r
+const BaseType_t xMaxFiles = 5;\r
+long lChar;\r
+int32_t lBytesRead, lFildes, lStatus;\r
+int iByte;\r
+\r
+ /* Read back the files that were created by prvCreateDemoFiles(). */\r
+ for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )\r
+ {\r
+ /* Generate the file name. */\r
+ sprintf( cFilePath, "/root%03d.txt", xFileNumber );\r
+\r
+ /* Print out the file name and the directory from which the file is\r
+ being read. */\r
+ printf( "Reading file %s\r\n", cFilePath );\r
+\r
+ /* Open the file for reading. */\r
+ lFildes = red_open( cFilePath, RED_O_RDONLY );\r
+ configASSERT( lFildes != -1 );\r
+\r
+ /* Read the file into the RAM buffer, checking the file contents are as\r
+ expected. The size of the file depends on the file number. */\r
+ for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )\r
+ {\r
+ /* Start with the RAM buffer clear. */\r
+ memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );\r
+\r
+ lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ configASSERT( lBytesRead == fsRAM_BUFFER_SIZE );\r
+\r
+ /* Check the RAM buffer is filled with the expected data. Each\r
+ file contains a different repeating ascii character that indicates\r
+ the number of the file. */\r
+ for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )\r
+ {\r
+ configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );\r
+ }\r
+ }\r
+\r
+ /* Close the file. */\r
+ lStatus = red_close( lFildes );\r
+ configASSERT( lStatus == 0 );\r
+ }\r
+\r
+ /* Generate the file name. */\r
+ sprintf( cFilePath, "%s/file.txt", pcDirectory2 );\r
+\r
+ /* Print out the file name and the directory from which the file is being\r
+ read. */\r
+ printf( "Reading file %s\r\n", cFilePath );\r
+\r
+ /* This time the file is opened for reading. */\r
+ lFildes = red_open( cFilePath, RED_O_RDONLY );\r
+ configASSERT( lFildes != -1 );\r
+\r
+ /* Read the file. */\r
+ lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );\r
+ configASSERT( lBytesRead == fsRAM_BUFFER_SIZE );\r
+\r
+ /* Verify the file 1 byte at a time. */\r
+ for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ )\r
+ {\r
+ configASSERT( cRAMBuffer[ iByte ] == ( char ) ( ( int ) '0' + iByte ) );\r
+ }\r
+\r
+ /* Finished so close the file. */\r
+ lStatus = red_close( lFildes );\r
+ configASSERT( lStatus == 0 );\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual C++ Express 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WIN32", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32\r
+ {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+[{000214A0-0000-0000-C000-000000000046}]\r
+Prop3=19,2\r
+[InternetShortcut]\r
+URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Reliance_Edge_Fail_Safe_File_System.shtml\r
+IDList=\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+/*\r
+ * Utility functions required to gather run time statistics. See:\r
+ * http://www.freertos.org/rtos-run-time-stats.html\r
+ *\r
+ * Note that this is a simulated port, where simulated time is a lot slower than\r
+ * real time, therefore the run time counter values have no real meaningful\r
+ * units.\r
+ *\r
+ * Also note that it is assumed this demo is going to be used for short periods\r
+ * of time only, and therefore timer overflows are not handled.\r
+*/\r
+\r
+/* FreeRTOS includes. */\r
+#include <FreeRTOS.h>\r
+\r
+/* Variables used in the creation of the run time stats time base. Run time \r
+stats record how much time each task spends in the Running state. */\r
+static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vConfigureTimerForRunTimeStats( void )\r
+{\r
+LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue;\r
+\r
+ /* Initialise the variables used to create the run time stats time base.\r
+ Run time stats record how much time each task spends in the Running \r
+ state. */\r
+\r
+ if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 )\r
+ {\r
+ llTicksPerHundedthMillisecond = 1;\r
+ }\r
+ else\r
+ {\r
+ /* How many times does the performance counter increment in 1/100th\r
+ millisecond. */\r
+ llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL;\r
+\r
+ /* What is the performance counter value now, this will be subtracted\r
+ from readings taken at run time. */\r
+ QueryPerformanceCounter( &liInitialRunTimeValue );\r
+ llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+unsigned long ulGetRunTimeCounterValue( void )\r
+{\r
+LARGE_INTEGER liCurrentCount;\r
+unsigned long ulReturn;\r
+\r
+ /* What is the performance counter value now? */\r
+ QueryPerformanceCounter( &liCurrentCount );\r
+\r
+ /* Subtract the performance counter value reading taken when the \r
+ application started to get a count from that reference point, then\r
+ scale to (simulated) 1/100ths of a millisecond. */\r
+ ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond );\r
+\r
+ return ulReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+ /******************************************************************************\r
+ *\r
+ * See the following URL for information on the commands defined in this file:\r
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS\r
+ #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0\r
+#endif\r
+\r
+\r
+/*\r
+ * Implements the run-time-stats command.\r
+ */\r
+static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the task-stats command.\r
+ */\r
+static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the echo-three-parameters command.\r
+ */\r
+static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the echo-parameters command.\r
+ */\r
+static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+\r
+/*\r
+ * Implements the "trace start" and "trace stop" commands;\r
+ */\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+ static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
+#endif\r
+\r
+/* Structure that defines the "run-time-stats" command line command. This\r
+generates a table that shows how much run time each task has */\r
+static const CLI_Command_Definition_t xRunTimeStats =\r
+{\r
+ "run-time-stats", /* The command string to type. */\r
+ "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",\r
+ prvRunTimeStatsCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the "task-stats" command line command. This generates\r
+a table that gives information on each task in the system. */\r
+static const CLI_Command_Definition_t xTaskStats =\r
+{\r
+ "task-stats", /* The command string to type. */\r
+ "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",\r
+ prvTaskStatsCommand, /* The function to run. */\r
+ 0 /* No parameters are expected. */\r
+};\r
+\r
+/* Structure that defines the "echo_3_parameters" command line command. This\r
+takes exactly three parameters that the command simply echos back one at a\r
+time. */\r
+static const CLI_Command_Definition_t xThreeParameterEcho =\r
+{\r
+ "echo-3-parameters",\r
+ "\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",\r
+ prvThreeParameterEchoCommand, /* The function to run. */\r
+ 3 /* Three parameters are expected, which can take any value. */\r
+};\r
+\r
+/* Structure that defines the "echo_parameters" command line command. This\r
+takes a variable number of parameters that the command simply echos back one at\r
+a time. */\r
+static const CLI_Command_Definition_t xParameterEcho =\r
+{\r
+ "echo-parameters",\r
+ "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",\r
+ prvParameterEchoCommand, /* The function to run. */\r
+ -1 /* The user can enter any number of commands. */\r
+};\r
+\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+ /* Structure that defines the "trace" command line command. This takes a single\r
+ parameter, which can be either "start" or "stop". */\r
+ static const CLI_Command_Definition_t xStartStopTrace =\r
+ {\r
+ "trace",\r
+ "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",\r
+ prvStartStopTraceCommand, /* The function to run. */\r
+ 1 /* One parameter is expected. Valid values are "start" and "stop". */\r
+ };\r
+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vRegisterSampleCLICommands( void )\r
+{\r
+ /* Register all the command line commands defined immediately above. */\r
+ FreeRTOS_CLIRegisterCommand( &xTaskStats );\r
+ FreeRTOS_CLIRegisterCommand( &xRunTimeStats );\r
+ FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );\r
+ FreeRTOS_CLIRegisterCommand( &xParameterEcho );\r
+\r
+ #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )\r
+ {\r
+ FreeRTOS_CLIRegisterCommand( & xStartStopTrace );\r
+ }\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n";\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Generate a table of task stats. */\r
+ strcpy( pcWriteBuffer, pcHeader );\r
+ vTaskList( pcWriteBuffer + strlen( pcHeader ) );\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n";\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Generate a table of task stats. */\r
+ strcpy( pcWriteBuffer, pcHeader );\r
+ vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength, xReturn;\r
+static BaseType_t lParameterNumber = 0;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ if( lParameterNumber == 0 )\r
+ {\r
+ /* The first time the function is called after the command has been\r
+ entered just a header string is returned. */\r
+ sprintf( pcWriteBuffer, "The three parameters were:\r\n" );\r
+\r
+ /* Next time the function is called the first parameter will be echoed\r
+ back. */\r
+ lParameterNumber = 1L;\r
+\r
+ /* There is more data to be returned as no parameters have been echoed\r
+ back yet. */\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ lParameterNumber, /* Return the next parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* Return the parameter string. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+ sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );\r
+ strncat( pcWriteBuffer, pcParameter, xParameterStringLength );\r
+ strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
+\r
+ /* If this is the last of the three parameters then there are no more\r
+ strings to return after this one. */\r
+ if( lParameterNumber == 3L )\r
+ {\r
+ /* If this is the last of the three parameters then there are no more\r
+ strings to return after this one. */\r
+ xReturn = pdFALSE;\r
+ lParameterNumber = 0L;\r
+ }\r
+ else\r
+ {\r
+ /* There are more parameters to return after this one. */\r
+ xReturn = pdTRUE;\r
+ lParameterNumber++;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+{\r
+const char *pcParameter;\r
+BaseType_t xParameterStringLength, xReturn;\r
+static BaseType_t lParameterNumber = 0;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ if( lParameterNumber == 0 )\r
+ {\r
+ /* The first time the function is called after the command has been\r
+ entered just a header string is returned. */\r
+ sprintf( pcWriteBuffer, "The parameters were:\r\n" );\r
+\r
+ /* Next time the function is called the first parameter will be echoed\r
+ back. */\r
+ lParameterNumber = 1L;\r
+\r
+ /* There is more data to be returned as no parameters have been echoed\r
+ back yet. */\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ lParameterNumber, /* Return the next parameter. */\r
+ &xParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ if( pcParameter != NULL )\r
+ {\r
+ /* Return the parameter string. */\r
+ memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
+ sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );\r
+ strncat( pcWriteBuffer, pcParameter, xParameterStringLength );\r
+ strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
+\r
+ /* There might be more parameters to return after this one. */\r
+ xReturn = pdTRUE;\r
+ lParameterNumber++;\r
+ }\r
+ else\r
+ {\r
+ /* No more parameters were found. Make sure the write buffer does\r
+ not contain a valid string. */\r
+ pcWriteBuffer[ 0 ] = 0x00;\r
+\r
+ /* No more data to return. */\r
+ xReturn = pdFALSE;\r
+\r
+ /* Start over the next time this command is executed. */\r
+ lParameterNumber = 0;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
+\r
+ static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
+ {\r
+ const char *pcParameter;\r
+ BaseType_t lParameterStringLength;\r
+\r
+ /* Remove compile time warnings about unused parameters, and check the\r
+ write buffer is not NULL. NOTE - for simplicity, this example assumes the\r
+ write buffer length is adequate, so does not check for buffer overflows. */\r
+ ( void ) pcCommandString;\r
+ ( void ) xWriteBufferLen;\r
+ configASSERT( pcWriteBuffer );\r
+\r
+ /* Obtain the parameter string. */\r
+ pcParameter = FreeRTOS_CLIGetParameter\r
+ (\r
+ pcCommandString, /* The command string itself. */\r
+ 1, /* Return the first parameter. */\r
+ &lParameterStringLength /* Store the parameter string length. */\r
+ );\r
+\r
+ /* Sanity check something was returned. */\r
+ configASSERT( pcParameter );\r
+\r
+ /* There are only two valid parameter values. */\r
+ if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )\r
+ {\r
+ /* Start or restart the trace. */\r
+ vTraceStop();\r
+ vTraceClear();\r
+ vTraceStart();\r
+\r
+ sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );\r
+ }\r
+ else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )\r
+ {\r
+ /* End the trace, if one is running. */\r
+ vTraceStop();\r
+ sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" );\r
+ }\r
+ else\r
+ {\r
+ sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );\r
+ }\r
+\r
+ /* There is no more data to return after this single string, so return\r
+ pdFALSE. */\r
+ return pdFALSE;\r
+ }\r
+\r
+#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+\r
+#pragma comment( lib, "ws2_32.lib" )\r
+\r
+/* Win32 includes. */\r
+#include <WinSock2.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Standard includes. */\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+\r
+/* FreeRTOS+CLI includes. */\r
+#include "FreeRTOS_CLI.h"\r
+\r
+/* Dimensions the buffer into which input characters are placed. */\r
+#define cmdMAX_INPUT_SIZE 60\r
+\r
+/* Dimensions the buffer into which string outputs can be placed. */\r
+#define cmdMAX_OUTPUT_SIZE 1024\r
+\r
+/* Dimensions the buffer passed to the recvfrom() call. */\r
+#define cmdSOCKET_INPUT_BUFFER_SIZE 60\r
+\r
+/* DEL acts as a backspace. */\r
+#define cmdASCII_DEL ( 0x7F )\r
+\r
+/*\r
+ * Open and configure the UDP socket.\r
+ */\r
+static SOCKET prvOpenUDPSocket( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Task that provides the input and output for the FreeRTOS+CLI command\r
+ * interpreter. In this case a WinSock UDP port is used for convenience as this\r
+ * demo runs in a simulated environment on a Windows PC. See the URL in the\r
+ * comments within main.c for the location of the online documentation.\r
+ */\r
+void vUDPCommandInterpreterTask( void *pvParameters )\r
+{\r
+long lBytes, lByte;\r
+signed char cInChar, cInputIndex = 0;\r
+static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];\r
+BaseType_t xMoreDataToFollow;\r
+volatile int iErrorCode = 0;\r
+struct sockaddr_in xClient;\r
+int xClientAddressLength = sizeof( struct sockaddr_in );\r
+SOCKET xSocket;\r
+\r
+ /* Just to prevent compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ /* Attempt to open the socket. */\r
+ xSocket = prvOpenUDPSocket();\r
+\r
+ if( xSocket != INVALID_SOCKET )\r
+ {\r
+ for( ;; )\r
+ {\r
+ /* Wait for incoming data on the opened socket. */\r
+ lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength );\r
+\r
+ if( lBytes == SOCKET_ERROR )\r
+ {\r
+ /* Something went wrong, but it is not handled by this simple\r
+ example. */\r
+ iErrorCode = WSAGetLastError();\r
+ }\r
+ else\r
+ {\r
+ /* Process each received byte in turn. */\r
+ lByte = 0;\r
+ while( lByte < lBytes )\r
+ {\r
+ /* The next character in the input buffer. */\r
+ cInChar = cLocalBuffer[ lByte ];\r
+ lByte++;\r
+\r
+ /* Newline characters are taken as the end of the command\r
+ string. */\r
+ if( cInChar == '\n' )\r
+ {\r
+ /* Process the input string received prior to the\r
+ newline. */\r
+ do\r
+ {\r
+ /* Pass the string to FreeRTOS+CLI. */\r
+ xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );\r
+\r
+ /* Send the output generated by the command's\r
+ implementation. */\r
+ sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
+\r
+ } while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */\r
+\r
+ /* All the strings generated by the command processing\r
+ have been sent. Clear the input string ready to receive\r
+ the next command. */\r
+ cInputIndex = 0;\r
+ memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );\r
+\r
+ /* Transmit a spacer, just to make the command console\r
+ easier to read. */\r
+ sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );\r
+ }\r
+ else\r
+ {\r
+ if( cInChar == '\r' )\r
+ {\r
+ /* Ignore the character. Newlines are used to\r
+ detect the end of the input string. */\r
+ }\r
+ else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) )\r
+ {\r
+ /* Backspace was pressed. Erase the last character\r
+ in the string - if any. */\r
+ if( cInputIndex > 0 )\r
+ {\r
+ cInputIndex--;\r
+ cInputString[ cInputIndex ] = '\0';\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* A character was entered. Add it to the string\r
+ entered so far. When a \n is entered the complete\r
+ string will be passed to the command interpreter. */\r
+ if( cInputIndex < cmdMAX_INPUT_SIZE )\r
+ {\r
+ cInputString[ cInputIndex ] = cInChar;\r
+ cInputIndex++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The socket could not be opened. */\r
+ vTaskDelete( NULL );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static SOCKET prvOpenUDPSocket( void )\r
+{\r
+WSADATA xWSAData;\r
+WORD wVersionRequested;\r
+struct sockaddr_in xServer;\r
+SOCKET xSocket = INVALID_SOCKET;\r
+\r
+ wVersionRequested = MAKEWORD( 2, 2 );\r
+\r
+ /* Prepare to use WinSock. */\r
+ if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )\r
+ {\r
+ fprintf( stderr, "Could not open Windows connection.\n" );\r
+ }\r
+ else\r
+ {\r
+ xSocket = socket( AF_INET, SOCK_DGRAM, 0 );\r
+ if( xSocket == INVALID_SOCKET)\r
+ {\r
+ fprintf( stderr, "Could not create socket.\n" );\r
+ WSACleanup();\r
+ }\r
+ else\r
+ {\r
+ /* Zero out the server structure. */\r
+ memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) );\r
+\r
+ /* Set family and port. */\r
+ xServer.sin_family = AF_INET;\r
+ xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER );\r
+\r
+ /* Assign the loopback address */\r
+ xServer.sin_addr.S_un.S_un_b.s_b1 = 127;\r
+ xServer.sin_addr.S_un.S_un_b.s_b2 = 0;\r
+ xServer.sin_addr.S_un.S_un_b.s_b3 = 0;\r
+ xServer.sin_addr.S_un.S_un_b.s_b4 = 1;\r
+\r
+ /* Bind the address to the socket. */\r
+ if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 )\r
+ {\r
+ fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER );\r
+ closesocket( xSocket );\r
+ xSocket = INVALID_SOCKET;\r
+ WSACleanup();\r
+ }\r
+ }\r
+ }\r
+\r
+ return xSocket;\r
+}\r
+\r
+\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup Label="ProjectConfigurations">\r
+ <ProjectConfiguration Include="Debug|Win32">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|Win32">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>\r
+ <ProjectName>RTOSDemo</ProjectName>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseOfMfc>false</UseOfMfc>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseOfMfc>false</UseOfMfc>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+ </ImportGroup>\r
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />\r
+ </ImportGroup>\r
+ <PropertyGroup Label="UserMacros" />\r
+ <PropertyGroup>\r
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>\r
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>\r
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <Midl>\r
+ <TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>\r
+ <HeaderFileName>\r
+ </HeaderFileName>\r
+ </Midl>\r
+ <ClCompile>\r
+ <Optimization>Disabled</Optimization>\r
+ <AdditionalIncludeDirectories>..\..\Source\Reliance-Edge\os\freertos\include;..\..\Source\Reliance-Edge\projects\freertos\win32-demo;..\..\Source\Reliance-Edge\core\include;..\..\Source\Reliance-Edge\include;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\FreeRTOS-Plus-CLI;.;.\ConfigurationFiles;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <MinimalRebuild>true</MinimalRebuild>\r
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+ <PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>\r
+ <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>\r
+ <ObjectFileName>.\Debug/</ObjectFileName>\r
+ <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>\r
+ <WarningLevel>Level4</WarningLevel>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <DisableLanguageExtensions>false</DisableLanguageExtensions>\r
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
+ </ClCompile>\r
+ <ResourceCompile>\r
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <Culture>0x0c09</Culture>\r
+ </ResourceCompile>\r
+ <Link>\r
+ <OutputFile>.\Debug/RTOSDemo.exe</OutputFile>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>\r
+ <SubSystem>Console</SubSystem>\r
+ <TargetMachine>MachineX86</TargetMachine>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>\r
+ </Link>\r
+ <Bscmake>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <OutputFile>.\Debug/WIN32.bsc</OutputFile>\r
+ </Bscmake>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Midl>\r
+ <TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>\r
+ <HeaderFileName>\r
+ </HeaderFileName>\r
+ </Midl>\r
+ <ClCompile>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>\r
+ <PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <StringPooling>true</StringPooling>\r
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>\r
+ <AssemblerListingLocation>.\Release/</AssemblerListingLocation>\r
+ <ObjectFileName>.\Release/</ObjectFileName>\r
+ <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <ResourceCompile>\r
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <Culture>0x0c09</Culture>\r
+ </ResourceCompile>\r
+ <Link>\r
+ <OutputFile>.\Release/RTOSDemo.exe</OutputFile>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>\r
+ <SubSystem>Console</SubSystem>\r
+ <TargetMachine>MachineX86</TargetMachine>\r
+ <AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ <Bscmake>\r
+ <SuppressStartupBanner>true</SuppressStartupBanner>\r
+ <OutputFile>.\Release/WIN32.bsc</OutputFile>\r
+ </Bscmake>\r
+ </ItemDefinitionGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\list.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c" />\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c" />\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\blockio.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\buffer.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\core.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\dir.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\format.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imap.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapextern.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapinline.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inode.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inodedata.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\volume.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\fse\fse.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osassert.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osbdev.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osclock.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osmutex.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osoutput.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostask.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostimestamp.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\posix\path.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\posix\posix.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\posix\fsstress.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\atoi.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\math.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\printf.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\rand.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\getopt.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\toolcmn.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\bitmap.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\crc.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\endian.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\memory.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\namelen.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\sign.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\string.c" />\r
+ <ClCompile Include="ConfigurationFiles\redconf.c" />\r
+ <ClCompile Include="File-Related-CLI-commands.c" />\r
+ <ClCompile Include="File-system-demo.c" />\r
+ <ClCompile Include="main.c">\r
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ </ClCompile>\r
+ <ClCompile Include="Run-time-stats-utils.c" />\r
+ <ClCompile Include="Sample-CLI-commands.c" />\r
+ <ClCompile Include="UDPCommandServer.c" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" />\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" />\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h" />\r
+ <ClInclude Include="..\..\Source\Reliance-Edge\os\freertos\include\ostypes.h" />\r
+ <ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h" />\r
+ <ClInclude Include="ConfigurationFiles\redconf.h" />\r
+ <ClInclude Include="ConfigurationFiles\redtypes.h" />\r
+ </ItemGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="Resource Files">\r
+ <UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>\r
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS">\r
+ <UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source">\r
+ <UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>\r
+ <Extensions>*.c</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source\Portable">\r
+ <UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+">\r
+ <UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+CLI">\r
+ <UniqueIdentifier>{fd43c0ed-fdbc-437f-a5a3-c50399690bd7}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+CLI\include">\r
+ <UniqueIdentifier>{c5889fe2-af0f-4cea-927f-6a6935ec5e14}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="Configuration Files">\r
+ <UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>\r
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS\Source\include">\r
+ <UniqueIdentifier>{ab23827c-126c-4e5a-bc99-8efa44d8a8bd}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge">\r
+ <UniqueIdentifier>{9c9c3b2d-6958-407d-b742-23fbf73678ed}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\test">\r
+ <UniqueIdentifier>{e47b8f1d-1582-4e56-9c2f-ca2cdbea1b86}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\port">\r
+ <UniqueIdentifier>{9ecfe142-5bd2-472b-9568-243fa6169874}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\driver">\r
+ <UniqueIdentifier>{28ee3d7e-231b-4094-8a10-ad89fc82f705}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\util">\r
+ <UniqueIdentifier>{a955d01e-1f95-4c34-9558-14c52b75576f}</UniqueIdentifier>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">\r
+ <Filter>FreeRTOS\Source\Portable</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\timers.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\list.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\queue.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c">\r
+ <Filter>FreeRTOS\Source</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">\r
+ <Filter>FreeRTOS\Source\Portable</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+CLI</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="UDPCommandServer.c" />\r
+ <ClCompile Include="File-system-demo.c" />\r
+ <ClCompile Include="main.c" />\r
+ <ClCompile Include="Run-time-stats-utils.c" />\r
+ <ClCompile Include="Sample-CLI-commands.c" />\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\printf.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\rand.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\posix\fsstress.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostimestamp.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osassert.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osbdev.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osclock.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osmutex.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osoutput.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostask.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\volume.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\blockio.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\buffer.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\core.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\dir.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\format.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\fse\fse.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imap.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapextern.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapinline.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inode.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inodedata.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\posix\path.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\posix\posix.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\bitmap.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\string.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\crc.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\endian.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\memory.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\namelen.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\util\sign.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="File-Related-CLI-commands.c" />\r
+ <ClCompile Include="ConfigurationFiles\redconf.c">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\atoi.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\tests\util\math.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\getopt.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\toolcmn.c">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+CLI\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h">\r
+ <Filter>FreeRTOS\Source\include</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\Source\Reliance-Edge\os\freertos\include\ostypes.h">\r
+ <Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ConfigurationFiles\redconf.h">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="ConfigurationFiles\redtypes.h">\r
+ <Filter>Configuration Files</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
--- /dev/null
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+/******************************************************************************\r
+ *\r
+ * This demo is described on the following web page:\r
+ * TODO: This link describes the FAT version of this demo.\r
+ * http://FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml\r
+ *\r
+ ******************************************************************************/\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include <FreeRTOS.h>\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Priorities at which the tasks are created. */\r
+#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Register the generic commands that can be used with FreeRTOS+CLI.\r
+ */\r
+extern void vRegisterSampleCLICommands( void );\r
+\r
+/*\r
+ * Register the file system commands that can be used with FreeRTOS+CLI.\r
+ */\r
+extern void vRegisterFileSystemCLICommands( void );\r
+\r
+/*\r
+ * The task that implements the UDP command interpreter using FreeRTOS+CLI.\r
+ */\r
+extern void vUDPCommandInterpreterTask( void *pvParameters );\r
+\r
+/*\r
+ * Creates and verifies different files on the volume, demonstrating the use of\r
+ * various different API functions.\r
+ */\r
+extern void vCreateAndVerifySampleFiles( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+#pragma warning - add link to documentation page\r
+int main( void )\r
+{\r
+const uint32_t ulLongTime_ms = 250UL;\r
+\r
+ /* Initialise the drive and file system, then create a few example\r
+ files. The output from this function just goes to the stdout window,\r
+ allowing the output to be viewed when the UDP command console is not\r
+ connected. */\r
+ vCreateAndVerifySampleFiles();\r
+\r
+ /* Register generic commands with the FreeRTOS+CLI command interpreter. */\r
+ vRegisterSampleCLICommands();\r
+\r
+ /* Register file system related commands with the FreeRTOS+CLI command\r
+ interpreter. */\r
+ vRegisterFileSystemCLICommands();\r
+\r
+ /* Create the task that handles the CLI on a UDP port. The port number\r
+ is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */\r
+ xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */\r
+ "CLI", /* The name of the task - just to assist debugging. */\r
+ configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */\r
+ mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */\r
+ NULL ); /* A handle to the task is not required, so NULL is passed. */\r
+\r
+ /* Start the RTOS scheduler. */\r
+ vTaskStartScheduler();\r
+\r
+ /* If all is well, the scheduler will now be running, and the following\r
+ line will never be reached. If the following line does execute, then\r
+ there was insufficient FreeRTOS heap memory available for the idle and/or\r
+ timer tasks to be created. See the memory management section on the\r
+ FreeRTOS web site for more details (this is standard text that is not not\r
+ really applicable to the Win32 simulator port). */\r
+ for( ;; )\r
+ {\r
+ Sleep( ulLongTime_ms );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+const unsigned long ulMSToSleep = 5;\r
+\r
+ /* This function is called on each cycle of the idle task if\r
+ configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU\r
+ load. */\r
+ Sleep( ulMSToSleep );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vAssertCalled( const char *pcFile, unsigned long ulLine )\r
+{\r
+volatile uint32_t ulSetToNonZeroToExitLoop = 0;\r
+\r
+ printf( "ASSERT FAILED: File %s, line %u\r\n", pcFile, ulLine );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ while( ulSetToNonZeroToExitLoop == 0 )\r
+ {\r
+ /* Do not leave the assert function unless the debugger is used to\r
+ set ulSetToNonZeroToExitLoop to a non-zero value. */\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+ /* vApplicationMallocFailedHook() will only be called if\r
+ configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook\r
+ function that will get called if a call to pvPortMalloc() fails.\r
+ pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
+ timer or semaphore is created. It is also called by various parts of the\r
+ demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the\r
+ size of the heap available to pvPortMalloc() is defined by\r
+ configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()\r
+ API function can be used to query the size of free heap space that remains\r
+ (although it does not provide information on how the remaining heap might\r
+ be fragmented). */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+\r
+\r
+\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
/* If the application writer needs to place the buffer used by the CLI at a\r
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in\r
-FreeRTOSConfig.h, and provide then declare an array as follows with the\r
-following name and size in one of the application files:\r
+FreeRTOSConfig.h, then declare an array with the following name and size in \r
+one of the application files:\r
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];\r
*/\r
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer\r
--- /dev/null
+Reliance Edge Credits\r
+=====================\r
+\r
+This is a list (or partial list) of people who have made non-trivial or\r
+noteworthy contributions to the Reliance Edge project. It is sorted by name.\r
+Entries are formatted as below:\r
+\r
+Real Name (githubaccount)\r
+Short description of how Real Name contributed to Reliance Edge.\r
+\r
+The real name may be withheld by request and the GitHub account name might be\r
+missing if the contributor does not use GitHub.\r
+\r
+Credits\r
+-------\r
+\r
+None yet! ;)\r
+\r
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE\r
+ Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+ Preamble\r
+\r
+ The licenses for most software are designed to take away your\r
+freedom to share and change it. By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software--to make sure the software is free for all its users. This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it. (Some other Free Software Foundation software is covered by\r
+the GNU Lesser General Public License instead.) You can apply it to\r
+your programs, too.\r
+\r
+ When we speak of free software, we are referring to freedom, not\r
+price. Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+ To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+ For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have. You must make sure that they, too, receive or can get the\r
+source code. And you must show them these terms so they know their\r
+rights.\r
+\r
+ We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+ Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software. If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+ Finally, any free program is threatened constantly by software\r
+patents. We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary. To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+ The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\r
+ GNU GENERAL PUBLIC LICENSE\r
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+ 0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License. The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language. (Hereinafter, translation is included without limitation in\r
+the term "modification".) Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope. The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+ 1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+ 2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+ a) You must cause the modified files to carry prominent notices\r
+ stating that you changed the files and the date of any change.\r
+\r
+ b) You must cause any work that you distribute or publish, that in\r
+ whole or in part contains or is derived from the Program or any\r
+ part thereof, to be licensed as a whole at no charge to all third\r
+ parties under the terms of this License.\r
+\r
+ c) If the modified program normally reads commands interactively\r
+ when run, you must cause it, when started running for such\r
+ interactive use in the most ordinary way, to print or display an\r
+ announcement including an appropriate copyright notice and a\r
+ notice that there is no warranty (or else, saying that you provide\r
+ a warranty) and that users may redistribute the program under\r
+ these conditions, and telling the user how to view a copy of this\r
+ License. (Exception: if the Program itself is interactive but\r
+ does not normally print such an announcement, your work based on\r
+ the Program is not required to print an announcement.)\r
+\r
+These requirements apply to the modified work as a whole. If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works. But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+ 3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+ a) Accompany it with the complete corresponding machine-readable\r
+ source code, which must be distributed under the terms of Sections\r
+ 1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+ b) Accompany it with a written offer, valid for at least three\r
+ years, to give any third party, for a charge no more than your\r
+ cost of physically performing source distribution, a complete\r
+ machine-readable copy of the corresponding source code, to be\r
+ distributed under the terms of Sections 1 and 2 above on a medium\r
+ customarily used for software interchange; or,\r
+\r
+ c) Accompany it with the information you received as to the offer\r
+ to distribute corresponding source code. (This alternative is\r
+ allowed only for noncommercial distribution and only if you\r
+ received the program in object code or executable form with such\r
+ an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it. For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable. However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\r
+ 4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License. Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+ 5. You are not required to accept this License, since you have not\r
+signed it. However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works. These actions are\r
+prohibited by law if you do not accept this License. Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+ 6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions. You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+ 7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License. If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all. For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices. Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\r
+ 8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded. In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+ 9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time. Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number. If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation. If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+ 10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission. For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this. Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+ NO WARRANTY\r
+\r
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ How to Apply These Terms to Your New Programs\r
+\r
+ If you develop a new program, and you want it to be of the greatest\r
+possible use to the public, the best way to achieve this is to make it\r
+free software which everyone can redistribute and change under these terms.\r
+\r
+ To do so, attach the following notices to the program. It is safest\r
+to attach them to the start of each source file to most effectively\r
+convey the exclusion of warranty; and each file should have at least\r
+the "copyright" line and a pointer to where the full notice is found.\r
+\r
+ <one line to give the program's name and a brief idea of what it does.>\r
+ Copyright (C) <year> <name of author>\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+Also add information on how to contact you by electronic and paper mail.\r
+\r
+If the program is interactive, make it output a short notice like this\r
+when it starts in an interactive mode:\r
+\r
+ Gnomovision version 69, Copyright (C) year name of author\r
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
+ This is free software, and you are welcome to redistribute it\r
+ under certain conditions; type `show c' for details.\r
+\r
+The hypothetical commands `show w' and `show c' should show the appropriate\r
+parts of the General Public License. Of course, the commands you use may\r
+be called something other than `show w' and `show c'; they could even be\r
+mouse-clicks or menu items--whatever suits your program.\r
+\r
+You should also get your employer (if you work as a programmer) or your\r
+school, if any, to sign a "copyright disclaimer" for the program, if\r
+necessary. Here is a sample; alter the names:\r
+\r
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.\r
+\r
+ <signature of Ty Coon>, 1 April 1989\r
+ Ty Coon, President of Vice\r
+\r
+This General Public License does not permit incorporating your program into\r
+proprietary programs. If your program is a subroutine library, you may\r
+consider it more useful to permit linking proprietary applications with the\r
+library. If this is what you want to do, use the GNU Lesser General\r
+Public License instead of this License.\r
+\r
--- /dev/null
+# Reliance Edge\r
+\r
+Reliance Edge is a small, portable, highly reliable power-fail safe file system\r
+for resource-constrained embedded systems like microcontrollers. It is written\r
+in C and provides a familiar POSIX-like file system API, making it easy to use\r
+in your application; or an alternate minimalist API if your application has\r
+simple storage needs. Reliance Edge is highly configurable and can be tuned to\r
+the precise needs of your application.\r
+\r
+## Documentation\r
+\r
+The complete documentation for Reliance Edge is distributed separately. It\r
+includes an API reference and detailed discussions of various aspects of using\r
+Reliance Edge, including porting, building, configuring, and testing. This\r
+complete documentation, called the _Developer's Guide_, can be obtained for free\r
+from here:\r
+\r
+<http://www.datalight.com/reliance-edge>\r
+\r
+In addition this README, see [doc/release_notes.md](doc/release_notes.md) for a\r
+list of updates to Reliance Edge and a list of known issues. There is also a\r
+quick-start guide in the doc/ directory that describes step-by-step how to\r
+compile and run Reliance Edge in a simulated Windows environment.\r
+\r
+## Why Use Reliance Edge?\r
+\r
+Reliance Edge is ideal for small embedded systems with data storage\r
+requirements, especially if there is a chance of sudden power loss or other\r
+system failures. Compared to "raw" disk access, using a file system like\r
+Reliance Edge removes the burden of tracking which sectors belong to which\r
+objects, and allows data to be updated more reliably. Compared to the FAT file\r
+system, using Reliance Edge eliminates the possibility that file system data\r
+will be left in an inconsistent state, corrupting the disk; Reliance Edge does\r
+not need a fsck/CHKDSK utility. Compared to journaling file systems, Reliance\r
+Edge has less overhead and results in less storage media wear for longer device\r
+lifetimes.\r
+\r
+Reliance Edge uses a unique transactional model that not only prevents file\r
+system corruption but also allows a set of changes to be made in an atomic "all\r
+or nothing" fashion. This is very useful for applications that make sets of\r
+interrelated changes. By using the features of Reliance Edge, a set of changes\r
+can be incorporated into a single atomic transaction, which is committed in its\r
+entirety or not at all even if interrupted by power loss; this means the\r
+application does not need code to recover from partially-finished updates.\r
+\r
+## Hardware\r
+\r
+The typical hardware for Reliance Edge is a 32-bit microcontroller, but other\r
+targets are possible. In its typical configurations, Reliance Edge needs at\r
+least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the ROM or NOR flash),\r
+and 500 to 700 bytes of stack.\r
+\r
+Reliance Edge is not designed for high-end embedded systems that run complicated\r
+operating systems like Linux or Windows Embedded Compact. Embedded systems of\r
+that variety are better served by other file systems, like Datalight's\r
+[Reliance Nitro](http://www.datalight.com/products/embedded-file-systems/reliance-nitro).\r
+\r
+## Getting Reliance Edge Working\r
+\r
+Before you can use Reliance Edge, it must be ported and configured. At a\r
+minimum, porting includes filling-in functions so that Reliance Edge can issue\r
+commands to your storage medium; depending on your needs, other functions may\r
+need to be filled in as well. These functions reside in a subdirectory in the\r
+os/ directory; see os/stub/ for a blank set of functions. Configuring includes\r
+creating a project directory (start by copying projects/newproj) and creating\r
+the two configuration files (redconf.h/redconf.c) using the Reliance Edge\r
+Configuration Utility (which can be downloaded from\r
+<http://www.datalight.com/reliance-edge>).\r
+\r
+These topics are covered in much greater detail in the _Developer's Guide_,\r
+linked above.\r
+\r
+## Using Reliance Edge\r
+\r
+Using Reliance Edge is a simple matter of including the primary Reliance Edge\r
+application header in your application (either include/redposix.h or\r
+include/redfse.h) and compiling and linking against Reliance Edge binaries.\r
+The Reliance Edge driver must be initialized before it is used (via the\r
+red\_init() or RedFseInit() functions) and then volumes can be mounted and file\r
+and directory functions invoked. The Reliance Edge API is documented in the\r
+_Developer's Guide_ (linked above) and also via comments in the source code.\r
+\r
+## Licensing\r
+\r
+Reliance Edge is an open-source project licensed under the GNU General Public\r
+License v2 (GPLv2). Businesses and individuals that for commercial or other\r
+reasons cannot comply with the terms of the GPLv2 license may obtain a\r
+commercial license before incorporating Reliance Edge into proprietary software\r
+for distribution in any form. Visit <http://www.datalight.com/reliance-edge>\r
+for more information. The commercial distribution also includes extra tests and\r
+tools not distributed with the GPLv2 version.\r
+\r
+See LICENSE.txt for the full license terms of this distribution of the product.\r
+\r
+## Getting Help\r
+\r
+If you need assistance using Reliance Edge, and you have already consulted the\r
+_Developer's Guide_, contact <RelianceEdgeSupport@datalight.com>.\r
+\r
+In the near future, a community forum or message board will be set up to\r
+facilitate discussion of Reliance Edge and allow users to get help from\r
+Datalight and from each other. In the meantime, please use the email address\r
+given above.\r
+\r
+## Contributing\r
+\r
+Contributions to Reliance Edge are welcome. Our policy is that Datalight must\r
+own the copyright of all code incorporated into Reliance Edge; if contributing a\r
+significant amount of code, you will be asked to file a copyright assignment\r
+agreement. See CONTRIBUTING.txt for further details and contribution\r
+guidelines.\r
+\r
+To report bugs, please create a GitHub issue or contact\r
+<RelianceEdgeSupport@datalight.com>.\r
+\r
--- /dev/null
+\r
+\r
+RELIANCE EDGE\r
+\r
+\r
+Reliance Edge is a small, portable, highly reliable power-fail safe file\r
+system for resource-constrained embedded systems like microcontrollers.\r
+It is written in C and provides a familiar POSIX-like file system API,\r
+making it easy to use in your application; or an alternate minimalist\r
+API if your application has simple storage needs. Reliance Edge is\r
+highly configurable and can be tuned to the precise needs of your\r
+application.\r
+\r
+\r
+Documentation\r
+\r
+The complete documentation for Reliance Edge is distributed separately.\r
+It includes an API reference and detailed discussions of various aspects\r
+of using Reliance Edge, including porting, building, configuring, and\r
+testing. This complete documentation, called the _Developer's Guide_,\r
+can be obtained for free from here:\r
+\r
+http://www.datalight.com/reliance-edge\r
+\r
+In addition this README, see doc/release_notes.md for a list of updates\r
+to Reliance Edge and a list of known issues. There is also a quick-start\r
+guide in the doc/ directory that describes step-by-step how to compile\r
+and run Reliance Edge in a simulated Windows environment.\r
+\r
+\r
+Why Use Reliance Edge?\r
+\r
+Reliance Edge is ideal for small embedded systems with data storage\r
+requirements, especially if there is a chance of sudden power loss or\r
+other system failures. Compared to "raw" disk access, using a file\r
+system like Reliance Edge removes the burden of tracking which sectors\r
+belong to which objects, and allows data to be updated more reliably.\r
+Compared to the FAT file system, using Reliance Edge eliminates the\r
+possibility that file system data will be left in an inconsistent state,\r
+corrupting the disk; Reliance Edge does not need a fsck/CHKDSK utility.\r
+Compared to journaling file systems, Reliance Edge has less overhead and\r
+results in less storage media wear for longer device lifetimes.\r
+\r
+Reliance Edge uses a unique transactional model that not only prevents\r
+file system corruption but also allows a set of changes to be made in an\r
+atomic "all or nothing" fashion. This is very useful for applications\r
+that make sets of interrelated changes. By using the features of\r
+Reliance Edge, a set of changes can be incorporated into a single atomic\r
+transaction, which is committed in its entirety or not at all even if\r
+interrupted by power loss; this means the application does not need code\r
+to recover from partially-finished updates.\r
+\r
+\r
+Hardware\r
+\r
+The typical hardware for Reliance Edge is a 32-bit microcontroller, but\r
+other targets are possible. In its typical configurations, Reliance Edge\r
+needs at least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the\r
+ROM or NOR flash), and 500 to 700 bytes of stack.\r
+\r
+Reliance Edge is not designed for high-end embedded systems that run\r
+complicated operating systems like Linux or Windows Embedded Compact.\r
+Embedded systems of that variety are better served by other file\r
+systems, like Datalight's Reliance Nitro.\r
+\r
+\r
+Getting Reliance Edge Working\r
+\r
+Before you can use Reliance Edge, it must be ported and configured. At a\r
+minimum, porting includes filling-in functions so that Reliance Edge can\r
+issue commands to your storage medium; depending on your needs, other\r
+functions may need to be filled in as well. These functions reside in a\r
+subdirectory in the os/ directory; see os/stub/ for a blank set of\r
+functions. Configuring includes creating a project directory (start by\r
+copying projects/newproj) and creating the two configuration files\r
+(redconf.h/redconf.c) using the Reliance Edge Configuration Utility\r
+(which can be downloaded from http://www.datalight.com/reliance-edge).\r
+\r
+These topics are covered in much greater detail in the _Developer's\r
+Guide_, linked above.\r
+\r
+\r
+Using Reliance Edge\r
+\r
+Using Reliance Edge is a simple matter of including the primary Reliance\r
+Edge application header in your application (either include/redposix.h\r
+or include/redfse.h) and compiling and linking against Reliance Edge\r
+binaries. The Reliance Edge driver must be initialized before it is used\r
+(via the red_init() or RedFseInit() functions) and then volumes can be\r
+mounted and file and directory functions invoked. The Reliance Edge API\r
+is documented in the _Developer's Guide_ (linked above) and also via\r
+comments in the source code.\r
+\r
+\r
+Licensing\r
+\r
+Reliance Edge is an open-source project licensed under the GNU General\r
+Public License v2 (GPLv2). Businesses and individuals that for\r
+commercial or other reasons cannot comply with the terms of the GPLv2\r
+license may obtain a commercial license before incorporating Reliance\r
+Edge into proprietary software for distribution in any form. Visit\r
+http://www.datalight.com/reliance-edge for more information. The\r
+commercial distribution also includes extra tests and tools not\r
+distributed with the GPLv2 version.\r
+\r
+See LICENSE.txt for the full license terms of this distribution of the\r
+product.\r
+\r
+\r
+Getting Help\r
+\r
+If you need assistance using Reliance Edge, and you have already\r
+consulted the _Developer's Guide_, contact\r
+RelianceEdgeSupport@datalight.com.\r
+\r
+In the near future, a community forum or message board will be set up to\r
+facilitate discussion of Reliance Edge and allow users to get help from\r
+Datalight and from each other. In the meantime, please use the email\r
+address given above.\r
+\r
+\r
+Contributing\r
+\r
+Contributions to Reliance Edge are welcome. Our policy is that Datalight\r
+must own the copyright of all code incorporated into Reliance Edge; if\r
+contributing a significant amount of code, you will be asked to file a\r
+copyright assignment agreement. See CONTRIBUTING.txt for further details\r
+and contribution guidelines.\r
+\r
+To report bugs, please create a GitHub issue or contact\r
+RelianceEdgeSupport@datalight.com.\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements block device I/O using logical blocks as the units.\r
+\r
+ The OS block device implementations operate on sectors. The core does I/O\r
+ in terms of logical blocks: this module translates from logical blocks to\r
+ sectors.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+/** @brief Read a range of logical blocks.\r
+\r
+ @param bVolNum The volume whose block device is being read from.\r
+ @param ulBlockStart The first block to read.\r
+ @param ulBlockCount The number of blocks to read.\r
+ @param pBuffer The buffer to populate with the data read.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+REDSTATUS RedIoRead(\r
+ uint8_t bVolNum,\r
+ uint32_t ulBlockStart,\r
+ uint32_t ulBlockCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)\r
+ || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)\r
+ || (ulBlockCount == 0U)\r
+ || (pBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;\r
+ uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;\r
+ uint32_t ulSectorCount = ulBlockCount << bSectorShift;\r
+\r
+ REDASSERT(bSectorShift < 32U);\r
+ REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);\r
+\r
+ ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write a range of logical blocks.\r
+\r
+ @param bVolNum The volume whose block device is being written to.\r
+ @param ulBlockStart The first block to write.\r
+ @param ulBlockCount The number of blocks to write.\r
+ @param pBuffer The buffer containing the data to write.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+REDSTATUS RedIoWrite(\r
+ uint8_t bVolNum,\r
+ uint32_t ulBlockStart,\r
+ uint32_t ulBlockCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)\r
+ || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)\r
+ || (ulBlockCount == 0U)\r
+ || (pBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;\r
+ uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;\r
+ uint32_t ulSectorCount = ulBlockCount << bSectorShift;\r
+\r
+ REDASSERT(bSectorShift < 32U);\r
+ REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);\r
+\r
+ ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedIoFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(bVolNum >= REDCONF_VOLUME_COUNT)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedOsBDevFlush(bVolNum);\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements the block device buffering system.\r
+\r
+ This module implements the block buffer cache. It has a number of block\r
+ sized buffers which are used to store data from a given block (identified\r
+ by both block number and volume number: this cache is shared among all\r
+ volumes). Block buffers may be either dirty or clean. Most I/O passes\r
+ through this module. When a buffer is needed for a block which is not in\r
+ the cache, a "victim" is selected via a simple LRU scheme.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+#if DINDIR_POINTERS > 0U\r
+ #define INODE_META_BUFFERS 3U /* Inode, double indirect, indirect */\r
+#elif REDCONF_INDIRECT_POINTERS > 0U\r
+ #define INODE_META_BUFFERS 2U /* Inode, indirect */\r
+#elif REDCONF_DIRECT_POINTERS == INODE_ENTRIES\r
+ #define INODE_META_BUFFERS 1U /* Inode only */\r
+#endif\r
+\r
+#define INODE_BUFFERS (INODE_META_BUFFERS + 1U) /* Add data buffer */\r
+\r
+#if REDCONF_IMAP_EXTERNAL == 1\r
+ #define IMAP_BUFFERS 1U\r
+#else\r
+ #define IMAP_BUFFERS 0U\r
+#endif\r
+\r
+#if (REDCONF_READ_ONLY == 1) || (REDCONF_API_FSE == 1)\r
+ /* Read, write, truncate, lookup: One inode all the way down, plus imap.\r
+ */\r
+ #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + IMAP_BUFFERS)\r
+#elif REDCONF_API_POSIX == 1\r
+ #if REDCONF_API_POSIX_RENAME == 1\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ /* Two parent directories all the way down. Source and destination inode\r
+ buffer. One inode buffer for cyclic rename detection. Imap. The\r
+ parent inode buffers are released before deleting the destination\r
+ inode, so that does not increase the minimum.\r
+ */\r
+ #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 3U + IMAP_BUFFERS)\r
+ #else\r
+ /* Two parent directories all the way down. Source inode buffer. One\r
+ inode buffer for cyclic rename detection. Imap.\r
+ */\r
+ #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 2U + IMAP_BUFFERS)\r
+ #endif\r
+ #else\r
+ /* Link/create: Needs a parent inode all the way down, an extra inode\r
+ buffer, and an imap buffer.\r
+\r
+ Unlink is the same, since the parent inode buffers are released before\r
+ the inode is deleted.\r
+ */\r
+ #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + 1U + IMAP_BUFFERS)\r
+ #endif\r
+#endif\r
+\r
+#if REDCONF_BUFFER_COUNT < MINIMUM_BUFFER_COUNT\r
+#error "REDCONF_BUFFER_COUNT is too low for the configuration"\r
+#endif\r
+\r
+\r
+/* A note on the typecasts in the below macros: Operands to bitwise operators\r
+ are subject to the "usual arithmetic conversions". This means that the\r
+ flags, which have uint16_t values, are promoted to int. MISRA-C:2012 R10.1\r
+ forbids using signed integers in bitwise operations, so we cast to uint32_t\r
+ to avoid the integer promotion, then back to uint16_t to reflect the actual\r
+ type.\r
+*/\r
+#define BFLAG_META_MASK (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_META_IMAP | BFLAG_META_INODE | BFLAG_META_INDIR | BFLAG_META_DINDIR)\r
+#define BFLAG_MASK (uint16_t)((uint32_t)BFLAG_DIRTY | BFLAG_NEW | BFLAG_META_MASK)\r
+\r
+\r
+/* An invalid block number. Used to indicate buffers which are not currently\r
+ in use.\r
+*/\r
+#define BBLK_INVALID UINT32_MAX\r
+\r
+\r
+/** @brief Metadata stored for each block buffer.\r
+\r
+ To make better use of CPU caching when searching the BUFFERHEAD array, this\r
+ structure should be kept small.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t ulBlock; /**< Block number the buffer is associated with; BBLK_INVALID if unused. */\r
+ uint8_t bVolNum; /**< Volume the block resides on. */\r
+ uint8_t bRefCount; /**< Number of references. */\r
+ uint16_t uFlags; /**< Buffer flags: mask of BFLAG_* values. */\r
+} BUFFERHEAD;\r
+\r
+\r
+/** @brief State information for the block buffer module.\r
+*/\r
+typedef struct\r
+{\r
+ /** Number of buffers which are referenced (have a bRefCount > 0).\r
+ */\r
+ uint16_t uNumUsed;\r
+\r
+ /** MRU array. Each element of the array stores a buffer index; each buffer\r
+ index appears in the array once and only once. The first element of the\r
+ array is the most-recently-used (MRU) buffer, followed by the next most\r
+ recently used, and so on, till the last element, which is the least-\r
+ recently-used (LRU) buffer.\r
+ */\r
+ uint8_t abMRU[REDCONF_BUFFER_COUNT];\r
+\r
+ /** Buffer heads, storing metadata for each buffer.\r
+ */\r
+ BUFFERHEAD aHead[REDCONF_BUFFER_COUNT];\r
+\r
+ /** Array of memory for the block buffers themselves.\r
+\r
+ Force 64-bit alignment of the aabBuffer array to ensure that it is safe\r
+ to cast buffer pointers to node structure pointers.\r
+ */\r
+ ALIGNED_2D_BYTE_ARRAY(b, aabBuffer, REDCONF_BUFFER_COUNT, REDCONF_BLOCK_SIZE);\r
+} BUFFERCTX;\r
+\r
+\r
+static bool BufferIsValid(const uint8_t *pbBuffer, uint16_t uFlags);\r
+static bool BufferToIdx(const void *pBuffer, uint8_t *pbIdx);\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS BufferWrite(uint8_t bIdx);\r
+static REDSTATUS BufferFinalize(uint8_t *pbBuffer, uint16_t uFlags);\r
+#endif\r
+static void BufferMakeLRU(uint8_t bIdx);\r
+static void BufferMakeMRU(uint8_t bIdx);\r
+static bool BufferFind(uint32_t ulBlock, uint8_t *pbIdx);\r
+\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+static void BufferEndianSwap(const void *pBuffer, uint16_t uFlags);\r
+static void BufferEndianSwapHeader(NODEHEADER *pHeader);\r
+static void BufferEndianSwapMaster(MASTERBLOCK *pMaster);\r
+static void BufferEndianSwapMetaRoot(METAROOT *pMetaRoot);\r
+static void BufferEndianSwapInode(INODE *pInode);\r
+static void BufferEndianSwapIndir(INDIR *pIndir);\r
+#endif\r
+\r
+\r
+static BUFFERCTX gBufCtx;\r
+\r
+\r
+/** @brief Initialize the buffers.\r
+*/\r
+void RedBufferInit(void)\r
+{\r
+ uint8_t bIdx;\r
+\r
+ RedMemSet(&gBufCtx, 0U, sizeof(gBufCtx));\r
+\r
+ for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)\r
+ {\r
+ /* When the buffers have been freshly initialized, acquire the buffers\r
+ in the order in which they appear in the array.\r
+ */\r
+ gBufCtx.abMRU[bIdx] = (uint8_t)((REDCONF_BUFFER_COUNT - bIdx) - 1U);\r
+ gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID;\r
+ }\r
+}\r
+\r
+\r
+/** @brief Acquire a buffer.\r
+\r
+ @param ulBlock Block number to acquire.\r
+ @param uFlags BFLAG_ values for the operation.\r
+ @param ppBuffer On success, populated with the acquired buffer.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+ @retval -RED_EBUSY All buffers are referenced.\r
+*/\r
+REDSTATUS RedBufferGet(\r
+ uint32_t ulBlock,\r
+ uint16_t uFlags,\r
+ void **ppBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint8_t bIdx;\r
+\r
+ if((ulBlock >= gpRedVolume->ulBlockCount) || ((uFlags & BFLAG_MASK) != uFlags) || (ppBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ if(BufferFind(ulBlock, &bIdx))\r
+ {\r
+ /* Error if the buffer exists and BFLAG_NEW was specified, since\r
+ the new flag is used when a block is newly allocated/created, so\r
+ the block was previously free and and there should never be an\r
+ existing buffer for a free block.\r
+\r
+ Error if the buffer exists but does not have the same type as\r
+ was requested.\r
+ */\r
+ if( ((uFlags & BFLAG_NEW) != 0U)\r
+ || ((uFlags & BFLAG_META_MASK) != (gBufCtx.aHead[bIdx].uFlags & BFLAG_META_MASK)))\r
+ {\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ }\r
+ else if(gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT)\r
+ {\r
+ /* The MINIMUM_BUFFER_COUNT is supposed to ensure that no operation\r
+ ever runs out of buffers, so this should never happen.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EBUSY;\r
+ }\r
+ else\r
+ {\r
+ BUFFERHEAD *pHead;\r
+\r
+ /* Search for the least recently used buffer which is not\r
+ referenced.\r
+ */\r
+ for(bIdx = (uint8_t)(REDCONF_BUFFER_COUNT - 1U); bIdx > 0U; bIdx--)\r
+ {\r
+ if(gBufCtx.aHead[gBufCtx.abMRU[bIdx]].bRefCount == 0U)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ bIdx = gBufCtx.abMRU[bIdx];\r
+ pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ if(pHead->bRefCount == 0U)\r
+ {\r
+ /* If the LRU buffer is valid and dirty, write it out before\r
+ repurposing it.\r
+ */\r
+ if(((pHead->uFlags & BFLAG_DIRTY) != 0U) && (pHead->ulBlock != BBLK_INVALID))\r
+ {\r
+ #if REDCONF_READ_ONLY == 1\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ #else\r
+ ret = BufferWrite(bIdx);\r
+ #endif\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* All the buffers are used, which should have been caught by\r
+ checking gBufCtx.uNumUsed.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EBUSY;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if((uFlags & BFLAG_NEW) == 0U)\r
+ {\r
+ /* Invalidate the LRU buffer. If the read fails, we do not\r
+ want the buffer head to continue to refer to the old\r
+ block number, since the read, even if it fails, may have\r
+ partially overwritten the buffer data (consider the case\r
+ where block size exceeds sector size, and some but not\r
+ all of the sectors are read successfully), and if the\r
+ buffer were to be used subsequently with its partially\r
+ erroneous contents, bad things could happen.\r
+ */\r
+ pHead->ulBlock = BBLK_INVALID;\r
+\r
+ ret = RedIoRead(gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]);\r
+\r
+ if((ret == 0) && ((uFlags & BFLAG_META) != 0U))\r
+ {\r
+ if(!BufferIsValid(gBufCtx.b.aabBuffer[bIdx], uFlags))\r
+ {\r
+ /* A corrupt metadata node is usually a critical\r
+ error. The master block is an exception since\r
+ it might be invalid because the volume is not\r
+ mounted; that condition is expected and should\r
+ not result in an assertion.\r
+ */\r
+ CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) != 0U);\r
+ ret = -RED_EIO;\r
+ }\r
+ }\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ if(ret == 0)\r
+ {\r
+ BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], uFlags);\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ RedMemSet(gBufCtx.b.aabBuffer[bIdx], 0U, REDCONF_BLOCK_SIZE);\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pHead->bVolNum = gbRedVolNum;\r
+ pHead->ulBlock = ulBlock;\r
+ pHead->uFlags = 0U;\r
+ }\r
+ }\r
+\r
+ /* Reference the buffer, update its flags, and promote it to MRU. This\r
+ happens both when BufferFind() found an existing buffer for the\r
+ block and when the LRU buffer was repurposed to create a buffer for\r
+ the block.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ pHead->bRefCount++;\r
+\r
+ if(pHead->bRefCount == 1U)\r
+ {\r
+ gBufCtx.uNumUsed++;\r
+ }\r
+\r
+ /* BFLAG_NEW tells this function to zero the buffer instead of\r
+ reading it from disk; it has no meaning later on, and thus is\r
+ not saved.\r
+ */\r
+ pHead->uFlags |= (uFlags & (~BFLAG_NEW));\r
+\r
+ BufferMakeMRU(bIdx);\r
+\r
+ *ppBuffer = gBufCtx.b.aabBuffer[bIdx];\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Release a buffer.\r
+\r
+ @param pBuffer The buffer to release.\r
+ */\r
+void RedBufferPut(\r
+ const void *pBuffer)\r
+{\r
+ uint8_t bIdx;\r
+\r
+ if(!BufferToIdx(pBuffer, &bIdx))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U);\r
+ gBufCtx.aHead[bIdx].bRefCount--;\r
+\r
+ if(gBufCtx.aHead[bIdx].bRefCount == 0U)\r
+ {\r
+ REDASSERT(gBufCtx.uNumUsed > 0U);\r
+ gBufCtx.uNumUsed--;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Flush all buffers for the active volume in the given range of blocks.\r
+\r
+ @param ulBlockStart Starting block number to flush.\r
+ @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush.\r
+ Must not be zero.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+REDSTATUS RedBufferFlush(\r
+ uint32_t ulBlockStart,\r
+ uint32_t ulBlockCount)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if( (ulBlockStart >= gpRedVolume->ulBlockCount)\r
+ || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount)\r
+ || (ulBlockCount == 0U))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint8_t bIdx;\r
+\r
+ for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)\r
+ {\r
+ BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ if( (pHead->bVolNum == gbRedVolNum)\r
+ && (pHead->ulBlock != BBLK_INVALID)\r
+ && ((pHead->uFlags & BFLAG_DIRTY) != 0U)\r
+ && (pHead->ulBlock >= ulBlockStart)\r
+ && (pHead->ulBlock < (ulBlockStart + ulBlockCount)))\r
+ {\r
+ ret = BufferWrite(bIdx);\r
+\r
+ if(ret == 0)\r
+ {\r
+ pHead->uFlags &= (~BFLAG_DIRTY);\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Mark a buffer dirty\r
+\r
+ @param pBuffer The buffer to mark dirty.\r
+*/\r
+void RedBufferDirty(\r
+ const void *pBuffer)\r
+{\r
+ uint8_t bIdx;\r
+\r
+ if(!BufferToIdx(pBuffer, &bIdx))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U);\r
+\r
+ gBufCtx.aHead[bIdx].uFlags |= BFLAG_DIRTY;\r
+ }\r
+}\r
+\r
+\r
+/** @brief Branch a buffer, marking it dirty and assigning a new block number.\r
+\r
+ @param pBuffer The buffer to branch.\r
+ @param ulBlockNew The new block number for the buffer.\r
+*/\r
+void RedBufferBranch(\r
+ const void *pBuffer,\r
+ uint32_t ulBlockNew)\r
+{\r
+ uint8_t bIdx;\r
+\r
+ if( !BufferToIdx(pBuffer, &bIdx)\r
+ || (ulBlockNew >= gpRedVolume->ulBlockCount))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ REDASSERT(pHead->bRefCount > 0U);\r
+ REDASSERT((pHead->uFlags & BFLAG_DIRTY) == 0U);\r
+\r
+ pHead->uFlags |= BFLAG_DIRTY;\r
+ pHead->ulBlock = ulBlockNew;\r
+ }\r
+}\r
+\r
+\r
+#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED\r
+/** @brief Discard a buffer, releasing it and marking it invalid.\r
+\r
+ @param pBuffer The buffer to discard.\r
+*/\r
+void RedBufferDiscard(\r
+ const void *pBuffer)\r
+{\r
+ uint8_t bIdx;\r
+\r
+ if(!BufferToIdx(pBuffer, &bIdx))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ REDASSERT(gBufCtx.aHead[bIdx].bRefCount == 1U);\r
+ REDASSERT(gBufCtx.uNumUsed > 0U);\r
+\r
+ gBufCtx.aHead[bIdx].bRefCount = 0U;\r
+ gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID;\r
+\r
+ gBufCtx.uNumUsed--;\r
+\r
+ BufferMakeLRU(bIdx);\r
+ }\r
+}\r
+#endif\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Discard a range of buffers, marking them invalid.\r
+\r
+ @param ulBlockStart The starting block number to discard\r
+ @param ulBlockCount The number of blocks, starting at @p ulBlockStart, to\r
+ discard. Must not be zero.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+ @retval -RED_EBUSY A block in the desired range is referenced.\r
+*/\r
+REDSTATUS RedBufferDiscardRange(\r
+ uint32_t ulBlockStart,\r
+ uint32_t ulBlockCount)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if( (ulBlockStart >= gpRedVolume->ulBlockCount)\r
+ || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount)\r
+ || (ulBlockCount == 0U))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint8_t bIdx;\r
+\r
+ for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)\r
+ {\r
+ BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ if( (pHead->bVolNum == gbRedVolNum)\r
+ && (pHead->ulBlock != BBLK_INVALID)\r
+ && (pHead->ulBlock >= ulBlockStart)\r
+ && (pHead->ulBlock < (ulBlockStart + ulBlockCount)))\r
+ {\r
+ if(pHead->bRefCount == 0U)\r
+ {\r
+ pHead->ulBlock = BBLK_INVALID;\r
+\r
+ BufferMakeLRU(bIdx);\r
+ }\r
+ else\r
+ {\r
+ /* This should never happen. There are three general cases\r
+ when this function is used:\r
+\r
+ 1) Discarding every block, as happens during unmount\r
+ and at the end of format. There should no longer be\r
+ any referenced buffers at those points.\r
+ 2) Discarding a block which has become free. All\r
+ buffers for such blocks should be put or branched\r
+ beforehand.\r
+ 3) Discarding of blocks that were just written straight\r
+ to disk, leaving stale data in the buffer. The write\r
+ code should never reference buffers for these blocks,\r
+ since they would not be needed or used.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EBUSY;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** Determine whether a metadata buffer is valid.\r
+\r
+ This includes checking its signature, CRC, and sequence number.\r
+\r
+ @param pbBuffer Pointer to the metadata buffer to validate.\r
+ @param uFlags The buffer flags provided by the caller. Used to determine\r
+ the expected signature.\r
+\r
+ @return Whether the metadata buffer is valid.\r
+\r
+ @retval true The metadata buffer is valid.\r
+ @retval false The metadata buffer is invalid.\r
+*/\r
+static bool BufferIsValid(\r
+ const uint8_t *pbBuffer,\r
+ uint16_t uFlags)\r
+{\r
+ bool fValid;\r
+\r
+ if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))\r
+ {\r
+ REDERROR();\r
+ fValid = false;\r
+ }\r
+ else\r
+ {\r
+ NODEHEADER buf;\r
+ uint16_t uMetaFlags = uFlags & BFLAG_META_MASK;\r
+\r
+ /* Casting pbBuffer to (NODEHEADER *) would run afoul MISRA-C:2012\r
+ R11.3, so instead copy the fields out.\r
+ */\r
+ RedMemCpy(&buf.ulSignature, &pbBuffer[NODEHEADER_OFFSET_SIG], sizeof(buf.ulSignature));\r
+ RedMemCpy(&buf.ulCRC, &pbBuffer[NODEHEADER_OFFSET_CRC], sizeof(buf.ulCRC));\r
+ RedMemCpy(&buf.ullSequence, &pbBuffer[NODEHEADER_OFFSET_SEQ], sizeof(buf.ullSequence));\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ buf.ulCRC = RedRev32(buf.ulCRC);\r
+ buf.ulSignature = RedRev32(buf.ulSignature);\r
+ buf.ullSequence = RedRev64(buf.ullSequence);\r
+ #endif\r
+\r
+ /* Make sure the signature is correct for the type of metadata block\r
+ requested by the caller.\r
+ */\r
+ switch(buf.ulSignature)\r
+ {\r
+ case META_SIG_MASTER:\r
+ fValid = (uMetaFlags == BFLAG_META_MASTER);\r
+ break;\r
+ #if REDCONF_IMAP_EXTERNAL == 1\r
+ case META_SIG_IMAP:\r
+ fValid = (uMetaFlags == BFLAG_META_IMAP);\r
+ break;\r
+ #endif\r
+ case META_SIG_INODE:\r
+ fValid = (uMetaFlags == BFLAG_META_INODE);\r
+ break;\r
+ #if DINDIR_POINTERS > 0U\r
+ case META_SIG_DINDIR:\r
+ fValid = (uMetaFlags == BFLAG_META_DINDIR);\r
+ break;\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ case META_SIG_INDIR:\r
+ fValid = (uMetaFlags == BFLAG_META_INDIR);\r
+ break;\r
+ #endif\r
+ default:\r
+ fValid = false;\r
+ break;\r
+ }\r
+\r
+ if(fValid)\r
+ {\r
+ uint32_t ulComputedCrc;\r
+\r
+ /* Check for disk corruption by comparing the stored CRC with one\r
+ computed from the data.\r
+\r
+ Also check the sequence number: if it is greater than the\r
+ current sequence number, the block is from a previous format\r
+ or the disk is writing blocks out of order. During mount,\r
+ before the metaroots have been read, the sequence number will\r
+ be unknown, and the check is skipped.\r
+ */\r
+ ulComputedCrc = RedCrcNode(pbBuffer);\r
+ if(buf.ulCRC != ulComputedCrc)\r
+ {\r
+ fValid = false;\r
+ }\r
+ else if(gpRedVolume->fMounted && (buf.ullSequence >= gpRedVolume->ullSequence))\r
+ {\r
+ fValid = false;\r
+ }\r
+ else\r
+ {\r
+ /* Buffer is valid. No action, fValid is already true.\r
+ */\r
+ }\r
+ }\r
+ }\r
+\r
+ return fValid;\r
+}\r
+\r
+\r
+/** @brief Derive the index of the buffer.\r
+\r
+ @param pBuffer The buffer to derive the index of.\r
+ @param pbIdx On success, populated with the index of the buffer.\r
+\r
+ @return Boolean indicating result.\r
+\r
+ @retval true Success.\r
+ @retval false Failure. @p pBuffer is not a valid buffer pointer.\r
+*/\r
+static bool BufferToIdx(\r
+ const void *pBuffer,\r
+ uint8_t *pbIdx)\r
+{\r
+ bool fRet = false;\r
+\r
+ if((pBuffer != NULL) && (pbIdx != NULL))\r
+ {\r
+ uint8_t bIdx;\r
+\r
+ /* pBuffer should be a pointer to one of the block buffers.\r
+\r
+ A good compiler should optimize this loop into a bounds check and an\r
+ alignment check, although GCC has been observed to not do so; if the\r
+ number of buffers is small, it should not make much difference. The\r
+ alternative is to use pointer comparisons, but this both deviates\r
+ from MISRA-C:2012 and involves undefined behavior.\r
+ */\r
+ for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)\r
+ {\r
+ if(pBuffer == &gBufCtx.b.aabBuffer[bIdx][0U])\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if( (bIdx < REDCONF_BUFFER_COUNT)\r
+ && (gBufCtx.aHead[bIdx].ulBlock != BBLK_INVALID)\r
+ && (gBufCtx.aHead[bIdx].bVolNum == gbRedVolNum))\r
+ {\r
+ *pbIdx = bIdx;\r
+ fRet = true;\r
+ }\r
+ }\r
+\r
+ return fRet;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write out a dirty buffer.\r
+\r
+ @param bIdx The index of the buffer to write.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS BufferWrite(\r
+ uint8_t bIdx)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(bIdx < REDCONF_BUFFER_COUNT)\r
+ {\r
+ const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ REDASSERT((pHead->uFlags & BFLAG_DIRTY) != 0U);\r
+\r
+ if((pHead->uFlags & BFLAG_META) != 0U)\r
+ {\r
+ ret = BufferFinalize(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoWrite(pHead->bVolNum, pHead->ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]);\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags);\r
+ #endif\r
+ }\r
+ }\r
+ else\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Finalize a metadata buffer.\r
+\r
+ This updates the CRC and the sequence number. It also sets the signature,\r
+ though this is only truly needed if the buffer is new.\r
+\r
+ @param pbBuffer Pointer to the metadata buffer to finalize.\r
+ @param uFlags The associated buffer flags. Used to determine the expected\r
+ signature.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL Invalid parameter; or maximum sequence number reached.\r
+*/\r
+static REDSTATUS BufferFinalize(\r
+ uint8_t *pbBuffer,\r
+ uint16_t uFlags)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if((pbBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulSignature;\r
+\r
+ switch(uFlags & BFLAG_META_MASK)\r
+ {\r
+ case BFLAG_META_MASTER:\r
+ ulSignature = META_SIG_MASTER;\r
+ break;\r
+ #if REDCONF_IMAP_EXTERNAL == 1\r
+ case BFLAG_META_IMAP:\r
+ ulSignature = META_SIG_IMAP;\r
+ break;\r
+ #endif\r
+ case BFLAG_META_INODE:\r
+ ulSignature = META_SIG_INODE;\r
+ break;\r
+ #if DINDIR_POINTERS > 0U\r
+ case BFLAG_META_DINDIR:\r
+ ulSignature = META_SIG_DINDIR;\r
+ break;\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ case BFLAG_META_INDIR:\r
+ ulSignature = META_SIG_INDIR;\r
+ break;\r
+ #endif\r
+ default:\r
+ ulSignature = 0U;\r
+ break;\r
+ }\r
+\r
+ if(ulSignature == 0U)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint64_t ullSeqNum = gpRedVolume->ullSequence;\r
+\r
+ ret = RedVolSeqNumIncrement();\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulCrc;\r
+\r
+ RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SIG], &ulSignature, sizeof(ulSignature));\r
+ RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SEQ], &ullSeqNum, sizeof(ullSeqNum));\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ BufferEndianSwap(pbBuffer, uFlags);\r
+ #endif\r
+\r
+ ulCrc = RedCrcNode(pbBuffer);\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ ulCrc = RedRev32(ulCrc);\r
+ #endif\r
+ RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_CRC], &ulCrc, sizeof(ulCrc));\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+/** @brief Swap the byte order of a metadata buffer\r
+\r
+ Does nothing if the buffer is not a metadata node. Also does nothing for\r
+ meta roots, which don't go through the buffers anyways.\r
+\r
+ @param pBuffer Pointer to the metadata buffer to swap\r
+ @param uFlags The associated buffer flags. Used to determin the type of\r
+ metadata node.\r
+*/\r
+static void BufferEndianSwap(\r
+ void *pBuffer,\r
+ uint16_t uFlags)\r
+{\r
+ if((pBuffer == NULL) || ((uFlags & BFLAG_MASK) != uFlags))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if((uFlags & BFLAG_META_MASK) != 0)\r
+ {\r
+ BufferEndianSwapHeader(pBuffer);\r
+\r
+ switch(uFlags & BFLAG_META_MASK)\r
+ {\r
+ case BFLAG_META_MASTER:\r
+ BufferEndianSwapMaster(pBuffer);\r
+ break;\r
+ case BFLAG_META_INODE:\r
+ BufferEndianSwapInode(pBuffer);\r
+ break;\r
+ #if DINDIR_POINTERS > 0U\r
+ case BFLAG_META_DINDIR:\r
+ BufferEndianSwapIndir(pBuffer);\r
+ break;\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ case BFLAG_META_INDIR:\r
+ BufferEndianSwapIndir(pBuffer);\r
+ break;\r
+ #endif\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* File data buffers do not need to be swapped.\r
+ */\r
+ }\r
+}\r
+\r
+\r
+/** @brief Swap the byte order of a metadata node header\r
+\r
+ @param pHeader Pointer to the metadata node header to swap\r
+*/\r
+static void BufferEndianSwapHeader(\r
+ NODEHEADER *pHeader)\r
+{\r
+ if(pHeader == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ pHeader->ulSignature = RedRev32(pHeader->ulSignature);\r
+ pHeader->ulCRC = RedRev32(pHeader->ulCRC);\r
+ pHeader->ullSequence = RedRev64(pHeader->ullSequence);\r
+ }\r
+}\r
+\r
+\r
+/** @brief Swap the byte order of a master block\r
+\r
+ @param pMaster Pointer to the master block to swap\r
+*/\r
+static void BufferEndianSwapMaster(\r
+ MASTERBLOCK *pMaster)\r
+{\r
+ if(pMaster == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ pMaster->ulVersion = RedRev32(pMaster->ulVersion);\r
+ pMaster->ulFormatTime = RedRev32(pMaster->ulFormatTime);\r
+ pMaster->ulInodeCount = RedRev32(pMaster->ulInodeCount);\r
+ pMaster->ulBlockCount = RedRev32(pMaster->ulBlockCount);\r
+ pMaster->uMaxNameLen = RedRev16(pMaster->uMaxNameLen);\r
+ pMaster->uDirectPointers = RedRev16(pMaster->uDirectPointers);\r
+ pMaster->uIndirectPointers = RedRev16(pMaster->uIndirectPointers);\r
+ }\r
+}\r
+\r
+\r
+/** @brief Swap the byte order of an inode\r
+\r
+ @param pInode Pointer to the inode to swap\r
+*/\r
+static void BufferEndianSwapInode(\r
+ INODE *pInode)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx;\r
+\r
+ pInode->ullSize = RedRev64(pInode->ullSize);\r
+\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ pInode->ulBlocks = RedRev32(pInode->ulBlocks);\r
+ #endif\r
+\r
+ #if REDCONF_INODE_TIMESTAMPS == 1\r
+ pInode->ulATime = RedRev32(pInode->ulATime);\r
+ pInode->ulMTime = RedRev32(pInode->ulMTime);\r
+ pInode->ulCTime = RedRev32(pInode->ulCTime);\r
+ #endif\r
+\r
+ pInode->uMode = RedRev16(pInode->uMode);\r
+\r
+ #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+ pInode->uNLink = RedRev16(pInode->uNLink);\r
+ #endif\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ pInode->ulPInode = RedRev32(pInode->ulPInode);\r
+ #endif\r
+\r
+ for(ulIdx = 0; ulIdx < INODE_ENTRIES; ulIdx++)\r
+ {\r
+ pInode->aulEntries[ulIdx] = RedRev32(pInode->aulEntries[ulIdx]);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+/** @brief Swap the byte order of an indirect or double indirect node\r
+\r
+ @param pIndir Pointer to the node to swap\r
+*/\r
+static void BufferEndianSwapIndir(\r
+ INDIR *pIndir)\r
+{\r
+ if(pIndir == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx;\r
+\r
+ pIndir->ulInode = RedRev32(pIndir->ulInode);\r
+\r
+ for(ulIdx = 0; ulIdx < INDIR_ENTRIES; ulIdx++)\r
+ {\r
+ pIndir->aulEntries[ulIdx] = RedRev32(pIndir->aulEntries[ulIdx]);\r
+ }\r
+ }\r
+}\r
+\r
+#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */\r
+#endif /* #ifdef REDCONF_ENDIAN_SWAP */\r
+\r
+\r
+/** @brief Mark a buffer as least recently used.\r
+\r
+ @param bIdx The index of the buffer to make LRU.\r
+*/\r
+static void BufferMakeLRU(\r
+ uint8_t bIdx)\r
+{\r
+ if(bIdx >= REDCONF_BUFFER_COUNT)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(bIdx != gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U])\r
+ {\r
+ uint8_t bMruIdx;\r
+\r
+ /* Find the current position of the buffer in the MRU array. We do not\r
+ need to check the last slot, since we already know from the above\r
+ check that the index is not there.\r
+ */\r
+ for(bMruIdx = 0U; bMruIdx < (REDCONF_BUFFER_COUNT - 1U); bMruIdx++)\r
+ {\r
+ if(bIdx == gBufCtx.abMRU[bMruIdx])\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(bMruIdx < (REDCONF_BUFFER_COUNT - 1U))\r
+ {\r
+ /* Move the buffer index to the back of the MRU array, making it\r
+ the LRU buffer.\r
+ */\r
+ RedMemMove(&gBufCtx.abMRU[bMruIdx], &gBufCtx.abMRU[bMruIdx + 1U], REDCONF_BUFFER_COUNT - ((uint32_t)bMruIdx + 1U));\r
+ gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U] = bIdx;\r
+ }\r
+ else\r
+ {\r
+ REDERROR();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Buffer already LRU, nothing to do.\r
+ */\r
+ }\r
+}\r
+\r
+\r
+/** @brief Mark a buffer as most recently used.\r
+\r
+ @param bIdx The index of the buffer to make MRU.\r
+*/\r
+static void BufferMakeMRU(\r
+ uint8_t bIdx)\r
+{\r
+ if(bIdx >= REDCONF_BUFFER_COUNT)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(bIdx != gBufCtx.abMRU[0U])\r
+ {\r
+ uint8_t bMruIdx;\r
+\r
+ /* Find the current position of the buffer in the MRU array. We do not\r
+ need to check the first slot, since we already know from the above\r
+ check that the index is not there.\r
+ */\r
+ for(bMruIdx = 1U; bMruIdx < REDCONF_BUFFER_COUNT; bMruIdx++)\r
+ {\r
+ if(bIdx == gBufCtx.abMRU[bMruIdx])\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(bMruIdx < REDCONF_BUFFER_COUNT)\r
+ {\r
+ /* Move the buffer index to the front of the MRU array, making it\r
+ the MRU buffer.\r
+ */\r
+ RedMemMove(&gBufCtx.abMRU[1U], &gBufCtx.abMRU[0U], bMruIdx);\r
+ gBufCtx.abMRU[0U] = bIdx;\r
+ }\r
+ else\r
+ {\r
+ REDERROR();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Buffer already MRU, nothing to do.\r
+ */\r
+ }\r
+}\r
+\r
+\r
+/** @brief Find a block in the buffers.\r
+\r
+ @param ulBlock The block number to find.\r
+ @param pbIdx If the block is buffered (true is returned), populated with\r
+ the index of the buffer.\r
+\r
+ @return Boolean indicating whether or not the block is buffered.\r
+\r
+ @retval true @p ulBlock is buffered, and its index has been stored in\r
+ @p pbIdx.\r
+ @retval false @p ulBlock is not buffered.\r
+*/\r
+static bool BufferFind(\r
+ uint32_t ulBlock,\r
+ uint8_t *pbIdx)\r
+{\r
+ bool ret = false;\r
+\r
+ if((ulBlock >= gpRedVolume->ulBlockCount) || (pbIdx == NULL))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ uint8_t bIdx;\r
+\r
+ for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++)\r
+ {\r
+ const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx];\r
+\r
+ if((pHead->bVolNum == gbRedVolNum) && (pHead->ulBlock == ulBlock))\r
+ {\r
+ *pbIdx = bIdx;\r
+ ret = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements the entry-points to the core file system.\r
+*/\r
+#include <redfs.h>\r
+#include <redcoreapi.h>\r
+#include <redcore.h>\r
+\r
+\r
+/* Minimum number of blocks needed for metadata on any volume: the master\r
+ block (1), the two metaroots (2), and one doubly-allocated inode (2),\r
+ resulting in 1 + 2 + 2 = 5.\r
+*/\r
+#define MINIMUM_METADATA_BLOCKS (5U)\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+static REDSTATUS CoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+static REDSTATUS CoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+static REDSTATUS CoreUnlink(uint32_t ulPInode, const char *pszName);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)\r
+static REDSTATUS CoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS CoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);\r
+#endif\r
+#if TRUNCATE_SUPPORTED\r
+static REDSTATUS CoreFileTruncate(uint32_t ulInode, uint64_t ullSize);\r
+#endif\r
+\r
+\r
+VOLUME gaRedVolume[REDCONF_VOLUME_COUNT];\r
+static COREVOLUME gaCoreVol[REDCONF_VOLUME_COUNT];\r
+\r
+const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf = &gaRedVolConf[0U];\r
+VOLUME * CONST_IF_ONE_VOLUME gpRedVolume = &gaRedVolume[0U];\r
+COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol = &gaCoreVol[0U];\r
+METAROOT *gpRedMR = &gaCoreVol[0U].aMR[0U];\r
+\r
+CONST_IF_ONE_VOLUME uint8_t gbRedVolNum;\r
+\r
+\r
+/** @brief Initialize the Reliance Edge file system driver.\r
+\r
+ Prepares the Reliance Edge file system driver to be used. Must be the first\r
+ Reliance Edge function to be invoked: no volumes can be mounted until the\r
+ driver has been initialized.\r
+\r
+ If this function is called when the Reliance Edge driver is already\r
+ initialized, the behavior is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedCoreInit(void)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint8_t bVolNum;\r
+ #if REDCONF_OUTPUT == 1\r
+ static uint8_t bSignedOn = 0U; /* Whether the sign on has been printed. */\r
+\r
+ if(bSignedOn == 0U)\r
+ {\r
+ RedSignOn();\r
+ bSignedOn = 1U;\r
+ }\r
+ #else\r
+ /* Call RedSignOn() even when output is disabled, to force the copyright\r
+ text to be referenced and pulled into the program data.\r
+ */\r
+ RedSignOn();\r
+ #endif\r
+\r
+ RedMemSet(gaRedVolume, 0U, sizeof(gaRedVolume));\r
+ RedMemSet(gaCoreVol, 0U, sizeof(gaCoreVol));\r
+\r
+ RedBufferInit();\r
+\r
+ for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)\r
+ {\r
+ VOLUME *pVol = &gaRedVolume[bVolNum];\r
+ COREVOLUME *pCoreVol = &gaCoreVol[bVolNum];\r
+ const VOLCONF *pVolConf = &gaRedVolConf[bVolNum];\r
+\r
+ if( (pVolConf->ulSectorSize < SECTOR_SIZE_MIN)\r
+ || ((REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize) != 0U)\r
+ || (pVolConf->ulInodeCount == 0U))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #if REDCONF_API_POSIX == 1\r
+ else if(pVolConf->pszPathPrefix == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ uint8_t bCmpVol;\r
+\r
+ /* Ensure there are no duplicate path prefixes. Check against all\r
+ previous volumes, which are already verified.\r
+ */\r
+ for(bCmpVol = 0U; bCmpVol < bVolNum; bCmpVol++)\r
+ {\r
+ const char *pszCmpPathPrefix = gaRedVolConf[bCmpVol].pszPathPrefix;\r
+\r
+ if(RedStrCmp(pVolConf->pszPathPrefix, pszCmpPathPrefix) == 0)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ break;\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ pVol->bBlockSectorShift = 0U;\r
+ while((pVolConf->ulSectorSize << pVol->bBlockSectorShift) < REDCONF_BLOCK_SIZE)\r
+ {\r
+ pVol->bBlockSectorShift++;\r
+ }\r
+\r
+ /* This should always be true since the block size is confirmed to\r
+ be a power of two (checked at compile time) and above we ensured\r
+ that (REDCONF_BLOCK_SIZE % pVolConf->ulSectorSize) == 0.\r
+ */\r
+ REDASSERT((pVolConf->ulSectorSize << pVol->bBlockSectorShift) == REDCONF_BLOCK_SIZE);\r
+\r
+ pVol->ulBlockCount = (uint32_t)(pVolConf->ullSectorCount >> pVol->bBlockSectorShift);\r
+\r
+ if(pVol->ulBlockCount < MINIMUM_METADATA_BLOCKS)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_READ_ONLY == 0\r
+ pVol->ulTransMask = REDCONF_TRANSACT_DEFAULT;\r
+ #endif\r
+\r
+ pVol->ullMaxInodeSize = INODE_SIZE_MAX;\r
+\r
+ /* To understand the following code, note that the fixed-\r
+ location metadata is located at the start of the disk, in\r
+ the following order:\r
+\r
+ - Master block (1 block)\r
+ - Metaroots (2 blocks)\r
+ - External imap blocks (variable * 2 blocks)\r
+ - Inode blocks (pVolConf->ulInodeCount * 2 blocks)\r
+ */\r
+\r
+ /* The imap needs bits for all inode and allocable blocks. If\r
+ that bitmap will fit into the metaroot, the inline imap is\r
+ used and there are no imap nodes on disk. The minus 3 is\r
+ there since the imap does not include bits for the master\r
+ block or metaroots.\r
+ */\r
+ pCoreVol->fImapInline = (pVol->ulBlockCount - 3U) <= METAROOT_ENTRIES;\r
+\r
+ if(pCoreVol->fImapInline)\r
+ {\r
+ #if REDCONF_IMAP_INLINE == 1\r
+ pCoreVol->ulInodeTableStartBN = 3U;\r
+ #else\r
+ ret = -RED_EINVAL;\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_IMAP_EXTERNAL == 1\r
+ pCoreVol->ulImapStartBN = 3U;\r
+\r
+ /* The imap does not include bits for itself, so add two to\r
+ the number of imap entries for the two blocks of each\r
+ imap node. This allows us to divide up the remaining\r
+ space, making sure to round up so all data blocks are\r
+ covered.\r
+ */\r
+ pCoreVol->ulImapNodeCount =\r
+ ((pVol->ulBlockCount - 3U) + ((IMAPNODE_ENTRIES + 2U) - 1U)) / (IMAPNODE_ENTRIES + 2U);\r
+\r
+ pCoreVol->ulInodeTableStartBN = pCoreVol->ulImapStartBN + (pCoreVol->ulImapNodeCount * 2U);\r
+ #else\r
+ ret = -RED_EINVAL;\r
+ #endif\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pCoreVol->ulFirstAllocableBN = pCoreVol->ulInodeTableStartBN + (pVolConf->ulInodeCount * 2U);\r
+\r
+ if(pCoreVol->ulFirstAllocableBN > pVol->ulBlockCount)\r
+ {\r
+ /* We can get here if there is not enough space for the number\r
+ of configured inodes.\r
+ */\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ pVol->ulBlocksAllocable = pVol->ulBlockCount - pCoreVol->ulFirstAllocableBN;\r
+ }\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* Make sure the configured endianness is correct.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint16_t uValue = 0xFF00U;\r
+ uint8_t abBytes[2U];\r
+\r
+ RedMemCpy(abBytes, &uValue, sizeof(abBytes));\r
+\r
+ #if REDCONF_ENDIAN_BIG == 1\r
+ if(abBytes[0U] != 0xFFU)\r
+ #else\r
+ if(abBytes[0U] != 0x00U)\r
+ #endif\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedOsClockInit();\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedOsMutexInit();\r
+\r
+ if(ret != 0)\r
+ {\r
+ (void)RedOsClockUninit();\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize the Reliance Edge file system driver.\r
+\r
+ Tears down the Reliance Edge file system driver. Cannot be used until all\r
+ Reliance Edge volumes are unmounted. A subsequent call to RedCoreInit()\r
+ will initialize the driver again.\r
+\r
+ The behavior of calling this function when the core is already uninitialized\r
+ is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBUSY At least one volume is still mounted.\r
+*/\r
+REDSTATUS RedCoreUninit(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ ret = RedOsMutexUninit();\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ ret = RedOsClockUninit();\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Set the current volume.\r
+\r
+ All core APIs operate on the current volume. This call must precede all\r
+ core accesses.\r
+\r
+ @param bVolNum The volume number to access.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number.\r
+*/\r
+REDSTATUS RedCoreVolSetCurrent(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(bVolNum >= REDCONF_VOLUME_COUNT)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ gbRedVolNum = bVolNum;\r
+ gpRedVolConf = &gaRedVolConf[bVolNum];\r
+ gpRedVolume = &gaRedVolume[bVolNum];\r
+ gpRedCoreVol = &gaCoreVol[bVolNum];\r
+ gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];\r
+ #endif\r
+\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if FORMAT_SUPPORTED\r
+/** @brief Format a file system volume.\r
+\r
+ Uses the statically defined volume configuration. After calling this\r
+ function, the volume needs to be mounted -- see RedCoreVolMount().\r
+\r
+ An error is returned if the volume is mounted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBUSY Volume is mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedCoreVolFormat(void)\r
+{\r
+ return RedVolFormat();\r
+}\r
+#endif /* FORMAT_SUPPORTED */\r
+\r
+\r
+/** @brief Mount a file system volume.\r
+\r
+ Prepares the file system volume to be accessed. Mount will fail if the\r
+ volume has never been formatted, or if the on-disk format is inconsistent\r
+ with the compile-time configuration.\r
+\r
+ If the volume is already mounted, the behavior is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.\r
+*/\r
+REDSTATUS RedCoreVolMount(void)\r
+{\r
+ return RedVolMount();\r
+}\r
+\r
+\r
+/** @brief Unmount a file system volume.\r
+\r
+ This function discards the in-memory state for the file system and marks it\r
+ as unmounted. Subsequent attempts to access the volume will fail until the\r
+ volume is mounted again.\r
+\r
+ If unmount automatic transaction points are enabled, this function will\r
+ commit a transaction point prior to unmounting. If unmount automatic\r
+ transaction points are disabled, this function will unmount without\r
+ transacting, effectively discarding the working state.\r
+\r
+ If the volume is already unmounted, the behavior is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO I/O error during unmount automatic transaction point.\r
+*/\r
+REDSTATUS RedCoreVolUnmount(void)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(!gpRedVolume->fReadOnly && ((gpRedVolume->ulTransMask & RED_TRANSACT_UMOUNT) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedOsBDevClose(gbRedVolNum);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ gpRedVolume->fMounted = false;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Commit a transaction point.\r
+\r
+ Reliance Edge is a transactional file system. All modifications, of both\r
+ metadata and filedata, are initially working state. A transaction point\r
+ is a process whereby the working state atomically becomes the committed\r
+ state, replacing the previous committed state. Whenever Reliance Edge is\r
+ mounted, including after power loss, the state of the file system after\r
+ mount is the most recent committed state. Nothing from the committed\r
+ state is ever missing, and nothing from the working state is ever included.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The volume is not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedCoreVolTransact(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#if REDCONF_API_POSIX == 1\r
+/** @brief Query file system status information.\r
+\r
+ @param pStatFS The buffer to populate with volume information.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval -RED_EINVAL Volume is not mounted; or @p pStatFS is `NULL`.\r
+*/\r
+REDSTATUS RedCoreVolStat(\r
+ REDSTATFS *pStatFS)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((pStatFS == NULL) || (!gpRedVolume->fMounted))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ RedMemSet(pStatFS, 0U, sizeof(*pStatFS));\r
+\r
+ pStatFS->f_bsize = REDCONF_BLOCK_SIZE;\r
+ pStatFS->f_frsize = REDCONF_BLOCK_SIZE;\r
+ pStatFS->f_blocks = gpRedVolume->ulBlockCount;\r
+ #if RESERVED_BLOCKS > 0U\r
+ pStatFS->f_bfree = (gpRedMR->ulFreeBlocks > RESERVED_BLOCKS) ? (gpRedMR->ulFreeBlocks - RESERVED_BLOCKS) : 0U;\r
+ #else\r
+ pStatFS->f_bfree = gpRedMR->ulFreeBlocks;\r
+ #endif\r
+ pStatFS->f_bavail = pStatFS->f_bfree;\r
+ pStatFS->f_files = gpRedVolConf->ulInodeCount;\r
+ pStatFS->f_ffree = gpRedMR->ulFreeInodes;\r
+ pStatFS->f_favail = gpRedMR->ulFreeInodes;\r
+\r
+ pStatFS->f_flag = RED_ST_NOSUID;\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(gpRedVolume->fReadOnly)\r
+ #endif\r
+ {\r
+ pStatFS->f_flag |= RED_ST_RDONLY;\r
+ }\r
+\r
+ pStatFS->f_namemax = REDCONF_NAME_MAX;\r
+ pStatFS->f_maxfsize = INODE_SIZE_MAX;\r
+ pStatFS->f_dev = gbRedVolNum;\r
+\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_API_POSIX == 1 */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1))\r
+/** @brief Update the transaction mask.\r
+\r
+ The following events are available when using the FSE API:\r
+\r
+ - #RED_TRANSACT_UMOUNT\r
+ - #RED_TRANSACT_WRITE\r
+ - #RED_TRANSACT_TRUNCATE\r
+ - #RED_TRANSACT_VOLFULL\r
+\r
+ The following events are available when using the POSIX-like API:\r
+\r
+ - #RED_TRANSACT_UMOUNT\r
+ - #RED_TRANSACT_CREAT\r
+ - #RED_TRANSACT_UNLINK\r
+ - #RED_TRANSACT_MKDIR\r
+ - #RED_TRANSACT_RENAME\r
+ - #RED_TRANSACT_LINK\r
+ - #RED_TRANSACT_CLOSE\r
+ - #RED_TRANSACT_WRITE\r
+ - #RED_TRANSACT_FSYNC\r
+ - #RED_TRANSACT_TRUNCATE\r
+ - #RED_TRANSACT_VOLFULL\r
+\r
+ The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all\r
+ automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of\r
+ all transaction flags, excluding those representing excluded functionality.\r
+\r
+ Attempting to enable events for excluded functionality will result in an\r
+ error.\r
+\r
+ @param ulEventMask A bitwise-OR'd mask of automatic transaction events to\r
+ be set as the current transaction mode.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p ulEventMask contains\r
+ invalid bits.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedCoreTransMaskSet(\r
+ uint32_t ulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted || ((ulEventMask & RED_TRANSACT_MASK) != ulEventMask))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ gpRedVolume->ulTransMask = ulEventMask;\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1)\r
+/** @brief Read the transaction mask.\r
+\r
+ If the volume is read-only, the returned event mask is always zero.\r
+\r
+ @param pulEventMask Populated with a bitwise-OR'd mask of automatic\r
+ transaction events which represent the current\r
+ transaction mode for the volume.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pulEventMask is `NULL`.\r
+*/\r
+REDSTATUS RedCoreTransMaskGet(\r
+ uint32_t *pulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted || (pulEventMask == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_READ_ONLY == 1\r
+ *pulEventMask = 0U;\r
+ #else\r
+ *pulEventMask = gpRedVolume->ulTransMask;\r
+ #endif\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+/** @brief Create a file or directory.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName A null-terminated name for the new inode.\r
+ @param fDir Whether to create a directory (true) or file (false).\r
+ @param pulInode On successful return, populated with the inode number of the\r
+ new file or directory.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pszName is not\r
+ a valid name; or @p pulInode is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode.\r
+ @retval -RED_ENOSPC There is not enough space on the volume to\r
+ createthe new directory entry; or the directory\r
+ is full.\r
+ @retval -RED_ENFILE No available inode slots.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_EEXIST @p pszName already exists in @p ulPInode.\r
+*/\r
+REDSTATUS RedCoreCreate(\r
+ uint32_t ulPInode,\r
+ const char *pszName,\r
+ bool fDir,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreCreate(ulPInode, pszName, fDir, pulInode);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreCreate(ulPInode, pszName, fDir, pulInode);\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_MKDIR) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ else if(!fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_CREAT) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ else\r
+ {\r
+ /* No automatic transaction for this operation.\r
+ */\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Create a file or directory.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName A null-terminated name for the new inode.\r
+ @param fDir Whether to create a directory (true) or file (false).\r
+ @param pulInode On successful return, populated with the inode number of the\r
+ new file or directory.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode.\r
+ @retval -RED_ENOSPC There is not enough space on the volume to\r
+ create the new directory entry; or the directory\r
+ is full.\r
+ @retval -RED_ENFILE No available inode slots.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_EEXIST @p pszName already exists in @p ulPInode.\r
+*/\r
+static REDSTATUS CoreCreate(\r
+ uint32_t ulPInode,\r
+ const char *pszName,\r
+ bool fDir,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pulInode == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ CINODE pino;\r
+\r
+ pino.ulInode = ulPInode;\r
+ ret = RedInodeMount(&pino, FTYPE_DIR, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = INODE_INVALID;\r
+ ret = RedInodeCreate(&ino, ulPInode, fDir ? RED_S_IFDIR : RED_S_IFREG);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeBranch(&pino);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryCreate(&pino, pszName, ino.ulInode);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulInode = ino.ulInode;\r
+ }\r
+ else\r
+ {\r
+ REDSTATUS ret2;\r
+\r
+ ret2 = RedInodeFree(&ino);\r
+ CRITICAL_ASSERT(ret2 == 0);\r
+ }\r
+\r
+ RedInodePut(&ino, 0U);\r
+ }\r
+\r
+ RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+/** @brief Create a hard link.\r
+\r
+ This creates an additional name (link) for @p ulInode. The new name refers\r
+ to the same file with the same contents. If a name is deleted, but the\r
+ underlying file has other names, the file continues to exist. The link\r
+ count (accessible via RedCoreStat()) indicates the number of names that a\r
+ file has. All of a file's names are on equal footing: there is nothing\r
+ special about the original name.\r
+\r
+ If @p ulInode names a directory, the operation will fail.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName The null-terminated name for the new link.\r
+ @param ulInode The inode to create a hard link to.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode\r
+ is not a valid inode.\r
+ @retval -RED_EEXIST @p pszName resolves to an existing file.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pszName is\r
+ `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EMLINK Creating the link would exceed the maximum link\r
+ count of @p ulInode.\r
+ @retval -RED_ENAMETOOLONG Attempting to create a link with a name that\r
+ exceeds the maximum name length.\r
+ @retval -RED_ENOSPC There is insufficient free space to expand the\r
+ directory that would contain the link.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_EPERM @p ulInode is a directory.\r
+ @retval -RED_EROFS The requested link requires writing in a\r
+ directory on a read-only file system.\r
+*/\r
+REDSTATUS RedCoreLink(\r
+ uint32_t ulPInode,\r
+ const char *pszName,\r
+ uint32_t ulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreLink(ulPInode, pszName, ulInode);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreLink(ulPInode, pszName, ulInode);\r
+ }\r
+ }\r
+\r
+ if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_LINK) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Create a hard link.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName The null-terminated name for the new link.\r
+ @param ulInode The inode to create a hard link to.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode\r
+ is not a valid inode.\r
+ @retval -RED_EEXIST @p pszName resolves to an existing file.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EMLINK Creating the link would exceed the maximum link\r
+ count of @p ulInode.\r
+ @retval -RED_ENAMETOOLONG Attempting to create a link with a name that\r
+ exceeds the maximum name length.\r
+ @retval -RED_ENOSPC There is insufficient free space to expand the\r
+ directory that would contain the link.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_EPERM @p ulInode is a directory.\r
+ @retval -RED_EROFS The requested link requires writing in a\r
+ directory on a read-only file system.\r
+*/\r
+static REDSTATUS CoreLink(\r
+ uint32_t ulPInode,\r
+ const char *pszName,\r
+ uint32_t ulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ CINODE pino;\r
+\r
+ pino.ulInode = ulPInode;\r
+ ret = RedInodeMount(&pino, FTYPE_DIR, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_FILE, false);\r
+\r
+ /* POSIX specifies EPERM as the errno thrown when link() is given a\r
+ directory. Switch the errno returned if EISDIR was the return\r
+ value.\r
+ */\r
+ if(ret == -RED_EISDIR)\r
+ {\r
+ ret = -RED_EPERM;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(ino.pInodeBuf->uNLink == UINT16_MAX)\r
+ {\r
+ ret = -RED_EMLINK;\r
+ }\r
+ else\r
+ {\r
+ ret = RedInodeBranch(&pino);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeBranch(&ino);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryCreate(&pino, pszName, ino.ulInode);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ino.pInodeBuf->uNLink++;\r
+ }\r
+\r
+ RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U);\r
+ }\r
+\r
+ RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+/** @brief Delete a file or directory.\r
+\r
+ The given name is deleted and the link count of the corresponding inode is\r
+ decremented. If the link count falls to zero (no remaining hard links),\r
+ the inode will be deleted.\r
+\r
+ If the path names a directory which is not empty, the unlink will fail.\r
+\r
+ If the deletion frees data in the committed state, it will not return to\r
+ free space until after a transaction point. Similarly, if the inode was\r
+ part of the committed state, the inode slot will not be available until\r
+ after a transaction point.\r
+\r
+ This function can fail when the disk is full. To fix this, transact and\r
+ try again: Reliance Edge guarantees that it is possible to delete at least\r
+ one file or directory after a transaction point. If disk full automatic\r
+ transactions are enabled, this will happen automatically.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName The null-terminated name of the file or directory to\r
+ delete.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pszName is\r
+ `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_ENOENT @p pszName does not name an existing file or\r
+ directory.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ modify the parent directory to perform the\r
+ deletion.\r
+ @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a\r
+ directory which is not empty.\r
+*/\r
+REDSTATUS RedCoreUnlink(\r
+ uint32_t ulPInode,\r
+ const char *pszName)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreUnlink(ulPInode, pszName);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreUnlink(ulPInode, pszName);\r
+ }\r
+ }\r
+\r
+ if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_UNLINK) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Delete a file or directory.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName The null-terminated name of the file or directory to\r
+ delete.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_ENOENT @p pszName does not name an existing file or\r
+ directory.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ modify the parent directory to perform the\r
+ deletion.\r
+ @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a\r
+ directory which is not empty.\r
+*/\r
+static REDSTATUS CoreUnlink(\r
+ uint32_t ulPInode,\r
+ const char *pszName)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ CINODE pino;\r
+\r
+ pino.ulInode = ulPInode;\r
+ ret = RedInodeMount(&pino, FTYPE_DIR, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulDeleteIdx;\r
+ uint32_t ulInode;\r
+\r
+ ret = RedDirEntryLookup(&pino, pszName, &ulDeleteIdx, &ulInode);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeBranch(&pino);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_EITHER, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(ino.fDirectory && (ino.pInodeBuf->ullSize > 0U))\r
+ {\r
+ ret = -RED_ENOTEMPTY;\r
+ }\r
+ else\r
+ {\r
+ #if RESERVED_BLOCKS > 0U\r
+ gpRedCoreVol->fUseReservedBlocks = true;\r
+ #endif\r
+\r
+ ret = RedDirEntryDelete(&pino, ulDeleteIdx);\r
+\r
+ #if RESERVED_BLOCKS > 0U\r
+ gpRedCoreVol->fUseReservedBlocks = false;\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* If the inode is deleted, buffers are needed to\r
+ read all of the indirects and free the data\r
+ blocks. Before doing that, to reduce the\r
+ minimum number of buffers needed to complete the\r
+ unlink, release the parent directory inode\r
+ buffers which are no longer needed.\r
+ */\r
+ RedInodePutCoord(&pino);\r
+\r
+ ret = RedInodeLinkDec(&ino);\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+ }\r
+\r
+ RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U);\r
+ }\r
+ }\r
+\r
+ RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) */\r
+\r
+\r
+#if REDCONF_API_POSIX == 1\r
+/** @brief Look up the inode number of a file or directory.\r
+\r
+ @param ulPInode The inode number of the parent directory.\r
+ @param pszName The null-terminated name of the file or directory to look\r
+ up.\r
+ @param pulInode On successful return, populated with the inode number named\r
+ by @p pszName.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulPInode is not a valid inode.\r
+ @retval -RED_EINVAL The volume is not mounted; @p pszName is `NULL`; or\r
+ @p pulInode is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT @p pszName does not name an existing file or directory.\r
+ @retval -RED_ENOTDIR @p ulPInode is not a directory.\r
+*/\r
+REDSTATUS RedCoreLookup(\r
+ uint32_t ulPInode,\r
+ const char *pszName,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((pulInode == NULL) || !gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulPInode;\r
+ ret = RedInodeMount(&ino, FTYPE_DIR, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryLookup(&ino, pszName, NULL, pulInode);\r
+\r
+ RedInodePut(&ino, 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_API_POSIX == 1 */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)\r
+/** @brief Rename a file or directory.\r
+\r
+ If @p pszDstName names an existing file or directory, the behavior depends\r
+ on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the\r
+ destination name exists, this function always fails with -RED_EEXIST.\r
+\r
+ If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one\r
+ atomic operation, the destination name is unlinked and the source name is\r
+ renamed to the destination name. Both names must be of the same type (both\r
+ files or both directories). As with RedCoreUnlink(), if the destination\r
+ name is a directory, it must be empty. The major exception to this\r
+ behavior is that if both names are links to the same inode, then the rename\r
+ does nothing and both names continue to exist.\r
+\r
+ If the rename deletes the old destination, it may free data in the\r
+ committed state, which will not return to free space until after a\r
+ transaction point. Similarly, if the deleted inode was part of the\r
+ committed state, the inode slot will not be available until after a\r
+ transaction point.\r
+\r
+ @param ulSrcPInode The inode number of the parent directory of the file or\r
+ directory to rename.\r
+ @param pszSrcName The name of the file or directory to rename.\r
+ @param ulDstPInode The new parent directory inode number of the file or\r
+ directory after the rename.\r
+ @param pszNewPath The new name of the file or directory after the rename.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or\r
+ @p ulDstPInode is not a valid inode number.\r
+ @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the\r
+ destination name exists.\r
+ @retval -RED_EINVAL The volume is not mounted; @p pszSrcName is\r
+ `NULL`; or @p pszDstName is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The destination name exists and is a directory,\r
+ and the source name is a non-directory.\r
+ @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer\r
+ than #REDCONF_NAME_MAX.\r
+ @retval -RED_ENOENT The source name is not an existing entry; or\r
+ either @p pszSrcName or @p pszDstName point to\r
+ an empty string.\r
+ @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or\r
+ @p ulDstPInode is not a directory; or the source\r
+ name is a directory and the destination name is\r
+ a file.\r
+ @retval -RED_ENOTEMPTY The destination name is a directory which is not\r
+ empty.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ extend the @p ulDstPInode directory.\r
+ @retval -RED_EROFS The directory to be removed resides on a\r
+ read-only file system.\r
+*/\r
+REDSTATUS RedCoreRename(\r
+ uint32_t ulSrcPInode,\r
+ const char *pszSrcName,\r
+ uint32_t ulDstPInode,\r
+ const char *pszDstName)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName);\r
+ }\r
+ }\r
+\r
+ if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_RENAME) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Rename a file or directory.\r
+\r
+ @param ulSrcPInode The inode number of the parent directory of the file or\r
+ directory to rename.\r
+ @param pszSrcName The name of the file or directory to rename.\r
+ @param ulDstPInode The new parent directory inode number of the file or\r
+ directory after the rename.\r
+ @param pszNewPath The new name of the file or directory after the rename.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or\r
+ @p ulDstPInode is not a valid inode number.\r
+ @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the\r
+ destination name exists.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The destination name exists and is a directory,\r
+ and the source name is a non-directory.\r
+ @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer\r
+ than #REDCONF_NAME_MAX.\r
+ @retval -RED_ENOENT The source name is not an existing entry; or\r
+ either @p pszSrcName or @p pszDstName point to\r
+ an empty string.\r
+ @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or\r
+ @p ulDstPInode is not a directory; or the source\r
+ name is a directory and the destination name is\r
+ a file.\r
+ @retval -RED_ENOTEMPTY The destination name is a directory which is not\r
+ empty.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ extend the @p ulDstPInode directory.\r
+ @retval -RED_EROFS The directory to be removed resides on a\r
+ read-only file system.\r
+*/\r
+static REDSTATUS CoreRename(\r
+ uint32_t ulSrcPInode,\r
+ const char *pszSrcName,\r
+ uint32_t ulDstPInode,\r
+ const char *pszDstName)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ bool fUpdateTimestamps = false;\r
+ CINODE SrcPInode;\r
+\r
+ SrcPInode.ulInode = ulSrcPInode;\r
+ ret = RedInodeMount(&SrcPInode, FTYPE_DIR, true);\r
+\r
+ if(ret == 0)\r
+ {\r
+ CINODE DstPInode;\r
+ CINODE *pDstPInode;\r
+\r
+ if(ulSrcPInode == ulDstPInode)\r
+ {\r
+ pDstPInode = &SrcPInode;\r
+ }\r
+ else\r
+ {\r
+ pDstPInode = &DstPInode;\r
+ DstPInode.ulInode = ulDstPInode;\r
+ ret = RedInodeMount(pDstPInode, FTYPE_DIR, true);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Initialize these to zero so we can unconditionally put them,\r
+ even if RedDirEntryRename() fails before mounting them.\r
+ */\r
+ CINODE SrcInode = {0U};\r
+ CINODE DstInode = {0U};\r
+\r
+ ret = RedDirEntryRename(&SrcPInode, pszSrcName, &SrcInode, pDstPInode, pszDstName, &DstInode);\r
+\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ if((ret == 0) && (DstInode.ulInode != INODE_INVALID) && (DstInode.ulInode != SrcInode.ulInode))\r
+ {\r
+ /* If the inode is deleted, buffers are needed to read all\r
+ of the indirects and free the data blocks. Before doing\r
+ that, to reduce the minimum number of buffers needed to\r
+ complete the rename, release parent directory inode\r
+ buffers which are no longer needed.\r
+ */\r
+ RedInodePutCoord(&SrcPInode);\r
+ RedInodePutCoord(pDstPInode);\r
+\r
+ ret = RedInodeLinkDec(&DstInode);\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+\r
+ if((ret == 0) && (DstInode.ulInode != SrcInode.ulInode))\r
+ #else\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ fUpdateTimestamps = true;\r
+ }\r
+\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ RedInodePut(&DstInode, 0U);\r
+ #endif\r
+\r
+ /* POSIX says updating ctime for the source inode is optional,\r
+ but searching around it looks like this is common for Linux\r
+ and other Unix file systems.\r
+ */\r
+ RedInodePut(&SrcInode, fUpdateTimestamps ? IPUT_UPDATE_CTIME : 0U);\r
+ RedInodePut(pDstPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ RedInodePut(&SrcPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) */\r
+\r
+\r
+#if REDCONF_API_POSIX == 1\r
+/** @brief Get the status of a file or directory.\r
+\r
+ See the ::REDSTAT type for the details of the information returned.\r
+\r
+ @param ulInode The inode number of the file or directory whose information\r
+ is to be retrieved.\r
+ @param pStat Pointer to a ::REDSTAT buffer to populate.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode.\r
+ @retval -RED_EINVAL The volume is not mounted; @p pStat is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedCoreStat(\r
+ uint32_t ulInode,\r
+ REDSTAT *pStat)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted || (pStat == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_EITHER, false);\r
+ if(ret == 0)\r
+ {\r
+ RedMemSet(pStat, 0U, sizeof(*pStat));\r
+\r
+ pStat->st_dev = gbRedVolNum;\r
+ pStat->st_ino = ulInode;\r
+ pStat->st_mode = ino.pInodeBuf->uMode;\r
+ #if REDCONF_API_POSIX_LINK == 1\r
+ pStat->st_nlink = ino.pInodeBuf->uNLink;\r
+ #else\r
+ pStat->st_nlink = 1U;\r
+ #endif\r
+ pStat->st_size = ino.pInodeBuf->ullSize;\r
+ #if REDCONF_INODE_TIMESTAMPS == 1\r
+ pStat->st_atime = ino.pInodeBuf->ulATime;\r
+ pStat->st_mtime = ino.pInodeBuf->ulMTime;\r
+ pStat->st_ctime = ino.pInodeBuf->ulCTime;\r
+ #endif\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ pStat->st_blocks = ino.pInodeBuf->ulBlocks;\r
+ #endif\r
+\r
+ RedInodePut(&ino, 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_API_POSIX == 1 */\r
+\r
+\r
+#if REDCONF_API_FSE == 1\r
+/** @brief Get the size of a file.\r
+\r
+ @param ulInode The inode number of the file whose size is to be retrieved.\r
+ @param pullSize On successful exit, populated with the file size.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode.\r
+ @retval -RED_EINVAL The volume is not mounted; @p pullSize is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR @p ulInode is a directory inode.\r
+*/\r
+REDSTATUS RedCoreFileSizeGet(\r
+ uint32_t ulInode,\r
+ uint64_t *pullSize)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted || (pullSize == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_FILE, false);\r
+ if(ret == 0)\r
+ {\r
+ *pullSize = ino.pInodeBuf->ullSize;\r
+\r
+ RedInodePut(&ino, 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_API_FSE == 1 */\r
+\r
+\r
+/** @brief Read from a file.\r
+\r
+ Data which has not yet been written, but which is before the end-of-file\r
+ (sparse data), shall read as zeroes. A short read -- where the number of\r
+ bytes read is less than requested -- indicates that the requested read was\r
+ partially or, if zero bytes were read, entirely beyond the end-of-file.\r
+\r
+ If @p ullStart is at or beyond the maximum file size, it is treated like\r
+ any other read entirely beyond the end-of-file: no data is read and\r
+ @p pulLen is populated with zero.\r
+\r
+ @param ulInode The inode number of the file to read.\r
+ @param ullStart The file offset to read from.\r
+ @param pulLen On entry, contains the number of bytes to read; on\r
+ successful exit, contains the number of bytes actually\r
+ read.\r
+ @param pBuffer The buffer to populate with the data read. Must be big\r
+ enough for the read request.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode number.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The inode is a directory inode.\r
+*/\r
+REDSTATUS RedCoreFileRead(\r
+ uint32_t ulInode,\r
+ uint64_t ullStart,\r
+ uint32_t *pulLen,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted || (pulLen == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0)\r
+ bool fUpdateAtime = (*pulLen > 0U) && !gpRedVolume->fReadOnly;\r
+ #else\r
+ bool fUpdateAtime = false;\r
+ #endif\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_FILE, fUpdateAtime);\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeDataRead(&ino, ullStart, pulLen, pBuffer);\r
+\r
+ #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0)\r
+ RedInodePut(&ino, ((ret == 0) && fUpdateAtime) ? IPUT_UPDATE_ATIME : 0U);\r
+ #else\r
+ RedInodePut(&ino, 0U);\r
+ #endif\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write to a file.\r
+\r
+ If the write extends beyond the end-of-file, the file size will be\r
+ increased.\r
+\r
+ A short write -- where the number of bytes written is less than requested\r
+ -- indicates either that the file system ran out of space but was still\r
+ able to write some of the request; or that the request would have caused\r
+ the file to exceed the maximum file size, but some of the data could be\r
+ written prior to the file size limit.\r
+\r
+ If an error is returned, either none of the data was written or a critical\r
+ error occurred (like an I/O error) and the file system volume will be\r
+ read-only.\r
+\r
+ @param ulInode The file number of the file to write.\r
+ @param ullStart The file offset to write at.\r
+ @param pulLen On entry, the number of bytes to write; on successful exit,\r
+ the number of bytes actually written.\r
+ @param pBuffer The buffer containing the data to be written. Must big\r
+ enough for the write request.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid file number.\r
+ @retval -RED_EFBIG No data can be written to the given file offset since\r
+ the resulting file size would exceed the maximum file\r
+ size.\r
+ @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The inode is a directory inode.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedCoreFileWrite(\r
+ uint32_t ulInode,\r
+ uint64_t ullStart,\r
+ uint32_t *pulLen,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer);\r
+ }\r
+ }\r
+\r
+ if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_WRITE) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Write to a file.\r
+\r
+ @param ulInode The file number of the file to write.\r
+ @param ullStart The file offset to write at.\r
+ @param pulLen On entry, the number of bytes to write; on successful exit,\r
+ the number of bytes actually written.\r
+ @param pBuffer The buffer containing the data to be written. Must big\r
+ enough for the write request.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid file number.\r
+ @retval -RED_EFBIG No data can be written to the given file offset since\r
+ the resulting file size would exceed the maximum file\r
+ size.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The inode is a directory inode.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+static REDSTATUS CoreFileWrite(\r
+ uint32_t ulInode,\r
+ uint64_t ullStart,\r
+ uint32_t *pulLen,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_FILE, true);\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeDataWrite(&ino, ullStart, pulLen, pBuffer);\r
+\r
+ RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#if TRUNCATE_SUPPORTED\r
+/** @brief Set the file size.\r
+\r
+ Allows the file size to be increased, decreased, or to remain the same. If\r
+ the file size is increased, the new area is sparse (will read as zeroes).\r
+ If the file size is decreased, the data beyond the new end-of-file will\r
+ return to free space once it is no longer part of the committed state\r
+ (either immediately or after the next transaction point).\r
+\r
+ @param ulInode The inode of the file to truncate.\r
+ @param ullSize The new file size, in bytes.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode number.\r
+ @retval -RED_EFBIG @p ullSize exceeds the maximum file size.\r
+ @retval -RED_EINVAL The volume is not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The inode is a directory inode.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedCoreFileTruncate(\r
+ uint32_t ulInode,\r
+ uint64_t ullSize)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ ret = CoreFileTruncate(ulInode, ullSize);\r
+\r
+ if( (ret == -RED_ENOSPC)\r
+ && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U)\r
+ && (gpRedCoreVol->ulAlmostFreeBlocks > 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = CoreFileTruncate(ulInode, ullSize);\r
+ }\r
+ }\r
+\r
+ if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_TRUNCATE) != 0U))\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Set the file size.\r
+\r
+ @param ulInode The inode of the file to truncate.\r
+ @param ullSize The new file size, in bytes.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode number.\r
+ @retval -RED_EFBIG @p ullSize exceeds the maximum file size.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The inode is a directory inode.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+static REDSTATUS CoreFileTruncate(\r
+ uint32_t ulInode,\r
+ uint64_t ullSize)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fReadOnly)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_FILE, true);\r
+ if(ret == 0)\r
+ {\r
+ #if RESERVED_BLOCKS > 0U\r
+ gpRedCoreVol->fUseReservedBlocks = (ullSize < ino.pInodeBuf->ullSize);\r
+ #endif\r
+\r
+ ret = RedInodeDataTruncate(&ino, ullSize);\r
+\r
+ #if RESERVED_BLOCKS > 0U\r
+ gpRedCoreVol->fUseReservedBlocks = false;\r
+ #endif\r
+\r
+ RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* TRUNCATE_SUPPORTED */\r
+\r
+\r
+#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1)\r
+/** @brief Read from a directory.\r
+\r
+ If files are added to the directory after it is opened, the new files may\r
+ or may not be returned by this function. If files are deleted, the deleted\r
+ files will not be returned.\r
+\r
+ @param ulInode The directory inode to read from.\r
+ @param pulPos A token which stores the position within the directory. To\r
+ read from the beginning of the directory, populate with\r
+ zero.\r
+ @param pszName Pointer to a buffer which must be big enough to store a\r
+ maximum size name, including a null terminator. On\r
+ successful exit, populated with the name of the next\r
+ directory entry.\r
+ @param pulInode On successful return, populated with the inode number of the\r
+ next directory entry.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode number.\r
+ @retval -RED_EINVAL The volume is not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT There are no more entries in the directory.\r
+ @retval -RED_ENOTDIR @p ulInode refers to a file.\r
+*/\r
+REDSTATUS RedCoreDirRead(\r
+ uint32_t ulInode,\r
+ uint32_t *pulPos,\r
+ char *pszName,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = ulInode;\r
+ ret = RedInodeMount(&ino, FTYPE_DIR, false);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryRead(&ino, pulPos, pszName, pulInode);\r
+\r
+ #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0)\r
+ if((ret == 0) && !gpRedVolume->fReadOnly)\r
+ {\r
+ ret = RedInodeBranch(&ino);\r
+ }\r
+\r
+ RedInodePut(&ino, ((ret == 0) && !gpRedVolume->fReadOnly) ? IPUT_UPDATE_ATIME : 0U);\r
+ #else\r
+ RedInodePut(&ino, 0U);\r
+ #endif\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements directory operations.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_API_POSIX == 1\r
+\r
+#include <redcore.h>\r
+\r
+\r
+#define DIR_INDEX_INVALID UINT32_MAX\r
+\r
+#if (REDCONF_NAME_MAX % 4U) != 0U\r
+#define DIRENT_PADDING (4U - (REDCONF_NAME_MAX % 4U))\r
+#else\r
+#define DIRENT_PADDING (0U)\r
+#endif\r
+#define DIRENT_SIZE (4U + REDCONF_NAME_MAX + DIRENT_PADDING)\r
+#define DIRENTS_PER_BLOCK (REDCONF_BLOCK_SIZE / DIRENT_SIZE)\r
+#define DIRENTS_MAX (uint32_t)REDMIN(UINT32_MAX, UINT64_SUFFIX(1) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK)\r
+\r
+\r
+/** @brief On-disk directory entry.\r
+*/\r
+typedef struct\r
+{\r
+ /** The inode number that the directory entry points at. If the directory\r
+ entry is available, this holds INODE_INVALID.\r
+ */\r
+ uint32_t ulInode;\r
+\r
+ /** The name of the directory entry. For names shorter than\r
+ REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of\r
+ the maximum length, the string is not null terminated.\r
+ */\r
+ char acName[REDCONF_NAME_MAX];\r
+\r
+ #if DIRENT_PADDING > 0U\r
+ /** Unused padding so that ulInode is always aligned on a four-byte\r
+ boundary.\r
+ */\r
+ uint8_t abPadding[DIRENT_PADDING];\r
+ #endif\r
+} DIRENT;\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)\r
+static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen);\r
+static uint64_t DirEntryIndexToOffset(uint32_t ulIdx);\r
+#endif\r
+static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset);\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Create a new entry in a directory.\r
+\r
+ @param pPInode A pointer to the cached inode structure of the directory\r
+ to which the new entry will be added.\r
+ @param pszName The name to be given to the new entry, terminated by a\r
+ null or a path separator.\r
+ @param ulInode The inode number the new name will point at.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC There is not enough space on the volume to\r
+ create the new directory entry; or the directory\r
+ is full.\r
+ @retval -RED_ENOTDIR @p pPInode is not a directory.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_EEXIST @p pszName already exists in @p ulPInode.\r
+ @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode\r
+ structure; or @p pszName is not a valid name.\r
+*/\r
+REDSTATUS RedDirEntryCreate(\r
+ CINODE *pPInode,\r
+ const char *pszName,\r
+ uint32_t ulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!CINODE_IS_DIRTY(pPInode) || (pszName == NULL) || !INODE_IS_VALID(ulInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulNameLen = RedNameLen(pszName);\r
+\r
+ if(ulNameLen == 0U)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ulNameLen > REDCONF_NAME_MAX)\r
+ {\r
+ ret = -RED_ENAMETOOLONG;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulEntryIdx;\r
+\r
+ ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL);\r
+ if(ret == 0)\r
+ {\r
+ ret = -RED_EEXIST;\r
+ }\r
+ else if(ret == -RED_ENOENT)\r
+ {\r
+ if(ulEntryIdx == DIR_INDEX_INVALID)\r
+ {\r
+ ret = -RED_ENOSPC;\r
+ }\r
+ else\r
+ {\r
+ ret = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, no action.\r
+ */\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen);\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#if DELETE_SUPPORTED\r
+/** @brief Delete an existing directory entry.\r
+\r
+ @param pPInode A pointer to the cached inode structure of the directory\r
+ containing the entry to be deleted.\r
+ @param ulDeleteIdx Position within the directory of the entry to be\r
+ deleted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC The file system does not have enough space to modify\r
+ the parent directory to perform the deletion.\r
+ @retval -RED_ENOTDIR @p pPInode is not a directory.\r
+ @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode\r
+ structure; or @p ulIdx is out of range.\r
+*/\r
+REDSTATUS RedDirEntryDelete(\r
+ CINODE *pPInode,\r
+ uint32_t ulDeleteIdx)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_DIRTY(pPInode) || (ulDeleteIdx >= DIRENTS_MAX))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pInodeBuf->ullSize)\r
+ {\r
+ uint32_t ulTruncIdx = ulDeleteIdx;\r
+ bool fDone = false;\r
+\r
+ /* We are deleting the last dirent in the directory, so search\r
+ backwards to find the last populated dirent, allowing us to truncate\r
+ the directory to that point.\r
+ */\r
+ while((ret == 0) && (ulTruncIdx > 0U) && !fDone)\r
+ {\r
+ ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);\r
+ uint32_t ulBlockIdx = (ulTruncIdx - 1U) % DIRENTS_PER_BLOCK;\r
+\r
+ do\r
+ {\r
+ if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)\r
+ {\r
+ fDone = true;\r
+ break;\r
+ }\r
+\r
+ ulTruncIdx--;\r
+ ulBlockIdx--;\r
+ } while(ulBlockIdx != UINT32_MAX);\r
+ }\r
+ else if(ret == -RED_ENODATA)\r
+ {\r
+ ret = 0;\r
+\r
+ REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U);\r
+ ulTruncIdx -= DIRENTS_PER_BLOCK;\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, loop will terminate; nothing else\r
+ to be done.\r
+ */\r
+ }\r
+ }\r
+\r
+ /* Truncate the directory, deleting the requested entry and any empty\r
+ dirents at the end of the directory.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The dirent to delete is not the last entry in the directory, so just\r
+ zero it.\r
+ */\r
+ ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* DELETE_SUPPORTED */\r
+\r
+\r
+/** @brief Perform a case-sensitive search of a directory for a given name.\r
+\r
+ If found, then position of the entry within the directory and the inode\r
+ number it points to are returned. As an optimization for directory entry\r
+ creation, in the case where the requested entry does not exist, the position\r
+ of the first available (unused) entry is returned.\r
+\r
+ @param pPInode A pointer to the cached inode structure of the directory\r
+ to search.\r
+ @param pszName The name of the desired entry, terminated by either a\r
+ null or a path separator.\r
+ @param pulEntryIdx On successful return, meaning that the desired entry\r
+ exists, populated with the position of the entry. If\r
+ returning an -RED_ENOENT error, populated with the\r
+ position of the first available entry, or set to\r
+ DIR_INDEX_INVALID if the directory is full. Optional.\r
+ @param pulInode On successful return, populated with the inode number\r
+ that the name points to. Optional; may be `NULL`.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT @p pszName does not name an existing file or\r
+ directory.\r
+ @retval -RED_ENOTDIR @p pPInode is not a directory.\r
+ @retval -RED_EINVAL @p pPInode is not a mounted cached inode\r
+ structure; or @p pszName is not a valid name; or\r
+ @p pulEntryIdx is `NULL`.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+*/\r
+REDSTATUS RedDirEntryLookup(\r
+ CINODE *pPInode,\r
+ const char *pszName,\r
+ uint32_t *pulEntryIdx,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pPInode) || (pszName == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulNameLen = RedNameLen(pszName);\r
+\r
+ if(ulNameLen == 0U)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ulNameLen > REDCONF_NAME_MAX)\r
+ {\r
+ ret = -RED_ENAMETOOLONG;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx = 0U;\r
+ uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);\r
+ uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */\r
+\r
+ /* Loop over the directory blocks, searching each block for a\r
+ dirent that matches the given name.\r
+ */\r
+ while((ret == 0) && (ulIdx < ulDirentCount))\r
+ {\r
+ ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);\r
+ uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx);\r
+ uint32_t ulBlockIdx;\r
+\r
+ for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)\r
+ {\r
+ const DIRENT *pDirent = &pDirents[ulBlockIdx];\r
+\r
+ if(pDirent->ulInode != INODE_INVALID)\r
+ {\r
+ /* The name in the dirent will not be null\r
+ terminated if it is of the maximum length, so\r
+ use a bounded string compare and then make sure\r
+ there is nothing more to the name.\r
+ */\r
+ if( (RedStrNCmp(pDirent->acName, pszName, ulNameLen) == 0)\r
+ && ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->acName[ulNameLen] == '\0')))\r
+ {\r
+ /* Found a matching dirent, stop and return its\r
+ information.\r
+ */\r
+ if(pulInode != NULL)\r
+ {\r
+ *pulInode = pDirent->ulInode;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ *pulInode = RedRev32(*pulInode);\r
+ #endif\r
+ }\r
+\r
+ ulIdx += ulBlockIdx;\r
+ break;\r
+ }\r
+ }\r
+ else if(ulFreeIdx == DIR_INDEX_INVALID)\r
+ {\r
+ ulFreeIdx = ulIdx + ulBlockIdx;\r
+ }\r
+ else\r
+ {\r
+ /* The directory entry is free, but we already found a free one, so there's\r
+ nothing to do here.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(ulBlockIdx < ulBlockLastIdx)\r
+ {\r
+ /* If we broke out of the for loop, we found a matching\r
+ dirent and can stop the search.\r
+ */\r
+ break;\r
+ }\r
+\r
+ ulIdx += ulBlockLastIdx;\r
+ }\r
+ else if(ret == -RED_ENODATA)\r
+ {\r
+ if(ulFreeIdx == DIR_INDEX_INVALID)\r
+ {\r
+ ulFreeIdx = ulIdx;\r
+ }\r
+\r
+ ret = 0;\r
+ ulIdx += DIRENTS_PER_BLOCK;\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, let the loop terminate, no action\r
+ here.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* If we made it all the way to the end of the directory\r
+ without stopping, then the given name does not exist in the\r
+ directory.\r
+ */\r
+ if(ulIdx == ulDirentCount)\r
+ {\r
+ /* If the directory had no sparse dirents, then the first\r
+ free dirent is beyond the end of the directory. If the\r
+ directory is already the maximum size, then there is no\r
+ free dirent.\r
+ */\r
+ if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX))\r
+ {\r
+ ulFreeIdx = ulDirentCount;\r
+ }\r
+\r
+ ulIdx = ulFreeIdx;\r
+\r
+ ret = -RED_ENOENT;\r
+ }\r
+\r
+ if(pulEntryIdx != NULL)\r
+ {\r
+ *pulEntryIdx = ulIdx;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)\r
+/** @brief Read the next entry from a directory, given a starting index.\r
+\r
+ @param pInode A pointer to the cached inode structure of the directory to\r
+ read from.\r
+ @param pulIdx On entry, the directory index to start reading from. On\r
+ successful return, populated with the directory index to use\r
+ for subsequent reads. On -RED_ENOENT return, populated with\r
+ the directory index immediately following the last valid\r
+ one.\r
+ @param pszName On successful return, populated with the name of the next\r
+ directory entry. Buffer must be at least\r
+ REDCONF_NAME_MAX + 1 in size, to store the maximum name\r
+ length plus a null terminator.\r
+ @param pulInode On successful return, populated with the inode number\r
+ pointed at by the next directory entry.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT There are no more entries in the directory.\r
+ @retval -RED_ENOTDIR @p pPInode is not a directory.\r
+ @retval -RED_EINVAL @p pPInode is not a mounted cached inode structure;\r
+ or @p pszName is `NULL`; or @p pulIdx is `NULL`; or\r
+ @p pulInode is `NULL`.\r
+*/\r
+REDSTATUS RedDirEntryRead(\r
+ CINODE *pPInode,\r
+ uint32_t *pulIdx,\r
+ char *pszName,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pPInode) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx = *pulIdx;\r
+ uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);\r
+\r
+ /* Starting either at the beginning of the directory or where we left\r
+ off, loop over the directory blocks, searching each block for a\r
+ non-sparse dirent to return as the next entry in the directory.\r
+ */\r
+ while((ret == 0) && (ulIdx < ulDirentCount))\r
+ {\r
+ uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK;\r
+\r
+ ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);\r
+ uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK));\r
+ uint32_t ulBlockIdx;\r
+\r
+ for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)\r
+ {\r
+ if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)\r
+ {\r
+ *pulIdx = ulIdx + 1U;\r
+ RedStrNCpy(pszName, pDirents[ulBlockIdx].acName, REDCONF_NAME_MAX);\r
+ pszName[REDCONF_NAME_MAX] = '\0';\r
+\r
+ *pulInode = pDirents[ulBlockIdx].ulInode;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ *pulInode = RedRev32(*pulInode);\r
+ #endif\r
+ break;\r
+ }\r
+\r
+ ulIdx++;\r
+ }\r
+\r
+ if(ulBlockIdx < ulBlockLastIdx)\r
+ {\r
+ REDASSERT(ulIdx <= ulDirentCount);\r
+ break;\r
+ }\r
+ }\r
+ else if(ret == -RED_ENODATA)\r
+ {\r
+ ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK);\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, loop will terminate; nothing else to do.\r
+ */\r
+ }\r
+\r
+ REDASSERT(ulIdx <= ulDirentCount);\r
+ }\r
+\r
+ if((ret == 0) && (ulIdx >= ulDirentCount))\r
+ {\r
+ *pulIdx = ulDirentCount;\r
+ ret = -RED_ENOENT;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)\r
+/** Rename a directory entry.\r
+\r
+ @param pSrcPInode The inode of the directory containing @p pszSrcName.\r
+ @param pszSrcName The name of the directory entry to be renamed.\r
+ @param pSrcInode On successful return, populated with the inode of the\r
+ source entry.\r
+ @param pDstPInode The inode of the directory in which @p pszDstName will\r
+ be created or replaced.\r
+ @param pszDstName The name of the directory entry to be created or\r
+ replaced.\r
+ @param pDstInode On successful return, if the destination previously\r
+ existed, populated with the inode previously pointed to\r
+ by the destination. This may be the same as the source\r
+ inode. If the destination did not exist, populated with\r
+ INODE_INVALID.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EEXIST #REDCONF_RENAME_ATOMIC is false and the\r
+ destination name exists.\r
+ @retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached\r
+ inode structure; or @p pSrcInode is `NULL`; or\r
+ @p pszSrcName is not a valid name; or\r
+ @p pDstPInode is not a mounted dirty cached\r
+ inode structure; or @p pDstInode is `NULL`; or\r
+ @p pszDstName is not a valid name.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR The destination name exists and is a directory,\r
+ and the source name is a non-directory.\r
+ @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer\r
+ than #REDCONF_NAME_MAX.\r
+ @retval -RED_ENOENT The source name is not an existing entry; or\r
+ either @p pszSrcName or @p pszDstName point to\r
+ an empty string.\r
+ @retval -RED_ENOTDIR @p pSrcPInode is not a directory; or\r
+ @p pDstPInode is not a directory; or the source\r
+ name is a directory and the destination name is\r
+ a file.\r
+ @retval -RED_ENOTEMPTY The destination name is a directory which is not\r
+ empty.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ extend the @p ulDstPInode directory.\r
+ @retval -RED_EROFS The directory to be removed resides on a\r
+ read-only file system.\r
+*/\r
+REDSTATUS RedDirEntryRename(\r
+ CINODE *pSrcPInode,\r
+ const char *pszSrcName,\r
+ CINODE *pSrcInode,\r
+ CINODE *pDstPInode,\r
+ const char *pszDstName,\r
+ CINODE *pDstInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( !CINODE_IS_DIRTY(pSrcPInode)\r
+ || (pszSrcName == NULL)\r
+ || (pSrcInode == NULL)\r
+ || !CINODE_IS_DIRTY(pDstPInode)\r
+ || (pszDstName == NULL)\r
+ || (pDstInode == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pSrcPInode->fDirectory || !pDstPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */\r
+ uint32_t ulSrcIdx;\r
+\r
+ /* Look up the source and destination names.\r
+ */\r
+ ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode);\r
+\r
+ if(ret == -RED_ENOENT)\r
+ {\r
+ if(ulDstIdx == DIR_INDEX_INVALID)\r
+ {\r
+ ret = -RED_ENOSPC;\r
+ }\r
+ else\r
+ {\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ pDstInode->ulInode = INODE_INVALID;\r
+ #endif\r
+ ret = 0;\r
+ }\r
+ }\r
+ #if REDCONF_RENAME_ATOMIC == 0\r
+ else if(ret == 0)\r
+ {\r
+ ret = -RED_EEXIST;\r
+ }\r
+ else\r
+ {\r
+ /* Nothing to do here, just propagate the error.\r
+ */\r
+ }\r
+ #endif\r
+ }\r
+\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ /* If both names point to the same inode, POSIX says to do nothing to\r
+ either name.\r
+ */\r
+ if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode))\r
+ #else\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true);\r
+\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ if((ret == 0) && (pDstInode->ulInode != INODE_INVALID))\r
+ {\r
+ /* Source and destination must be the same type (file/dir).\r
+ */\r
+ ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true);\r
+\r
+ /* If renaming directories, the destination must be empty.\r
+ */\r
+ if((ret == 0) && pDstInode->fDirectory && (pDstInode->pInodeBuf->ullSize > 0U))\r
+ {\r
+ ret = -RED_ENOTEMPTY;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ /* If we are renaming a directory, make sure the rename isn't\r
+ cyclic (e.g., renaming "foo" into "foo/bar").\r
+ */\r
+ if((ret == 0) && pSrcInode->fDirectory)\r
+ {\r
+ ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName));\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx);\r
+\r
+ if(ret == -RED_ENOSPC)\r
+ {\r
+ REDSTATUS ret2;\r
+\r
+ /* If there was not enough space to branch the parent\r
+ directory inode and data block containin the source\r
+ entry, revert destination directory entry to its\r
+ previous state.\r
+ */\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ if(pDstInode->ulInode != INODE_INVALID)\r
+ {\r
+ ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName));\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx);\r
+ }\r
+\r
+ if(ret2 != 0)\r
+ {\r
+ ret = ret2;\r
+ CRITICAL_ERROR();\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Check for a cyclic rename.\r
+\r
+ A cyclic rename is renaming a directory into a subdirectory of itself. For\r
+ example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be\r
+ allowed since they would corrupt the directory tree.\r
+\r
+ @param ulSrcInode The inode number of the directory being renamed.\r
+ @param pDstPInode A pointer to the cached inode structure of the directory\r
+ into which the source is being renamed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL The rename is cyclic; or invalid parameters.\r
+ @retval -RED_ENOTDIR @p pDstPInode is not a directory.\r
+*/\r
+static REDSTATUS DirCyclicRenameCheck(\r
+ uint32_t ulSrcInode,\r
+ const CINODE *pDstPInode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!INODE_IS_VALID(ulSrcInode) || !CINODE_IS_MOUNTED(pDstPInode))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ulSrcInode == pDstPInode->ulInode)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pDstPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ CINODE NextParent;\r
+ /* Used to prevent infinite loop in case of corrupted directory\r
+ structure.\r
+ */\r
+ uint32_t ulIteration = 0U;\r
+\r
+ NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode;\r
+\r
+ while( (NextParent.ulInode != ulSrcInode)\r
+ && (NextParent.ulInode != INODE_ROOTDIR)\r
+ && (NextParent.ulInode != INODE_INVALID)\r
+ && (ulIteration < gpRedVolConf->ulInodeCount))\r
+ {\r
+ ret = RedInodeMount(&NextParent, FTYPE_DIR, false);\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ NextParent.ulInode = NextParent.pInodeBuf->ulPInode;\r
+\r
+ RedInodePut(&NextParent, 0U);\r
+\r
+ ulIteration++;\r
+ }\r
+\r
+ if((ret == 0) && (ulIteration == gpRedVolConf->ulInodeCount))\r
+ {\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+\r
+ if((ret == 0) && (ulSrcInode == NextParent.ulInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Update the contents of a directory entry.\r
+\r
+ @param pPInode A pointer to the cached inode structure of the directory\r
+ whose entry is being written.\r
+ @param ulIdx The index of the directory entry to write.\r
+ @param ulInode The inode number the directory entry is to point at.\r
+ @param pszName The name of the directory entry.\r
+ @param ulNameLen The length of @p pszName.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC There is not enough space on the volume to write the\r
+ directory entry.\r
+ @retval -RED_ENOTDIR @p pPInode is not a directory.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS DirEntryWrite(\r
+ CINODE *pPInode,\r
+ uint32_t ulIdx,\r
+ uint32_t ulInode,\r
+ const char *pszName,\r
+ uint32_t ulNameLen)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( !CINODE_IS_DIRTY(pPInode)\r
+ || (ulIdx >= DIRENTS_MAX)\r
+ || (!INODE_IS_VALID(ulInode) && (ulInode != INODE_INVALID))\r
+ || (pszName == NULL)\r
+ || (ulNameLen > REDCONF_NAME_MAX)\r
+ || ((ulNameLen == 0U) != (ulInode == INODE_INVALID)))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pPInode->fDirectory)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint64_t ullOffset = DirEntryIndexToOffset(ulIdx);\r
+ uint32_t ulLen = DIRENT_SIZE;\r
+ static DIRENT de;\r
+\r
+ RedMemSet(&de, 0U, sizeof(de));\r
+\r
+ de.ulInode = ulInode;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ de.ulInode = RedRev32(de.ulInode);\r
+ #endif\r
+\r
+ RedStrNCpy(de.acName, pszName, ulNameLen);\r
+\r
+ ret = RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Convert a directory entry index to a byte offset.\r
+\r
+ @param ulIdx Directory entry index.\r
+\r
+ @return Byte offset in the directory corresponding with ulIdx.\r
+*/\r
+static uint64_t DirEntryIndexToOffset(\r
+ uint32_t ulIdx)\r
+{\r
+ uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK;\r
+ uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK;\r
+ uint64_t ullOffset;\r
+\r
+ REDASSERT(ulIdx < DIRENTS_MAX);\r
+\r
+ ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2;\r
+ ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE;\r
+\r
+ return ullOffset;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Convert a byte offset to a directory entry index.\r
+\r
+ @param ullOffset Byte offset in the directory.\r
+\r
+ @return Directory entry index corresponding with @p ullOffset.\r
+*/\r
+static uint32_t DirOffsetToEntryIndex(\r
+ uint64_t ullOffset)\r
+{\r
+ uint32_t ulIdx;\r
+\r
+ REDASSERT(ullOffset < INODE_SIZE_MAX);\r
+ REDASSERT(((uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) % DIRENT_SIZE) == 0U);\r
+\r
+ /* Avoid doing any 64-bit divides.\r
+ */\r
+ ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK;\r
+ ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE;\r
+\r
+ return ulIdx;\r
+}\r
+\r
+\r
+#endif /* REDCONF_API_POSIX == 1 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements the Reliance Edge file system formatter.\r
+*/\r
+#include <redfs.h>\r
+#include <redcoreapi.h>\r
+#include <redcore.h>\r
+\r
+#if FORMAT_SUPPORTED\r
+\r
+\r
+/** @brief Format a file system volume.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBUSY Volume is mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedVolFormat(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->fMounted)\r
+ {\r
+ ret = -RED_EBUSY;\r
+ }\r
+ else\r
+ {\r
+ ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ MASTERBLOCK *pMB;\r
+ REDSTATUS ret2;\r
+\r
+ /* Overwrite the master block with zeroes, so that if formatting is\r
+ interrupted, the volume will not be mountable.\r
+ */\r
+ ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB));\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);\r
+\r
+ RedBufferDiscard(pMB);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoFlush(gbRedVolNum);\r
+ }\r
+\r
+ #if REDCONF_IMAP_EXTERNAL == 1\r
+ if((ret == 0) && !gpRedCoreVol->fImapInline)\r
+ {\r
+ uint32_t ulImapBlock;\r
+ uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U);\r
+ uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY);\r
+\r
+ /* Technically it is only necessary to create one copy of each imap\r
+ node (the copy the metaroot points at), but creating them both\r
+ avoids headaches during disk image analysis from stale imaps\r
+ left over from previous formats.\r
+ */\r
+ for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++)\r
+ {\r
+ IMAPNODE *pImap;\r
+\r
+ ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap));\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ RedBufferPut(pImap);\r
+ }\r
+ }\r
+ #endif\r
+\r
+ /* Write the first metaroot.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR));\r
+\r
+ gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable;\r
+ #if REDCONF_API_POSIX == 1\r
+ gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount;\r
+ #endif\r
+ gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;\r
+\r
+ /* The branched flag is typically set automatically when bits in\r
+ the imap change. It is set here explicitly because the imap has\r
+ only been initialized, not changed.\r
+ */\r
+ gpRedCoreVol->fBranched = true;\r
+\r
+ ret = RedVolTransact();\r
+ }\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ /* Create the root directory.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ CINODE rootdir;\r
+\r
+ rootdir.ulInode = INODE_ROOTDIR;\r
+ ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR);\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedInodePut(&rootdir, 0U);\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if REDCONF_API_FSE == 1\r
+ /* The FSE API does not support creating or deletes files, so all the\r
+ inodes are created during setup.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulInodeIdx;\r
+\r
+ for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++)\r
+ {\r
+ CINODE ino;\r
+\r
+ ino.ulInode = INODE_FIRST_FREE + ulInodeIdx;\r
+ ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG);\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedInodePut(&ino, 0U);\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ /* Write the second metaroot.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedVolTransact();\r
+ }\r
+\r
+ /* Populate and write out the master block.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB));\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pMB->ulVersion = RED_DISK_LAYOUT_VERSION;\r
+ RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum));\r
+ pMB->ulFormatTime = RedOsClockGetTime();\r
+ pMB->ulInodeCount = gpRedVolConf->ulInodeCount;\r
+ pMB->ulBlockCount = gpRedVolume->ulBlockCount;\r
+ pMB->uMaxNameLen = REDCONF_NAME_MAX;\r
+ pMB->uDirectPointers = REDCONF_DIRECT_POINTERS;\r
+ pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS;\r
+ pMB->bBlockSizeP2 = BLOCK_SIZE_P2;\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ pMB->bFlags |= MBFLAG_API_POSIX;\r
+ #endif\r
+ #if REDCONF_INODE_TIMESTAMPS == 1\r
+ pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS;\r
+ #endif\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ pMB->bFlags |= MBFLAG_INODE_BLOCKS;\r
+ #endif\r
+ #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+ pMB->bFlags |= MBFLAG_INODE_NLINK;\r
+ #endif\r
+\r
+ ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);\r
+\r
+ RedBufferPut(pMB);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoFlush(gbRedVolNum);\r
+ }\r
+\r
+ ret2 = RedOsBDevClose(gbRedVolNum);\r
+ if(ret == 0)\r
+ {\r
+ ret = ret2;\r
+ }\r
+ }\r
+\r
+ /* Discard the buffers so a subsequent format will not run into blocks it\r
+ does not expect.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#endif /* FORMAT_SUPPORTED */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements allocation routines.\r
+\r
+ This module implements routines for working with the imap, a bitmap which\r
+ tracks which blocks are allocated or free. Some of the functionality is\r
+ delegated to imapinline.c and imapextern.c.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+/** @brief Get the allocation bit of a block from either metaroot.\r
+\r
+ Will pass the call down either to the inline imap or to the external imap\r
+ implementation, whichever is appropriate for the current volume.\r
+\r
+ @param bMR The metaroot index: either 0 or 1.\r
+ @param ulBlock The block number to query.\r
+ @param pfAllocated On successful return, populated with the allocation bit\r
+ of the block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;\r
+ or @p pfAllocated is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedImapBlockGet(\r
+ uint8_t bMR,\r
+ uint32_t ulBlock,\r
+ bool *pfAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (bMR > 1U)\r
+ || (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount)\r
+ || (pfAllocated == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)\r
+ if(gpRedCoreVol->fImapInline)\r
+ {\r
+ ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);\r
+ }\r
+ else\r
+ {\r
+ ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);\r
+ }\r
+ #elif REDCONF_IMAP_INLINE == 1\r
+ ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);\r
+ #else\r
+ ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);\r
+ #endif\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Set the allocation bit of a block in the working metaroot.\r
+\r
+ Will pass the call down either to the inline imap or to the external imap\r
+ implementation, whichever is appropriate for the current volume.\r
+\r
+ @param ulBlock The block number to allocate or free.\r
+ @param fAllocated Whether to allocate the block (true) or free it (false).\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable\r
+ and @p fAllocated is 1.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedImapBlockSet(\r
+ uint32_t ulBlock,\r
+ bool fAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)\r
+ && ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U))\r
+ || ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable))))\r
+ {\r
+ /* Attempting either to free more blocks than are allocable, or\r
+ allocate a block when there are none available. This could indicate\r
+ metadata corruption.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)\r
+ if(gpRedCoreVol->fImapInline)\r
+ {\r
+ ret = RedImapIBlockSet(ulBlock, fAllocated);\r
+ }\r
+ else\r
+ {\r
+ ret = RedImapEBlockSet(ulBlock, fAllocated);\r
+ }\r
+ #elif REDCONF_IMAP_INLINE == 1\r
+ ret = RedImapIBlockSet(ulBlock, fAllocated);\r
+ #else\r
+ ret = RedImapEBlockSet(ulBlock, fAllocated);\r
+ #endif\r
+\r
+ /* Any change to the allocation state of a block indicates that the\r
+ volume is now branched.\r
+ */\r
+ gpRedCoreVol->fBranched = true;\r
+ }\r
+\r
+ /* If a block was marked as no longer in use, discard it from the buffers.\r
+ */\r
+ if((ret == 0) && (!fAllocated))\r
+ {\r
+ ret = RedBufferDiscardRange(ulBlock, 1U);\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+\r
+ /* Adjust the free/almost free block count if the block was allocable.\r
+ */\r
+ if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN))\r
+ {\r
+ if(fAllocated)\r
+ {\r
+ gpRedMR->ulFreeBlocks--;\r
+ }\r
+ else\r
+ {\r
+ bool fWasAllocated;\r
+\r
+ /* Whether the block became free or almost free depends on its\r
+ previous allocation state. If it was used, then it is now\r
+ almost free. Otherwise, it was new and is now free.\r
+ */\r
+ ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated);\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fWasAllocated)\r
+ {\r
+ gpRedCoreVol->ulAlmostFreeBlocks++;\r
+ }\r
+ else\r
+ {\r
+ gpRedMR->ulFreeBlocks++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Allocate one block.\r
+\r
+ @param pulBlock On successful return, populated with the allocated block\r
+ number.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pulBlock is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the allocation.\r
+*/\r
+REDSTATUS RedImapAllocBlock(\r
+ uint32_t *pulBlock)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pulBlock == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedMR->ulFreeBlocks == 0U)\r
+ {\r
+ ret = -RED_ENOSPC;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock;\r
+ bool fAllocated = false;\r
+\r
+ do\r
+ {\r
+ ALLOCSTATE state;\r
+\r
+ ret = RedImapBlockState(gpRedMR->ulAllocNextBlock, &state);\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(state == ALLOCSTATE_FREE)\r
+ {\r
+ ret = RedImapBlockSet(gpRedMR->ulAllocNextBlock, true);\r
+ CRITICAL_ASSERT(ret == 0);\r
+\r
+ *pulBlock = gpRedMR->ulAllocNextBlock;\r
+ fAllocated = true;\r
+ }\r
+\r
+ /* Increment the next block number, wrapping it when the end of\r
+ the volume is reached.\r
+ */\r
+ gpRedMR->ulAllocNextBlock++;\r
+ if(gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount)\r
+ {\r
+ gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;\r
+ }\r
+ }\r
+ }\r
+ while((ret == 0) && !fAllocated && (gpRedMR->ulAllocNextBlock != ulStopBlock));\r
+\r
+ if((ret == 0) && !fAllocated)\r
+ {\r
+ /* The free block count was already determined to be non-zero, no\r
+ error occurred while looking for free blocks, but no free blocks\r
+ were found. This indicates metadata corruption.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Get the allocation state of a block.\r
+\r
+ Takes into account the allocation bits from both metaroots, and returns one\r
+ of four possible allocation state values:\r
+\r
+ - ::ALLOCSTATE_FREE Free and may be allocated; writeable.\r
+ - ::ALLOCSTATE_USED In-use and transacted; not writeable.\r
+ - ::ALLOCSTATE_NEW In-use but not transacted; writeable.\r
+ - ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable.\r
+\r
+ @param ulBlock The block number to query.\r
+ @param pState On successful return, populated with the state of the block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedImapBlockState(\r
+ uint32_t ulBlock,\r
+ ALLOCSTATE *pState)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount)\r
+ || (pState == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fBitCurrent;\r
+\r
+ ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent);\r
+\r
+ if(ret == 0)\r
+ {\r
+ bool fBitOld;\r
+\r
+ ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fBitCurrent)\r
+ {\r
+ if(fBitOld)\r
+ {\r
+ *pState = ALLOCSTATE_USED;\r
+ }\r
+ else\r
+ {\r
+ *pState = ALLOCSTATE_NEW;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(fBitOld)\r
+ {\r
+ *pState = ALLOCSTATE_AFREE;\r
+ }\r
+ else\r
+ {\r
+ *pState = ALLOCSTATE_FREE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements routines for the external imap.\r
+\r
+ The external imap is used on volumes that are too big for the imap bitmap\r
+ to be stored entirely in the metaroot, so instead the bitmap is stored in\r
+ imap nodes on disk, and the metaroot bitmap is used to toggle between imap\r
+ nodes.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_IMAP_EXTERNAL == 1\r
+\r
+#include <redcore.h>\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap);\r
+static bool ImapNodeIsBranched(uint32_t ulImapNode);\r
+#endif\r
+\r
+\r
+/** @brief Get the allocation bit of a block from the imap as it exists in\r
+ either metaroot.\r
+\r
+ @param bMR The metaroot index: either 0 or 1.\r
+ @param ulBlock The block number to query.\r
+ @param pfAllocated On successful exit, populated with the allocation bit\r
+ of the block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;\r
+ or @p pfAllocated is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedImapEBlockGet(\r
+ uint8_t bMR,\r
+ uint32_t ulBlock,\r
+ bool *pfAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( gpRedCoreVol->fImapInline\r
+ || (bMR > 1U)\r
+ || (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount)\r
+ || (pfAllocated == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;\r
+ uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;\r
+ uint8_t bMRToRead = bMR;\r
+ IMAPNODE *pImap;\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ /* If the imap node is not branched, then both copies of the imap are\r
+ identical. If the old metaroot copy is requested, use the current\r
+ copy instead, since it is more likely to be buffered.\r
+ */\r
+ if(bMR == (1U - gpRedCoreVol->bCurMR))\r
+ {\r
+ if(!ImapNodeIsBranched(ulImapNode))\r
+ {\r
+ bMRToRead = 1U - bMR;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap));\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES);\r
+\r
+ RedBufferPut(pImap);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Set the allocation bit of a block in the working-state imap.\r
+\r
+ @param ulBlock The block number to allocate or free.\r
+ @param fAllocated Whether to allocate the block (true) or free it (false).\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulBlock is out of range.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedImapEBlockSet(\r
+ uint32_t ulBlock,\r
+ bool fAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( gpRedCoreVol->fImapInline\r
+ || (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;\r
+ uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;\r
+ IMAPNODE *pImap;\r
+\r
+ ret = ImapNodeBranch(ulImapNode, &pImap);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES;\r
+\r
+ if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated)\r
+ {\r
+ /* The driver shouldn't ever set a bit in the imap to its\r
+ current value. That shouldn't ever be needed, and it\r
+ indicates that the driver is doing unnecessary I/O, or\r
+ that the imap is corrupt.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else if(fAllocated)\r
+ {\r
+ RedBitSet(pImap->abEntries, ulImapEntry);\r
+ }\r
+ else\r
+ {\r
+ RedBitClear(pImap->abEntries, ulImapEntry);\r
+ }\r
+\r
+ RedBufferPut(pImap);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Branch an imap node and get a buffer for it.\r
+\r
+ If the imap node is already branched, it can be overwritten in its current\r
+ location, and this function just gets it buffered dirty. If the node is not\r
+ already branched, the metaroot must be updated to toggle the imap node to\r
+ its alternate location, thereby preserving the committed state copy of the\r
+ imap node.\r
+\r
+ @param ulImapNode The imap node to branch and buffer.\r
+ @param ppImap On successful return, populated with the imap node\r
+ buffer, which will be marked dirty.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS ImapNodeBranch(\r
+ uint32_t ulImapNode,\r
+ IMAPNODE **ppImap)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ImapNodeIsBranched(ulImapNode))\r
+ {\r
+ /* Imap node is already branched, so just get it buffered dirty.\r
+ */\r
+ ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap));\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulBlockCurrent;\r
+ uint32_t ulBlockOld;\r
+\r
+ /* The metaroot currently points to the committed state imap node.\r
+ Toggle the metaroot to point at the alternate, writeable location.\r
+ */\r
+ if(RedBitGet(gpRedMR->abEntries, ulImapNode))\r
+ {\r
+ RedBitClear(gpRedMR->abEntries, ulImapNode);\r
+ }\r
+ else\r
+ {\r
+ RedBitSet(gpRedMR->abEntries, ulImapNode);\r
+ }\r
+\r
+ ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode);\r
+ ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode);\r
+\r
+ ret = RedBufferDiscardRange(ulBlockCurrent, 1U);\r
+\r
+ /* Buffer the committed copy then reassign the block number to the\r
+ writeable location. This also dirties the buffer.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap));\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedBufferBranch(*ppImap, ulBlockCurrent);\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Determine whether an imap node is branched.\r
+\r
+ If the imap node is branched, it can be overwritten in its current location.\r
+\r
+ @param ulImapNode The imap node to examine.\r
+\r
+ @return Whether the imap node is branched.\r
+*/\r
+static bool ImapNodeIsBranched(\r
+ uint32_t ulImapNode)\r
+{\r
+ bool fNodeBitSetInMetaroot0 = RedBitGet(gpRedCoreVol->aMR[0U].abEntries, ulImapNode);\r
+ bool fNodeBitSetInMetaroot1 = RedBitGet(gpRedCoreVol->aMR[1U].abEntries, ulImapNode);\r
+\r
+ /* If the imap node is not branched, both metaroots will point to the same\r
+ copy of the node.\r
+ */\r
+ return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Calculate the block number of the imap node location indicated by the\r
+ given metaroot.\r
+\r
+ An imap node has two locations on disk. A bit in the metaroot bitmap\r
+ indicates which location is the valid one, according to that metaroot. This\r
+ function returns the block number of the imap node which is valid in the\r
+ given metaroot.\r
+\r
+ @param bMR Which metaroot to examine.\r
+ @param ulImapNode The imap node for which to calculate the block number.\r
+\r
+ @return Block number of the imap node, as indicated by the given metaroot.\r
+*/\r
+uint32_t RedImapNodeBlock(\r
+ uint8_t bMR,\r
+ uint32_t ulImapNode)\r
+{\r
+ uint32_t ulBlock;\r
+\r
+ REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount);\r
+\r
+ ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U);\r
+\r
+ if(bMR > 1U)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode))\r
+ {\r
+ /* Bit is set, so point ulBlock at the second copy of the node.\r
+ */\r
+ ulBlock++;\r
+ }\r
+ else\r
+ {\r
+ /* ulBlock already points at the first copy of the node.\r
+ */\r
+ }\r
+\r
+ return ulBlock;\r
+}\r
+\r
+#endif /* REDCONF_IMAP_EXTERNAL == 1 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements routines for the inline imap.\r
+\r
+ The inline imap is used on volumes that are small enough for the imap bitmap\r
+ to be entirely contained within the metaroot.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_IMAP_INLINE == 1\r
+\r
+#include <redcore.h>\r
+\r
+\r
+/** @brief Get the allocation bit of a block from either metaroot.\r
+\r
+ @param bMR The metaroot index: either 0 or 1.\r
+ @param ulBlock The block number to query.\r
+ @param pfAllocated On successful return, populated with the allocation bit\r
+ of the block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;\r
+ @p pfAllocated is `NULL`; or the current volume does not\r
+ use the inline imap.\r
+*/\r
+REDSTATUS RedImapIBlockGet(\r
+ uint8_t bMR,\r
+ uint32_t ulBlock,\r
+ bool *pfAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (!gpRedCoreVol->fImapInline)\r
+ || (bMR > 1U)\r
+ || (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount)\r
+ || (pfAllocated == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ *pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN);\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Set the allocation bit of a block in the working metaroot.\r
+\r
+ @param ulBlock The block number to allocate or free.\r
+ @param fAllocated Whether to allocate the block (true) or free it (false).\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulBlock is out of range; or the current volume does\r
+ not use the inline imap.\r
+*/\r
+REDSTATUS RedImapIBlockSet(\r
+ uint32_t ulBlock,\r
+ bool fAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if( (!gpRedCoreVol->fImapInline)\r
+ || (ulBlock < gpRedCoreVol->ulInodeTableStartBN)\r
+ || (ulBlock >= gpRedVolume->ulBlockCount))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;\r
+\r
+ if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated)\r
+ {\r
+ /* The driver shouldn't ever set a bit in the imap to its current\r
+ value. This is more of a problem with the external imap, but it\r
+ is checked here for consistency.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else if(fAllocated)\r
+ {\r
+ RedBitSet(gpRedMR->abEntries, ulOffset);\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ RedBitClear(gpRedMR->abEntries, ulOffset);\r
+ ret = 0;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+#endif /* REDCONF_IMAP_INLINE == 1 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements inode functions.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS InodeIsBranched(uint32_t ulInode, bool *pfIsBranched);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+static REDSTATUS InodeFindFree(uint32_t *pulInode);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS InodeGetWriteableCopy(uint32_t ulInode, uint8_t *pbWhich);\r
+#endif\r
+static REDSTATUS InodeGetCurrentCopy(uint32_t ulInode, uint8_t *pbWhich);\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS InodeBitSet(uint32_t ulInode, uint8_t bWhich, bool fAllocated);\r
+#endif\r
+static uint32_t InodeBlock(uint32_t ulInode, uint8_t bWhich);\r
+\r
+\r
+/** @brief Mount an existing inode.\r
+\r
+ Will populate all fields of the cached inode structure, except those which\r
+ are populated during seek.\r
+\r
+ @param pInode A pointer to the cached inode structure. The\r
+ pInode->ulInode field must already be initialized with the\r
+ inode number to mount. All other fields will be discarded.\r
+ @param type The expected inode type.\r
+ @param fBranch Whether to branch the inode.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+ @retval -RED_EROFS @p fBranch is true but the driver is read-only.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EBADF The inode number is free; or the inode number is not\r
+ valid.\r
+ @retval -RED_EISDIR @p type is ::FTYPE_FILE and the inode is a directory.\r
+ @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the inode is a file.\r
+*/\r
+REDSTATUS RedInodeMount(\r
+ CINODE *pInode,\r
+ FTYPE type,\r
+ bool fBranch)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(pInode == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!INODE_IS_VALID(pInode->ulInode))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+ #if REDCONF_API_FSE == 1\r
+ else if(type == FTYPE_DIR)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #endif\r
+ #if REDCONF_READ_ONLY == 1\r
+ else if(fBranch)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EROFS;\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ uint32_t ulInode = pInode->ulInode;\r
+ uint8_t bWhich = 0U; /* Init'd to quiet warnings. */\r
+\r
+ RedMemSet(pInode, 0U, sizeof(*pInode));\r
+ pInode->ulInode = ulInode;\r
+\r
+ ret = InodeGetCurrentCopy(pInode->ulInode, &bWhich);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferGet(InodeBlock(pInode->ulInode, bWhich), BFLAG_META_INODE, CAST_VOID_PTR_PTR(&pInode->pInodeBuf));\r
+ }\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(ret == 0)\r
+ {\r
+ ret = InodeIsBranched(pInode->ulInode, &pInode->fBranched);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(RED_S_ISREG(pInode->pInodeBuf->uMode))\r
+ {\r
+ #if REDCONF_API_POSIX == 1\r
+ pInode->fDirectory = false;\r
+\r
+ if(type == FTYPE_DIR)\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ #endif\r
+ }\r
+ #if REDCONF_API_POSIX == 1\r
+ else if(RED_S_ISDIR(pInode->pInodeBuf->uMode))\r
+ {\r
+ pInode->fDirectory = true;\r
+\r
+ if(type == FTYPE_FILE)\r
+ {\r
+ ret = -RED_EISDIR;\r
+ }\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ /* Missing or unsupported inode type.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ }\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ if((ret == 0) && fBranch)\r
+ {\r
+ ret = RedInodeBranch(pInode);\r
+ }\r
+ #endif\r
+\r
+ if(ret != 0)\r
+ {\r
+ RedInodePut(pInode, 0U);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)\r
+/** @brief Create an inode.\r
+\r
+ @param pInode Pointer to the cached inode structure. If pInode->ulInode\r
+ is #INODE_INVALID, a free inode will be found; otherwise,\r
+ pInode->ulInode will be the inode number (an error will be\r
+ returned if it is not free).\r
+ @param ulPInode The parent inode number.\r
+ @param uMode The inode mode.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF pInode->ulInode is an invalid inode number other than\r
+ #INODE_INVALID.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+ @retval -RED_EEXIST Tried to create an inode with an inode number that is\r
+ already in use.\r
+ @retval -RED_ENFILE All inode slots are already in use.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeCreate(\r
+ CINODE *pInode,\r
+ uint32_t ulPInode,\r
+ uint16_t uMode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ /* ulPInode must be a valid inode number, unless we are creating the root\r
+ directory, in which case ulPInode must be INODE_INVALID (the root\r
+ directory has no parent).\r
+ */\r
+ if( (pInode == NULL)\r
+ || (!INODE_IS_VALID(ulPInode) && ((ulPInode != INODE_INVALID) || (pInode->ulInode != INODE_ROOTDIR))))\r
+ #else\r
+ if(pInode == NULL)\r
+ #endif\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulInode = pInode->ulInode;\r
+\r
+ RedMemSet(pInode, 0U, sizeof(*pInode));\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ if(ulInode == INODE_INVALID)\r
+ {\r
+ /* Caller requested that an inode number be allocated. Search for\r
+ an unused inode number, error if there isn't one.\r
+ */\r
+ ret = InodeFindFree(&pInode->ulInode);\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ /* Caller requested creation of a specific inode number. Make sure\r
+ it's valid and doesn't already exist.\r
+ */\r
+ if(INODE_IS_VALID(ulInode))\r
+ {\r
+ bool fFree;\r
+\r
+ ret = RedInodeIsFree(ulInode, &fFree);\r
+ if(ret == 0)\r
+ {\r
+ if(fFree)\r
+ {\r
+ pInode->ulInode = ulInode;\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EEXIST;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bWriteableWhich;\r
+\r
+ ret = InodeGetWriteableCopy(pInode->ulInode, &bWriteableWhich);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedBufferGet(InodeBlock(pInode->ulInode, bWriteableWhich),\r
+ (uint16_t)((uint32_t)BFLAG_META_INODE | BFLAG_DIRTY | BFLAG_NEW), CAST_VOID_PTR_PTR(&pInode->pInodeBuf));\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Mark the inode block as allocated.\r
+ */\r
+ ret = InodeBitSet(pInode->ulInode, bWriteableWhich, true);\r
+\r
+ if(ret != 0)\r
+ {\r
+ RedBufferPut(pInode->pInodeBuf);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ #if REDCONF_INODE_TIMESTAMPS == 1\r
+ uint32_t ulNow = RedOsClockGetTime();\r
+\r
+ pInode->pInodeBuf->ulATime = ulNow;\r
+ pInode->pInodeBuf->ulMTime = ulNow;\r
+ pInode->pInodeBuf->ulCTime = ulNow;\r
+ #endif\r
+\r
+ pInode->pInodeBuf->uMode = uMode;\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ #if REDCONF_API_POSIX_LINK == 1\r
+ pInode->pInodeBuf->uNLink = 1U;\r
+ #endif\r
+ pInode->pInodeBuf->ulPInode = ulPInode;\r
+ #else\r
+ (void)ulPInode;\r
+ #endif\r
+\r
+ pInode->fBranched = true;\r
+ pInode->fDirty = true;\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ gpRedMR->ulFreeInodes--;\r
+ #endif\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED) */\r
+\r
+\r
+#if DELETE_SUPPORTED\r
+/** @brief Delete an inode.\r
+\r
+ @param pInode Pointer to the cached inode structure.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF The inode is free.\r
+ @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeDelete(\r
+ CINODE *pInode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ if(pInode->pInodeBuf->ullSize != 0U)\r
+ {\r
+ ret = RedInodeDataTruncate(pInode, UINT64_SUFFIX(0));\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedInodeFree(pInode);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Decrement an inode link count and delete the inode if the link count\r
+ falls to zero.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pInode is not a mounted cachde inode.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeLinkDec(\r
+ CINODE *pInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #if REDCONF_API_POSIX_LINK == 1\r
+ else if(pInode->pInodeBuf->uNLink > 1U)\r
+ {\r
+ ret = RedInodeBranch(pInode);\r
+\r
+ if(ret == 0)\r
+ {\r
+ pInode->pInodeBuf->uNLink--;\r
+ }\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ ret = RedInodeDelete(pInode);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* DELETE_SUPPORTED */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+/** @brief Free an inode.\r
+\r
+ @param pInode Pointer to the cached inode structure.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF The inode is free.\r
+ @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeFree(\r
+ CINODE *pInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot0Allocated;\r
+\r
+ RedBufferDiscard(pInode->pInodeBuf);\r
+ pInode->pInodeBuf = NULL;\r
+\r
+ /* Determine which of the two slots for the inode is currently\r
+ allocated, and free that slot.\r
+ */\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 0U, &fSlot0Allocated);\r
+\r
+ if(ret == 0)\r
+ {\r
+ bool fSlot1Allocated;\r
+\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 1U, &fSlot1Allocated);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fSlot0Allocated)\r
+ {\r
+ if(fSlot1Allocated)\r
+ {\r
+ /* Both inode slots should never be allocated at\r
+ the same time.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ ret = InodeBitSet(pInode->ulInode, 0U, false);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(!fSlot1Allocated)\r
+ {\r
+ /* The inode in unallocated, which should have been\r
+ caught when it was mounted.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EBADF;\r
+ }\r
+ else\r
+ {\r
+ ret = InodeBitSet(pInode->ulInode, 1U, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ pInode->ulInode = INODE_INVALID;\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(gpRedMR->ulFreeInodes >= gpRedVolConf->ulInodeCount)\r
+ {\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ gpRedMR->ulFreeInodes++;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */\r
+\r
+\r
+/** @brief Put the cached inode structure.\r
+\r
+ This puts all of the buffers in the ::CINODE structure. Also updates inode\r
+ timestamp fields if requested.\r
+\r
+ @param pInode The cached inode structure.\r
+ @param bTimeFields The inode timestamp fields to update.\r
+*/\r
+void RedInodePut(\r
+ CINODE *pInode,\r
+ uint8_t bTimeFields)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedInodePutCoord(pInode);\r
+\r
+ if(pInode->pInodeBuf != NULL)\r
+ {\r
+ #if (REDCONF_READ_ONLY == 0) && (REDCONF_INODE_TIMESTAMPS == 1)\r
+ if((bTimeFields & IPUT_UPDATE_MASK) != 0U)\r
+ {\r
+ if(!pInode->fBranched || !pInode->fDirty)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulNow = RedOsClockGetTime();\r
+\r
+ #if REDCONF_ATIME == 1\r
+ if((bTimeFields & IPUT_UPDATE_ATIME) != 0U)\r
+ {\r
+ pInode->pInodeBuf->ulATime = ulNow;\r
+ }\r
+ #endif\r
+\r
+ if((bTimeFields & IPUT_UPDATE_MTIME) != 0U)\r
+ {\r
+ pInode->pInodeBuf->ulMTime = ulNow;\r
+ }\r
+\r
+ if((bTimeFields & IPUT_UPDATE_CTIME) != 0U)\r
+ {\r
+ pInode->pInodeBuf->ulCTime = ulNow;\r
+ }\r
+ }\r
+ }\r
+ #else\r
+ (void)bTimeFields;\r
+ #endif\r
+\r
+ RedBufferPut(pInode->pInodeBuf);\r
+ pInode->pInodeBuf = NULL;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/** @brief Put all buffers in the cached inode structure except for the inode\r
+ node buffer.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+*/\r
+void RedInodePutCoord(\r
+ CINODE *pInode)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedInodePutData(pInode);\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ RedInodePutIndir(pInode);\r
+ #endif\r
+ #if DINDIR_POINTERS > 0U\r
+ RedInodePutDindir(pInode);\r
+ #endif\r
+ }\r
+}\r
+\r
+\r
+#if DINDIR_POINTERS > 0U\r
+/** @brief Put the double indirect buffer.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+*/\r
+void RedInodePutDindir(\r
+ CINODE *pInode)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(pInode->pDindir != NULL)\r
+ {\r
+ RedBufferPut(pInode->pDindir);\r
+ pInode->pDindir = NULL;\r
+ }\r
+ else\r
+ {\r
+ /* No double indirect buffer, nothing to put.\r
+ */\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+/** @brief Put the indirect buffer.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+*/\r
+void RedInodePutIndir(\r
+ CINODE *pInode)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(pInode->pIndir != NULL)\r
+ {\r
+ RedBufferPut(pInode->pIndir);\r
+ pInode->pIndir = NULL;\r
+ }\r
+ else\r
+ {\r
+ /* No indirect buffer, nothing to put.\r
+ */\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Put the inode data buffer.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+*/\r
+void RedInodePutData(\r
+ CINODE *pInode)\r
+{\r
+ if(pInode == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(pInode->pbData != NULL)\r
+ {\r
+ RedBufferPut(pInode->pbData);\r
+ pInode->pbData = NULL;\r
+ }\r
+ else\r
+ {\r
+ /* No data buffer, nothing to put.\r
+ */\r
+ }\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Determine if an inode is branched.\r
+\r
+ @param ulInode The inode number to examine.\r
+ @param pfIsBranched On successful return, populated with whether the inode\r
+ is branched.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pInode is `NULL`; or @p ulInode is not a valid inode\r
+ number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS InodeIsBranched(\r
+ uint32_t ulInode,\r
+ bool *pfIsBranched)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!INODE_IS_VALID(ulInode) || (pfIsBranched == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ALLOCSTATE state;\r
+\r
+ ret = RedImapBlockState(InodeBlock(ulInode, 0U), &state);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(state == ALLOCSTATE_NEW)\r
+ {\r
+ *pfIsBranched = true;\r
+ }\r
+ else\r
+ {\r
+ ret = RedImapBlockState(InodeBlock(ulInode, 1U), &state);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(state == ALLOCSTATE_NEW)\r
+ {\r
+ *pfIsBranched = true;\r
+ }\r
+ else\r
+ {\r
+ *pfIsBranched = false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Branch an inode.\r
+\r
+ A branched inode is one in which the allocation state for one copy is free\r
+ or almost free, and the other copy is in the new state. The copy which is\r
+ in the new state is the writeable copy, which is also buffered and dirty.\r
+\r
+ @param pInode Pointer to the cached inode structure which has already been\r
+ mounted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeBranch(\r
+ CINODE *pInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(!pInode->fBranched)\r
+ {\r
+ uint8_t bWhich;\r
+\r
+ ret = InodeGetWriteableCopy(pInode->ulInode, &bWhich);\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedBufferBranch(pInode->pInodeBuf, InodeBlock(pInode->ulInode, bWhich));\r
+ pInode->fBranched = true;\r
+ pInode->fDirty = true;\r
+ }\r
+\r
+ /* Toggle the inode slots: the old slot block becomes almost free\r
+ (still used by the committed state) and the new slot block becomes\r
+ new.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = InodeBitSet(pInode->ulInode, 1U - bWhich, false);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = InodeBitSet(pInode->ulInode, bWhich, true);\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+ else\r
+ {\r
+ RedBufferDirty(pInode->pInodeBuf);\r
+ pInode->fDirty = true;\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+/** @brief Find a free inode number.\r
+\r
+ @param pulInode On successful return, populated with a free inode number.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pulInode is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENFILE No available inode numbers.\r
+*/\r
+static REDSTATUS InodeFindFree(\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pulInode == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(gpRedMR->ulFreeInodes == 0U)\r
+ {\r
+ ret = -RED_ENFILE;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulInode;\r
+\r
+ ret = 0;\r
+\r
+ for(ulInode = INODE_FIRST_FREE; ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount); ulInode++)\r
+ {\r
+ bool fFree;\r
+\r
+ ret = RedInodeIsFree(ulInode, &fFree);\r
+\r
+ if((ret != 0) || fFree)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount))\r
+ {\r
+ *pulInode = ulInode;\r
+ }\r
+ else\r
+ {\r
+ /* If gpRedMR->ulFreeInodes > 0, we should have found an inode.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_ENFILE;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1)\r
+/** @brief Determine whether an inode number is available.\r
+\r
+ @param ulInode The node number to examine.\r
+ @param pfFree On successful return, populated with whether the inode\r
+ number is available (true) or in use (false).\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pfFree is `NULL`; or @p ulInode is not a valid inode\r
+ number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeIsFree(\r
+ uint32_t ulInode,\r
+ bool *pfFree)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pfFree == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot0Allocated;\r
+\r
+ *pfFree = false;\r
+\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated);\r
+ if((ret == 0) && !fSlot0Allocated)\r
+ {\r
+ bool fSlot1Allocated;\r
+\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated);\r
+ if((ret == 0) && !fSlot1Allocated)\r
+ {\r
+ *pfFree = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Determine which copy of the inode is currently writeable.\r
+\r
+ @param ulInode The inode number to examine.\r
+ @param pbWhich On successful return, populated with which copy of the inode\r
+ (either 0 or 1) is writeable.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode\r
+ number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS InodeGetWriteableCopy(\r
+ uint32_t ulInode,\r
+ uint8_t *pbWhich)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pbWhich == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot0Allocated;\r
+\r
+ /* The writeable inode slot is the one which is free in the committed\r
+ state, so query the committed state metaroot.\r
+ */\r
+ ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(!fSlot0Allocated)\r
+ {\r
+ *pbWhich = 0U;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot1Allocated;\r
+\r
+ ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(!fSlot1Allocated)\r
+ {\r
+ *pbWhich = 1U;\r
+ }\r
+ else\r
+ {\r
+ /* Both inode slots were allocated, which should never\r
+ happen.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Determine which copy of the inode is current.\r
+\r
+ @param ulInode The inode number to examine.\r
+ @param pbWhich On successful return, populated with which copy of the inode\r
+ (either 0 or 1) is current.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is an unallocated inode number.\r
+ @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode\r
+ number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS InodeGetCurrentCopy(\r
+ uint32_t ulInode,\r
+ uint8_t *pbWhich)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(pbWhich == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot0Allocated;\r
+\r
+ /* The current inode slot is the one which is allocated in the working\r
+ state metaroot.\r
+ */\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated);\r
+ if(ret == 0)\r
+ {\r
+ if(fSlot0Allocated)\r
+ {\r
+ *pbWhich = 0U;\r
+ }\r
+ else\r
+ {\r
+ bool fSlot1Allocated;\r
+\r
+ ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated);\r
+ if(ret == 0)\r
+ {\r
+ if(fSlot1Allocated)\r
+ {\r
+ *pbWhich = 1U;\r
+ }\r
+ else\r
+ {\r
+ /* Neither slot for this inode was allocated, so the\r
+ inode is actually free.\r
+ */\r
+ ret = -RED_EBADF;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Get whether a copy of an inode is allocated.\r
+\r
+ @param bMR The metaroot index: either 0 or 1.\r
+ @param ulInode The inode number.\r
+ @param bWhich Which copy of the inode to get.\r
+ @param pfAllocated On successful return, populated with whether the given\r
+ copy of the inode is allocated.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bMR is not 1 or 0; @p ulInode is not a valid inode\r
+ number; or @p bWhich is not 1 or 0; or @p pfAllocated is\r
+ `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeBitGet(\r
+ uint8_t bMR,\r
+ uint32_t ulInode,\r
+ uint8_t bWhich,\r
+ bool *pfAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!INODE_IS_VALID(ulInode) || (bWhich > 1U))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedImapBlockGet(bMR, InodeBlock(ulInode, bWhich), pfAllocated);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Set whether a copy of an inode is allocated.\r
+\r
+ @param ulInode The inode number.\r
+ @param bWhich Which copy of the inode to set.\r
+ @param fAllocated If true, the inode is set to allocated; if false, the\r
+ inode is set to free.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p ulInode is not a valid inode number; or @p bWhich is\r
+ not 1 or 0.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS InodeBitSet(\r
+ uint32_t ulInode,\r
+ uint8_t bWhich,\r
+ bool fAllocated)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(!INODE_IS_VALID(ulInode) || (bWhich > 1U))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedImapBlockSet(InodeBlock(ulInode, bWhich), fAllocated);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Determine the block number of an inode.\r
+\r
+ @param ulInode The inode number.\r
+ @param bWhich Which copy of the inode.\r
+\r
+ @return The block number of the inode.\r
+*/\r
+static uint32_t InodeBlock(\r
+ uint32_t ulInode,\r
+ uint8_t bWhich)\r
+{\r
+ REDASSERT(INODE_IS_VALID(ulInode));\r
+ REDASSERT(bWhich <= 1U);\r
+\r
+ return gpRedCoreVol->ulInodeTableStartBN + ((ulInode - INODE_FIRST_VALID) * 2U) + bWhich;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements inode I/O functions.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+/* This value is used to initialize the uIndirEntry and uDindirEntry members of\r
+ the CINODE structure. After seeking, a value of COORD_ENTRY_INVALID in\r
+ uIndirEntry indicates that there is no indirect node in the path through the\r
+ file metadata structure, and a value of COORD_ENTRY_INVALID in uDindirEntry\r
+ indicates that there is no double indirect node.\r
+*/\r
+#define COORD_ENTRY_INVALID (UINT16_MAX)\r
+\r
+/* This enumeration is used by the BranchBlock() and BranchBlockCost()\r
+ functions to determine which blocks of the file metadata structure need to\r
+ be branched, and which to ignore. DINDIR requires requires branching the\r
+ double indirect only, INDIR requires branching the double indirect\r
+ (if present) and the indirect, and FILE_DATA requires branching the indirect\r
+ and double indirect (if present) and the file data block.\r
+*/\r
+typedef enum\r
+{\r
+ BRANCHDEPTH_DINDIR = 0U,\r
+ BRANCHDEPTH_INDIR = 1U,\r
+ BRANCHDEPTH_FILE_DATA = 2U,\r
+ BRANCHDEPTH_MAX = BRANCHDEPTH_FILE_DATA\r
+} BRANCHDEPTH;\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED\r
+static REDSTATUS Shrink(CINODE *pInode, uint64_t ullSize);\r
+#if DINDIR_POINTERS > 0U\r
+static REDSTATUS TruncDindir(CINODE *pInode, bool *pfFreed);\r
+#endif\r
+#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+static REDSTATUS TruncIndir(CINODE *pInode, bool *pfFreed);\r
+#endif\r
+static REDSTATUS TruncDataBlock(const CINODE *pInode, uint32_t *pulBlock, bool fPropagate);\r
+#endif\r
+static REDSTATUS ExpandPrepare(CINODE *pInode);\r
+#endif\r
+static void SeekCoord(CINODE *pInode, uint32_t ulBlock);\r
+static REDSTATUS ReadUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, uint8_t *pbBuffer);\r
+static REDSTATUS ReadAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t ulBlockCount, uint8_t *pbBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS WriteUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, const uint8_t *pbBuffer);\r
+static REDSTATUS WriteAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulBlockCount, const uint8_t *pbBuffer);\r
+#endif\r
+static REDSTATUS GetExtent(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulExtentStart, uint32_t *pulExtentLen);\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS BranchBlock(CINODE *pInode, BRANCHDEPTH depth, bool fBuffer);\r
+static REDSTATUS BranchOneBlock(uint32_t *pulBlock, void **ppBuffer, uint16_t uBFlag);\r
+static REDSTATUS BranchBlockCost(const CINODE *pInode, BRANCHDEPTH depth, uint32_t *pulCost);\r
+static uint32_t FreeBlockCount(void);\r
+#endif\r
+\r
+\r
+/** @brief Read data from an inode.\r
+\r
+ @param pInode A pointer to the cached inode structure of the inode from\r
+ which to read.\r
+ @param ullStart The file offset at which to read.\r
+ @param pulLen On input, the number of bytes to attempt to read. On\r
+ successful return, populated with the number of bytes\r
+ actually read.\r
+ @param pBuffer The buffer to read into.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or\r
+ @p pulLen is `NULL`; or @p pBuffer is `NULL`.\r
+*/\r
+REDSTATUS RedInodeDataRead(\r
+ CINODE *pInode,\r
+ uint64_t ullStart,\r
+ uint32_t *pulLen,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || (pulLen == NULL) || (pBuffer == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ullStart >= pInode->pInodeBuf->ullSize)\r
+ {\r
+ *pulLen = 0U;\r
+ }\r
+ else if(*pulLen == 0U)\r
+ {\r
+ /* Do nothing, just return success.\r
+ */\r
+ }\r
+ else\r
+ {\r
+ uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);\r
+ uint32_t ulReadIndex = 0U;\r
+ uint32_t ulLen = *pulLen;\r
+ uint32_t ulRemaining;\r
+\r
+ /* Reading beyond the end of the file is not allowed. If the requested\r
+ read extends beyond the end of the file, truncate the read length so\r
+ that the read stops at the end of the file.\r
+ */\r
+ if((pInode->pInodeBuf->ullSize - ullStart) < ulLen)\r
+ {\r
+ ulLen = (uint32_t)(pInode->pInodeBuf->ullSize - ullStart);\r
+ }\r
+\r
+ ulRemaining = ulLen;\r
+\r
+ /* Unaligned partial block at start.\r
+ */\r
+ if((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U)\r
+ {\r
+ uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U));\r
+ uint32_t ulThisRead = REDMIN(ulRemaining, ulBytesInFirstBlock);\r
+\r
+ ret = ReadUnaligned(pInode, ullStart, ulThisRead, pbBuffer);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulReadIndex += ulThisRead;\r
+ ulRemaining -= ulThisRead;\r
+ }\r
+ }\r
+\r
+ /* Whole blocks.\r
+ */\r
+ if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE))\r
+ {\r
+ uint32_t ulBlockOffset = (uint32_t)((ullStart + ulReadIndex) >> BLOCK_SIZE_P2);\r
+ uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2;\r
+\r
+ REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U);\r
+\r
+ ret = ReadAligned(pInode, ulBlockOffset, ulBlockCount, &pbBuffer[ulReadIndex]);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulReadIndex += ulBlockCount << BLOCK_SIZE_P2;\r
+ ulRemaining -= ulBlockCount << BLOCK_SIZE_P2;\r
+ }\r
+ }\r
+\r
+ /* Aligned partial block at end.\r
+ */\r
+ if((ret == 0) && (ulRemaining > 0U))\r
+ {\r
+ REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE);\r
+ REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U);\r
+\r
+ ret = ReadUnaligned(pInode, ullStart + ulReadIndex, ulRemaining, &pbBuffer[ulReadIndex]);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulLen = ulLen;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write to an inode.\r
+\r
+ @param pInode A pointer to the cached inode structure of the inode into\r
+ which to write.\r
+ @param ullStart The file offset at which to write.\r
+ @param pulLen On input, the number of bytes to attempt to write. On\r
+ successful return, populated with the number of bytes\r
+ actually written.\r
+ @param pBuffer The buffer to write from.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EFBIG @p ullStart is greater than the maximum file size; or\r
+ @p ullStart is equal to the maximum file size and the\r
+ write length is non-zero.\r
+ @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or\r
+ @p pulLen is `NULL`; or @p pBuffer is `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+*/\r
+REDSTATUS RedInodeDataWrite(\r
+ CINODE *pInode,\r
+ uint64_t ullStart,\r
+ uint32_t *pulLen,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_DIRTY(pInode) || (pulLen == NULL) || (pBuffer == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if((ullStart > INODE_SIZE_MAX) || ((ullStart == INODE_SIZE_MAX) && (*pulLen > 0U)))\r
+ {\r
+ ret = -RED_EFBIG;\r
+ }\r
+ else if(*pulLen == 0U)\r
+ {\r
+ /* Do nothing, just return success.\r
+ */\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+ uint32_t ulWriteIndex = 0U;\r
+ uint32_t ulLen = *pulLen;\r
+ uint32_t ulRemaining;\r
+\r
+ if((INODE_SIZE_MAX - ullStart) < ulLen)\r
+ {\r
+ ulLen = (uint32_t)(INODE_SIZE_MAX - ullStart);\r
+ }\r
+\r
+ ulRemaining = ulLen;\r
+\r
+ /* If the write is beyond the current end of the file, and the current\r
+ end of the file is not block-aligned, then there may be some data\r
+ that needs to be zeroed in the last block.\r
+ */\r
+ if(ullStart > pInode->pInodeBuf->ullSize)\r
+ {\r
+ ret = ExpandPrepare(pInode);\r
+ }\r
+\r
+ /* Partial block at start.\r
+ */\r
+ if((ret == 0) && (((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U) || (ulRemaining < REDCONF_BLOCK_SIZE)))\r
+ {\r
+ uint32_t ulBytesInFirstBlock = REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U));\r
+ uint32_t ulThisWrite = REDMIN(ulRemaining, ulBytesInFirstBlock);\r
+\r
+ ret = WriteUnaligned(pInode, ullStart, ulThisWrite, pbBuffer);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulWriteIndex += ulThisWrite;\r
+ ulRemaining -= ulThisWrite;\r
+ }\r
+ }\r
+\r
+ /* Whole blocks.\r
+ */\r
+ if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE))\r
+ {\r
+ uint32_t ulBlockOffset = (uint32_t)((ullStart + ulWriteIndex) >> BLOCK_SIZE_P2);\r
+ uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2;\r
+ uint32_t ulBlocksWritten = ulBlockCount;\r
+\r
+ REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U);\r
+\r
+ ret = WriteAligned(pInode, ulBlockOffset, &ulBlocksWritten, &pbBuffer[ulWriteIndex]);\r
+\r
+ if((ret == -RED_ENOSPC) && (ulWriteIndex > 0U))\r
+ {\r
+ ulBlocksWritten = 0U;\r
+ ret = 0;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulWriteIndex += ulBlocksWritten << BLOCK_SIZE_P2;\r
+ ulRemaining -= ulBlocksWritten << BLOCK_SIZE_P2;\r
+\r
+ if(ulBlocksWritten < ulBlockCount)\r
+ {\r
+ ulRemaining = 0U;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Partial block at end.\r
+ */\r
+ if((ret == 0) && (ulRemaining > 0U))\r
+ {\r
+ REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE);\r
+ REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U);\r
+ REDASSERT(ulWriteIndex > 0U);\r
+\r
+ ret = WriteUnaligned(pInode, ullStart + ulWriteIndex, ulRemaining, &pbBuffer[ulWriteIndex]);\r
+\r
+ if(ret == -RED_ENOSPC)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else if(ret == 0)\r
+ {\r
+ ulWriteIndex += ulRemaining;\r
+\r
+ REDASSERT(ulWriteIndex == ulLen);\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, return it.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulLen = ulWriteIndex;\r
+\r
+ if((ullStart + ulWriteIndex) > pInode->pInodeBuf->ullSize)\r
+ {\r
+ pInode->pInodeBuf->ullSize = ullStart + ulWriteIndex;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED\r
+/** @brief Change the size of an inode.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @praam ullSize The new file size for the inode.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EFBIG @p ullSize is greater than the maximum file size.\r
+ @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+*/\r
+REDSTATUS RedInodeDataTruncate(\r
+ CINODE *pInode,\r
+ uint64_t ullSize)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ /* The inode does not need to be dirtied when it is being deleted, because\r
+ the inode buffer will be discarded without ever being written to disk.\r
+ Thus, we only check to see if it's mounted here.\r
+ */\r
+ if(!CINODE_IS_MOUNTED(pInode))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(ullSize > INODE_SIZE_MAX)\r
+ {\r
+ ret = -RED_EFBIG;\r
+ }\r
+ else\r
+ {\r
+ if(ullSize > pInode->pInodeBuf->ullSize)\r
+ {\r
+ ret = ExpandPrepare(pInode);\r
+ }\r
+ else if(ullSize < pInode->pInodeBuf->ullSize)\r
+ {\r
+ ret = Shrink(pInode, ullSize);\r
+ }\r
+ else\r
+ {\r
+ /* Size is staying the same, nothing to do.\r
+ */\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pInode->pInodeBuf->ullSize = ullSize;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Free all file data beyond a specified point.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ullSize The point beyond which to free all file data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS Shrink(\r
+ CINODE *pInode,\r
+ uint64_t ullSize)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ /* pInode->fDirty is checked explicitly here, instead of using the\r
+ CINODE_IS_DIRTY() macro, to avoid a duplicate mount check.\r
+ */\r
+ if(!CINODE_IS_MOUNTED(pInode) || ((ullSize > 0U) && !pInode->fDirty))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulTruncBlock = (uint32_t)((ullSize + REDCONF_BLOCK_SIZE - 1U) >> BLOCK_SIZE_P2);\r
+\r
+ RedInodePutData(pInode);\r
+\r
+ #if REDCONF_DIRECT_POINTERS > 0U\r
+ while(ulTruncBlock < REDCONF_DIRECT_POINTERS)\r
+ {\r
+ ret = TruncDataBlock(pInode, &pInode->pInodeBuf->aulEntries[ulTruncBlock], true);\r
+\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ ulTruncBlock++;\r
+ }\r
+ #endif\r
+\r
+ #if REDCONF_INDIRECT_POINTERS > 0U\r
+ while((ret == 0) && (ulTruncBlock < (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS)))\r
+ {\r
+ ret = RedInodeDataSeek(pInode, ulTruncBlock);\r
+\r
+ if((ret == 0) || (ret == -RED_ENODATA))\r
+ {\r
+ bool fFreed;\r
+\r
+ ret = TruncIndir(pInode, &fFreed);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fFreed)\r
+ {\r
+ pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = BLOCK_SPARSE;\r
+ }\r
+\r
+ /* The next seek will go to the beginning of the next\r
+ indirect.\r
+ */\r
+ ulTruncBlock += (INDIR_ENTRIES - pInode->uIndirEntry);\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ while((ret == 0) && (ulTruncBlock < INODE_DATA_BLOCKS))\r
+ {\r
+ ret = RedInodeDataSeek(pInode, ulTruncBlock);\r
+\r
+ if((ret == 0) || (ret == -RED_ENODATA))\r
+ {\r
+ bool fFreed;\r
+\r
+ /* TruncDindir() invokes seek as it goes along, which will\r
+ update the entry values (possibly all three of these);\r
+ make a copy so we can compute things correctly after.\r
+ */\r
+ uint16_t uOrigInodeEntry = pInode->uInodeEntry;\r
+ uint16_t uOrigDindirEntry = pInode->uDindirEntry;\r
+ uint16_t uOrigIndirEntry = pInode->uIndirEntry;\r
+\r
+ ret = TruncDindir(pInode, &fFreed);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(fFreed)\r
+ {\r
+ pInode->pInodeBuf->aulEntries[uOrigInodeEntry] = BLOCK_SPARSE;\r
+ }\r
+\r
+ /* The next seek will go to the beginning of the next\r
+ double indirect.\r
+ */\r
+ ulTruncBlock += (DINDIR_DATA_BLOCKS - (uOrigDindirEntry * INDIR_ENTRIES)) - uOrigIndirEntry;\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if DINDIR_POINTERS > 0U\r
+/** @brief Truncate a double indirect.\r
+\r
+ @param pInode A pointer to the cached inode, whose coordinates indicate\r
+ the truncation boundary.\r
+ @param pfFreed On successful return, populated with whether the double\r
+ indirect node was freed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS TruncDindir(\r
+ CINODE *pInode,\r
+ bool *pfFreed)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || (pfFreed == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(pInode->pDindir == NULL)\r
+ {\r
+ *pfFreed = false;\r
+ }\r
+ else\r
+ {\r
+ bool fBranch = false;\r
+ uint16_t uEntry;\r
+\r
+ /* The double indirect is definitely going to be branched (instead of\r
+ deleted) if any of its indirect pointers which are entirely prior to\r
+ the truncation boundary are non-sparse.\r
+ */\r
+ for(uEntry = 0U; !fBranch && (uEntry < pInode->uDindirEntry); uEntry++)\r
+ {\r
+ fBranch = pInode->pDindir->aulEntries[uEntry] != BLOCK_SPARSE;\r
+ }\r
+\r
+ /* Unless we already know for a fact that the double indirect is going\r
+ to be branched, examine the contents of the indirect pointer which\r
+ straddles the truncation boundary. If the indirect is going to be\r
+ deleted, we know this indirect pointer is going away, and that might\r
+ mean the double indirect is going to be deleted also.\r
+ */\r
+ if(!fBranch && (pInode->pDindir->aulEntries[pInode->uDindirEntry] != BLOCK_SPARSE))\r
+ {\r
+ for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++)\r
+ {\r
+ fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE;\r
+ }\r
+ }\r
+\r
+ if(fBranch)\r
+ {\r
+ ret = BranchBlock(pInode, BRANCHDEPTH_DINDIR, false);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulBlock = pInode->ulLogicalBlock;\r
+ uint16_t uStart = pInode->uDindirEntry; /* pInode->uDindirEntry will change. */\r
+\r
+ for(uEntry = uStart; uEntry < INDIR_ENTRIES; uEntry++)\r
+ {\r
+ /* Seek so that TruncIndir() has the correct indirect\r
+ buffer and indirect entry.\r
+ */\r
+ ret = RedInodeDataSeek(pInode, ulBlock);\r
+\r
+ if(ret == -RED_ENODATA)\r
+ {\r
+ ret = 0;\r
+ }\r
+\r
+ if((ret == 0) && (pInode->ulIndirBlock != BLOCK_SPARSE))\r
+ {\r
+ bool fIndirFreed;\r
+\r
+ ret = TruncIndir(pInode, &fIndirFreed);\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* All of the indirects after the one which straddles\r
+ the truncation boundary should definitely end up\r
+ deleted.\r
+ */\r
+ REDASSERT((uEntry == uStart) || fIndirFreed);\r
+\r
+ /* If the double indirect is being freed, all of the\r
+ indirects should be freed too.\r
+ */\r
+ REDASSERT(fIndirFreed || fBranch);\r
+\r
+ if(fBranch && fIndirFreed)\r
+ {\r
+ pInode->pDindir->aulEntries[uEntry] = BLOCK_SPARSE;\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ ulBlock += (INDIR_ENTRIES - pInode->uIndirEntry);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pfFreed = !fBranch;\r
+\r
+ if(!fBranch)\r
+ {\r
+ RedInodePutDindir(pInode);\r
+\r
+ ret = RedImapBlockSet(pInode->ulDindirBlock, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* DINDIR_POINTERS > 0U */\r
+\r
+\r
+#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+/** @brief Truncate a indirect.\r
+\r
+ @param pInode A pointer to the cached inode, whose coordinates indicate\r
+ the truncation boundary.\r
+ @param pfFreed On successful return, populated with whether the indirect\r
+ node was freed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS TruncIndir(\r
+ CINODE *pInode,\r
+ bool *pfFreed)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || (pfFreed == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(pInode->pIndir == NULL)\r
+ {\r
+ *pfFreed = false;\r
+ }\r
+ else\r
+ {\r
+ bool fBranch = false;\r
+ uint16_t uEntry;\r
+\r
+ /* Scan the range of entries which are not being truncated. If there\r
+ is anything there, then the indirect will not be empty after the\r
+ truncate, so it is branched and modified instead of deleted.\r
+ */\r
+ for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++)\r
+ {\r
+ fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE;\r
+ }\r
+\r
+ if(fBranch)\r
+ {\r
+ ret = BranchBlock(pInode, BRANCHDEPTH_INDIR, false);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ for(uEntry = pInode->uIndirEntry; uEntry < INDIR_ENTRIES; uEntry++)\r
+ {\r
+ ret = TruncDataBlock(pInode, &pInode->pIndir->aulEntries[uEntry], fBranch);\r
+\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pfFreed = !fBranch;\r
+\r
+ if(!fBranch)\r
+ {\r
+ RedInodePutIndir(pInode);\r
+\r
+ ret = RedImapBlockSet(pInode->ulIndirBlock, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */\r
+\r
+\r
+/** @brief Truncate a file data block.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param pulBlock On entry, contains the block to be truncated. On\r
+ successful return, if @p fPropagate is true, populated\r
+ with BLOCK_SPARSE, otherwise unmodified.\r
+ @param fPropagate Whether the parent node is being branched.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS TruncDataBlock(\r
+ const CINODE *pInode,\r
+ uint32_t *pulBlock,\r
+ bool fPropagate)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || (pulBlock == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(*pulBlock != BLOCK_SPARSE)\r
+ {\r
+ ret = RedImapBlockSet(*pulBlock, false);\r
+\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ if(ret == 0)\r
+ {\r
+ if(pInode->pInodeBuf->ulBlocks == 0U)\r
+ {\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ pInode->pInodeBuf->ulBlocks--;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if((ret == 0) && fPropagate)\r
+ {\r
+ *pulBlock = BLOCK_SPARSE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Data block is sparse, nothing to truncate.\r
+ */\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* DELETE_SUPPORTED || TRUNCATE_SUPPORTED */\r
+\r
+\r
+/** @brief Prepare to increase the file size.\r
+\r
+ When the inode size is increased, a sparse region is created. It is\r
+ possible that a prior shrink operation to an unaligned size left stale data\r
+ beyond the end of the file in the last data block. That data is not zeroed\r
+ while shrinking the inode in order to transfer the disk full burden from the\r
+ shrink operation to the expand operation.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS ExpandPrepare(\r
+ CINODE *pInode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_DIRTY(pInode))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulOldSizeByteInBlock = (uint32_t)(pInode->pInodeBuf->ullSize & (REDCONF_BLOCK_SIZE - 1U));\r
+\r
+ if(ulOldSizeByteInBlock != 0U)\r
+ {\r
+ ret = RedInodeDataSeek(pInode, (uint32_t)(pInode->pInodeBuf->ullSize >> BLOCK_SIZE_P2));\r
+\r
+ if(ret == -RED_ENODATA)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else if(ret == 0)\r
+ {\r
+ ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true);\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedMemSet(&pInode->pbData[ulOldSizeByteInBlock], 0U, REDCONF_BLOCK_SIZE - ulOldSizeByteInBlock);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ REDERROR();\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Seek to a given position within an inode, then buffer the data block.\r
+\r
+ On successful return, pInode->pbData will be populated with a buffer\r
+ corresponding to the @p ulBlock block offset.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlock The block offset to seek to and buffer.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_ENODATA The block offset is sparse.\r
+ @retval -RED_EINVAL @p ulBlock is too large.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeDataSeekAndRead(\r
+ CINODE *pInode,\r
+ uint32_t ulBlock)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = RedInodeDataSeek(pInode, ulBlock);\r
+\r
+ if((ret == 0) && (pInode->pbData == NULL))\r
+ {\r
+ REDASSERT(pInode->ulDataBlock != BLOCK_SPARSE);\r
+\r
+ ret = RedBufferGet(pInode->ulDataBlock, 0U, CAST_VOID_PTR_PTR(&pInode->pbData));\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Seek to a given position within an inode.\r
+\r
+ On successful return, pInode->ulDataBlock will be populated with the\r
+ physical block number corresponding to the @p ulBlock block offset.\r
+\r
+ Note: Callers of this function depend on its parameter checking.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlock The block offset to seek to.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_ENODATA The block offset is sparse.\r
+ @retval -RED_EINVAL @p ulBlock is too large; or @p pInode is not a\r
+ mounted cached inode pointer.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedInodeDataSeek(\r
+ CINODE *pInode,\r
+ uint32_t ulBlock)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || (ulBlock >= INODE_DATA_BLOCKS))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ SeekCoord(pInode, ulBlock);\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ if(pInode->uDindirEntry != COORD_ENTRY_INVALID)\r
+ {\r
+ if(pInode->ulDindirBlock == BLOCK_SPARSE)\r
+ {\r
+ /* If the double indirect is unallocated, so is the indirect.\r
+ */\r
+ pInode->ulIndirBlock = BLOCK_SPARSE;\r
+ }\r
+ else\r
+ {\r
+ if(pInode->pDindir == NULL)\r
+ {\r
+ ret = RedBufferGet(pInode->ulDindirBlock, BFLAG_META_DINDIR, CAST_VOID_PTR_PTR(&pInode->pDindir));\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pInode->ulIndirBlock = pInode->pDindir->aulEntries[pInode->uDindirEntry];\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ if((ret == 0) && (pInode->uIndirEntry != COORD_ENTRY_INVALID))\r
+ {\r
+ if(pInode->ulIndirBlock == BLOCK_SPARSE)\r
+ {\r
+ /* If the indirect is unallocated, so is the data block.\r
+ */\r
+ pInode->ulDataBlock = BLOCK_SPARSE;\r
+ }\r
+ else\r
+ {\r
+ if(pInode->pIndir == NULL)\r
+ {\r
+ ret = RedBufferGet(pInode->ulIndirBlock, BFLAG_META_INDIR, CAST_VOID_PTR_PTR(&pInode->pIndir));\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ pInode->ulDataBlock = pInode->pIndir->aulEntries[pInode->uIndirEntry];\r
+ }\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if((ret == 0) && (pInode->ulDataBlock == BLOCK_SPARSE))\r
+ {\r
+ ret = -RED_ENODATA;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Seek to the coordinates.\r
+\r
+ Compute the new coordinates, and put any buffers which are not needed or are\r
+ no longer appropriate.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlock The block offset to seek to.\r
+*/\r
+static void SeekCoord(\r
+ CINODE *pInode,\r
+ uint32_t ulBlock)\r
+{\r
+ if(!CINODE_IS_MOUNTED(pInode) || (ulBlock >= INODE_DATA_BLOCKS))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if((pInode->ulLogicalBlock != ulBlock) || !pInode->fCoordInited)\r
+ {\r
+ RedInodePutData(pInode);\r
+ pInode->ulLogicalBlock = ulBlock;\r
+\r
+ #if REDCONF_DIRECT_POINTERS > 0U\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ if(ulBlock < REDCONF_DIRECT_POINTERS)\r
+ #endif\r
+ {\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ RedInodePutCoord(pInode);\r
+ #endif\r
+\r
+ pInode->uInodeEntry = (uint16_t)ulBlock;\r
+ pInode->ulDataBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ pInode->uDindirEntry = COORD_ENTRY_INVALID;\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ pInode->uIndirEntry = COORD_ENTRY_INVALID;\r
+ #endif\r
+ }\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ else\r
+ #endif\r
+ #endif\r
+ #if REDCONF_INDIRECT_POINTERS > 0U\r
+ #if REDCONF_INDIRECT_POINTERS < INODE_ENTRIES\r
+ if(ulBlock < (INODE_INDIR_BLOCKS + REDCONF_DIRECT_POINTERS))\r
+ #endif\r
+ {\r
+ uint32_t ulIndirRangeOffset = ulBlock - REDCONF_DIRECT_POINTERS;\r
+ uint16_t uInodeEntry = (uint16_t)((ulIndirRangeOffset / INDIR_ENTRIES) + REDCONF_DIRECT_POINTERS);\r
+ uint16_t uIndirEntry = (uint16_t)(ulIndirRangeOffset % INDIR_ENTRIES);\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ RedInodePutDindir(pInode);\r
+ #endif\r
+\r
+ /* If the inode entry is not changing, then the previous indirect\r
+ is still the correct one. Otherwise, the old indirect will be\r
+ released and the new one will be read later.\r
+ */\r
+ if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited)\r
+ {\r
+ RedInodePutIndir(pInode);\r
+\r
+ pInode->uInodeEntry = uInodeEntry;\r
+\r
+ pInode->ulIndirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];\r
+ }\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ pInode->uDindirEntry = COORD_ENTRY_INVALID;\r
+ #endif\r
+ pInode->uIndirEntry = uIndirEntry;\r
+\r
+ /* At this point, the following pInode members are needed but not\r
+ yet populated:\r
+\r
+ - pIndir\r
+ - ulDataBlock\r
+ */\r
+ }\r
+ #if DINDIR_POINTERS > 0U\r
+ else\r
+ #endif\r
+ #endif\r
+ #if DINDIR_POINTERS > 0U\r
+ {\r
+ uint32_t ulDindirRangeOffset = (ulBlock - REDCONF_DIRECT_POINTERS) - INODE_INDIR_BLOCKS;\r
+ uint16_t uInodeEntry = (uint16_t)((ulDindirRangeOffset / DINDIR_DATA_BLOCKS) + REDCONF_DIRECT_POINTERS + REDCONF_INDIRECT_POINTERS);\r
+ uint32_t ulDindirNodeOffset = ulDindirRangeOffset % DINDIR_DATA_BLOCKS;\r
+ uint16_t uDindirEntry = (uint16_t)(ulDindirNodeOffset / INDIR_ENTRIES);\r
+ uint16_t uIndirEntry = (uint16_t)(ulDindirNodeOffset % INDIR_ENTRIES);\r
+\r
+ /* If the inode entry is not changing, then the previous double\r
+ indirect is still the correct one. Otherwise, the old double\r
+ indirect will be released and the new one will be read later.\r
+ */\r
+ if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited)\r
+ {\r
+ RedInodePutIndir(pInode);\r
+ RedInodePutDindir(pInode);\r
+\r
+ pInode->uInodeEntry = uInodeEntry;\r
+\r
+ pInode->ulDindirBlock = pInode->pInodeBuf->aulEntries[pInode->uInodeEntry];\r
+ }\r
+ /* If neither the inode entry nor double indirect entry are\r
+ changing, then the previous indirect is still the correct one.\r
+ Otherwise, it old indirect will be released and the new one will\r
+ be read later.\r
+ */\r
+ else if(pInode->uDindirEntry != uDindirEntry)\r
+ {\r
+ RedInodePutIndir(pInode);\r
+ }\r
+ else\r
+ {\r
+ /* Data buffer has already been put, nothing to do.\r
+ */\r
+ }\r
+\r
+ pInode->uDindirEntry = uDindirEntry;\r
+ pInode->uIndirEntry = uIndirEntry;\r
+\r
+ /* At this point, the following pInode members are needed but not\r
+ yet populated:\r
+\r
+ - pDindir\r
+ - pIndir\r
+ - ulIndirBlock\r
+ - ulDataBlock\r
+ */\r
+ }\r
+ #elif (REDCONF_DIRECT_POINTERS > 0U) && (REDCONF_INDIRECT_POINTERS > 0U)\r
+ else\r
+ {\r
+ /* There are no double indirects, so the block should have been in\r
+ the direct or indirect range.\r
+ */\r
+ REDERROR();\r
+ }\r
+ #endif\r
+\r
+ pInode->fCoordInited = true;\r
+ }\r
+ else\r
+ {\r
+ /* Seeking to the current position, nothing to do.\r
+ */\r
+ }\r
+}\r
+\r
+\r
+/** @brief Read an unaligned portion of a block.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ullStart The file offset at which to read.\r
+ @param ulLen The number of bytes to read.\r
+ @param pbBuffer The buffer to read into.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS ReadUnaligned(\r
+ CINODE *pInode,\r
+ uint64_t ullStart,\r
+ uint32_t ulLen,\r
+ uint8_t *pbBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ /* This read should not cross a block boundary.\r
+ */\r
+ if( ((ullStart >> BLOCK_SIZE_P2) != (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2))\r
+ || (pbBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedInodeDataSeekAndRead(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2));\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedMemCpy(pbBuffer, &pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], ulLen);\r
+ }\r
+ else if(ret == -RED_ENODATA)\r
+ {\r
+ /* Sparse block, return zeroed data.\r
+ */\r
+ RedMemSet(pbBuffer, 0U, ulLen);\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ /* No action, just return the error.\r
+ */\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Read one or more whole blocks.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlockStart The file block offset at which to read.\r
+ @param ulBlockCount The number of blocks to read.\r
+ @param pbBuffer The buffer to read into.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS ReadAligned(\r
+ CINODE *pInode,\r
+ uint32_t ulBlockStart,\r
+ uint32_t ulBlockCount,\r
+ uint8_t *pbBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(pbBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulBlockIndex = 0U;\r
+\r
+ /* Read the data from disk one contiguous extent at a time.\r
+ */\r
+ while((ret == 0) && (ulBlockIndex < ulBlockCount))\r
+ {\r
+ uint32_t ulExtentStart;\r
+ uint32_t ulExtentLen = ulBlockCount - ulBlockIndex;\r
+\r
+ ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen);\r
+\r
+ if(ret == 0)\r
+ {\r
+ #if REDCONF_READ_ONLY == 0\r
+ /* Before reading directly from disk, flush any dirty file data\r
+ buffers in the range to avoid reading stale data.\r
+ */\r
+ ret = RedBufferFlush(ulExtentStart, ulExtentLen);\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ ret = RedIoRead(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulBlockIndex += ulExtentLen;\r
+ }\r
+ }\r
+ }\r
+ else if(ret == -RED_ENODATA)\r
+ {\r
+ /* Sparse block, return zeroed data.\r
+ */\r
+ RedMemSet(&pbBuffer[ulBlockIndex << BLOCK_SIZE_P2], 0U, REDCONF_BLOCK_SIZE);\r
+ ulBlockIndex++;\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ /* An unexpected error occurred; the loop will terminate.\r
+ */\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write an unaligned portion of a block.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ullStart The file offset at which to write.\r
+ @param ulLen The number of bytes to write.\r
+ @param pbBuffer The buffer to write from.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS WriteUnaligned(\r
+ CINODE *pInode,\r
+ uint64_t ullStart,\r
+ uint32_t ulLen,\r
+ const uint8_t *pbBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ /* This write should not cross a block boundary.\r
+ */\r
+ if( ((ullStart >> BLOCK_SIZE_P2) != (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2))\r
+ || (pbBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedInodeDataSeek(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2));\r
+\r
+ if((ret == 0) || (ret == -RED_ENODATA))\r
+ {\r
+ ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true);\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedMemCpy(&pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], pbBuffer, ulLen);\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Write one or more whole blocks.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlockStart The file block offset at which to write.\r
+ @param pulBlockCount On entry, the number of blocks to attempt to write.\r
+ On successful return, the number of blocks actually\r
+ written.\r
+ @param pbBuffer The buffer to write from.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS WriteAligned(\r
+ CINODE *pInode,\r
+ uint32_t ulBlockStart,\r
+ uint32_t *pulBlockCount,\r
+ const uint8_t *pbBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if((pulBlockCount == NULL) || (pbBuffer == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ bool fFull = false;\r
+ uint32_t ulBlockCount = *pulBlockCount;\r
+ uint32_t ulBlockIndex;\r
+\r
+ /* Branch all of the file data blocks in advance.\r
+ */\r
+ for(ulBlockIndex = 0U; (ulBlockIndex < ulBlockCount) && !fFull; ulBlockIndex++)\r
+ {\r
+ ret = RedInodeDataSeek(pInode, ulBlockStart + ulBlockIndex);\r
+\r
+ if((ret == 0) || (ret == -RED_ENODATA))\r
+ {\r
+ ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, false);\r
+\r
+ if(ret == -RED_ENOSPC)\r
+ {\r
+ if(ulBlockIndex > 0U)\r
+ {\r
+ ret = 0;\r
+ }\r
+\r
+ fFull = true;\r
+ }\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ ulBlockCount = ulBlockIndex;\r
+ ulBlockIndex = 0U;\r
+\r
+ if(fFull)\r
+ {\r
+ ulBlockCount--;\r
+ }\r
+\r
+ /* Write the data to disk one contiguous extent at a time.\r
+ */\r
+ while((ret == 0) && (ulBlockIndex < ulBlockCount))\r
+ {\r
+ uint32_t ulExtentStart;\r
+ uint32_t ulExtentLen = ulBlockCount - ulBlockIndex;\r
+\r
+ ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoWrite(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]);\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* If there is any buffered file data for the extent we\r
+ just wrote, those buffers are now stale.\r
+ */\r
+ ret = RedBufferDiscardRange(ulExtentStart, ulExtentLen);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulBlockIndex += ulExtentLen;\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulBlockCount = ulBlockCount;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+/** @brief Get the physical block number and count of contiguous blocks given a\r
+ starting logical block number.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param ulBlockStart The file block offset for the start of the extent.\r
+ @param pulExtentStart On successful return, the starting physical block\r
+ number of the contiguous extent.\r
+ @param pulExtentLen On entry, the maximum length of the extent; on\r
+ successful return, the length of the contiguous\r
+ extent.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENODATA The block offset is sparse.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS GetExtent(\r
+ CINODE *pInode,\r
+ uint32_t ulBlockStart,\r
+ uint32_t *pulExtentStart,\r
+ uint32_t *pulExtentLen)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((pulExtentStart == NULL) || (pulExtentLen == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedInodeDataSeek(pInode, ulBlockStart);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulExtentLen = *pulExtentLen;\r
+ uint32_t ulFirstBlock = pInode->ulDataBlock;\r
+ uint32_t ulRunLen = 1U;\r
+\r
+ while((ret == 0) && (ulRunLen < ulExtentLen))\r
+ {\r
+ ret = RedInodeDataSeek(pInode, ulBlockStart + ulRunLen);\r
+\r
+ /* The extent ends when we find a sparse data block or when the\r
+ data block is not contiguous with the preceding data block.\r
+ */\r
+ if((ret == -RED_ENODATA) || ((ret == 0) && (pInode->ulDataBlock != (ulFirstBlock + ulRunLen))))\r
+ {\r
+ ret = 0;\r
+ break;\r
+ }\r
+\r
+ ulRunLen++;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulExtentStart = ulFirstBlock;\r
+ *pulExtentLen = ulRunLen;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Allocate or branch the file metadata path and data block if necessary.\r
+\r
+ Optionally, can stop allocating/branching at a certain depth.\r
+\r
+ @param pInode A pointer to the cached inode structure.\r
+ @param depth A BRANCHDEPTH_ value indicating the lowest depth to branch.\r
+ @param fBuffer Whether to buffer the data block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+*/\r
+static REDSTATUS BranchBlock(\r
+ CINODE *pInode,\r
+ BRANCHDEPTH depth,\r
+ bool fBuffer)\r
+{\r
+ REDSTATUS ret;\r
+ uint32_t ulCost = 0U; /* Init'd to quiet warnings. */\r
+\r
+ ret = BranchBlockCost(pInode, depth, &ulCost);\r
+\r
+ if((ret == 0) && (ulCost > FreeBlockCount()))\r
+ {\r
+ ret = -RED_ENOSPC;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ #if DINDIR_POINTERS > 0U\r
+ if(pInode->uDindirEntry != COORD_ENTRY_INVALID)\r
+ {\r
+ ret = BranchOneBlock(&pInode->ulDindirBlock, CAST_VOID_PTR_PTR(&pInode->pDindir), BFLAG_META_DINDIR);\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* In case we just created the double indirect.\r
+ */\r
+ pInode->pDindir->ulInode = pInode->ulInode;\r
+\r
+ pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDindirBlock;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ {\r
+ if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR))\r
+ {\r
+ ret = BranchOneBlock(&pInode->ulIndirBlock, CAST_VOID_PTR_PTR(&pInode->pIndir), BFLAG_META_INDIR);\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* In case we just created the indirect.\r
+ */\r
+ pInode->pIndir->ulInode = pInode->ulInode;\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ if(pInode->uDindirEntry != COORD_ENTRY_INVALID)\r
+ {\r
+ pInode->pDindir->aulEntries[pInode->uDindirEntry] = pInode->ulIndirBlock;\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulIndirBlock;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ if(depth == BRANCHDEPTH_FILE_DATA)\r
+ {\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ bool fAllocedNew = (pInode->ulDataBlock == BLOCK_SPARSE);\r
+ #endif\r
+ void **ppBufPtr = (fBuffer || (pInode->pbData != NULL)) ? CAST_VOID_PTR_PTR(&pInode->pbData) : NULL;\r
+\r
+ ret = BranchOneBlock(&pInode->ulDataBlock, ppBufPtr, 0U);\r
+\r
+ if(ret == 0)\r
+ {\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ if(pInode->uIndirEntry != COORD_ENTRY_INVALID)\r
+ {\r
+ pInode->pIndir->aulEntries[pInode->uIndirEntry] = pInode->ulDataBlock;\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ pInode->pInodeBuf->aulEntries[pInode->uInodeEntry] = pInode->ulDataBlock;\r
+ }\r
+\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ if(fAllocedNew)\r
+ {\r
+ if(pInode->pInodeBuf->ulBlocks < INODE_DATA_BLOCKS)\r
+ {\r
+ pInode->pInodeBuf->ulBlocks++;\r
+ }\r
+ else\r
+ {\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ }\r
+ #endif\r
+ }\r
+ }\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Branch a block.\r
+\r
+ The block can be a double indirect, indirect, or file data block.\r
+\r
+ The caller should have already handled the disk full implications of\r
+ branching this block.\r
+\r
+ @param pulBlock On entry, the current block number, which may be\r
+ BLOCK_SPARSE if the block is to be newly allocated. On\r
+ successful return, populated with the new block number,\r
+ which may be the same as the original block number if it\r
+ was not BLOCK_SPARSE and the block was already branched.\r
+ @param ppBuffer If NULL, indicates that the caller does not want to buffer\r
+ the branched block. If non-NULL, the caller does want the\r
+ branched block buffered, and the following is true: On\r
+ entry, the current buffer for the block, if there is one, or\r
+ NULL if there is no buffer. On successful exit, populated\r
+ with a buffer for the block, which will be dirty. If the\r
+ block number is initially BLOCK_SPARSE, there should be no\r
+ buffer for the block.\r
+ @param uBFlag The buffer type flags: BFLAG_META_DINDIR, BFLAG_META_INDIR,\r
+ or zero for file data.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS BranchOneBlock(\r
+ uint32_t *pulBlock,\r
+ void **ppBuffer,\r
+ uint16_t uBFlag)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(pulBlock == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ALLOCSTATE state = ALLOCSTATE_FREE;\r
+ uint32_t ulPrevBlock = *pulBlock;\r
+\r
+ if(ulPrevBlock != BLOCK_SPARSE)\r
+ {\r
+ ret = RedImapBlockState(ulPrevBlock, &state);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(state == ALLOCSTATE_NEW)\r
+ {\r
+ /* Block is already branched, so simply get it buffered dirty\r
+ if requested.\r
+ */\r
+ if(ppBuffer != NULL)\r
+ {\r
+ if(*ppBuffer != NULL)\r
+ {\r
+ RedBufferDirty(*ppBuffer);\r
+ }\r
+ else\r
+ {\r
+ ret = RedBufferGet(ulPrevBlock, uBFlag | BFLAG_DIRTY, ppBuffer);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Block does not exist or is committed state, so allocate a\r
+ new block for the branch.\r
+ */\r
+ ret = RedImapAllocBlock(pulBlock);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(ulPrevBlock == BLOCK_SPARSE)\r
+ {\r
+ /* Block did not exist previously, so just get it\r
+ buffered if requested.\r
+ */\r
+ if(ppBuffer != NULL)\r
+ {\r
+ if(*ppBuffer != NULL)\r
+ {\r
+ /* How could there be an existing buffer when\r
+ the block did not exist?\r
+ */\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = RedBufferGet(*pulBlock, (uint16_t)((uint32_t)uBFlag | BFLAG_NEW | BFLAG_DIRTY), ppBuffer);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Branch the buffer for the committed state block to\r
+ the newly allocated location.\r
+ */\r
+ if(ppBuffer != NULL)\r
+ {\r
+ if(*ppBuffer == NULL)\r
+ {\r
+ ret = RedBufferGet(ulPrevBlock, uBFlag, ppBuffer);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ RedBufferBranch(*ppBuffer, *pulBlock);\r
+ }\r
+ }\r
+\r
+ /* Mark the committed state block almost free.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedImapBlockSet(ulPrevBlock, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Compute the free space cost of branching a block.\r
+\r
+ The caller must first use RedInodeDataSeek() to the block to be branched.\r
+\r
+ @param pInode A pointer to the cached inode structure, whose coordinates\r
+ indicate the block to be branched.\r
+ @param depth A BRANCHDEPTH_ value indicating how much of the file\r
+ metadata structure needs to be branched.\r
+ @param pulCost On successful return, populated with the number of blocks\r
+ that must be allocated from free space in order to branch\r
+ the given block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EINVAL Invalid parameters.\r
+*/\r
+static REDSTATUS BranchBlockCost(\r
+ const CINODE *pInode,\r
+ BRANCHDEPTH depth,\r
+ uint32_t *pulCost)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!CINODE_IS_MOUNTED(pInode) || !pInode->fCoordInited || (depth > BRANCHDEPTH_MAX) || (pulCost == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ALLOCSTATE state;\r
+\r
+ /* ulCost is initialized to the maximum number of blocks that could\r
+ be branched, and decremented for every block we determine does not\r
+ need to be branched.\r
+ */\r
+ #if DINDIR_POINTERS > 0U\r
+ uint32_t ulCost = 3U;\r
+ #elif REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ uint32_t ulCost = 2U;\r
+ #else\r
+ uint32_t ulCost = 1U;\r
+ #endif\r
+\r
+ #if DINDIR_POINTERS > 0U\r
+ if(pInode->uDindirEntry != COORD_ENTRY_INVALID)\r
+ {\r
+ if(pInode->ulDindirBlock != BLOCK_SPARSE)\r
+ {\r
+ ret = RedImapBlockState(pInode->ulDindirBlock, &state);\r
+\r
+ if((ret == 0) && (state == ALLOCSTATE_NEW))\r
+ {\r
+ /* Double indirect already branched.\r
+ */\r
+ ulCost--;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* At this inode offset there are no double indirects.\r
+ */\r
+ ulCost--;\r
+ }\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ {\r
+ if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (depth >= BRANCHDEPTH_INDIR))\r
+ {\r
+ if(pInode->ulIndirBlock != BLOCK_SPARSE)\r
+ {\r
+ ret = RedImapBlockState(pInode->ulIndirBlock, &state);\r
+\r
+ if((ret == 0) && (state == ALLOCSTATE_NEW))\r
+ {\r
+ /* Indirect already branched.\r
+ */\r
+ ulCost--;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Either not branching this deep, or at this inode offset\r
+ there are no indirects.\r
+ */\r
+ ulCost--;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ if(depth == BRANCHDEPTH_FILE_DATA)\r
+ {\r
+ if(pInode->ulDataBlock != BLOCK_SPARSE)\r
+ {\r
+ ret = RedImapBlockState(pInode->ulDataBlock, &state);\r
+\r
+ if((ret == 0) && (state == ALLOCSTATE_NEW))\r
+ {\r
+ /* File data block already branched.\r
+ */\r
+ ulCost--;\r
+\r
+ /* If the file data block is branched, then its parent\r
+ nodes should be branched as well.\r
+ */\r
+ REDASSERT(ulCost == 0U);\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Not branching this deep.\r
+ */\r
+ ulCost--;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulCost = ulCost;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Yields the number of currently available free blocks.\r
+\r
+ Accounts for reserved blocks, subtracting the number of reserved blocks if\r
+ they are unavailable.\r
+\r
+ @return Number of currently available free blocks.\r
+*/\r
+static uint32_t FreeBlockCount(void)\r
+{\r
+ uint32_t ulFreeBlocks = gpRedMR->ulFreeBlocks;\r
+\r
+ #if RESERVED_BLOCKS > 0U\r
+ if(!gpRedCoreVol->fUseReservedBlocks)\r
+ {\r
+ if(ulFreeBlocks >= RESERVED_BLOCKS)\r
+ {\r
+ ulFreeBlocks -= RESERVED_BLOCKS;\r
+ }\r
+ else\r
+ {\r
+ ulFreeBlocks = 0U;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ return ulFreeBlocks;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements core volume operations.\r
+*/\r
+#include <redfs.h>\r
+#include <redcore.h>\r
+\r
+\r
+static bool MetarootIsValid(METAROOT *pMR, bool *pfSectorCRCIsValid);\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+static void MetaRootEndianSwap(METAROOT *pMetaRoot);\r
+#endif\r
+\r
+\r
+/** @brief Mount a file system volume.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.\r
+*/\r
+REDSTATUS RedVolMount(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);\r
+ #else\r
+ ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDONLY);\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedVolMountMaster();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedVolMountMetaroot();\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ (void)RedOsBDevClose(gbRedVolNum);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Mount the master block.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO Master block missing, corrupt, or inconsistent with the\r
+ compile-time driver settings.\r
+*/\r
+REDSTATUS RedVolMountMaster(void)\r
+{\r
+ REDSTATUS ret;\r
+ MASTERBLOCK *pMB;\r
+\r
+ /* Read the master block, to ensure that the disk was formatted with\r
+ Reliance Edge.\r
+ */\r
+ ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_META_MASTER, CAST_VOID_PTR_PTR(&pMB));\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Verify that the driver was compiled with the same settings that\r
+ the disk was formatted with. If not, the user has made a\r
+ mistake: either the driver settings are wrong, or the disk needs\r
+ to be reformatted.\r
+ */\r
+ if( (pMB->ulVersion != RED_DISK_LAYOUT_VERSION)\r
+ || (pMB->ulInodeCount != gpRedVolConf->ulInodeCount)\r
+ || (pMB->ulBlockCount != gpRedVolume->ulBlockCount)\r
+ || (pMB->uMaxNameLen != REDCONF_NAME_MAX)\r
+ || (pMB->uDirectPointers != REDCONF_DIRECT_POINTERS)\r
+ || (pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS)\r
+ || (pMB->bBlockSizeP2 != BLOCK_SIZE_P2)\r
+ || (((pMB->bFlags & MBFLAG_API_POSIX) != 0U) != (REDCONF_API_POSIX == 1))\r
+ || (((pMB->bFlags & MBFLAG_INODE_TIMESTAMPS) != 0U) != (REDCONF_INODE_TIMESTAMPS == 1))\r
+ || (((pMB->bFlags & MBFLAG_INODE_BLOCKS) != 0U) != (REDCONF_INODE_BLOCKS == 1)))\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ #if REDCONF_API_POSIX == 1\r
+ else if(((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) != (REDCONF_API_POSIX_LINK == 1))\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ #else\r
+ else if((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U)\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ /* Master block configuration is valid.\r
+\r
+ Save the sequence number of the master block in the volume,\r
+ since we need it later (see RedVolMountMetaroot()) and we do\r
+ not want to re-buffer the master block.\r
+ */\r
+ gpRedVolume->ullSequence = pMB->hdr.ullSequence;\r
+ }\r
+\r
+ RedBufferPut(pMB);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Mount the latest metaroot.\r
+\r
+ This function also populates the volume contexts.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO Both metaroots are missing or corrupt.\r
+*/\r
+REDSTATUS RedVolMountMetaroot(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[0U]);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[1U]);\r
+ }\r
+\r
+ /* Determine which metaroot is the most recent copy that was written\r
+ completely.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bMR = UINT8_MAX;\r
+ bool fSectorCRCIsValid;\r
+\r
+ if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid))\r
+ {\r
+ bMR = 0U;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]);\r
+ #endif\r
+ }\r
+ else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ else\r
+ {\r
+ /* Metaroot is not valid, so it is ignored and there's nothing\r
+ to do here.\r
+ */\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid))\r
+ {\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]);\r
+ #endif\r
+\r
+ if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence))\r
+ {\r
+ bMR = 1U;\r
+ }\r
+ }\r
+ else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ else\r
+ {\r
+ /* Metaroot is not valid, so it is ignored and there's nothing\r
+ to do here.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(bMR == UINT8_MAX)\r
+ {\r
+ /* Neither metaroot was valid.\r
+ */\r
+ ret = -RED_EIO;\r
+ }\r
+ else\r
+ {\r
+ gpRedCoreVol->bCurMR = bMR;\r
+ gpRedMR = &gpRedCoreVol->aMR[bMR];\r
+ }\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Normally the metaroot contains the highest sequence number, but the\r
+ master block is the last block written during format, so on a\r
+ freshly formatted volume the master block sequence number (stored in\r
+ gpRedVolume->ullSequence) will be higher than that in the metaroot.\r
+ */\r
+ if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence)\r
+ {\r
+ gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence;\r
+ }\r
+\r
+ /* gpRedVolume->ullSequence stores the *next* sequence number; to avoid\r
+ giving the next node written to disk the same sequence number as the\r
+ metaroot, increment it here.\r
+ */\r
+ ret = RedVolSeqNumIncrement();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ gpRedVolume->fMounted = true;\r
+ #if REDCONF_READ_ONLY == 0\r
+ gpRedVolume->fReadOnly = false;\r
+ #endif\r
+\r
+ #if RESERVED_BLOCKS > 0U\r
+ gpRedCoreVol->fUseReservedBlocks = false;\r
+ #endif\r
+ gpRedCoreVol->ulAlmostFreeBlocks = 0U;\r
+\r
+ gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR;\r
+ gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR;\r
+ gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Determine whether the metaroot is valid.\r
+\r
+ @param pMR The metaroot buffer.\r
+ @param pfSectorCRCIsValid Populated with whether the first sector of the\r
+ metaroot buffer is valid.\r
+\r
+ @return Whether the metaroot is valid.\r
+\r
+ @retval true The metaroot buffer is valid.\r
+ @retval false The metaroot buffer is invalid.\r
+*/\r
+static bool MetarootIsValid(\r
+ METAROOT *pMR,\r
+ bool *pfSectorCRCIsValid)\r
+{\r
+ bool fRet = false;\r
+\r
+ if(pfSectorCRCIsValid == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else if(pMR == NULL)\r
+ {\r
+ REDERROR();\r
+ *pfSectorCRCIsValid = false;\r
+ }\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ else if(RedRev32(pMR->hdr.ulSignature) != META_SIG_METAROOT)\r
+ #else\r
+ else if(pMR->hdr.ulSignature != META_SIG_METAROOT)\r
+ #endif\r
+ {\r
+ *pfSectorCRCIsValid = false;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMR);\r
+ uint32_t ulSectorCRC = pMR->ulSectorCRC;\r
+ uint32_t ulCRC;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ ulSectorCRC = RedRev32(ulSectorCRC);\r
+ #endif\r
+\r
+ /* The sector CRC was zero when the CRC was computed during the\r
+ transaction, so it must be zero here.\r
+ */\r
+ pMR->ulSectorCRC = 0U;\r
+\r
+ ulCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);\r
+\r
+ fRet = ulCRC == ulSectorCRC;\r
+ *pfSectorCRCIsValid = fRet;\r
+\r
+ if(fRet)\r
+ {\r
+ if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)\r
+ {\r
+ ulCRC = RedCrc32Update(ulCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);\r
+ }\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ ulCRC = RedRev32(ulCRC);\r
+ #endif\r
+\r
+ fRet = ulCRC == pMR->hdr.ulCRC;\r
+ }\r
+ }\r
+\r
+ return fRet;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Commit a transaction point.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedVolTransact(void)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ REDASSERT(!gpRedVolume->fReadOnly); /* Should be checked by caller. */\r
+\r
+ if(gpRedCoreVol->fBranched)\r
+ {\r
+ gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks;\r
+ gpRedCoreVol->ulAlmostFreeBlocks = 0U;\r
+\r
+ ret = RedBufferFlush(0U, gpRedVolume->ulBlockCount);\r
+\r
+ if(ret == 0)\r
+ {\r
+ gpRedMR->hdr.ulSignature = META_SIG_METAROOT;\r
+ gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence;\r
+\r
+ ret = RedVolSeqNumIncrement();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(gpRedMR);\r
+ uint32_t ulSectorCRC;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ MetaRootEndianSwap(gpRedMR);\r
+ #endif\r
+\r
+ gpRedMR->ulSectorCRC = 0U;\r
+\r
+ ulSectorCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);\r
+\r
+ if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)\r
+ {\r
+ gpRedMR->hdr.ulCRC = RedCrc32Update(ulSectorCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);\r
+ }\r
+ else\r
+ {\r
+ gpRedMR->hdr.ulCRC = ulSectorCRC;\r
+ }\r
+\r
+ gpRedMR->ulSectorCRC = ulSectorCRC;\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ gpRedMR->hdr.ulCRC = RedRev32(gpRedMR->hdr.ulCRC);\r
+ gpRedMR->ulSectorCRC = RedRev32(gpRedMR->ulSectorCRC);\r
+ #endif\r
+\r
+ /* Flush the block device before writing the metaroot, so that all\r
+ previously written blocks are guaranteed to be on the media before\r
+ the metaroot is written. Otherwise, if the block device reorders\r
+ the writes, the metaroot could reach the media before metadata it\r
+ points at, creating a window for disk corruption if power is lost.\r
+ */\r
+ ret = RedIoFlush(gbRedVolNum);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoWrite(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + gpRedCoreVol->bCurMR, 1U, gpRedMR);\r
+\r
+ #ifdef REDCONF_ENDIAN_SWAP\r
+ MetaRootEndianSwap(gpRedMR);\r
+ #endif\r
+ }\r
+\r
+ /* Flush the block device to force the metaroot write to the media. This\r
+ guarantees the transaction point is really complete before we return.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = RedIoFlush(gbRedVolNum);\r
+ }\r
+\r
+ /* Toggle to the other metaroot buffer. The working state and committed\r
+ state metaroot buffers exchange places.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR;\r
+\r
+ gpRedCoreVol->aMR[bNextMR] = *gpRedMR;\r
+ gpRedCoreVol->bCurMR = bNextMR;\r
+\r
+ gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];\r
+\r
+ gpRedCoreVol->fBranched = false;\r
+ }\r
+\r
+ CRITICAL_ASSERT(ret == 0);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+static void MetaRootEndianSwap(\r
+ METAROOT *pMetaRoot)\r
+{\r
+ if(pMetaRoot == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ pMetaRoot->ulSectorCRC = RedRev32(pMetaRoot->ulSectorCRC);\r
+ pMetaRoot->ulFreeBlocks = RedRev32(pMetaRoot->ulFreeBlocks);\r
+ #if REDCONF_API_POSIX == 1\r
+ pMetaRoot->ulFreeInodes = RedRev32(pMetaRoot->ulFreeInodes);\r
+ #endif\r
+ pMetaRoot->ulAllocNextBlock = RedRev32(pMetaRoot->ulAllocNextBlock);\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Process a critical file system error.\r
+\r
+ @param pszFileName The file in which the error occurred.\r
+ @param ulLineNum The line number at which the error occurred.\r
+*/\r
+void RedVolCriticalError(\r
+ const char *pszFileName,\r
+ uint32_t ulLineNum)\r
+{\r
+ #if REDCONF_OUTPUT == 1\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(!gpRedVolume->fReadOnly)\r
+ {\r
+ RedOsOutputString("Critical file system error in Reliance Edge, setting volume to READONLY\n");\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ RedOsOutputString("Critical file system error in Reliance Edge (volume already READONLY)\n");\r
+ }\r
+ #endif\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ gpRedVolume->fReadOnly = true;\r
+ #endif\r
+\r
+ #if REDCONF_ASSERTS == 1\r
+ RedOsAssertFail(pszFileName, ulLineNum);\r
+ #else\r
+ (void)pszFileName;\r
+ (void)ulLineNum;\r
+ #endif\r
+}\r
+\r
+\r
+/** @brief Increment the sequence number.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL Cannot increment sequence number: maximum value reached.\r
+ This should not ever happen.\r
+*/\r
+REDSTATUS RedVolSeqNumIncrement(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gpRedVolume->ullSequence == UINT64_MAX)\r
+ {\r
+ /* In practice this should never, ever happen; to get here, there would\r
+ need to be UINT64_MAX disk writes, which would take eons: longer\r
+ than the lifetime of any product or storage media. If this assert\r
+ fires and the current year is still written with four digits,\r
+ suspect memory corruption.\r
+ */\r
+ CRITICAL_ERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ gpRedVolume->ullSequence++;\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDCORE_H\r
+#define REDCORE_H\r
+\r
+\r
+#include <redstat.h>\r
+#include <redvolume.h>\r
+#include "rednodes.h"\r
+#include "redcoremacs.h"\r
+#include "redcorevol.h"\r
+\r
+\r
+#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */\r
+#define META_SIG_METAROOT (0x4154454DU) /* 'META' */\r
+#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */\r
+#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */\r
+#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */\r
+#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */\r
+\r
+\r
+REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer);\r
+REDSTATUS RedIoFlush(uint8_t bVolNum);\r
+#endif\r
+\r
+\r
+/** Indicates a block buffer is dirty (its contents are different than the\r
+ contents of the corresponding block on disk); or, when passed into\r
+ RedBufferGet(), indicates that the buffer should be marked dirty.\r
+*/\r
+#define BFLAG_DIRTY ((uint16_t) 0x0001U)\r
+\r
+/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its\r
+ contents should be zeroed instead of being read from disk. Always used in\r
+ combination with BFLAG_DIRTY.\r
+*/\r
+#define BFLAG_NEW ((uint16_t) 0x0002U)\r
+\r
+/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node.\r
+*/\r
+#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META))\r
+\r
+/** Indicates that a block buffer is an imap (IMAPNODE) metadata node.\r
+*/\r
+#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META))\r
+\r
+/** Indicates that a block buffer is an inode (INODE) metadata node.\r
+*/\r
+#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META))\r
+\r
+/** Indicates that a block buffer is an indirect (INDIR) metadata node.\r
+*/\r
+#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META))\r
+\r
+/** Indicates that a block buffer is a double indirect (DINDIR) metadata node.\r
+*/\r
+#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META))\r
+\r
+/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet()\r
+ should not use this flag; instead, use one of the BFLAG_META_* flags.\r
+*/\r
+#define BFLAG_META ((uint16_t) 0x8000U)\r
+\r
+\r
+void RedBufferInit(void);\r
+REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer);\r
+void RedBufferPut(const void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount);\r
+void RedBufferDirty(const void *pBuffer);\r
+void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew);\r
+#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED\r
+void RedBufferDiscard(const void *pBuffer);\r
+#endif\r
+#endif\r
+REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount);\r
+\r
+\r
+/** @brief Allocation state of a block.\r
+*/\r
+typedef enum\r
+{\r
+ ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */\r
+ ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */\r
+ ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */\r
+ ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */\r
+} ALLOCSTATE;\r
+\r
+REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated);\r
+REDSTATUS RedImapAllocBlock(uint32_t *pulBlock);\r
+#endif\r
+REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState);\r
+\r
+#if REDCONF_IMAP_INLINE == 1\r
+REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);\r
+REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated);\r
+#endif\r
+\r
+#if REDCONF_IMAP_EXTERNAL == 1\r
+REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);\r
+REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated);\r
+uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode);\r
+#endif\r
+\r
+\r
+/** @brief Cached inode structure.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t ulInode; /**< The inode number of the cached inode. */\r
+ #if REDCONF_API_POSIX == 1\r
+ bool fDirectory; /**< True if the inode is a directory. */\r
+ #endif\r
+ #if REDCONF_READ_ONLY == 0\r
+ bool fBranched; /**< True if the inode is branched (writeable). */\r
+ bool fDirty; /**< True if the inode buffer is dirty. */\r
+ #endif\r
+ bool fCoordInited; /**< True after the first seek. */\r
+\r
+ INODE *pInodeBuf; /**< Pointer to the inode buffer. */\r
+ #if DINDIR_POINTERS > 0U\r
+ DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ INDIR *pIndir; /**< Pointer to the indirect node buffer. */\r
+ #endif\r
+ uint8_t *pbData; /**< Pointer to the data block buffer. */\r
+\r
+ /* All the members below this point are part of the seek coordinates; see\r
+ RedInodeDataSeek().\r
+ */\r
+ uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */\r
+ #if DINDIR_POINTERS > 0U\r
+ uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */\r
+ #endif\r
+ uint32_t ulDataBlock; /**< Physical block number of the file data block. */\r
+\r
+ uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */\r
+ #if DINDIR_POINTERS > 0U\r
+ uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */\r
+ #endif\r
+ #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+ uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */\r
+ #endif\r
+} CINODE;\r
+\r
+#define CINODE_IS_MOUNTED(pInode) (((pInode) != NULL) && INODE_IS_VALID((pInode)->ulInode) && ((pInode)->pInodeBuf != NULL))\r
+#define CINODE_IS_DIRTY(pInode) (CINODE_IS_MOUNTED(pInode) && (pInode)->fDirty)\r
+\r
+\r
+#define IPUT_UPDATE_ATIME (0x01U)\r
+#define IPUT_UPDATE_MTIME (0x02U)\r
+#define IPUT_UPDATE_CTIME (0x04U)\r
+#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME)\r
+\r
+\r
+REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedInodeBranch(CINODE *pInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)\r
+REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode);\r
+#endif\r
+#if DELETE_SUPPORTED\r
+REDSTATUS RedInodeDelete(CINODE *pInode);\r
+REDSTATUS RedInodeLinkDec(CINODE *pInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+REDSTATUS RedInodeFree(CINODE *pInode);\r
+#endif\r
+void RedInodePut(CINODE *pInode, uint8_t bTimeFields);\r
+void RedInodePutCoord(CINODE *pInode);\r
+#if DINDIR_POINTERS > 0U\r
+void RedInodePutDindir(CINODE *pInode);\r
+#endif\r
+#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES\r
+void RedInodePutIndir(CINODE *pInode);\r
+#endif\r
+void RedInodePutData(CINODE *pInode);\r
+#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1)\r
+REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree);\r
+#endif\r
+REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated);\r
+\r
+REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);\r
+#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED\r
+REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize);\r
+#endif\r
+#endif\r
+REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock);\r
+REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock);\r
+\r
+#if REDCONF_API_POSIX == 1\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode);\r
+#endif\r
+#if DELETE_SUPPORTED\r
+REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx);\r
+#endif\r
+REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode);\r
+#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)\r
+REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)\r
+REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode);\r
+#endif\r
+#endif\r
+\r
+REDSTATUS RedVolMount(void);\r
+REDSTATUS RedVolMountMaster(void);\r
+REDSTATUS RedVolMountMetaroot(void);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedVolTransact(void);\r
+#endif\r
+void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum);\r
+REDSTATUS RedVolSeqNumIncrement(void);\r
+\r
+#if FORMAT_SUPPORTED\r
+REDSTATUS RedVolFormat(void);\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDCOREMACS_H\r
+#define REDCOREMACS_H\r
+\r
+\r
+#define BLOCK_NUM_MASTER (0UL) /* Block number of the master block. */\r
+#define BLOCK_NUM_FIRST_METAROOT (1UL) /* Block number of the first metaroot. */\r
+\r
+#define BLOCK_SPARSE (0U)\r
+\r
+#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS)\r
+#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES)\r
+\r
+#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES)\r
+#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS)\r
+#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS)\r
+#define INODE_SIZE_MAX (UINT64_SUFFIX(1) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS)\r
+\r
+\r
+/* First inode number that can be allocated.\r
+*/\r
+#if REDCONF_API_POSIX == 1\r
+#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U)\r
+#else\r
+#define INODE_FIRST_FREE (INODE_FIRST_VALID)\r
+#endif\r
+\r
+/** @brief Determine if an inode number is valid.\r
+*/\r
+#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)))\r
+\r
+\r
+/* The number of blocks reserved to allow a truncate or delete operation to\r
+ complete when the disk is otherwise full.\r
+\r
+ The more expensive of the two operations is delete, which has to actually\r
+ write to a file data block to remove the directory entry.\r
+*/\r
+#if REDCONF_READ_ONLY == 1\r
+ #define RESERVED_BLOCKS 0U\r
+#elif (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+ #if DINDIR_POINTERS > 0U\r
+ #define RESERVED_BLOCKS 3U\r
+ #elif REDCONF_INDIRECT_POINTERS > 0U\r
+ #define RESERVED_BLOCKS 2U\r
+ #else\r
+ #define RESERVED_BLOCKS 1U\r
+ #endif\r
+#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))\r
+ #if DINDIR_POINTERS > 0U\r
+ #define RESERVED_BLOCKS 2U\r
+ #elif REDCONF_INDIRECT_POINTERS > 0U\r
+ #define RESERVED_BLOCKS 1U\r
+ #else\r
+ #define RESERVED_BLOCKS 0U\r
+ #endif\r
+#else\r
+ #define RESERVED_BLOCKS 0U\r
+#endif\r
+\r
+\r
+#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR())\r
+#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__)\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDCOREVOL_H\r
+#define REDCOREVOL_H\r
+\r
+\r
+/** @brief Per-volume run-time data specific to the core.\r
+*/\r
+typedef struct\r
+{\r
+ /** Whether this volume uses the inline imap (true) or external imap\r
+ (false). Computed at initialization time based on the block count.\r
+ */\r
+ bool fImapInline;\r
+\r
+#if REDCONF_IMAP_EXTERNAL == 1\r
+ /** First block number of the on-disk imap. Valid only when fImapInline\r
+ is false.\r
+ */\r
+ uint32_t ulImapStartBN;\r
+\r
+ /** The number of double-allocated imap nodes that make up the imap.\r
+ */\r
+ uint32_t ulImapNodeCount;\r
+#endif\r
+\r
+ /** Block number where the inode table starts.\r
+ */\r
+ uint32_t ulInodeTableStartBN;\r
+\r
+ /** First block number that can be allocated.\r
+ */\r
+ uint32_t ulFirstAllocableBN;\r
+\r
+ /** The two metaroot structures, committed and working state.\r
+ */\r
+ METAROOT aMR[2U];\r
+\r
+ /** The index of the current metaroot; must be 0 or 1.\r
+ */\r
+ uint8_t bCurMR;\r
+\r
+ /** Whether the volume has been branched or not.\r
+ */\r
+ bool fBranched;\r
+\r
+ /** The number of blocks which will become free after the next transaction.\r
+ */\r
+ uint32_t ulAlmostFreeBlocks;\r
+\r
+ #if RESERVED_BLOCKS > 0U\r
+ /** Whether to use the blocks reserved for operations that create free\r
+ space.\r
+ */\r
+ bool fUseReservedBlocks;\r
+ #endif\r
+} COREVOLUME;\r
+\r
+/* Pointer to the core volume currently being accessed; populated during\r
+ RedCoreVolSetCurrent().\r
+*/\r
+extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol;\r
+\r
+/* Pointer to the metaroot currently being accessed; populated during\r
+ RedCoreVolSetCurrent() and RedCoreVolTransact().\r
+*/\r
+extern METAROOT *gpRedMR;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDNODES_H\r
+#define REDNODES_H\r
+\r
+\r
+#define NODEHEADER_SIZE (16U)\r
+#define NODEHEADER_OFFSET_SIG (0U)\r
+#define NODEHEADER_OFFSET_CRC (4U)\r
+#define NODEHEADER_OFFSET_SEQ (8U)\r
+\r
+/** @brief Common header for all metadata nodes.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */\r
+ uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */\r
+ uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */\r
+} NODEHEADER;\r
+\r
+\r
+/** Flag set in the master block when REDCONF_API_POSIX == 1. */\r
+#define MBFLAG_API_POSIX (0x01U)\r
+\r
+/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */\r
+#define MBFLAG_INODE_TIMESTAMPS (0x02U)\r
+\r
+/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */\r
+#define MBFLAG_INODE_BLOCKS (0x04U)\r
+\r
+/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */\r
+#define MBFLAG_INODE_NLINK (0x08U)\r
+\r
+\r
+/** @brief Node which identifies the volume and stores static volume information.\r
+*/\r
+typedef struct\r
+{\r
+ NODEHEADER hdr; /**< Common node header. */\r
+\r
+ uint32_t ulVersion; /**< On-disk layout version number. */\r
+ char acBuildNum[8U]; /**< Build number of the product (not null terminated). */\r
+ uint32_t ulFormatTime; /**< Date and time the volume was formatted. */\r
+ uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */\r
+ uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */\r
+ uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */\r
+ uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */\r
+ uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */\r
+ uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */\r
+ uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */\r
+} MASTERBLOCK;\r
+\r
+\r
+#if REDCONF_API_POSIX == 1\r
+#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */\r
+#else\r
+#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */\r
+#endif\r
+#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */\r
+#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U)\r
+\r
+/** @brief Metadata root node; each volume has two.\r
+*/\r
+typedef struct\r
+{\r
+ NODEHEADER hdr; /**< Common node header. */\r
+\r
+ uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */\r
+ uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */\r
+ #if REDCONF_API_POSIX == 1\r
+ uint32_t ulFreeInodes; /**< Number of inode slots that are free. */\r
+ #endif\r
+ uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */\r
+\r
+ /** Imap bitmap. With inline imaps, this is the imap bitmap that indicates\r
+ which inode blocks are used and which allocable blocks are used.\r
+ Otherwise, this bitmap toggles nodes in the external imap between one\r
+ of two possible block locations.\r
+ */\r
+ uint8_t abEntries[METAROOT_ENTRY_BYTES];\r
+} METAROOT;\r
+\r
+\r
+#if REDCONF_IMAP_EXTERNAL == 1\r
+#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */\r
+#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */\r
+#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U)\r
+\r
+/** @brief One node of the external imap.\r
+*/\r
+typedef struct\r
+{\r
+ NODEHEADER hdr; /**< Common node header. */\r
+\r
+ /** Bitmap which indicates which inode blocks are used and which allocable\r
+ blocks are used.\r
+ */\r
+ uint8_t abEntries[IMAPNODE_ENTRY_BYTES];\r
+} IMAPNODE;\r
+#endif\r
+\r
+\r
+#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \\r
+ ((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U))\r
+#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U)\r
+\r
+#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS))\r
+ #error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS"\r
+#endif\r
+#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS))\r
+ #error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS"\r
+#endif\r
+\r
+/** @brief Stores metadata for a file or directory.\r
+*/\r
+typedef struct\r
+{\r
+ NODEHEADER hdr; /**< Common node header. */\r
+\r
+ uint64_t ullSize; /**< Size of the inode, in bytes. */\r
+#if REDCONF_INODE_BLOCKS == 1\r
+ uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */\r
+#endif\r
+#if REDCONF_INODE_TIMESTAMPS == 1\r
+ uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */\r
+ uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */\r
+ uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */\r
+#endif\r
+ uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */\r
+#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+ uint16_t uNLink; /**< Link count, number of names pointing to the inode. */\r
+#else\r
+ uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */\r
+#endif\r
+#if REDCONF_API_POSIX == 1\r
+ uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */\r
+#endif\r
+\r
+ /** Block numbers for lower levels of the file metadata structure. Some\r
+ fraction of these entries are for direct pointers (file data block\r
+ numbers), some for indirect pointers, some for double-indirect\r
+ pointers; the number allocated to each is static but user-configurable.\r
+ For all types, an array slot is zero if the range is sparse or beyond\r
+ the end of file.\r
+ */\r
+ uint32_t aulEntries[INODE_ENTRIES];\r
+} INODE;\r
+\r
+\r
+#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U)\r
+#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U)\r
+\r
+/** @brief Node for storing block pointers.\r
+*/\r
+typedef struct\r
+{\r
+ NODEHEADER hdr; /**< Common node header. */\r
+\r
+ uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */\r
+\r
+ /** For indirect nodes, stores block numbers of file data. For double\r
+ indirect nodes, stores block numbers of indirect nodes. An array\r
+ slot is zero if the corresponding block or indirect range is beyond\r
+ the end of file or entirely sparse.\r
+ */\r
+ uint32_t aulEntries[INDIR_ENTRIES];\r
+} INDIR, DINDIR;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+Datalight Coding Style\r
+======================\r
+\r
+This is a description of the Datalight Coding Style intended for third parties\r
+who want to contribute code to Reliance Edge. This document is derived from the\r
+DDSS Coding Guidelines, but only contains a subset of the content which is most\r
+likely to be relevant to third party contributors.\r
+\r
+Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes\r
+many rules that affect coding style. Unfortunately the MISRA-C:2012 document is\r
+not freely available, and is much too long to be effectively summarized, but if\r
+you are familiar with the rules, adhere to them. A few important rules of\r
+thumb: avoid the goto and continue keywords; avoid using more than one break\r
+in a loop; and avoid having more than one return from a function (single point\r
+of exit); default cases in every switch statement; avoid recursion; and make\r
+generous use of parentheses. Outside of the file system driver, in tests and\r
+host tools, the MISRA-C rules are relaxed.\r
+\r
+Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this\r
+style are matters of preference, but when contributing code to Datalight an\r
+effort should be made to use this style for the sake of consistency.\r
+\r
+Below is an example function, which illustrates several key points of Datalight\r
+Coding Style:\r
+\r
+/** @brief One-sentence description of what this function does.\r
+\r
+ Additional description.\r
+\r
+ @param ulFirstParameter Description of the parameter.\r
+ @param pszPointer Description of the parameter.\r
+\r
+ @return Describe the return value.\r
+\r
+ @retval true Optional description of specific return value.\r
+ @retval false Optional description of specific return value.\r
+*/\r
+bool ExampleFunction(\r
+ uint32_t ulFirstParameter,\r
+ char *pszPointer)\r
+{\r
+ bool fStatus = true;\r
+\r
+ /* This is a single-line comment.\r
+ */\r
+ if(ulFirstParameter > 0U)\r
+ {\r
+ /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit\r
+ amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt\r
+ ut labore et dolore magna aliqua.\r
+ */\r
+ FunctionCall();\r
+\r
+ while(fStatus)\r
+ {\r
+ fStatus = AnotherFunction(ulFirstParameter, pszPointer);\r
+ }\r
+ }\r
+\r
+ return fStatus;\r
+}\r
+\r
+Tab Stop Conventions\r
+--------------------\r
+\r
+In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in\r
+other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a\r
+tab width of 8.\r
+\r
+Naming\r
+------\r
+\r
+Datalight uses CamelCase for functions and variables. Type names are generally\r
+UPPERCASE, except for standard types like uint32_t. Preprocessor macros are\r
+UPPERCASE, with words separated by underscores (for example, INODE_INVALID).\r
+\r
+Doxygen Documentation\r
+---------------------\r
+\r
+Doxygen is used to document functions (including static functions), along with\r
+types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash\r
+(thus "@param" not "\param").\r
+\r
+Function Declarations\r
+---------------------\r
+\r
+Multi-line function declarations are preferred, as they tend to be more\r
+readable. Use the following form:\r
+\r
+static bool ExampleFunctionDeclaration(\r
+ uint32_t ulFirstParameter,\r
+ char *pszPointer,\r
+ uint8_t **ppbBuffer)\r
+{\r
+ uint16_t uLocalVar; /* descriptive comment */\r
+ uint8_t *pbBuffer = NULL; /* descriptive comment */\r
+\r
+ Function body...\r
+}\r
+\r
+The following guidelines should be used:\r
+\r
+- Align both the data-type and the variable names, for parameters and locals, at\r
+ the same level if practical.\r
+- For pointer types, the '*' belongs to the variable name---it's not part of the\r
+ data-type, so keep it with the variable name.\r
+- If useful, single line comments may be used to describe local variables (not\r
+ a requirement).\r
+- For functions with no parameters, the "void" declaration does not need to be\r
+ on a separate line.\r
+- Generally each variable should be declared on a separate line. This promotes\r
+ readability, and facilitates having a comment for each variable.\r
+\r
+Function declarations should be spaced apart by two blank lines between the\r
+closing brace which ends a function and the Doxygen comment which starts the\r
+next.\r
+\r
+Curly Braces\r
+------------\r
+\r
+Datalight lines up all curly braces vertically. As per MISRA-C, curly braces\r
+are never omitted, even if the braces contain only a single statement.\r
+\r
+For consistency, even structure declarations and initializations should use the\r
+same style, with the curly braces lined up vertically. One exception is for\r
+structure initializations where both the opening and closing curly braces can\r
+fit on the same line. If so, do it.\r
+\r
+Code Comments\r
+-------------\r
+\r
+Datalight uses the standard C style /* comments */. C++ style comments (//) are\r
+never used. The Datalight standard comment style is shown below. This style\r
+applies to all general comments within the code.\r
+\r
+/* This is a single-line comment.\r
+*/\r
+if(ulFirstParameter > 0U)\r
+{\r
+ /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet,\r
+ consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore\r
+ et dolore magna aliqua.\r
+ */\r
+ while(fStatus)\r
+ {\r
+ }\r
+}\r
+\r
+Note the characteristics:\r
+\r
+- The /* and */ align with the natural 4 character indentation.\r
+- The comment text is exactly indented another 4 characters.\r
+- The comment text starts on the same line as the opening /*.\r
+- The terminating */ is on its own line.\r
+- There is usually a single blank line preceding the comment, however if the\r
+ preceding line is an opening curly brace, then an extra blank line is not\r
+ necessary.\r
+- There is usually no blank line after the comment, but rather the closing */\r
+ "attaches" the comment to the code about which the comment refers.\r
+- These comments should always fit with the standard 80 character margin.\r
+\r
+Comments where the /* and */ are on the same line may be used in a few places:\r
+\r
+- For variable or parameter descriptions, where the comment fits on the same\r
+ line as the declaration.\r
+- For structure member declarations, where the comment fits on the same line as\r
+ the declaration.\r
+- For macros or preprocessor logic, where the comment fits on the same line.\r
+\r
+It is OK for such comments to exceed the 80 character margin by a small amount,\r
+if necessary, as this sometimes promotes code readability.\r
+\r
+Indentation Style\r
+-----------------\r
+\r
+The general paradigm used in Datalight code is that curly braces line up\r
+vertically, and everything in between them is indented. This should include all\r
+comments, labels, and preprocessor symbols. The only things which are aligned\r
+at the left-most columns are:\r
+\r
+- Symbols, variables, declarations, and preprocessor logic which are at the\r
+ module-scope (outside of a function)\r
+- Comments which are outside of a function\r
+- Function declarations\r
+- Function open and closing curly braces\r
+\r
+Typically comments are always lined up directly with the code to which they\r
+apply.\r
+\r
+Labels (when used; gotos are disallowed in driver code) are lined up two\r
+characters to the left of the code they reside in, to make them stand out, while\r
+as the same time, still remaining subservient to the level of curly braces in\r
+which they reside. For example:\r
+\r
+bool ExampleLabelUsage(void)\r
+{\r
+ MutexLock();\r
+\r
+ Lots of complicated code...\r
+\r
+ Unlock:\r
+\r
+ MutexUnlock();\r
+\r
+ return fSuccess;\r
+}\r
+\r
+Preprocessor logic, such as controlling features which are conditionally\r
+compiled in or out, should not disrupt the flow of the code, but rather should\r
+be indented in similar fashion to the code it controls, but positioned two\r
+characters to the left. For example, consider the following code snippet. The\r
+preprocessor conditions are both indented relative to the outer curly braces,\r
+but do not disrupt the normal code flow.\r
+\r
+int32_t red_statvfs(\r
+ const char *pszVolume,\r
+ REDSTATFS *pStatvfs)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolStat(pStatvfs);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+Note that, like anything else between curly brackets, the contents of a switch\r
+statement are indented:\r
+\r
+switch(ulSignature)\r
+{\r
+ case META_SIG_MASTER:\r
+ fValid = (uFlags == BFLAG_META_MASTER);\r
+ break;\r
+ case META_SIG_IMAP:\r
+ fValid = (uFlags == BFLAG_META_IMAP);\r
+ break;\r
+ case META_SIG_INODE:\r
+ fValid = (uFlags == BFLAG_META_INODE);\r
+ break;\r
+ case META_SIG_DINDIR:\r
+ fValid = (uFlags == BFLAG_META_DINDIR);\r
+ break;\r
+ case META_SIG_INDIR:\r
+ fValid = (uFlags == BFLAG_META_INDIR);\r
+ break;\r
+ default:\r
+ fValid = false;\r
+ break;\r
+}\r
+\r
+Maximum Line Length\r
+-------------------\r
+\r
+The maximum line length for code need not be rigidly limited to the traditional\r
+80 characters. Nevertheless the line lengths should be kept reasonable.\r
+Anything longer than 100 to 120 characters should probably be broken up. The\r
+most important consideration is readability---fitting on the screen is important\r
+for readability, but equally important is facilitating an easy understanding of\r
+the logical code flow.\r
+\r
+There are a few exceptions on both sides of the issue. Generally comments\r
+should be limited to 80 characters always. Some lines of code may exceed the\r
+120 character length by a large margin, if it makes the code more understandable\r
+and maintainable. This is especially true when dealing with code that generates\r
+output which needs to be lined up.\r
+\r
+Regardless of everything else, no lines should exceed 250 characters because\r
+some editors cannot handle anything larger.\r
+\r
+Maximum Display Output Line Length\r
+----------------------------------\r
+\r
+Any code which displays TTY style output, whether on a screen or a terminal,\r
+should be constructed so the output is readable and wraps properly on an 80\r
+character wide display. This primarily applies to the "standard" output from\r
+various tests and tools as well as syntax output for those tests and tools;\r
+debug output can violate this rule.\r
+\r
+Preprocessor Notation\r
+---------------------\r
+\r
+Don't use preprocessor notation where the # is separated from the keyword by one\r
+or more white spaces. For example, don't do:\r
+\r
+#ifndef SYMBOL1\r
+# define SYMBOL1\r
+#endif\r
+\r
+Instead, do:\r
+\r
+#ifndef SYMBOL1\r
+ #define SYMBOL1\r
+#endif\r
+\r
+Hexadecimal Notation\r
+--------------------\r
+\r
+Use uppercase for any alphabetic hexadecimal digits, and lower case for the\r
+notational element. For example:\r
+\r
+#define HEXNUM 0x123abd /* Bad */\r
+#define HEXNUM 0X123ABD /* Bad */\r
+#define HEXNUM 0x123ABD /* Good */\r
+\r
+Hungarian Notation\r
+------------------\r
+\r
+Datalight uses Hungarian notation. The following type prefixes are used:\r
+\r
+Type Prefix | Meaning\r
+----------- | -------\r
+c | char\r
+uc | unsigned char\r
+i | int\r
+n | unsigned int or size_t\r
+b | uint8_t\r
+u | uint16_t\r
+ul | uint32_t\r
+ull | uint64_t\r
+sz | array of char that will be null-terminated\r
+f | bool\r
+h | A handle\r
+fn | A function (always used with the "p" modifier)\r
+\r
+There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t,\r
+although some code uses unofficial variants (like "ll" for int64_t).\r
+\r
+The following modifiers may be used in combination with the type prefixes\r
+defined above, or in combination with other types:\r
+\r
+Modifier | Meaning\r
+-------- | -------\r
+a | An array\r
+p | A pointer\r
+g | A global variable\r
+\r
+Notes:\r
+\r
+- There is no standard Hungarian for structure declarations, however the use of\r
+ the "a" and "p" modifiers is completely appropriate (and expected).\r
+- For those data types which do not have any standard defined Hungarian prefix,\r
+ using none is preferable to misusing another prefix which would lead to\r
+ confusion.\r
+- The "p" pointer modifier must be used such that a variable which is a pointer\r
+ to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the\r
+ variable name should have the same number of "p" prefixes as the declaration\r
+ has asterisks. This allows pointer expressions to be easily decoded using\r
+ cancellation.\r
+\r
+Variable Scope\r
+--------------\r
+\r
+Declare a variable in the narrowest scope in which it is meaningful.\r
+Unnecessarily declaring all variables at the beginning of a function, where they\r
+may be physically far from where they are actually used, makes the code harder\r
+to maintain.\r
+\r
+When multiple blocks of code share a variable, but not its value, declare the\r
+variable separately for each code block.\r
+\r
+For example, if two separate blocks contain loops indexed by a variable ulIndex\r
+declare it separately in each block rather than declaring it once in a wider\r
+scope and using it in both places.\r
+\r
+Using distinct declarations in the two blocks allows the compiler to check for\r
+failure to initialize the variable in the second block. If there is a single\r
+declaration, the (now meaningless) value left over from the first block can be\r
+used erroneously in the second block.\r
+\r
--- /dev/null
+# Reliance Edge Release Notes\r
+\r
+This file contains a list of updates made to Reliance Edge over the course of\r
+recent releases and a list of known issues.\r
+\r
+## Release History and Changes\r
+\r
+### Reliance Edge v1.0, July 2015\r
+\r
+#### Common Code Changes\r
+\r
+- First release of commercial kit and MISRA C:2012 Design Assurance Package.\r
+ The commercial kit includes many new tools and tests which were not previously\r
+ available.\r
+- Overhauled parsing of command-line parameters to be consistent for all tools\r
+ and tests. Command-line tools now use Unix-style short and long options (such\r
+ as `-H` and `--help`) instead of DOS-style switches (such as `/?`).\r
+- Renamed all os/\*/include/ostypes.h headers to os/\*/include/redostypes.h, so\r
+ that all headers use the product prefix. If you created a port using v0.9,\r
+ this header needs to be renamed and its header guard (#ifndef OSTYPES_H etc.)\r
+ should also be updated.\r
+- Add a new header for OS-specific MISRA C:2012 deviation macros, located at\r
+ os/\*/include/redosdeviations.h. If you created a port using v0.9, copy the\r
+ template from os/stub/include/redosdeviations.h into the include directory.\r
+- Eliminated support for sector sizes less than 256. If using a smaller sector\r
+ size (say for a RAM disk), this must now be emulated in the implementation of\r
+ the block device OS service.\r
+- Added RedFseFormat() as an optional FSE API, allowing FSE applications to\r
+ format the volume at run-time.\r
+ - This added a new macro to redconf.h: existing redconf.h files from v0.9 must\r
+ be updated to work with v1.0. Open redconf.h with the configuration tool,\r
+ ignore the warning about the missing macro, and save it.\r
+- Internal restructuring has renamed the macros for the string and memory\r
+ functions used in redconf.h. An existing redconf.h file from v0.9 will need\r
+ to be updated; for a file containing the old names, the new config tool will\r
+ default to using the (slow) Reliance Edge string/memory functions; to use the\r
+ C library or custom versions, this will need to be selected in the\r
+ configuration utility.\r
+- Fix a bug which would result in an error when attempting to create a name with\r
+ one or more trailing path separators (such as `red_mkdir("/foo/bar/")`).\r
+- Fix a bug where an open handle for an inode on one volume would prevent the\r
+ same inode number from being deleted on a different volume.\r
+\r
+#### FreeRTOS Port Changes\r
+\r
+- The implementation of the timestamp OS service no longer requires that\r
+ `configUSE_TIMERS` be set to `1`.\r
+\r
+### Reliance Edge v0.9 (Beta), April 2015\r
+\r
+First public release.\r
+\r
+## Known Issues\r
+\r
+### Visual Studio 2005\r
+\r
+The Reliance Edge Win32 port (used for the host tools and the Win32 test\r
+project) cannot be compiled by Visual Studio 2005. This is not going to be\r
+fixed since VS2005 is an old toolset. Newer versions of Visual Studio, starting\r
+with Visual Studio 2008, work just fine.\r
+\r
--- /dev/null
+\r
+\r
+RELIANCE EDGE RELEASE NOTES\r
+\r
+\r
+This file contains a list of updates made to Reliance Edge over the\r
+course of recent releases and a list of known issues.\r
+\r
+\r
+Release History and Changes\r
+\r
+Reliance Edge v1.0, July 2015\r
+\r
+Common Code Changes\r
+\r
+- First release of commercial kit and MISRA C:2012 Design\r
+ Assurance Package. The commercial kit includes many new tools and\r
+ tests which were not previously available.\r
+- Overhauled parsing of command-line parameters to be consistent for\r
+ all tools and tests. Command-line tools now use Unix-style short and\r
+ long options (such as -H and --help) instead of DOS-style switches\r
+ (such as /?).\r
+- Renamed all os/*/include/ostypes.h headers to\r
+ os/*/include/redostypes.h, so that all headers use the\r
+ product prefix. If you created a port using v0.9, this header needs\r
+ to be renamed and its header guard (#ifndef OSTYPES_H etc.) should\r
+ also be updated.\r
+- Add a new header for OS-specific MISRA C:2012 deviation macros,\r
+ located at os/*/include/redosdeviations.h. If you created a port\r
+ using v0.9, copy the template from os/stub/include/redosdeviations.h\r
+ into the include directory.\r
+- Eliminated support for sector sizes less than 256. If using a\r
+ smaller sector size (say for a RAM disk), this must now be emulated\r
+ in the implementation of the block device OS service.\r
+- Added RedFseFormat() as an optional FSE API, allowing FSE\r
+ applications to format the volume at run-time.\r
+- This added a new macro to redconf.h: existing redconf.h files from\r
+ v0.9 must be updated to work with v1.0. Open redconf.h with the\r
+ configuration tool, ignore the warning about the missing macro, and\r
+ save it.\r
+- Internal restructuring has renamed the macros for the string and\r
+ memory functions used in redconf.h. An existing redconf.h file from\r
+ v0.9 will need to be updated; for a file containing the old names,\r
+ the new config tool will default to using the (slow) Reliance Edge\r
+ string/memory functions; to use the C library or custom versions,\r
+ this will need to be selected in the configuration utility.\r
+- Fix a bug which would result in an error when attempting to create a\r
+ name with one or more trailing path separators (such as\r
+ red_mkdir("/foo/bar/")).\r
+- Fix a bug where an open handle for an inode on one volume would\r
+ prevent the same inode number from being deleted on a\r
+ different volume.\r
+\r
+FreeRTOS Port Changes\r
+\r
+- The implementation of the timestamp OS service no longer requires\r
+ that configUSE_TIMERS be set to 1.\r
+\r
+Reliance Edge v0.9 (Beta), April 2015\r
+\r
+First public release.\r
+\r
+\r
+Known Issues\r
+\r
+Visual Studio 2005\r
+\r
+The Reliance Edge Win32 port (used for the host tools and the Win32 test\r
+project) cannot be compiled by Visual Studio 2005. This is not going to\r
+be fixed since VS2005 is an old toolset. Newer versions of Visual\r
+Studio, starting with Visual Studio 2008, work just fine.\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implementation of the Reliance Edge FSE API.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_API_FSE == 1\r
+\r
+/** @defgroup red_group_fse The File System Essentials Interface\r
+ @{\r
+*/\r
+\r
+#include <redvolume.h>\r
+#include <redcoreapi.h>\r
+#include <redfse.h>\r
+\r
+\r
+static REDSTATUS FseEnter(uint8_t bVolNum);\r
+static void FseLeave(void);\r
+\r
+\r
+static bool gfFseInited; /* Whether driver is initialized. */\r
+\r
+\r
+/** @brief Initialize the Reliance Edge file system driver.\r
+\r
+ Prepares the Reliance Edge file system driver to be used. Must be the first\r
+ Reliance Edge function to be invoked: no volumes can be mounted until the\r
+ driver has been initialized.\r
+\r
+ If this function is called when the Reliance Edge driver is already\r
+ initialized, it does nothing and returns success.\r
+\r
+ This function is not thread safe: attempting to initialize from multiple\r
+ threads could leave things in a bad state.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedFseInit(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gfFseInited)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ ret = RedCoreInit();\r
+\r
+ if(ret == 0)\r
+ {\r
+ gfFseInited = true;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize the Reliance Edge file system driver.\r
+\r
+ Tears down the Reliance Edge file system driver. Cannot be used until all\r
+ Reliance Edge volumes are unmounted. A subsequent call to RedFseInit()\r
+ will initialize the driver again.\r
+\r
+ If this function is called when the Reliance Edge driver is already\r
+ uninitialized, it does nothing and returns success.\r
+\r
+ This function is not thread safe: attempting to uninitialize from multiple\r
+ threads could leave things in a bad state.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBUSY At least one volume is still mounted.\r
+*/\r
+REDSTATUS RedFseUninit(void)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(!gfFseInited)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexAcquire();\r
+ #endif\r
+\r
+ for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)\r
+ {\r
+ if(gaRedVolume[bVolNum].fMounted)\r
+ {\r
+ ret = -RED_EBUSY;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ gfFseInited = false;\r
+ }\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexRelease();\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreUninit();\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Mount a file system volume.\r
+\r
+ Prepares the file system volume to be accessed. Mount will fail if the\r
+ volume has never been formatted, or if the on-disk format is inconsistent\r
+ with the compile-time configuration.\r
+\r
+ If the volume is already mounted, this function does nothing and returns\r
+ success.\r
+\r
+ @param bVolNum The volume number of the volume to be mounted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is\r
+ uninitialized.\r
+ @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.\r
+*/\r
+REDSTATUS RedFseMount(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(!gpRedVolume->fMounted)\r
+ {\r
+ ret = RedCoreVolMount();\r
+ }\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Unmount a file system volume.\r
+\r
+ This function discards the in-memory state for the file system and marks it\r
+ as unmounted. Subsequent attempts to access the volume will fail until the\r
+ volume is mounted again.\r
+\r
+ If unmount automatic transaction points are enabled, this function will\r
+ commit a transaction point prior to unmounting. If unmount automatic\r
+ transaction points are disabled, this function will unmount without\r
+ transacting, effectively discarding the working state.\r
+\r
+ Before unmounting, this function will wait for any active file system\r
+ thread to complete by acquiring the FS mutex. The volume will be marked as\r
+ unmounted before the FS mutex is released, so subsequent FS threads will\r
+ possibly block and then see an error when attempting to access a volume\r
+ which is unmounting or unmounted.\r
+\r
+ If the volume is already unmounted, this function does nothing and returns\r
+ success.\r
+\r
+ @param bVolNum The volume number of the volume to be unmounted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is\r
+ uninitialized.\r
+ @retval -RED_EIO I/O error during unmount automatic transaction point.\r
+*/\r
+REDSTATUS RedFseUnmount(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(gpRedVolume->fMounted)\r
+ {\r
+ ret = RedCoreVolUnmount();\r
+ }\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)\r
+/** @brief Format a file system volume.\r
+\r
+ Uses the statically defined volume configuration. After calling this\r
+ function, the volume needs to be mounted -- see RedFseMount().\r
+\r
+ An error is returned if the volume is mounted.\r
+\r
+ @param bVolNum The volume number of the volume to be formatted.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBUSY The volume is mounted.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is\r
+ uninitialized.\r
+ @retval -RED_EIO I/O error formatting the volume.\r
+*/\r
+REDSTATUS RedFseFormat(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolFormat();\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Read from a file.\r
+\r
+ Data which has not yet been written, but which is before the end-of-file\r
+ (sparse data), shall read as zeroes. A short read -- where the number of\r
+ bytes read is less than requested -- indicates that the requested read was\r
+ partially or, if zero bytes were read, entirely beyond the end-of-file.\r
+\r
+ If @p ullFileOffset is at or beyond the maximum file size, it is treated\r
+ like any other read entirely beyond the end-of-file: no data is read and\r
+ zero is returned.\r
+\r
+ @param bVolNum The volume number of the file to read.\r
+ @param ulFileNum The file number of the file to read.\r
+ @param ullFileOffset The file offset to read from.\r
+ @param ulLength The number of bytes to read.\r
+ @param pBuffer The buffer to populate with the data read. Must be\r
+ at least ulLength bytes in size.\r
+\r
+ @return The number of bytes read (nonnegative) or a negated ::REDSTATUS\r
+ code indicating the operation result (negative).\r
+\r
+ @retval >=0 The number of bytes read from the file.\r
+ @retval -RED_EBADF @p ulFileNum is not a valid file number.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;\r
+ or @p pBuffer is `NULL`; or @p ulLength exceeds\r
+ INT32_MAX and cannot be returned properly.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+int32_t RedFseRead(\r
+ uint8_t bVolNum,\r
+ uint32_t ulFileNum,\r
+ uint64_t ullFileOffset,\r
+ uint32_t ulLength,\r
+ void *pBuffer)\r
+{\r
+ int32_t ret;\r
+\r
+ if(ulLength > (uint32_t)INT32_MAX)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = FseEnter(bVolNum);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulReadLen = ulLength;\r
+\r
+ ret = RedCoreFileRead(ulFileNum, ullFileOffset, &ulReadLen, pBuffer);\r
+\r
+ FseLeave();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = (int32_t)ulReadLen;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write to a file.\r
+\r
+ If the write extends beyond the end-of-file, the file size will be\r
+ increased.\r
+\r
+ A short write -- where the number of bytes written is less than requested\r
+ -- indicates either that the file system ran out of space but was still\r
+ able to write some of the request; or that the request would have caused\r
+ the file to exceed the maximum file size, but some of the data could be\r
+ written prior to the file size limit.\r
+\r
+ If an error is returned (negative return), either none of the data was\r
+ written or a critical error occurred (like an I/O error) and the file\r
+ system volume will be read-only.\r
+\r
+ @param bVolNum The volume number of the file to write.\r
+ @param ulFileNum The file number of the file to write.\r
+ @param ullFileOffset The file offset to write at.\r
+ @param ulLength The number of bytes to write.\r
+ @param pBuffer The buffer containing the data to be written. Must\r
+ be at least ulLength bytes in size.\r
+\r
+ @return The number of bytes written (nonnegative) or a negated ::REDSTATUS\r
+ code indicating the operation result (negative).\r
+\r
+ @retval >0 The number of bytes written to the file.\r
+ @retval -RED_EBADF @p ulFileNum is not a valid file number.\r
+ @retval -RED_EFBIG No data can be written to the given file offset since\r
+ the resulting file size would exceed the maximum file\r
+ size.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;\r
+ or @p pBuffer is `NULL`; or @p ulLength exceeds\r
+ INT32_MAX and cannot be returned properly.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC No data can be written because there is insufficient\r
+ free space.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+int32_t RedFseWrite(\r
+ uint8_t bVolNum,\r
+ uint32_t ulFileNum,\r
+ uint64_t ullFileOffset,\r
+ uint32_t ulLength,\r
+ const void *pBuffer)\r
+{\r
+ int32_t ret;\r
+\r
+ if(ulLength > (uint32_t)INT32_MAX)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = FseEnter(bVolNum);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulWriteLen = ulLength;\r
+\r
+ ret = RedCoreFileWrite(ulFileNum, ullFileOffset, &ulWriteLen, pBuffer);\r
+\r
+ FseLeave();\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = (int32_t)ulWriteLen;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)\r
+/** @brief Truncate a file (set the file size).\r
+\r
+ Allows the file size to be increased, decreased, or to remain the same. If\r
+ the file size is increased, the new area is sparse (will read as zeroes).\r
+ If the file size is decreased, the data beyond the new end-of-file will\r
+ return to free space once it is no longer part of the committed state\r
+ (either immediately or after the next transaction point).\r
+\r
+ This function can fail when the disk is full if @p ullNewFileSize is\r
+ non-zero. If decreasing the file size, this can be fixed by transacting and\r
+ trying again: Reliance Edge guarantees that it is possible to perform a\r
+ truncate of at least one file that decreases the file size after a\r
+ transaction point. If disk full transactions are enabled, this will happen\r
+ automatically.\r
+\r
+ @param bVolNum The volume number of the file to truncate.\r
+ @param ulFileNum The file number of the file to truncate.\r
+ @param ullNewFileSize The new file size, in bytes.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulFileNum is not a valid file number.\r
+ @retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOSPC Insufficient free space to perform the truncate.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedFseTruncate(\r
+ uint8_t bVolNum,\r
+ uint32_t ulFileNum,\r
+ uint64_t ullNewFileSize)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreFileTruncate(ulFileNum, ullNewFileSize);\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Retrieve the size of a file.\r
+\r
+ @param bVolNum The volume number of the file whose size is being read.\r
+ @param ulFileNum The file number of the file whose size is being read.\r
+\r
+ @return The size of the file (nonnegative) or a negated ::REDSTATUS code\r
+ indicating the operation result (negative).\r
+\r
+ @retval >=0 The size of the file.\r
+ @retval -RED_EBADF @p ulFileNum is not a valid file number.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+int64_t RedFseSizeGet(\r
+ uint8_t bVolNum,\r
+ uint32_t ulFileNum)\r
+{\r
+ int64_t ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint64_t ullSize;\r
+\r
+ ret = RedCoreFileSizeGet(ulFileNum, &ullSize);\r
+\r
+ FseLeave();\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Unless there is an on-disk format change, the maximum file size\r
+ is guaranteed to be less than INT64_MAX, and so it can be safely\r
+ returned in an int64_t.\r
+ */\r
+ REDASSERT(ullSize < (uint64_t)INT64_MAX);\r
+\r
+ ret = (int64_t)ullSize;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)\r
+/** @brief Update the transaction mask.\r
+\r
+ The following events are available:\r
+\r
+ - #RED_TRANSACT_UMOUNT\r
+ - #RED_TRANSACT_WRITE\r
+ - #RED_TRANSACT_TRUNCATE\r
+ - #RED_TRANSACT_VOLFULL\r
+\r
+ The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all\r
+ automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of\r
+ all transaction flags, excluding those representing excluded functionality.\r
+\r
+ Attempting to enable events for excluded functionality will result in an\r
+ error.\r
+\r
+ @param bVolNum The volume number of the volume whose transaction mask\r
+ is being changed.\r
+ @param ulEventMask A bitwise-OR'd mask of automatic transaction events to\r
+ be set as the current transaction mode.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;\r
+ or @p ulEventMask contains invalid bits.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedFseTransMaskSet(\r
+ uint8_t bVolNum,\r
+ uint32_t ulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreTransMaskSet(ulEventMask);\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_API_FSE_TRANSMASKGET == 1\r
+/** @brief Read the transaction mask.\r
+\r
+ If the volume is read-only, the returned event mask is always zero.\r
+\r
+ @param bVolNum The volume number of the volume whose transaction mask\r
+ is being retrieved.\r
+ @param pulEventMask Populated with a bitwise-OR'd mask of automatic\r
+ transaction events which represent the current\r
+ transaction mode for the volume.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;\r
+ or @p pulEventMask is `NULL`.\r
+*/\r
+REDSTATUS RedFseTransMaskGet(\r
+ uint8_t bVolNum,\r
+ uint32_t *pulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreTransMaskGet(pulEventMask);\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Commit a transaction point.\r
+\r
+ Reliance Edge is a transactional file system. All modifications, of both\r
+ metadata and filedata, are initially working state. A transaction point\r
+ is a process whereby the working state atomically becomes the committed\r
+ state, replacing the previous committed state. Whenever Reliance Edge is\r
+ mounted, including after power loss, the state of the file system after\r
+ mount is the most recent committed state. Nothing from the committed\r
+ state is ever missing, and nothing from the working state is ever included.\r
+\r
+ @param bVolNum The volume number of the volume to transact.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EROFS The file system volume is read-only.\r
+*/\r
+REDSTATUS RedFseTransact(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = FseEnter(bVolNum);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolTransact();\r
+\r
+ FseLeave();\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+/** @} */\r
+\r
+/** @brief Enter the file system driver.\r
+\r
+ @param bVolNum The volume to be accessed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum\r
+ is not a valid volume number.\r
+*/\r
+static REDSTATUS FseEnter(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gfFseInited)\r
+ {\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexAcquire();\r
+ #endif\r
+\r
+ /* This also serves to range-check the volume number (even in single\r
+ volume configurations).\r
+ */\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ if(ret != 0)\r
+ {\r
+ RedOsMutexRelease();\r
+ }\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Leave the file system driver.\r
+*/\r
+static void FseLeave(void)\r
+{\r
+ REDASSERT(gfFseInited);\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexRelease();\r
+ #endif\r
+}\r
+\r
+\r
+#endif /* REDCONF_API_FSE == 1 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Defines macros used to interact with the Reliance Edge API.\r
+*/\r
+#ifndef REDAPIMACS_H\r
+#define REDAPIMACS_H\r
+\r
+\r
+/** Clear all events: manual transactions only. */\r
+#define RED_TRANSACT_MANUAL 0x00000000U\r
+\r
+/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */\r
+#define RED_TRANSACT_UMOUNT 0x00000001U\r
+\r
+/** Transact after a successful red_open() which created a file. */\r
+#define RED_TRANSACT_CREAT 0x00000002U\r
+\r
+/** Transact after a successful red_unlink() or red_rmdir(). */\r
+#define RED_TRANSACT_UNLINK 0x00000004U\r
+\r
+/** Transact after a successful red_mkdir(). */\r
+#define RED_TRANSACT_MKDIR 0x00000008U\r
+\r
+/** Transact after a successful red_rename(). */\r
+#define RED_TRANSACT_RENAME 0x00000010U\r
+\r
+/** Transact after a successful red_link(). */\r
+#define RED_TRANSACT_LINK 0x00000020U\r
+\r
+/** Transact after a successful red_close(). */\r
+#define RED_TRANSACT_CLOSE 0x00000040U\r
+\r
+/** Transact after a successful red_write() or RedFseWrite(). */\r
+#define RED_TRANSACT_WRITE 0x00000080U\r
+\r
+/** Transact after a successful red_fsync(). */\r
+#define RED_TRANSACT_FSYNC 0x00000100U\r
+\r
+/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */\r
+#define RED_TRANSACT_TRUNCATE 0x00000200U\r
+\r
+/** Transact to free space in disk full situations. */\r
+#define RED_TRANSACT_VOLFULL 0x00000400U\r
+\r
+#if REDCONF_READ_ONLY == 1\r
+\r
+/** Mask of all supported automatic transaction events. */\r
+#define RED_TRANSACT_MASK 0U\r
+\r
+#elif REDCONF_API_POSIX == 1\r
+\r
+/** @brief Mask of all supported automatic transaction events.\r
+*/\r
+#define RED_TRANSACT_MASK \\r
+( \\r
+ RED_TRANSACT_UMOUNT | \\r
+ RED_TRANSACT_CREAT | \\r
+ ((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \\r
+ ((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \\r
+ ((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \\r
+ ((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \\r
+ RED_TRANSACT_CLOSE | \\r
+ RED_TRANSACT_WRITE | \\r
+ RED_TRANSACT_FSYNC | \\r
+ ((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \\r
+ RED_TRANSACT_VOLFULL \\r
+)\r
+\r
+#else /* REDCONF_API_FSE == 1 */\r
+\r
+/** @brief Mask of all supported automatic transaction events.\r
+*/\r
+#define RED_TRANSACT_MASK \\r
+( \\r
+ RED_TRANSACT_UMOUNT | \\r
+ RED_TRANSACT_WRITE | \\r
+ ((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \\r
+ RED_TRANSACT_VOLFULL \\r
+)\r
+\r
+#endif /* REDCONF_READ_ONLY */\r
+\r
+#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT\r
+#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT"\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Compile-time validity checks for the REDCONF macros.\r
+*/\r
+#ifndef REDCONFIGCHK_H\r
+#define REDCONFIGCHK_H\r
+\r
+#ifndef REDCONF_READ_ONLY\r
+ #error "Configuration error: REDCONF_READ_ONLY must be defined."\r
+#endif\r
+#ifndef REDCONF_API_POSIX\r
+ #error "Configuration error: REDCONF_API_POSIX must be defined."\r
+#endif\r
+#ifndef REDCONF_API_FSE\r
+ #error "Configuration error: REDCONF_API_FSE must be defined."\r
+#endif\r
+\r
+#if REDCONF_API_POSIX == 1\r
+ #ifndef REDCONF_API_POSIX_FORMAT\r
+ #error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_UNLINK\r
+ #error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_MKDIR\r
+ #error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_RMDIR\r
+ #error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_RENAME\r
+ #error "Configuration error: REDCONF_API_POSIX_RENAME must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_LINK\r
+ #error "Configuration error: REDCONF_API_POSIX_LINK must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_FTRUNCATE\r
+ #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_POSIX_READDIR\r
+ #error "Configuration error: REDCONF_API_POSIX_READDIR must be defined."\r
+ #endif\r
+ #ifndef REDCONF_NAME_MAX\r
+ #error "Configuration error: REDCONF_NAME_MAX must be defined."\r
+ #endif\r
+ #ifndef REDCONF_PATH_SEPARATOR\r
+ #error "Configuration error: REDCONF_PATH_SEPARATOR must be defined."\r
+ #endif\r
+ #ifndef REDCONF_RENAME_ATOMIC\r
+ #error "Configuration error: REDCONF_RENAME_ATOMIC must be defined."\r
+ #endif\r
+ #ifndef REDCONF_HANDLE_COUNT\r
+ #error "Configuration error: REDCONF_HANDLE_COUNT must be defined."\r
+ #endif\r
+#endif\r
+#if REDCONF_API_FSE == 1\r
+ #ifndef REDCONF_API_FSE_FORMAT\r
+ #error "Configuration error: REDCONF_API_FSE_FORMAT must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_FSE_TRUNCATE\r
+ #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_FSE_TRANSMASKSET\r
+ #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined."\r
+ #endif\r
+ #ifndef REDCONF_API_FSE_TRANSMASKGET\r
+ #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined."\r
+ #endif\r
+#endif\r
+\r
+#ifndef REDCONF_TASK_COUNT\r
+ #error "Configuration error: REDCONF_TASK_COUNT must be defined."\r
+#endif\r
+#ifndef REDCONF_ENDIAN_BIG\r
+ #error "Configuration error: REDCONF_ENDIAN_BIG must be defined."\r
+#endif\r
+#ifndef REDCONF_ALIGNMENT_SIZE\r
+ #error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined."\r
+#endif\r
+#ifndef REDCONF_CRC_ALGORITHM\r
+ #error "Configuration error: REDCONF_CRC_ALGORITHM must be defined."\r
+#endif\r
+#ifndef REDCONF_INODE_TIMESTAMPS\r
+ #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined."\r
+#endif\r
+#ifndef REDCONF_ATIME\r
+ #error "Configuration error: REDCONF_ATIME must be defined."\r
+#endif\r
+#ifndef REDCONF_DIRECT_POINTERS\r
+ #error "Configuration error: REDCONF_DIRECT_POINTERS must be defined."\r
+#endif\r
+#ifndef REDCONF_INDIRECT_POINTERS\r
+ #error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined."\r
+#endif\r
+#ifndef REDCONF_INODE_BLOCKS\r
+ #error "Configuration error: REDCONF_INODE_BLOCKS must be defined."\r
+#endif\r
+#ifndef REDCONF_IMAP_EXTERNAL\r
+ #error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined."\r
+#endif\r
+#ifndef REDCONF_IMAP_INLINE\r
+ #error "Configuration error: REDCONF_IMAP_INLINE must be defined."\r
+#endif\r
+#ifndef REDCONF_OUTPUT\r
+ #error "Configuration error: REDCONF_OUTPUT must be defined."\r
+#endif\r
+#ifndef REDCONF_ASSERTS\r
+ #error "Configuration error: REDCONF_ASSERTS must be defined."\r
+#endif\r
+#ifndef REDCONF_TRANSACT_DEFAULT\r
+ #error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined."\r
+#endif\r
+#ifndef REDCONF_BUFFER_COUNT\r
+ #error "Configuration error: REDCONF_BUFFER_COUNT must be defined."\r
+#endif\r
+#ifndef REDCONF_BLOCK_SIZE\r
+ #error "Configuration error: REDCONF_BLOCK_SIZE must be defined."\r
+#endif\r
+#ifndef REDCONF_VOLUME_COUNT\r
+ #error "Configuration error: REDCONF_VOLUME_COUNT must be defined."\r
+#endif\r
+#ifndef REDCONF_IMAGE_BUILDER\r
+ #error "Configuration error: REDCONF_IMAGE_BUILDER must be defined."\r
+#endif\r
+#ifndef REDCONF_CHECKER\r
+ #error "Configuration error: REDCONF_CHECKER must be defined."\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1)\r
+ #error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1"\r
+#endif\r
+\r
+#if (REDCONF_API_POSIX != 0) && (REDCONF_API_POSIX != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX must be either 0 or 1."\r
+#endif\r
+#if (REDCONF_API_FSE != 0) && (REDCONF_API_FSE != 1)\r
+ #error "Configuration error: REDCONF_API_FSE must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_API_FSE == 0) && (REDCONF_API_POSIX == 0)\r
+ #error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1."\r
+#endif\r
+\r
+#if REDCONF_API_POSIX == 1\r
+ #if REDCONF_API_FSE != 0\r
+ #error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1"\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1)\r
+ #error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_NAME_MAX < 1U) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4U))\r
+ #error "Configuration error: invalid value of REDCONF_NAME_MAX"\r
+ #endif\r
+\r
+ #if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127)\r
+ #error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR"\r
+ #endif\r
+\r
+ #if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1)\r
+ #error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U)\r
+ #error "Configuration error: invalid value of REDCONF_HANDLE_COUNT"\r
+ #endif\r
+#endif\r
+#if REDCONF_API_FSE == 1\r
+ #if (REDCONF_API_FSE_FORMAT != 0) && (REDCONF_API_FSE_FORMAT != 1)\r
+ #error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1)\r
+ #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1)\r
+ #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1."\r
+ #endif\r
+\r
+ #if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1)\r
+ #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1."\r
+ #endif\r
+#endif\r
+\r
+#if REDCONF_TASK_COUNT < 1U\r
+ #error "Configuration error: invalid value of REDCONF_TASK_COUNT"\r
+#endif\r
+\r
+#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1)\r
+ #error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U)\r
+ #error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE"\r
+#endif\r
+\r
+/* REDCONF_CRC_ALGORITHM checked in crc.c\r
+*/\r
+\r
+#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1)\r
+ #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1)\r
+ #error "Configuration error: REDCONF_ATIME must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_INODE_TIMESTAMPS == 0) && (REDCONF_ATIME == 1)\r
+ #error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0."\r
+#endif\r
+\r
+/* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h\r
+*/\r
+\r
+#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1)\r
+ #error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1."\r
+#endif\r
+\r
+/* Further validity checking of imap specs done in RelCoreInit()\r
+*/\r
+#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1)\r
+ #error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1."\r
+#endif\r
+#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1)\r
+ #error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1."\r
+#endif\r
+#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0)\r
+ #error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set"\r
+#endif\r
+\r
+#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1)\r
+ #error "Configuration error: REDCONF_OUTPUT must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1)\r
+ #error "Configuration error: REDCONF_ASSERTS must be either 0 or 1."\r
+#endif\r
+\r
+/* REDCONF_BLOCK_SIZE checked in redmacs.h\r
+*/\r
+\r
+#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U)\r
+ #error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255"\r
+#endif\r
+\r
+/* REDCONF_BUFFER_COUNT lower limit checked in buffer.c\r
+*/\r
+#if REDCONF_BUFFER_COUNT > 255U\r
+ #error "REDCONF_BUFFER_COUNT cannot be greater than 255"\r
+#endif\r
+\r
+#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1)\r
+ #error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1."\r
+#endif\r
+\r
+#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1)\r
+ #error "Configuration error: REDCONF_CHECKER must be either 0 or 1."\r
+#endif\r
+\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDCOREAPI_H\r
+#define REDCOREAPI_H\r
+\r
+\r
+#include <redstat.h>\r
+\r
+\r
+REDSTATUS RedCoreInit(void);\r
+REDSTATUS RedCoreUninit(void);\r
+\r
+REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum);\r
+\r
+#if FORMAT_SUPPORTED\r
+REDSTATUS RedCoreVolFormat(void);\r
+#endif\r
+#if REDCONF_CHECKER == 1\r
+REDSTATUS RedCoreVolCheck(void);\r
+#endif\r
+REDSTATUS RedCoreVolMount(void);\r
+REDSTATUS RedCoreVolUnmount(void);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedCoreVolTransact(void);\r
+#endif\r
+#if REDCONF_API_POSIX == 1\r
+REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS);\r
+#endif\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1))\r
+REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask);\r
+#endif\r
+#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1)\r
+REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask);\r
+#endif\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)\r
+REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)\r
+REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName);\r
+#endif\r
+#if REDCONF_API_POSIX == 1\r
+REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)\r
+REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName);\r
+#endif\r
+#if REDCONF_API_POSIX == 1\r
+REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat);\r
+#endif\r
+#if REDCONF_API_FSE == 1\r
+REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize);\r
+#endif\r
+\r
+REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);\r
+#endif\r
+#if TRUNCATE_SUPPORTED\r
+REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize);\r
+#endif\r
+\r
+#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1)\r
+REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode);\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief This header contains macros which deviate from MISRA C:2012\r
+*/\r
+#ifndef REDDEVIATIONS_H\r
+#define REDDEVIATIONS_H\r
+\r
+\r
+/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The\r
+ rule prohibits the use of language extensions. The ULL suffix became part\r
+ of the C standard with C99. Since this code base adheres to C89, use of\r
+ this suffix is a language extension. Reliance Edge needs to deal with\r
+ 64-bit quantities, which by convention are explicitly suffixed. In at\r
+ least one case, with the INODE_SIZE_MAX macro, the code needs a way to force\r
+ a constant to be 64-bits even though its value is not so large that it would\r
+ be automatically promoted to 64-bits. Thus the need for this macro and the\r
+ deviation. In practice, the ULL suffix has proven to be a nearly universal\r
+ extension among C89 compilers.\r
+\r
+ As rule 19.2 is advisory, a deviation record is not required. This notice\r
+ is the only record of the deviation. PC-Lint does not issue an error for\r
+ this deviation so there is no error inhibition option.\r
+\r
+ Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory).\r
+ The rule prohibits use of the ## preprocessor operator. The code is not\r
+ obscure, and the operator is used only once, so this is deemed to be safe.\r
+\r
+ As rule 20.10 is advisory, a deviation record is not required. This notice\r
+ is the only record of the deviation.\r
+\r
+ Consistent use of this macro, even in non MISRA C code, is encouraged to\r
+ make it easier to search for 64-bit values.\r
+\r
+*/\r
+#define UINT64_SUFFIX(number) (number##ULL)\r
+\r
+\r
+/** @brief Append a suffix to a constant so that it is a signed 64-bit value.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the\r
+ description of UINT64_SUFFIX() for details.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See\r
+ the description of UINT64_SUFFIX() for details.\r
+*/\r
+#define INT64_SUFFIX(number) (number##LL)\r
+\r
+\r
+/** @brief Cast a pointer to a const uint8_t pointer.\r
+\r
+ All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).\r
+ Because there are no alignment requirements for a uint8_t pointer, this is\r
+ safe. However, it is technically a deviation from the rule.\r
+\r
+ As Rule 11.5 is advisory, a deviation record is not required. This notice\r
+ and the PC-Lint error inhibition option are the only records of the\r
+ deviation.\r
+*/\r
+#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR))\r
+\r
+\r
+/** @brief Cast a pointer to a uint8_t pointer.\r
+\r
+ All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).\r
+ Because there are no alignment requirements for a uint8_t pointer, this is\r
+ safe. However, it is technically a deviation from the rule.\r
+\r
+ As Rule 11.5 is advisory, a deviation record is not required. This notice\r
+ and the PC-Lint error inhibition option are the only records of the\r
+ deviation.\r
+*/\r
+#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR))\r
+\r
+\r
+/** @brief Cast a pointer to a const uint32_t pointer.\r
+\r
+ Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory).\r
+ It is only used in cases where the pointer is known to be aligned, and thus\r
+ it is safe to do so.\r
+\r
+ As Rule 11.5 is advisory, a deviation record is not required. This notice\r
+ and the PC-Lint error inhibition option are the only records of the\r
+ deviation.\r
+\r
+ Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required).\r
+ As Rule 11.3 is required, a separate deviation record is required.\r
+\r
+ Regarding the cast to (const void *): this is there to placate some\r
+ compilers which emit warnings when a type with lower alignment requirements\r
+ (such as const uint8_t *) is cast to a type with higher alignment\r
+ requirements. In the places where this macro is used, the pointer is\r
+ checked to be of sufficient alignment.\r
+*/\r
+#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR))\r
+\r
+\r
+/** @brief Cast a pointer to a pointer to (void **).\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required).\r
+ It is only used for populating a node structure pointer with a buffer\r
+ pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so.\r
+\r
+ As Rule 11.3 is required, a separate deviation record is required.\r
+*/\r
+#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR))\r
+\r
+\r
+/** @brief Create a two-dimensional byte array which is safely aligned.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory).\r
+ A union is required to force alignment of the block buffers, which are used\r
+ to access metadata nodes, which must be safely aligned for 64-bit types.\r
+\r
+ As rule 19.2 is advisory, a deviation record is not required. This notice\r
+ and the PC-Lint error inhibition option are the only records of the\r
+ deviation.\r
+*/\r
+#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \\r
+ union \\r
+ { \\r
+ uint8_t nam[size1][size2]; \\r
+ uint64_t DummyAlign; \\r
+ } un\r
+\r
+\r
+/** @brief Determine whether RedMemMove() must copy memory in the forward\r
+ direction, instead of in the reverse.\r
+\r
+ In order to copy between overlapping memory regions, RedMemMove() must copy\r
+ forward if the destination memory is lower, and backward if the destination\r
+ memory is higher. Failure to do so would yield incorrect results.\r
+\r
+ The only way to make this determination without gross inefficiency is to\r
+ use pointer comparison. Pointer comparisons are undefined unless both\r
+ pointers point within the same object or array (or one element past the end\r
+ of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is\r
+ normally only used when memory regions overlap, which would not result in\r
+ undefined behavior, it (like memmove()) is supposed to work even for non-\r
+ overlapping regions, which would make this function invoke undefined\r
+ behavior. Experience has shown the pointer comparisons of this sort behave\r
+ intuitively on common platforms, even though the behavior is undefined. For\r
+ those platforms where this is not the case, this implementation of memmove()\r
+ should be replaced with an alternate one.\r
+\r
+ Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As\r
+ Rule 18.3 is required, a separate deviation record is required.\r
+*/\r
+#define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src))\r
+\r
+\r
+/** @brief Cast a pointer to a (const DIRENT *).\r
+\r
+ Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required).\r
+ It is used for populating a directory entry structure pointer with a\r
+ buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only\r
+ requires 4-byte alignment, thus the typecast is safe.\r
+\r
+ As Rule 11.3 is required, a separate deviation record is required.\r
+*/\r
+#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR))\r
+\r
+\r
+/** @brief Determine whether a pointer is aligned.\r
+\r
+ A pointer is aligned if its address is an even multiple of\r
+ ::REDCONF_ALIGNMENT_SIZE.\r
+\r
+ This is used in the slice-by-8 RedCrc32Update() function, which needs to\r
+ know whether a pointer is aligned, since the slice-by-8 algorithm needs to\r
+ access the memory in an aligned fashion, and if the pointer is not aligned,\r
+ this can result in faults or suboptimal performance (depending on platform).\r
+\r
+ There is no way to perform this check without deviating from MISRA C rules\r
+ against casting pointers to integer types. Usage of this macro deviates\r
+ from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites\r
+ against converting pointers to integers is that the chosen integer type may\r
+ not be able to represent the pointer; this is a non-issue here since we use\r
+ uintptr_t. The text says the rule still applies when using uintptr_t due to\r
+ concern about unaligned pointers, but that is not an issue here since the\r
+ integer value of the pointer is not saved and not converted back into a\r
+ pointer and dereferenced. The result of casting a pointer to a sufficiently\r
+ large integer is implementation-defined, but macros similar to this one have\r
+ been used by Datalight for a long time in a wide variety of environments and\r
+ they have always worked as expected.\r
+\r
+ As Rule 11.4 is advisory, a deviation record is not required. This notice\r
+ and the PC-Lint error inhibition option are the only records of the\r
+ deviation.\r
+\r
+ @note PC-Lint also thinks this macro as it is used below violates Rule 11.6\r
+ (required). This is a false positive, since Rule 11.6 only applies to\r
+ void pointers. Below, we use it on a pointer-to-object (uint8_t *),\r
+ which is covered by Rule 11.4.\r
+*/\r
+#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U)\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Error values for Reliance Edge APIs\r
+*/\r
+#ifndef REDERRNO_H\r
+#define REDERRNO_H\r
+\r
+\r
+/** @brief Return type for Reliance Edge error values.\r
+*/\r
+typedef int32_t REDSTATUS;\r
+\r
+\r
+/* The errno numbers are the same as Linux.\r
+*/\r
+\r
+/** Operation not permitted. */\r
+#define RED_EPERM 1\r
+\r
+/** No such file or directory. */\r
+#define RED_ENOENT 2\r
+\r
+/** I/O error. */\r
+#define RED_EIO 5\r
+\r
+/** Bad file number. */\r
+#define RED_EBADF 9\r
+\r
+/** Out of memory */\r
+#define RED_ENOMEM 12\r
+\r
+/** Device or resource busy. */\r
+#define RED_EBUSY 16\r
+\r
+/** File exists. */\r
+#define RED_EEXIST 17\r
+\r
+/** Cross-device link. */\r
+#define RED_EXDEV 18\r
+\r
+/** Not a directory. */\r
+#define RED_ENOTDIR 20\r
+\r
+/** Is a directory. */\r
+#define RED_EISDIR 21\r
+\r
+/** Invalid argument. */\r
+#define RED_EINVAL 22\r
+\r
+/** File table overflow. */\r
+#define RED_ENFILE 23\r
+\r
+/** Too many open files. */\r
+#define RED_EMFILE 24\r
+\r
+/** File too large. */\r
+#define RED_EFBIG 27\r
+\r
+/** No space left on device. */\r
+#define RED_ENOSPC 28\r
+\r
+/** Read-only file system. */\r
+#define RED_EROFS 30\r
+\r
+/** Too many links. */\r
+#define RED_EMLINK 31\r
+\r
+/** Math result not representable. */\r
+#define RED_ERANGE 34\r
+\r
+/** File name too long. */\r
+#define RED_ENAMETOOLONG 36\r
+\r
+/** Function not implemented. */\r
+#define RED_ENOSYS 38\r
+\r
+/** Directory not empty. */\r
+#define RED_ENOTEMPTY 39\r
+\r
+/** No data available. */\r
+#define RED_ENODATA 61\r
+\r
+/** Too many users. */\r
+#define RED_EUSERS 87\r
+\r
+/** Nothing will be okay ever again. */\r
+#define RED_EFUBAR RED_EINVAL\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDEXCLUDE_H\r
+#define REDEXCLUDE_H\r
+\r
+\r
+#define DELETE_SUPPORTED \\r
+ ( \\r
+ (REDCONF_READ_ONLY == 0) \\r
+ && ( (REDCONF_API_POSIX == 1) \\r
+ && ( (REDCONF_API_POSIX_RMDIR == 1) \\r
+ || (REDCONF_API_POSIX_UNLINK == 1) \\r
+ || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))))\r
+\r
+#define TRUNCATE_SUPPORTED \\r
+ ( \\r
+ (REDCONF_READ_ONLY == 0) \\r
+ && ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \\r
+ || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))))\r
+\r
+#define FORMAT_SUPPORTED \\r
+ ( \\r
+ (REDCONF_READ_ONLY == 0) \\r
+ && ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) \\r
+ || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_FORMAT == 1)) \\r
+ || (REDCONF_IMAGE_BUILDER == 1)))\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDFS_H\r
+#define REDFS_H\r
+\r
+\r
+#include <redconf.h>\r
+#include "redconfigchk.h"\r
+#include <redtypes.h>\r
+#include "rederrno.h"\r
+#include "reddeviations.h"\r
+#include "redmacs.h"\r
+#include "redapimacs.h"\r
+#include "redutils.h"\r
+#include "redosserv.h"\r
+#include "redmisc.h"\r
+#include "redver.h"\r
+#include "redexclude.h"\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Interface for the Reliance Edge FSE API.\r
+\r
+ The FSE (File Systems Essentials) API is a minimalist file system API\r
+ intended for simple use cases with a fixed number of statically-defined\r
+ files. It does not support creating or deleting files dynamically. Files\r
+ are referenced by a fixed file number, rather than by name; there are no\r
+ file names and no directories. There are also no file handles: files are\r
+ not opened or closed, and file offsets are given explicitly.\r
+\r
+ If the FSE API is too limited to meet the needs of your application,\r
+ consider using the more feature-rich POSIX-like file system API instead.\r
+*/\r
+#ifndef REDFSE_H\r
+#define REDFSE_H\r
+\r
+/* This header is intended for application use; some applications are written\r
+ in C++.\r
+*/\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <redconf.h>\r
+\r
+#if REDCONF_API_FSE == 1\r
+\r
+#include <redtypes.h>\r
+#include "redapimacs.h"\r
+#include "rederrno.h"\r
+\r
+\r
+/** @brief First valid file number.\r
+\r
+ This macro can be used to statically define file numbers for given files,\r
+ as in the below example:\r
+\r
+ ~~~{.c}\r
+ #define LOG_FILE (RED_FILENUM_FIRST_VALID)\r
+ #define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U)\r
+ #define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U)\r
+ #define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U)\r
+ ~~~\r
+*/\r
+#define RED_FILENUM_FIRST_VALID (2U)\r
+\r
+\r
+REDSTATUS RedFseInit(void);\r
+REDSTATUS RedFseUninit(void);\r
+REDSTATUS RedFseMount(uint8_t bVolNum);\r
+REDSTATUS RedFseUnmount(uint8_t bVolNum);\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)\r
+REDSTATUS RedFseFormat(uint8_t bVolNum);\r
+#endif\r
+int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)\r
+REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize);\r
+#endif\r
+int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum);\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)\r
+REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask);\r
+#endif\r
+#if REDCONF_API_FSE_TRANSMASKGET == 1\r
+REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedFseTransact(uint8_t bVolNum);\r
+#endif\r
+\r
+#endif /* REDCONF_API_FSE == 1 */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
--- /dev/null
+/*-\r
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Dieter Baron and Thomas Klausner.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/** @file\r
+ @brief Interfaces for getopt() and getopt_long() work-alike functions.\r
+\r
+ This code was taken from FreeBSD and slightly modified, mostly to rename\r
+ symbols with external linkage to avoid naming conflicts in systems where\r
+ there are real getopt()/getopt_long() implementations. Changed to use\r
+ fixed-width types to allow code using these interfaces to be consistent\r
+ with the rest of the product.\r
+*/\r
+#ifndef REDGETOPT_H\r
+#define REDGETOPT_H\r
+\r
+\r
+#define red_no_argument 0\r
+#define red_required_argument 1\r
+#define red_optional_argument 2\r
+\r
+\r
+/** @brief Specifies a long option.\r
+*/\r
+typedef struct\r
+{\r
+ /* name of long option */\r
+ const char *name;\r
+ /*\r
+ * one of red_no_argument, red_required_argument, and red_optional_argument:\r
+ * whether option takes an argument\r
+ */\r
+ int32_t has_arg;\r
+ /* if not NULL, set *flag to val when option found */\r
+ int32_t *flag;\r
+ /* if flag not NULL, value to set *flag to; else return value */\r
+ int32_t val;\r
+} REDOPTION;\r
+\r
+\r
+int32_t RedGetopt(int32_t nargc, char * const *nargv, const char *options);\r
+int32_t RedGetoptLong(int32_t nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx);\r
+\r
+\r
+extern const char *red_optarg;\r
+extern int32_t red_optind;\r
+extern int32_t red_opterr;\r
+extern int32_t red_optopt;\r
+extern int32_t red_optreset;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDMACS_H\r
+#define REDMACS_H\r
+\r
+\r
+#ifndef NULL\r
+#define NULL ((void *)0)\r
+#endif\r
+\r
+#ifndef UINT8_MAX\r
+#define UINT8_MAX (0xFFU)\r
+#endif\r
+#ifndef UINT16_MAX\r
+#define UINT16_MAX (0xFFFFU)\r
+#endif\r
+#ifndef UINT32_MAX\r
+#define UINT32_MAX (0xFFFFFFFFU)\r
+#endif\r
+#ifndef UINT64_MAX\r
+#define UINT64_MAX UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)\r
+#endif\r
+#ifndef INT32_MAX\r
+#define INT32_MAX (0x7FFFFFFF)\r
+#endif\r
+#ifndef INT64_MAX\r
+#define INT64_MAX INT64_SUFFIX(0x7FFFFFFFFFFFFFFF)\r
+#endif\r
+\r
+#ifndef true\r
+#define true (1)\r
+#endif\r
+#ifndef false\r
+#define false (0)\r
+#endif\r
+\r
+#define SECTOR_SIZE_MIN (256U)\r
+\r
+#if REDCONF_BLOCK_SIZE == 256U\r
+#define BLOCK_SIZE_P2 8U\r
+#elif REDCONF_BLOCK_SIZE == 512U\r
+#define BLOCK_SIZE_P2 9U\r
+#elif REDCONF_BLOCK_SIZE == 1024U\r
+#define BLOCK_SIZE_P2 10U\r
+#elif REDCONF_BLOCK_SIZE == 2048U\r
+#define BLOCK_SIZE_P2 11U\r
+#elif REDCONF_BLOCK_SIZE == 4096U\r
+#define BLOCK_SIZE_P2 12U\r
+#elif REDCONF_BLOCK_SIZE == 8192U\r
+#define BLOCK_SIZE_P2 13U\r
+#elif REDCONF_BLOCK_SIZE == 16384U\r
+#define BLOCK_SIZE_P2 14U\r
+#elif REDCONF_BLOCK_SIZE == 32768U\r
+#define BLOCK_SIZE_P2 15U\r
+#elif REDCONF_BLOCK_SIZE == 65536U\r
+#define BLOCK_SIZE_P2 16U\r
+#else\r
+#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536"\r
+#endif\r
+\r
+#define REDMIN(a, b) (((a) < (b)) ? (a) : (b))\r
+\r
+#define INODE_INVALID (0U) /* General-purpose invalid inode number (must be zero). */\r
+#define INODE_FIRST_VALID (2U) /* First valid inode number. */\r
+#define INODE_ROOTDIR (INODE_FIRST_VALID) /* Inode number of the root directory. */\r
+\r
+/* Expands to a "const" qualifier when the volume count is one, otherwise\r
+ expands to nothing. This is useful for variables that never change in\r
+ single-volume configurations but do change in multi-volume configurations.\r
+*/\r
+#if REDCONF_VOLUME_COUNT == 1U\r
+ #define CONST_IF_ONE_VOLUME const\r
+#else\r
+ #define CONST_IF_ONE_VOLUME\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDMISC_H\r
+#define REDMISC_H\r
+\r
+\r
+/** @brief Type of an inode or handle.\r
+\r
+ Used to indicate the actual or expected type of an inode or handle.\r
+*/\r
+typedef enum\r
+{\r
+ FTYPE_FILE, /**< Type is file. */\r
+ FTYPE_DIR, /**< Type is directory. */\r
+\r
+ /** Type is either file or directory: used only to indicate an expected\r
+ type, never as an actual type.\r
+ */\r
+ FTYPE_EITHER\r
+} FTYPE;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDOSSERV_H\r
+#define REDOSSERV_H\r
+\r
+\r
+#include <redostypes.h>\r
+\r
+\r
+/** @brief Type of access requested when opening a block device.\r
+*/\r
+typedef enum\r
+{\r
+ BDEV_O_RDONLY, /**< Open block device for read access. */\r
+ BDEV_O_WRONLY, /**< Open block device for write access. */\r
+ BDEV_O_RDWR /**< Open block device for read and write access. */\r
+} BDEVOPENMODE;\r
+\r
+REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode);\r
+REDSTATUS RedOsBDevClose(uint8_t bVolNum);\r
+REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);\r
+REDSTATUS RedOsBDevFlush(uint8_t bVolNum);\r
+#endif\r
+\r
+/* Non-standard API: for host machines only.\r
+*/\r
+REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec);\r
+\r
+\r
+#if REDCONF_TASK_COUNT > 1U\r
+REDSTATUS RedOsMutexInit(void);\r
+REDSTATUS RedOsMutexUninit(void);\r
+void RedOsMutexAcquire(void);\r
+void RedOsMutexRelease(void);\r
+#endif\r
+#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)\r
+uint32_t RedOsTaskId(void);\r
+#endif\r
+\r
+REDSTATUS RedOsClockInit(void);\r
+REDSTATUS RedOsClockUninit(void);\r
+uint32_t RedOsClockGetTime(void);\r
+\r
+REDSTATUS RedOsTimestampInit(void);\r
+REDSTATUS RedOsTimestampUninit(void);\r
+REDTIMESTAMP RedOsTimestamp(void);\r
+uint64_t RedOsTimePassed(REDTIMESTAMP tsSince);\r
+\r
+#if REDCONF_OUTPUT == 1\r
+void RedOsOutputString(const char *pszString);\r
+#endif\r
+\r
+#if REDCONF_ASSERTS == 1\r
+void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum);\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Interface for the Reliance Edge POSIX-like API.\r
+\r
+ The POSIX-like file system API is the primary file system API for\r
+ Reliance Edge, which supports the full functionality of the file system.\r
+ This API aims to be compatible with POSIX where reasonable, but it is\r
+ simplified considerably to meet the needs of resource-constrained embedded\r
+ systems. The API has also been extended to provide access to the unique\r
+ features of Reliance Edge, and to cover areas (like mountins and formatting)\r
+ which do not have APIs in the POSIX specification.\r
+*/\r
+#ifndef REDPOSIX_H\r
+#define REDPOSIX_H\r
+\r
+/* This header is intended for application use; some applications are written\r
+ in C++.\r
+*/\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <redconf.h>\r
+\r
+#if REDCONF_API_POSIX == 1\r
+\r
+#include <redtypes.h>\r
+#include "redapimacs.h"\r
+#include "rederrno.h"\r
+#include "redstat.h"\r
+\r
+/** Open for reading only. */\r
+#define RED_O_RDONLY 0x00000001U\r
+\r
+/** Open for writing only. */\r
+#define RED_O_WRONLY 0x00000002U\r
+\r
+/** Open for reading and writing. */\r
+#define RED_O_RDWR 0x00000004U\r
+\r
+/** File offset for all writes is end-of-file. */\r
+#define RED_O_APPEND 0x00000008U\r
+\r
+/** Create the file. */\r
+#define RED_O_CREAT 0x00000010U\r
+\r
+/** Error if path already exists. */\r
+#define RED_O_EXCL 0x00000020U\r
+\r
+/** Truncate file to size zero. */\r
+#define RED_O_TRUNC 0x00000040U\r
+\r
+\r
+/** @brief Last file system error (errno).\r
+\r
+ Under normal circumstances, each task using the file system has an\r
+ independent `red_errno` value. Applications do not need to worry about\r
+ one task obliterating an error value that another task needed to read. The\r
+ value is initially zero. When one of the POSIX-like APIs return an\r
+ indication of error, `red_errno` is set to an error value.\r
+\r
+ In some circumstances, `red_errno` will be a global errno location which\r
+ is shared by multiple tasks. If the calling task is not registered as a\r
+ file system user and all of the task slots are full, there can be no\r
+ task-specific errno, so the global errno is used. Likewise, if the file\r
+ system driver is uninitialized, there are no registered file system users\r
+ and `red_errno` always refers to the global errno. Under these\r
+ circumstances, multiple tasks manipulating `red_errno` could be\r
+ problematic. When the task count is set to one, `red_errno` always refers\r
+ to the global errno.\r
+\r
+ Note that `red_errno` is usable as an lvalue; i.e., in addition to reading\r
+ the error value, the error value can be set:\r
+\r
+ ~~~{.c}\r
+ red_errno = 0;\r
+ ~~~\r
+*/\r
+#define red_errno (*red_errnoptr())\r
+\r
+\r
+/** @brief Positions from which to seek within a file.\r
+*/\r
+typedef enum\r
+{\r
+ /* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior\r
+ to the release of Unix System V in 1983, the SEEK_* symbols did not\r
+ exist and C programs hard-coded the 0/1/2 values with those meanings.\r
+ */\r
+ RED_SEEK_SET = 0, /**< Set file offset to given offset. */\r
+ RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */\r
+ RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */\r
+} REDWHENCE;\r
+\r
+\r
+#if REDCONF_API_POSIX_READDIR == 1\r
+/** @brief Opaque directory handle.\r
+*/\r
+typedef struct sREDHANDLE REDDIR;\r
+\r
+\r
+/** @brief Directory entry information.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t d_ino; /**< File serial number (inode number). */\r
+ char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */\r
+ REDSTAT d_stat; /**< File information (POSIX extension). */\r
+} REDDIRENT;\r
+#endif\r
+\r
+\r
+int32_t red_init(void);\r
+int32_t red_uninit(void);\r
+int32_t red_mount(const char *pszVolume);\r
+int32_t red_umount(const char *pszVolume);\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)\r
+int32_t red_format(const char *pszVolume);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+int32_t red_transact(const char *pszVolume);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask);\r
+#endif\r
+int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask);\r
+int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs);\r
+int32_t red_open(const char *pszPath, uint32_t ulOpenMode);\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1)\r
+int32_t red_unlink(const char *pszPath);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1)\r
+int32_t red_mkdir(const char *pszPath);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1)\r
+int32_t red_rmdir(const char *pszPath);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)\r
+int32_t red_rename(const char *pszOldPath, const char *pszNewPath);\r
+#endif\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1)\r
+int32_t red_link(const char *pszPath, const char *pszHardLink);\r
+#endif\r
+int32_t red_close(int32_t iFildes);\r
+int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength);\r
+#if REDCONF_READ_ONLY == 0\r
+int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength);\r
+#endif\r
+#if REDCONF_READ_ONLY == 0\r
+int32_t red_fsync(int32_t iFildes);\r
+#endif\r
+int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence);\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)\r
+int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize);\r
+#endif\r
+int32_t red_fstat(int32_t iFildes, REDSTAT *pStat);\r
+#if REDCONF_API_POSIX_READDIR == 1\r
+REDDIR *red_opendir(const char *pszPath);\r
+REDDIRENT *red_readdir(REDDIR *pDirStream);\r
+void red_rewinddir(REDDIR *pDirStream);\r
+int32_t red_closedir(REDDIR *pDirStream);\r
+#endif\r
+REDSTATUS *red_errnoptr(void);\r
+\r
+#endif /* REDCONF_API_POSIX */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDSTAT_H\r
+#define REDSTAT_H\r
+\r
+\r
+/** Mode bit for a directory. */\r
+#define RED_S_IFDIR 0x4000U\r
+\r
+/** Mode bit for a regular file. */\r
+#define RED_S_IFREG 0x8000U\r
+\r
+/** @brief Test for a directory.\r
+*/\r
+#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U)\r
+\r
+/** @brief Test for a regular file.\r
+*/\r
+#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U)\r
+\r
+\r
+/** File system is read-only. */\r
+#define RED_ST_RDONLY 0x00000001U\r
+\r
+/** File system ignores suid and sgid bits. */\r
+#define RED_ST_NOSUID 0x00000002U\r
+\r
+\r
+/** @brief Status information on an inode.\r
+*/\r
+typedef struct\r
+{\r
+ uint8_t st_dev; /**< Volume number of volume containing file. */\r
+ uint32_t st_ino; /**< File serial number (inode number). */\r
+ uint16_t st_mode; /**< Mode of file. */\r
+ uint16_t st_nlink; /**< Number of hard links to the file. */\r
+ uint64_t st_size; /**< File size in bytes. */\r
+ #if REDCONF_INODE_TIMESTAMPS == 1\r
+ uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */\r
+ uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */\r
+ uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */\r
+ #endif\r
+ #if REDCONF_INODE_BLOCKS == 1\r
+ uint32_t st_blocks; /**< Number of blocks allocated for this object. */\r
+ #endif\r
+} REDSTAT;\r
+\r
+\r
+/** @brief Status information on a file system volume.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t f_bsize; /**< File system block size. */\r
+ uint32_t f_frsize; /**< Fundamental file system block size. */\r
+ uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */\r
+ uint32_t f_bfree; /**< Total number of free blocks. */\r
+ uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */\r
+ uint32_t f_files; /**< Total number of file serial numbers. */\r
+ uint32_t f_ffree; /**< Total number of free file serial numbers. */\r
+ uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */\r
+ uint32_t f_fsid; /**< File system ID (useless, populated with zero). */\r
+ uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */\r
+ uint32_t f_namemax; /**< Maximum filename length. */\r
+ uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */\r
+ uint32_t f_dev; /**< Volume number (POSIX extension). */\r
+} REDSTATFS;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Prototypes for Reliance Edge test entry points.\r
+*/\r
+#ifndef REDTESTS_H\r
+#define REDTESTS_H\r
+\r
+#include <redtypes.h>\r
+#include "redtestutils.h"\r
+#include "redver.h"\r
+\r
+/* This macro is only defined by the error injection project.\r
+*/\r
+#ifdef REDCONF_ERROR_INJECTION\r
+#include <rederrinject.h>\r
+#endif\r
+\r
+#define FSSTRESS_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_GPL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_PATH_SEPARATOR == '/') \\r
+ && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_UNLINK == 1) && (REDCONF_API_POSIX_MKDIR == 1) \\r
+ && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_RENAME == 1) && (REDCONF_API_POSIX_LINK == 1) \\r
+ && (REDCONF_API_POSIX_FTRUNCATE == 1) && (REDCONF_API_POSIX_READDIR == 1))\r
+\r
+#define FSE_STRESS_TEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \\r
+ && (REDCONF_API_FSE_FORMAT == 1) && (REDCONF_API_FSE_TRANSMASKSET == 1) && (REDCONF_API_FSE_TRANSMASKGET == 1) \\r
+ && (REDCONF_API_FSE_TRUNCATE == 1))\r
+\r
+#define POSIX_API_TEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \\r
+ && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_UNLINK == 1))\r
+\r
+#define FSE_API_TEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \\r
+ && (REDCONF_API_FSE_FORMAT == 1))\r
+\r
+#define STOCH_POSIX_TEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \\r
+ && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_READDIR == 1) \\r
+ && (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_UNLINK == 1) \\r
+ && (REDCONF_API_POSIX_RENAME == 1))\r
+\r
+#define FSIOTEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_API_POSIX == 1))\r
+\r
+#define BDEVTEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0))\r
+\r
+#define DISKFULL_TEST_SUPPORTED \\r
+ ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \\r
+ && (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \\r
+ && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1))\r
+\r
+\r
+typedef enum\r
+{\r
+ PARAMSTATUS_OK, /* Parameters were good; continue. */\r
+ PARAMSTATUS_BAD, /* Parameters were bad; stop. */\r
+ PARAMSTATUS_HELP /* Help request; not an error, but stop. */\r
+} PARAMSTATUS;\r
+\r
+\r
+#if FSSTRESS_SUPPORTED\r
+typedef struct\r
+{\r
+ bool fNoCleanup; /**< --no-cleanup */\r
+ uint32_t ulLoops; /**< --loops */\r
+ uint32_t ulNops; /**< --nops */\r
+ bool fNamePad; /**< --namepad */\r
+ uint32_t ulSeed; /**< --seed */\r
+ bool fVerbose; /**< --verbose */\r
+} FSSTRESSPARAM;\r
+\r
+PARAMSTATUS FsstressParseParams(int argc, char *argv[], FSSTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void FsstressDefaultParams(FSSTRESSPARAM *pParam);\r
+int FsstressStart(const FSSTRESSPARAM *pParam);\r
+#endif\r
+\r
+#if STOCH_POSIX_TEST_SUPPORTED\r
+typedef struct\r
+{\r
+ const char *pszVolume; /**< Volume path prefix. */\r
+ uint32_t ulIterations; /**< --iterations */\r
+ uint32_t ulFileListMax; /**< --files */\r
+ uint32_t ulDirListMax; /**< --dirs */\r
+ uint32_t ulOpenFileListMax; /**< --open-files */\r
+ uint32_t ulOpenDirListMax; /**< --open-dirs */\r
+ uint32_t ulRandomSeed; /**< --seed */\r
+} STOCHPOSIXPARAM;\r
+\r
+PARAMSTATUS RedStochPosixParseParams(int argc, char *argv[], STOCHPOSIXPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void RedStochPosixDefaultParams(STOCHPOSIXPARAM *pParam);\r
+int RedStochPosixStart(const STOCHPOSIXPARAM *pParam);\r
+#endif\r
+\r
+#if FSE_STRESS_TEST_SUPPORTED\r
+typedef struct\r
+{\r
+ uint8_t bVolNum; /**< Volume number. */\r
+ uint32_t ulFileCount; /**< --files */\r
+ uint32_t ulMaxFileSize; /**< --max */\r
+ uint32_t ulMaxOpSize; /**< --buffer-size */\r
+ uint32_t ulNops; /**< --nops */\r
+ uint32_t ulLoops; /**< --loops */\r
+ uint32_t ulSampleRate; /**< --sample-rate */\r
+ uint64_t ullSeed; /**< --seed */\r
+} FSESTRESSPARAM;\r
+\r
+PARAMSTATUS FseStressParseParams(int argc, char *argv[], FSESTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void FseStressDefaultParams(FSESTRESSPARAM *pParam);\r
+int FseStressStart(const FSESTRESSPARAM *pParam);\r
+#endif\r
+\r
+#if POSIX_API_TEST_SUPPORTED\r
+typedef struct\r
+{\r
+ const char *pszVolume; /**< Volume path prefix. */\r
+ bool fQuick; /**< --quick */\r
+ bool fQuitOnFailure; /**< --quit-on-failure */\r
+ bool fDebugErrors; /**< --debug */\r
+} POSIXTESTPARAM;\r
+\r
+PARAMSTATUS RedPosixTestParseParams(int argc, char *argv[], POSIXTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void RedPosixTestDefaultParams(POSIXTESTPARAM *pParam);\r
+int RedPosixTestStart(const POSIXTESTPARAM *pParam);\r
+#endif\r
+\r
+\r
+#if FSE_API_TEST_SUPPORTED\r
+typedef struct\r
+{\r
+ uint8_t bVolNum; /**< Volume number. */\r
+ bool fQuitOnFailure; /**< --quit-on-failure */\r
+ bool fDebugErrors; /**< --debug */\r
+} FSETESTPARAM;\r
+\r
+PARAMSTATUS RedFseTestParseParams(int argc, char *argv[], FSETESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void RedFseTestDefaultParams(FSETESTPARAM *pParam);\r
+int RedFseTestStart(const FSETESTPARAM *pParam);\r
+#endif\r
+\r
+#if FSIOTEST_SUPPORTED\r
+typedef enum\r
+{\r
+ TESTFS_RELEDGE, /* Datalight Reliance Edge */\r
+ TESTFS_FATFS, /* ChaN's FatFs */\r
+ TESTFS_FATSL /* FreeRTOS+FAT SL */\r
+} TESTFS;\r
+\r
+typedef struct\r
+{\r
+ TESTFS testfs; /**< --fs */\r
+ const char *pszVolume; /**< Volume path prefix. */\r
+ bool fSeqRead; /**< --seq=r */\r
+ bool fSeqWrite; /**< --seq=w */\r
+ bool fSeqRewrite; /**< --seq=e */\r
+ bool fRandomRead; /**< --rand=r */\r
+ bool fRandomWrite; /**< --rand=w */\r
+ bool fMixedWrite; /**< --mixed */\r
+ bool fScanTest; /**< --scan */\r
+ uint32_t ulFSBlockSize; /**< --block-size */\r
+ uint32_t ulMaxFileSize; /**< --max */\r
+ uint32_t ulRandomReadPasses; /**< --rand-pass=r:w (r part) */\r
+ uint32_t ulRandomWritePasses; /**< --rand-pass=r:w (w part) */\r
+ uint32_t ulMixedWritePasses; /**< --mixed-pass */\r
+ int32_t iFlushOnWriteRatio; /**< --rand-fow */\r
+ uint32_t ulBufferMin; /**< --start */\r
+ uint32_t ulBufferSize; /**< --buffer-size */\r
+ bool fWriteVerify; /**< --verify */\r
+ uint32_t ulSampleRate; /**< --sample-rate */\r
+ uint32_t ulScanCount; /**< --scan-files */\r
+ uint64_t ullSeed; /**< --seed */\r
+} FSIOTESTPARAM;\r
+\r
+PARAMSTATUS FSIOTestParseParams(int argc, char *argv[], FSIOTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void FSIOTestDefaultParams(FSIOTESTPARAM *pParam);\r
+int FSIOTestStart(const FSIOTESTPARAM *pParam);\r
+#endif\r
+\r
+#if BDEVTEST_SUPPORTED\r
+typedef struct\r
+{\r
+ uint8_t bDrvNum; /**< Volume number (for sector size/count). */\r
+ bool fSeqWrite; /**< --seq:w */\r
+ bool fSeqRead; /**< --seq:r */\r
+ bool fRandWrite; /**< --rand:w */\r
+ bool fRandRead; /**< --rand:r */\r
+ uint32_t ulSampleSecs; /**< --sample-rate */\r
+ uint32_t ulPasses; /**< --passes */\r
+ uint32_t ulMinIOSectors; /**< --count=min[:max] (min part) */\r
+ uint32_t ulMaxIOSectors; /**< --count=min[:max] (max part) */\r
+ uint32_t ulMaxSizeKB; /**< --max */\r
+ uint32_t ulTestSeconds; /**< --time */\r
+ bool fVerify; /**< --verify */\r
+ bool fAsyncWrites; /**< --async */\r
+ uint64_t ullSeed; /**< --seed */\r
+} BDEVTESTPARAM;\r
+\r
+PARAMSTATUS BDevTestParseParams(int argc, char *argv[], BDEVTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void BDevTestDefaultParams(BDEVTESTPARAM *pParam);\r
+int BDevTestStart(const BDEVTESTPARAM *pParam);\r
+#endif\r
+\r
+#if DISKFULL_TEST_SUPPORTED\r
+typedef struct\r
+{\r
+ const char *pszVolume; /**< Volume path prefix. */\r
+ bool fQuitOnFailure; /**< --quit-on-failure */\r
+ bool fDebugErrors; /**< --debug */\r
+} DISKFULLTESTPARAM;\r
+\r
+PARAMSTATUS DiskFullTestParseParams(int argc, char *argv[], DISKFULLTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);\r
+void DiskFullTestDefaultParams(DISKFULLTESTPARAM *pParam);\r
+int DiskFullTestStart(const DISKFULLTESTPARAM *pParam);\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Reliance Edge utilities only needed for tests.\r
+*/\r
+#ifndef REDTESTUTILS_H\r
+#define REDTESTUTILS_H\r
+\r
+\r
+#define ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))\r
+\r
+\r
+void RedRandSeed(uint64_t ullSeed);\r
+uint64_t RedRand64(uint64_t *pullSeed);\r
+uint32_t RedRand32(uint32_t *pulSeed);\r
+\r
+char *RedRatio(char *pBuffer, uint32_t ulBufferLen, uint64_t ullDividend, uint64_t ullDivisor, uint32_t ulDecPlaces);\r
+uint64_t RedMulDiv64(uint64_t ullBase, uint32_t ulMultiplier, uint64_t ullDivisor);\r
+uint64_t RedUint64DivMod32(uint64_t ullDividend, uint32_t ulDivisor, uint32_t *pulRemainder);\r
+uint64_t RedUint64DivMod64(uint64_t ullDividend, uint64_t ullDivisor, uint64_t *pullRemainder);\r
+\r
+char *RedScaleBytes(uint32_t ulByteValue, char *pszBuffer, uint32_t ulBufferSize);\r
+char *RedScaleKB(uint32_t ulKBValue, char *pszBuffer, uint32_t ulBufferSize);\r
+uint32_t RedGetKBPerSecond(uint64_t ullKB, uint32_t ulMS);\r
+uint32_t RedGetKBPerSecondSectors(uint32_t ulBytesPerSector, uint64_t ullSectors, uint64_t ullUS);\r
+\r
+int32_t RedAtoI(const char *pszNum);\r
+const char *RedHtoUL(const char *pszNum, uint32_t *pulNum);\r
+const char *RedHtoULL(const char *pszNum, uint64_t *pullNum);\r
+const char *RedNtoUL(const char *pszNum, uint32_t *pulNum);\r
+const char *RedNtoULL(const char *pszNum, uint64_t *pullNum);\r
+const char *RedSizeToUL(const char *pszNum, uint32_t *pulResult);\r
+\r
+int32_t RedStrICmp(const char *pszStr1, const char *pszStr2);\r
+int32_t RedStrNICmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);\r
+char RedToLower(char c);\r
+\r
+#include <stdarg.h>\r
+\r
+#if REDCONF_OUTPUT == 1\r
+void RedPrintf(const char *pszFormat, ...);\r
+void RedVPrintf(const char *pszFormat, va_list arglist);\r
+#endif\r
+int32_t RedSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, ...);\r
+int32_t RedVSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, va_list arglist);\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Interfaces for common-code utilities for tools and tests.\r
+*/\r
+#ifndef REDTOOLCMN_H\r
+#define REDTOOLCMN_H\r
+\r
+\r
+uint8_t RedFindVolumeNumber(const char *pszVolume);\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDUTILS_H\r
+#define REDUTILS_H\r
+\r
+\r
+#if REDCONF_ASSERTS == 1\r
+#define REDERROR() RedOsAssertFail(__FILE__, __LINE__)\r
+#define REDASSERT(EXP) ((EXP) ? (void)0 : REDERROR())\r
+#else\r
+#define REDERROR() ((void)0)\r
+#define REDASSERT(EXP) ((void)0)\r
+#endif\r
+\r
+\r
+void RedMemCpy(void *pDest, const void *pSrc, uint32_t ulLen);\r
+void RedMemMove(void *pDest, const void *pSrc, uint32_t ulLen);\r
+void RedMemSet(void *pDest, uint8_t bVal, uint32_t ulLen);\r
+int32_t RedMemCmp(const void *pMem1, const void *pMem2, uint32_t ulLen);\r
+\r
+uint32_t RedStrLen(const char *pszStr);\r
+int32_t RedStrCmp(const char *pszStr1, const char *pszStr2);\r
+int32_t RedStrNCmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);\r
+void RedStrNCpy(char *pszDst, const char *pszSrc, uint32_t ulLen);\r
+\r
+uint32_t RedCrc32Update(uint32_t ulInitCrc32, const void *pBuffer, uint32_t ulLength);\r
+uint32_t RedCrcNode(const void *pBuffer);\r
+\r
+#if REDCONF_API_POSIX == 1\r
+uint32_t RedNameLen(const char *pszName);\r
+#endif\r
+\r
+bool RedBitGet(const uint8_t *pbBitmap, uint32_t ulBit);\r
+void RedBitSet(uint8_t *pbBitmap, uint32_t ulBit);\r
+void RedBitClear(uint8_t *pbBitmap, uint32_t ulBit);\r
+\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+uint64_t RedRev64(uint64_t ullToRev);\r
+uint32_t RedRev32(uint32_t ulToRev);\r
+uint16_t RedRev16(uint16_t uToRev);\r
+#endif\r
+\r
+void RedSignOn(void);\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
+
+ Copyright (c) 2014-2015 Datalight, Inc.
+ All Rights Reserved Worldwide.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; use version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but "AS-IS," 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 along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+/* Businesses and individuals that for commercial or other reasons cannot
+ comply with the terms of the GPLv2 license may obtain a commercial license
+ before incorporating Reliance Edge into proprietary software for
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for
+ more information.
+*/
+/** @file
+ @brief Macros for version numbers, build number, and product information.
+*/
+#ifndef REDVER_H
+#define REDVER_H
+
+
+/** @brief Consecutive number assigned to each automated build.
+
+ <!-- This macro is updated automatically: do not edit! -->
+*/
+#define RED_BUILD_NUMBER "664"
+
+#define RED_KIT_GPL 0U /* Open source GPL kit. */
+#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */
+#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */
+
+/** @brief Indicates the Reliance Edge kit.
+
+ <!-- This macro is updated automatically: do not edit! -->
+*/
+#define RED_KIT RED_KIT_GPL
+
+
+/** @brief Version number to display in output.
+*/
+#define RED_VERSION "v1.0"
+
+
+/** @brief On-disk version number.
+
+ This is incremented only when the on-disk layout is updated in such a way
+ which is incompatible with previously released versions of the file system.
+*/
+#define RED_DISK_LAYOUT_VERSION 1U
+
+
+/** @brief Base name of the file system product.
+*/
+#define RED_PRODUCT_BASE_NAME "Reliance Edge"
+
+
+/* Specifies whether the product is in alpha stage, beta stage, or neither.
+*/
+#if 0
+ #if 1
+ #define ALPHABETA " (Alpha)"
+ #else
+ #define ALPHABETA " (Beta)"
+ #endif
+#else
+ #define ALPHABETA ""
+#endif
+
+/** @brief Full product name and version.
+*/
+#define RED_PRODUCT_NAME "Datalight "RED_PRODUCT_BASE_NAME" "RED_VERSION" Build "RED_BUILD_NUMBER ALPHABETA
+
+
+/** @brief Product copyright.
+*/
+#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2015 Datalight, Inc. All Rights Reserved Worldwide."
+
+
+/** @brief Product patents.
+*/
+#define RED_PRODUCT_PATENT "Patents: US#7284101."
+
+
+/** @brief Product edition.
+*/
+#if RED_KIT == RED_KIT_GPL
+#define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled "__DATE__" at "__TIME__
+#elif RED_KIT == RED_KIT_COMMERCIAL
+#define RED_PRODUCT_EDITION "Commercial Edition -- Compiled "__DATE__" at "__TIME__
+#else
+#define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled "__DATE__" at "__TIME__
+#endif
+
+
+#endif
+
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+*/\r
+#ifndef REDVOLUME_H\r
+#define REDVOLUME_H\r
+\r
+\r
+/** @brief Per-volume configuration structure.\r
+\r
+ Contains the configuration values that may differ between volumes. Must be\r
+ declared in an array in redconf.c in the Reliance Edge project directory and\r
+ statically initialized with values representing the volume configuration of\r
+ the target system.\r
+*/\r
+typedef struct\r
+{\r
+ /** The sector size for the block device underlying the volume: the basic\r
+ unit for reading and writing to the storage media. Commonly ranges\r
+ between 512 and 4096, but any power-of-two value not greater than the\r
+ block size will work.\r
+ */\r
+ uint32_t ulSectorSize;\r
+\r
+ /** The number of sectors in this file system volume.\r
+ */\r
+ uint64_t ullSectorCount;\r
+\r
+ /** Whether a sector write on the block device underlying the volume is\r
+ atomic. It is atomic if when the sector write is interrupted, the\r
+ contents of the sector are guaranteed to be either all of the new data,\r
+ or all of the old data. If unsure, leave as false.\r
+ */\r
+ bool fAtomicSectorWrite;\r
+\r
+ /** This is the maximum number of inodes (files and directories). This\r
+ number includes the root directory inode (inode 2; created during\r
+ format), but does not include inodes 0 or 1, which do not exist on\r
+ disk. The number of inodes cannot be less than 1.\r
+ */\r
+ uint32_t ulInodeCount;\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ /** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc.\r
+ */\r
+ const char *pszPathPrefix;\r
+ #endif\r
+} VOLCONF;\r
+\r
+extern const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT];\r
+extern const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf;\r
+\r
+\r
+/** @brief Per-volume run-time data.\r
+*/\r
+typedef struct\r
+{\r
+ /** Whether the volume is currently mounted.\r
+ */\r
+ bool fMounted;\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ /** Whether the volume is read-only.\r
+ */\r
+ bool fReadOnly;\r
+\r
+ /** The active automatic transaction mask.\r
+ */\r
+ uint32_t ulTransMask;\r
+ #endif\r
+\r
+ /** The power of 2 difference between sector size and block size.\r
+ */\r
+ uint8_t bBlockSectorShift;\r
+\r
+ /** The number of logical blocks in this file system volume. The unit here\r
+ is the global block size.\r
+ */\r
+ uint32_t ulBlockCount;\r
+\r
+ /** The total number of allocable blocks; Also the maximum count of free\r
+ blocks.\r
+ */\r
+ uint32_t ulBlocksAllocable;\r
+\r
+ /** The maximum number of bytes that an inode is capable of addressing.\r
+ */\r
+ uint64_t ullMaxInodeSize;\r
+\r
+ /** The current metadata sequence number. This value is included in all\r
+ metadata nodes and incremented every time a metadata node is written.\r
+ It is assumed to never wrap around.\r
+ */\r
+ uint64_t ullSequence;\r
+} VOLUME;\r
+\r
+/* Array of VOLUME structures, populated at during RedCoreInit().\r
+*/\r
+extern VOLUME gaRedVolume[REDCONF_VOLUME_COUNT];\r
+\r
+/* Volume number currently being accessed; populated during\r
+ RedCoreVolSetCurrent().\r
+*/\r
+extern CONST_IF_ONE_VOLUME uint8_t gbRedVolNum;\r
+\r
+/* Pointer to the volume currently being accessed; populated during\r
+ RedCoreVolSetCurrent().\r
+*/\r
+extern VOLUME * CONST_IF_ONE_VOLUME gpRedVolume;\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code.\r
+*/\r
+#ifndef REDOSDEVIATIONS_H\r
+#define REDOSDEVIATIONS_H\r
+\r
+\r
+#if REDCONF_OUTPUT == 1\r
+/* Needed for PRINT_ASSERT() and OUTPUT_CHARACTER().\r
+*/\r
+#include <stdio.h>\r
+#endif\r
+\r
+\r
+#if REDCONF_ASSERTS == 1\r
+#if REDCONF_OUTPUT == 1\r
+/** Print a formatted message for an assertion.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using\r
+ printf() is the most convenient way to output this information; and the risk\r
+ of "unspecified, undefined and implementation-defined" behavior causing\r
+ problems (as cited in the rationale for the rule) is small. The driver does\r
+ not depend on this string being outputted correctly. Furthermore, use of\r
+ printf() disappears when either asserts or output are disabled.\r
+\r
+ As Rule 21.6 is required, a separate deviation record is required.\r
+*/\r
+#define PRINT_ASSERT(file, line) \\r
+ (void)printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line))\r
+#else\r
+#define PRINT_ASSERT(file, line) do { (void)(file); (void)(line); } while(false)\r
+#endif /* REDCONF_OUTPUT == 1 */\r
+#endif /* REDCONF_ASSERTS == 1 */\r
+\r
+\r
+/** Cast a value to unsigned long.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is\r
+ used in two places to cast a uint64_t value (used by the block device\r
+ abstraction for sector numbers) to unsigned long, since third-party code\r
+ which is not under the control of this project uses unsigned long for sector\r
+ numbers. The cast is guaranteed to not lose any information, since when the\r
+ disk is opened the sector count is verified to be less than or equal to an\r
+ unsigned long value. The text of the directive mentions that "it might be\r
+ desirable not to apply this guideline when interfacing with ... code outside\r
+ the project's control", which describes the situation for this deviation.\r
+\r
+ As Directive 4.6 is advisory, a deviation record is not required. This\r
+ notice is the only record of the deviation.\r
+*/\r
+#define CAST_ULONG(ull) ((unsigned long)(ull))\r
+\r
+\r
+/** Cast a const-qualified pointer to a pointer which is *not* const-qualified.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is\r
+ used in exactly one place in order to cope with a poorly designed\r
+ third-party interface. Reliance Edge, at every level of the stack, uses\r
+ const-qualified pointers for buffers used in write operations, since the\r
+ data is read from the buffer, and the buffer does not need to be modified\r
+ (consistent with Rule 8.13). One of the third-party block device interfaces\r
+ that Reliance Edge interfaces with does not follow this convention: it uses\r
+ an unqualified pointer for the buffer parameter of its sector write\r
+ function. This forces the need for the cast to avoid warnings. The\r
+ implementation of the sector write function is provided by the user, so it\r
+ is to be hoped that the buffer is not actually modified.\r
+\r
+ As Rule 11.8 is required, a separate deviation record is required.\r
+*/\r
+#define CAST_AWAY_CONST(type, ptr) ((type *)(ptr))\r
+\r
+\r
+/** Allocate zero-initialized (cleared) memory.\r
+\r
+ All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required)\r
+ and Rule 21.3 (required). In the context of the single place it is actually\r
+ used, this macro also deviates from Rule 22.1 (required).\r
+\r
+ This macro is used in the FreeRTOS block device code in order to allocate a\r
+ RAM disk, when that implementation of the block device is selected. The\r
+ primary rationale for all these deviations is that a) the RAM disk cannot be\r
+ allocated statically (since the volume information is stored in a\r
+ structure), and b) the RAM disk is primarily intended as a temporary testing\r
+ tool for users who want to try out Reliance Edge before the real storage\r
+ media is available. In most real systems, Reliance Edge is used with\r
+ non-volatile storage like SD/MMC or eMMC, not with RAM disks.\r
+\r
+ Rule 22.1 states that all resources which are allocated must also be\r
+ explicitly freed. The RAM disk is allocated and never freed, deviating from\r
+ that rule. This is done because the data in the RAM disk is emulating a\r
+ non-volatile storage medium, and thus needs to persist even after the block\r
+ device is closed, to allow the file system to be ormatted and then mounted,\r
+ or unmounted and remounted in the course of a test. Thus the memory will\r
+ remain allocated until the target device is rebooted. This is assumed to be\r
+ acceptable for the primary purpose of the RAM disk, which is preliminary\r
+ testing.\r
+\r
+ As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate\r
+ deviation records are required.\r
+*/\r
+#define ALLOCATE_CLEARED_MEMORY(nelem, elsize) calloc(nelem, elsize)\r
+\r
+\r
+#if REDCONF_OUTPUT == 1\r
+/** Output a character to a serial port or other display device.\r
+\r
+ Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).\r
+ FreeRTOS does not include a standard method of printing characters, so\r
+ putchar() is the most convenient and portable way to accomplish the task.\r
+ The risk of "unspecified, undefined and implementation-defined" behavior\r
+ causing problems (as cited in the rationale for the rule) is small. The\r
+ driver does not depend on the character being outputted correctly.\r
+ Furthermore, use of putchar() disappears when output is disabled.\r
+\r
+ As Rule 21.6 is required, a separate deviation record is required.\r
+*/\r
+#define OUTPUT_CHARACTER(ch) (void)putchar(ch)\r
+#endif\r
+\r
+\r
+#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)\r
+/** Cast a TaskHandle_t (a pointer type) to uintptr_t.\r
+\r
+ Usage of this macro deivate from MISRA-C:2012 Rule 11.4 (advisory). This\r
+ macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes\r
+ natively use an integer for task IDs; others use pointers. RedOsTaskId()\r
+ uses integers, FreeRTOS uses pointers; to reconcile this difference, the\r
+ pointer must be cast to integer. This is fairly safe, since the resulting\r
+ integer is never cast back to a pointer; and although the integer\r
+ representation of a pointer is implementation-defined, the representation is\r
+ irrelevant provided that unique pointers are converted to unique integers.\r
+\r
+ As Rule 11.4 is advisory, a deviation record is not required. This notice\r
+ is the only record of the deviation.\r
+*/\r
+#define CAST_TASK_PTR_TO_UINTPTR(taskptr) ((uintptr_t)(taskptr))\r
+#endif\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Defines OS-specific types for use in common code.\r
+*/\r
+#ifndef REDOSTYPES_H\r
+#define REDOSTYPES_H\r
+\r
+\r
+/** @brief Implementation-defined timestamp type.\r
+\r
+ This can be an integer, a structure, or a pointer: anything that is\r
+ convenient for the implementation. Since the underlying type is not fixed,\r
+ common code should treat this as an opaque type.\r
+*/\r
+typedef uint32_t REDTIMESTAMP;\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements assertion handling.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_ASSERTS == 1\r
+\r
+#include <redosdeviations.h>\r
+\r
+\r
+/** @brief Invoke the native assertion handler.\r
+\r
+ @param pszFileName Null-terminated string containing the name of the file\r
+ where the assertion fired.\r
+ @param ulLineNum Line number in @p pszFileName where the assertion\r
+ fired.\r
+*/\r
+void RedOsAssertFail(\r
+ const char *pszFileName,\r
+ uint32_t ulLineNum)\r
+{\r
+ PRINT_ASSERT(pszFileName, ulLineNum);\r
+\r
+ for( ;; )\r
+ {\r
+ }\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements block device I/O.\r
+*/\r
+#include <FreeRTOS.h>\r
+\r
+#include <redfs.h>\r
+#include <redvolume.h>\r
+#include <redosdeviations.h>\r
+\r
+\r
+/*------------------------------------------------------------------------------\r
+ Porting Note:\r
+\r
+ Several example implementations of this module for FreeRTOS are available.\r
+ If you are lucky, you can use one of these implementations; otherwise, these\r
+ can serve as examples of how to implement this service.\r
+------------------------------------------------------------------------------*/\r
+\r
+/** @brief The F_DRIVER example implementation.\r
+\r
+ This implementation is designed to reuse an existing block device driver\r
+ that was written for FreeRTOS+FAT SL. If you have such a driver, with\r
+ little work it can be "dropped in" and used for Reliance Edge. The only\r
+ customization required is that gpfnRedOsBDevInit needs to be defined and\r
+ pointed at the F_DRIVERINIT function. This can be done in this module or in\r
+ another C file.\r
+\r
+ The disadantage of using the FreeRTOS F_DRIVER functions is that they only\r
+ support single-sector reads and writes. Reliance Edge will issue\r
+ multi-sector requests, and servicing these one sector at a time will\r
+ significantly slow down the file system.\r
+*/\r
+#define BDEV_F_DRIVER 0U\r
+\r
+/** @brief The FatFs example implementation.\r
+\r
+ This implementation is designed to reuse an existing block device driver\r
+ that was written for FatFs. If you have such a driver, it can be linked\r
+ in and used immediately. The FatFs `diskio.h` header must be in the include\r
+ directory path.\r
+*/\r
+#define BDEV_FATFS 1U\r
+\r
+/** @brief The Atmel Studio Framework SD/MMC driver example implementation.\r
+\r
+ This implementation uses a modified version of the open source SD/MMC driver\r
+ included in the Atmel Studio Framework (ASF) and will work as-is for many\r
+ varieties of Atmel hardware. This example assumes relatively minor\r
+ modifications to the ASF SD/MMC driver to make it support multi-sector read\r
+ and write requests, which greatly improves performance. The modified driver\r
+ is distributed with Reliance Edge and is included in FreeRTOS Atmel projects\r
+ (such as in projects/freertos/atmel/sam4e-ek/src/ASF).\r
+\r
+ This example can easily be modified to work with an unmodified version of\r
+ the ASF SD/MMC driver. Simply replace sd_mmc_mem_2_ram_multi() and\r
+ sd_mmc_ram_2_mem_multi() with sd_mmc_mem_2_ram() and sd_mmc_ram_2_mem()\r
+ respectively, and add a for loop to loop over each sector in the request.\r
+ However, as described in the manual, there are considerable performance\r
+ advantages to issuing real multi-sector requests, so using the modified\r
+ driver is recommended.\r
+*/\r
+#define BDEV_ATMEL_SDMMC 2U\r
+\r
+/** @brief The RAM disk example implementation.\r
+\r
+ This implementation uses a RAM disk. It will allow you to compile and test\r
+ Reliance Edge even if your storage driver is not yet ready. On typical\r
+ target hardware, the amount of spare RAM will be limited so generally only\r
+ very small disks will be available.\r
+*/\r
+#define BDEV_RAM_DISK 3U\r
+\r
+/** @brief Pick which example implementation is compiled.\r
+\r
+ Must be one of:\r
+ - #BDEV_F_DRIVER\r
+ - #BDEV_FATFS\r
+ - #BDEV_ATMEL_SDMMC\r
+ - #BDEV_RAM_DISK\r
+*/\r
+#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK\r
+\r
+\r
+static REDSTATUS DiskOpen(uint8_t bVolNum, BDEVOPENMODE mode);\r
+static REDSTATUS DiskClose(uint8_t bVolNum);\r
+static REDSTATUS DiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);\r
+#if REDCONF_READ_ONLY == 0\r
+static REDSTATUS DiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);\r
+static REDSTATUS DiskFlush(uint8_t bVolNum);\r
+#endif\r
+\r
+\r
+/** @brief Initialize a block device.\r
+\r
+ This function is called when the file system needs access to a block\r
+ device.\r
+\r
+ Upon successful return, the block device should be fully initialized and\r
+ ready to service read/write/flush/close requests.\r
+\r
+ The behavior of calling this function on a block device which is already\r
+ open is undefined.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ initialized.\r
+ @param mode The open mode, indicating the type of access required.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedOsBDevOpen(\r
+ uint8_t bVolNum,\r
+ BDEVOPENMODE mode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(bVolNum >= REDCONF_VOLUME_COUNT)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = DiskOpen(bVolNum, mode);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize a block device.\r
+\r
+ This function is called when the file system no longer needs access to a\r
+ block device. If any resource were allocated by RedOsBDevOpen() to service\r
+ block device requests, they should be freed at this time.\r
+\r
+ Upon successful return, the block device must be in such a state that it\r
+ can be opened again.\r
+\r
+ The behavior of calling this function on a block device which is already\r
+ closed is undefined.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ uninitialized.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number.\r
+*/\r
+REDSTATUS RedOsBDevClose(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(bVolNum >= REDCONF_VOLUME_COUNT)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = DiskClose(bVolNum);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Read sectors from a physical block device.\r
+\r
+ The behavior of calling this function is undefined if the block device is\r
+ closed or if it was opened with ::BDEV_O_WRONLY.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being read from.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to read.\r
+ @param pBuffer The buffer into which to read the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is\r
+ `NULL`, or @p ullStartSector and/or @p ulSectorCount\r
+ refer to an invalid range of sectors.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedOsBDevRead(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if( (bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount)\r
+ || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount)\r
+ || (pBuffer == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = DiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write sectors to a physical block device.\r
+\r
+ The behavior of calling this function is undefined if the block device is\r
+ closed or if it was opened with ::BDEV_O_RDONLY.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being written to.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to write.\r
+ @param pBuffer The buffer from which to write the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is\r
+ `NULL`, or @p ullStartSector and/or @p ulSectorCount\r
+ refer to an invalid range of sectors.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedOsBDevWrite(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if( (bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount)\r
+ || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount)\r
+ || (pBuffer == NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = DiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ This function must synchronously flush all software and hardware caches\r
+ beneath the file system, ensuring that all sectors written previously are\r
+ committed to permanent storage.\r
+\r
+ If the environment has no caching beneath the file system, the\r
+ implementation of this function can do nothing and return success.\r
+\r
+ The behavior of calling this function is undefined if the block device is\r
+ closed or if it was opened with ::BDEV_O_RDONLY.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p bVolNum is an invalid volume number.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+REDSTATUS RedOsBDevFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(bVolNum >= REDCONF_VOLUME_COUNT)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = DiskFlush(bVolNum);\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#if BDEV_EXAMPLE_IMPLEMENTATION == BDEV_F_DRIVER\r
+\r
+#include <api_mdriver.h>\r
+\r
+\r
+/* This must be declared and initialized elsewere (e.g., in project code) to\r
+ point at the initialization function for the F_DRIVER block device.\r
+*/\r
+extern const F_DRIVERINIT gpfnRedOsBDevInit;\r
+\r
+static F_DRIVER *gapFDriver[REDCONF_VOLUME_COUNT];\r
+\r
+\r
+/** @brief Initialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ initialized.\r
+ @param mode The open mode, indicating the type of access required.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskOpen(\r
+ uint8_t bVolNum,\r
+ BDEVOPENMODE mode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ (void)mode;\r
+\r
+ if((gpfnRedOsBDevInit == NULL) || (gapFDriver[bVolNum] != NULL))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ F_DRIVER *pDriver;\r
+\r
+ pDriver = gpfnRedOsBDevInit(bVolNum);\r
+ if(pDriver != NULL)\r
+ {\r
+ F_PHY geom;\r
+ int iErr;\r
+\r
+ /* Validate that the geometry is consistent with the volume\r
+ configuration.\r
+ */\r
+ iErr = pDriver->getphy(pDriver, &geom);\r
+ if(iErr == 0)\r
+ {\r
+ if( (geom.bytes_per_sector != gaRedVolConf[bVolNum].ulSectorSize)\r
+ || (geom.number_of_sectors < gaRedVolConf[bVolNum].ullSectorCount))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ gapFDriver[bVolNum] = pDriver;\r
+ ret = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ pDriver->release(pDriver);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ uninitialized.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskClose(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapFDriver[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ gapFDriver[bVolNum]->release(gapFDriver[bVolNum]);\r
+ gapFDriver[bVolNum] = NULL;\r
+\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Read sectors from a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being read from.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to read.\r
+ @param pBuffer The buffer into which to read the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskRead(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ F_DRIVER *pDriver = gapFDriver[bVolNum];\r
+\r
+ if(pDriver == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint32_t ulSectorIdx;\r
+ int iErr;\r
+\r
+ for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)\r
+ {\r
+ iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize],\r
+ CAST_ULONG(ullSectorStart + ulSectorCount));\r
+ if(iErr != 0)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write sectors to a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being written to.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to write.\r
+ @param pBuffer The buffer from which to write the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The block device is not open.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskWrite(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ F_DRIVER *pDriver = gapFDriver[bVolNum];\r
+\r
+ if(pDriver == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint32_t ulSectorIdx;\r
+ int iErr;\r
+\r
+ for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)\r
+ {\r
+ /* We have to cast pbBuffer to non-const since the writesector\r
+ prototype is flawed, using a non-const pointer for the buffer.\r
+ */\r
+ iErr = pDriver->writesector(pDriver, CAST_AWAY_CONST(uint8_t, &pbBuffer[ulSectorIdx * ulSectorSize]),\r
+ CAST_ULONG(ullSectorStart + ulSectorCount));\r
+ if(iErr != 0)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapFDriver[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ /* The F_DRIVER interface does not include a flush function, so to be\r
+ reliable the F_DRIVER implementation must use synchronous writes.\r
+ */\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_FATFS\r
+\r
+#include <task.h>\r
+#include <diskio.h>\r
+\r
+/* disk_read() and disk_write() use an unsigned 8-bit value to specify the\r
+ sector count, so no transfer can be larger than 255 sectors.\r
+*/\r
+#define MAX_SECTOR_TRANSFER UINT8_MAX\r
+\r
+\r
+/** @brief Initialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ initialized.\r
+ @param mode The open mode, indicating the type of access required.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskOpen(\r
+ uint8_t bVolNum,\r
+ BDEVOPENMODE mode)\r
+{\r
+ DSTATUS status;\r
+ uint32_t ulTries;\r
+ REDSTATUS ret = 0;\r
+\r
+ /* With some implementations of disk_initialize(), such as the one\r
+ implemented by Atmel for the ASF, the first time the disk is opened, the\r
+ SD card can take a while to get ready, in which time disk_initialize()\r
+ returns an error. Try numerous times, waiting half a second after each\r
+ failure. Empirically, this has been observed to succeed on the second\r
+ try, so trying 10x more than that provides a margin of error.\r
+ */\r
+ for(ulTries = 0U; ulTries < 20U; ulTries++)\r
+ {\r
+ /* Assuming that the volume number is also the correct drive number.\r
+ If this is not the case in your environment, a static constant array\r
+ can be declared to map volume numbers to the correct driver number.\r
+ */\r
+ status = disk_initialize(bVolNum);\r
+ if(status == 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ vTaskDelay(500U / portTICK_PERIOD_MS);\r
+ }\r
+\r
+ if(status != 0)\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+\r
+ /* Retrieve the sector size and sector count to ensure they are compatible\r
+ with our compile-time geometry.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ WORD wSectorSize;\r
+ DWORD dwSectorCount;\r
+ DRESULT result;\r
+\r
+ result = disk_ioctl(bVolNum, GET_SECTOR_SIZE, &wSectorSize);\r
+ if(result == RES_OK)\r
+ {\r
+ result = disk_ioctl(bVolNum, GET_SECTOR_COUNT, &dwSectorCount);\r
+ if(result == RES_OK)\r
+ {\r
+ if( (wSectorSize != gaRedVolConf[bVolNum].ulSectorSize)\r
+ || (dwSectorCount < gaRedVolConf[bVolNum].ullSectorCount))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ uninitialized.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskClose(\r
+ uint8_t bVolNum)\r
+{\r
+ (void)bVolNum;\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Read sectors from a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being read from.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to read.\r
+ @param pBuffer The buffer into which to read the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskRead(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint32_t ulSectorIdx = 0U;\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);\r
+\r
+ while(ulSectorIdx < ulSectorCount)\r
+ {\r
+ uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);\r
+ DRESULT result;\r
+\r
+ result = disk_read(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer);\r
+ if(result != RES_OK)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+\r
+ ulSectorIdx += ulTransfer;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write sectors to a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being written to.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to write.\r
+ @param pBuffer The buffer from which to write the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskWrite(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint32_t ulSectorIdx = 0U;\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+\r
+ while(ulSectorIdx < ulSectorCount)\r
+ {\r
+ uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);\r
+ DRESULT result;\r
+\r
+ result = disk_write(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer);\r
+ if(result != RES_OK)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+\r
+ ulSectorIdx += ulTransfer;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+ DRESULT result;\r
+\r
+ result = disk_ioctl(bVolNum, CTRL_SYNC, NULL);\r
+ if(result == RES_OK)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_ATMEL_SDMMC\r
+\r
+#include <task.h>\r
+\r
+#include <conf_sd_mmc.h>\r
+#include <sd_mmc.h>\r
+#include <sd_mmc_mem.h>\r
+#include <ctrl_access.h>\r
+\r
+/* sd_mmc_mem_2_ram_multi() and sd_mmc_ram_2_mem_multi() use an unsigned\r
+ 16-bit value to specify the sector count, so no transfer can be larger\r
+ than UINT16_MAX sectors.\r
+*/\r
+#define MAX_SECTOR_TRANSFER UINT16_MAX\r
+\r
+\r
+/** @brief Initialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ initialized.\r
+ @param mode The open mode, indicating the type of access required.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EROFS The device is read-only media and write access was\r
+ requested.\r
+*/\r
+static REDSTATUS DiskOpen(\r
+ uint8_t bVolNum,\r
+ BDEVOPENMODE mode)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint32_t ulTries;\r
+ Ctrl_status cs;\r
+\r
+ /* Note: Assuming the volume number is the same as the SD card slot. The\r
+ ASF SD/MMC driver supports two SD slots. This implementation will need\r
+ to be modified if multiple volumes share a single SD card.\r
+ */\r
+\r
+ /* The first time the disk is opened, the SD card can take a while to get\r
+ ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY\r
+ or CTRL_NO_PRESENT. Try numerous times, waiting half a second after\r
+ each failure. Empirically, this has been observed to succeed on the\r
+ second try, so trying 10x more than that provides a margin of error.\r
+ */\r
+ for(ulTries = 0U; ulTries < 20U; ulTries++)\r
+ {\r
+ cs = sd_mmc_test_unit_ready(bVolNum);\r
+ if((cs != CTRL_NO_PRESENT) && (cs != CTRL_BUSY))\r
+ {\r
+ break;\r
+ }\r
+\r
+ vTaskDelay(500U / portTICK_PERIOD_MS);\r
+ }\r
+\r
+ if(cs == CTRL_GOOD)\r
+ {\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(mode != BDEV_O_RDONLY)\r
+ {\r
+ if(sd_mmc_wr_protect(bVolNum))\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ uint32_t ulSectorLast;\r
+\r
+ (void)sd_mmc_read_capacity(bVolNum, &ulSectorLast);\r
+\r
+ /* The ASF SD/MMC driver only supports 512-byte sectors.\r
+ */\r
+ if( (gaRedVolConf[bVolNum].ulSectorSize != 512U)\r
+ || (((uint64_t)ulSectorLast + 1U) < gaRedVolConf[bVolNum].ullSectorCount))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ uninitialized.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskClose(\r
+ uint8_t bVolNum)\r
+{\r
+ (void)bVolNum;\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Read sectors from a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being read from.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to read.\r
+ @param pBuffer The buffer into which to read the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskRead(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint32_t ulSectorIdx = 0U;\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);\r
+\r
+ while(ulSectorIdx < ulSectorCount)\r
+ {\r
+ uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);\r
+ Ctrl_status cs;\r
+\r
+ cs = sd_mmc_mem_2_ram_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx),\r
+ (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]);\r
+ if(cs != CTRL_GOOD)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+\r
+ ulSectorIdx += ulTransfer;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write sectors to a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being written to.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to write.\r
+ @param pBuffer The buffer from which to write the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskWrite(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret = 0;\r
+ uint32_t ulSectorIdx = 0U;\r
+ uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+\r
+ while(ulSectorIdx < ulSectorCount)\r
+ {\r
+ uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER);\r
+ Ctrl_status cs;\r
+\r
+ cs = sd_mmc_ram_2_mem_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx),\r
+ (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]);\r
+ if(cs != CTRL_GOOD)\r
+ {\r
+ ret = -RED_EIO;\r
+ break;\r
+ }\r
+\r
+ ulSectorIdx += ulTransfer;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+ Ctrl_status cs;\r
+\r
+ /* The ASF SD/MMC driver appears to write sectors synchronously, so it\r
+ should be fine to do nothing and return success. However, Atmel's\r
+ implementation of the FatFs diskio.c file does the equivalent of the\r
+ below when the disk is flushed. Just in case this is important for some\r
+ non-obvious reason, do the same.\r
+ */\r
+ cs = sd_mmc_test_unit_ready(bVolNum);\r
+ if(cs == CTRL_GOOD)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK\r
+\r
+#include <stdlib.h> /* For ALLOCATE_CLEARED_MEMORY(), which expands to calloc(). */\r
+\r
+\r
+static uint8_t *gapbRamDisk[REDCONF_VOLUME_COUNT];\r
+\r
+\r
+/** @brief Initialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ initialized.\r
+ @param mode The open mode, indicating the type of access required.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS DiskOpen(\r
+ uint8_t bVolNum,\r
+ BDEVOPENMODE mode)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ (void)mode;\r
+\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ gapbRamDisk[bVolNum] = ALLOCATE_CLEARED_MEMORY(gaRedVolume[bVolNum].ulBlockCount, REDCONF_BLOCK_SIZE);\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EIO;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ uninitialized.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskClose(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ /* This implementation uses dynamically allocated memory, but must\r
+ retain previously written data after the block device is closed, and\r
+ thus the memory cannot be freed and will remain allocated until\r
+ reboot.\r
+ */\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Read sectors from a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being read from.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to read.\r
+ @param pBuffer The buffer into which to read the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskRead(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize;\r
+\r
+ RedMemCpy(pBuffer, &gapbRamDisk[bVolNum][ullByteOffset], ulByteCount);\r
+\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write sectors to a disk.\r
+\r
+ @param bVolNum The volume number of the volume whose block device\r
+ is being written to.\r
+ @param ullSectorStart The starting sector number.\r
+ @param ulSectorCount The number of sectors to write.\r
+ @param pBuffer The buffer from which to write the sector data.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskWrite(\r
+ uint8_t bVolNum,\r
+ uint64_t ullSectorStart,\r
+ uint32_t ulSectorCount,\r
+ const void *pBuffer)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize;\r
+ uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize;\r
+\r
+ RedMemCpy(&gapbRamDisk[bVolNum][ullByteOffset], pBuffer, ulByteCount);\r
+\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Flush any caches beneath the file system.\r
+\r
+ @param bVolNum The volume number of the volume whose block device is being\r
+ flushed.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+static REDSTATUS DiskFlush(\r
+ uint8_t bVolNum)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gapbRamDisk[bVolNum] == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_READ_ONLY == 0 */\r
+\r
+\r
+#else\r
+\r
+#error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value"\r
+\r
+#endif /* BDEV_EXAMPLE_IMPLEMENTATION == ... */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements real-time clock functions.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+/** @brief Initialize the real time clock.\r
+\r
+ The behavior of calling this function when the RTC is already initialized\r
+ is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedOsClockInit(void)\r
+{\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Uninitialize the real time clock.\r
+\r
+ The behavior of calling this function when the RTC is not initialized is\r
+ undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedOsClockUninit(void)\r
+{\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Get the date/time.\r
+\r
+ The behavior of calling this function when the RTC is not initialized is\r
+ undefined.\r
+\r
+ @return The number of seconds since January 1, 1970 excluding leap seconds\r
+ (in other words, standard Unix time). If the resolution or epoch\r
+ of the RTC is different than this, the implementation must convert\r
+ it to the expected representation.\r
+*/\r
+uint32_t RedOsClockGetTime(void)\r
+{\r
+ /* FreeRTOS does not provide an RTC abstraction since most of the systems\r
+ it targets have no RTC hardware. If your hardware includes an RTC that\r
+ you would like to use, this function must be customized.\r
+ */\r
+ return 0;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements a synchronization object to provide mutual exclusion.\r
+*/\r
+#include <FreeRTOS.h>\r
+#include <semphr.h>\r
+\r
+#include <redfs.h>\r
+\r
+#if REDCONF_TASK_COUNT > 1U\r
+\r
+\r
+static SemaphoreHandle_t xMutex;\r
+\r
+\r
+/** @brief Initialize the mutex.\r
+\r
+ After initialization, the mutex is in the released state.\r
+\r
+ The behavior of calling this function when the mutex is still initialized\r
+ is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedOsMutexInit(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ xMutex = xSemaphoreCreateMutex();\r
+ if(xMutex != NULL)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_ENOMEM;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Uninitialize the mutex.\r
+\r
+ The behavior of calling this function when the mutex is not initialized is\r
+ undefined; likewise, the behavior of uninitializing the mutex when it is\r
+ in the acquired state is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedOsMutexUninit(void)\r
+{\r
+ vSemaphoreDelete(xMutex);\r
+ xMutex = NULL;\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Acquire the mutex.\r
+\r
+ The behavior of calling this function when the mutex is not initialized is\r
+ undefined; likewise, the behavior of recursively acquiring the mutex is\r
+ undefined.\r
+*/\r
+void RedOsMutexAcquire(void)\r
+{\r
+ while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE)\r
+ {\r
+ }\r
+}\r
+\r
+\r
+/** @brief Release the mutex.\r
+\r
+ The behavior is undefined in the following cases:\r
+\r
+ - Releasing the mutex when the mutex is not initialized.\r
+ - Releasing the mutex when it is not in the acquired state.\r
+ - Releasing the mutex from a task or thread other than the one which\r
+ acquired the mutex.\r
+*/\r
+void RedOsMutexRelease(void)\r
+{\r
+ BaseType_t xSuccess;\r
+\r
+ xSuccess = xSemaphoreGive(xMutex);\r
+ REDASSERT(xSuccess == pdTRUE);\r
+ (void)xSuccess;\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements outputting a character string.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_OUTPUT == 1\r
+\r
+#include <redosdeviations.h>\r
+\r
+\r
+/** @brief Write a string to a user-visible output location.\r
+\r
+ Write a null-terminated string to the serial port, console, terminal, or\r
+ other display device, such that the text is visible to the user.\r
+\r
+ @param pszString A null-terminated string.\r
+*/\r
+void RedOsOutputString(\r
+ const char *pszString)\r
+{\r
+ if(pszString == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx = 0U;\r
+\r
+ while(pszString[ulIdx] != '\0')\r
+ {\r
+ OUTPUT_CHARACTER(pszString[ulIdx]);\r
+\r
+ /* Serial output often requires a \r to print newlines correctly.\r
+ */\r
+ if(pszString[ulIdx] == '\n')\r
+ {\r
+ OUTPUT_CHARACTER('\r');\r
+ }\r
+\r
+ ulIdx++;\r
+ }\r
+ }\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements task functions.\r
+*/\r
+#include <FreeRTOS.h>\r
+#include <task.h>\r
+\r
+#include <redfs.h>\r
+\r
+#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)\r
+\r
+#include <redosdeviations.h>\r
+\r
+#if INCLUDE_xTaskGetCurrentTaskHandle != 1\r
+ #error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1 and REDCONF_API_POSIX == 1"\r
+#endif\r
+\r
+\r
+/** @brief Get the current task ID.\r
+\r
+ This task ID must be unique for all tasks using the file system.\r
+\r
+ @return The task ID. Must not be 0.\r
+*/\r
+uint32_t RedOsTaskId(void)\r
+{\r
+ /* Simply casting the xTaskGetCurrentTaskHandle() return value results in\r
+ warnings from some compilers, so use variables.\r
+ */\r
+ TaskHandle_t xTask = xTaskGetCurrentTaskHandle();\r
+ uintptr_t taskptr = CAST_TASK_PTR_TO_UINTPTR(xTask);\r
+ uint32_t ulTaskPtr = (uint32_t)taskptr;\r
+\r
+ /* Assert no information was lost casting from uintptr_t to uint32_t.\r
+ */\r
+ REDASSERT(ulTaskPtr == taskptr);\r
+\r
+ /* NULL is a valid task handle in FreeRTOS, so add one to all task IDs.\r
+ */\r
+ REDASSERT((ulTaskPtr + 1U) != 0U);\r
+ return ulTaskPtr + 1U;\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements timestamp functions.\r
+\r
+ The functionality implemented herein is not needed for the file system\r
+ driver, only to provide accurate results with performance tests.\r
+*/\r
+#include <FreeRTOS.h>\r
+#include <task.h>\r
+\r
+#include <redfs.h>\r
+\r
+\r
+/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If\r
+ 1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a\r
+ little inaccurate.\r
+*/\r
+#define MICROSECS_PER_TICK (1000000U / configTICK_RATE_HZ)\r
+\r
+\r
+/** @brief Initialize the timestamp service.\r
+\r
+ The behavior of invoking this function when timestamps are already\r
+ initialized is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_ENOSYS The timestamp service has not been implemented.\r
+*/\r
+REDSTATUS RedOsTimestampInit(void)\r
+{\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Uninitialize the timestamp service.\r
+\r
+ The behavior of invoking this function when timestamps are not initialized\r
+ is undefined.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+*/\r
+REDSTATUS RedOsTimestampUninit(void)\r
+{\r
+ return 0;\r
+}\r
+\r
+\r
+/** @brief Retrieve a timestamp.\r
+\r
+ The behavior of invoking this function when timestamps are not initialized\r
+ is undefined\r
+\r
+ @return A timestamp which can later be passed to RedOsTimePassed() to\r
+ determine the amount of time which passed between the two calls.\r
+*/\r
+REDTIMESTAMP RedOsTimestamp(void)\r
+{\r
+ return xTaskGetTickCount();\r
+}\r
+\r
+\r
+/** @brief Determine how much time has passed since a timestamp was retrieved.\r
+\r
+ The behavior of invoking this function when timestamps are not initialized\r
+ is undefined.\r
+\r
+ @param tsSince A timestamp acquired earlier via RedOsTimestamp().\r
+\r
+ @return The number of microseconds which have passed since @p tsSince.\r
+*/\r
+uint64_t RedOsTimePassed(\r
+ REDTIMESTAMP tsSince)\r
+{\r
+ /* This works even if the tick count has wrapped around, provided it has\r
+ only wrapped around once.\r
+ */\r
+ uint32_t ulTicksPassed = (uint32_t)xTaskGetTickCount() - tsSince;\r
+ uint64_t ullMicrosecs = (uint64_t)ulTicksPassed * MICROSECS_PER_TICK;\r
+\r
+ return ullMicrosecs;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements path utilities for the POSIX-like API layer.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_API_POSIX == 1\r
+\r
+#include <redcoreapi.h>\r
+#include <redvolume.h>\r
+#include <redposix.h>\r
+#include "redpath.h"\r
+\r
+\r
+static bool IsRootDir(const char *pszLocalPath);\r
+static bool PathHasMoreNames(const char *pszPathIdx);\r
+\r
+\r
+/** @brief Split a path into its component parts: a volume and a volume-local\r
+ path.\r
+\r
+ @param pszPath The path to split.\r
+ @param pbVolNum On successful return, if non-NULL, populated with\r
+ the volume number extracted from the path.\r
+ @param ppszLocalPath On successful return, populated with the\r
+ volume-local path: the path stripped of any volume\r
+ path prefixing. If this parameter is NULL, that\r
+ indicates there should be no local path, and any\r
+ characters beyond the prefix (other than path\r
+ separators) are treated as an error.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pszPath is `NULL`.\r
+ @retval -RED_ENOENT @p pszPath could not be matched to any volume; or\r
+ @p ppszLocalPath is NULL but @p pszPath includes a local\r
+ path.\r
+*/\r
+REDSTATUS RedPathSplit(\r
+ const char *pszPath,\r
+ uint8_t *pbVolNum,\r
+ const char **ppszLocalPath)\r
+{\r
+ REDSTATUS ret = 0;\r
+\r
+ if(pszPath == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ const char *pszLocalPath = pszPath;\r
+ uint8_t bMatchVol = UINT8_MAX;\r
+ uint32_t ulMatchLen = 0U;\r
+ uint8_t bDefaultVolNum = UINT8_MAX;\r
+ uint8_t bVolNum;\r
+\r
+ for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)\r
+ {\r
+ const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix;\r
+ uint32_t ulPrefixLen = RedStrLen(pszPrefix);\r
+\r
+ if(ulPrefixLen == 0U)\r
+ {\r
+ /* A volume with a path prefix of an empty string is the\r
+ default volume, used when the path does not match the\r
+ prefix of any other volume.\r
+\r
+ The default volume should only be found once. During\r
+ initialization, RedCoreInit() ensures that all volume\r
+ prefixes are unique (including empty prefixes).\r
+ */\r
+ REDASSERT(bDefaultVolNum == UINT8_MAX);\r
+ bDefaultVolNum = bVolNum;\r
+ }\r
+ /* For a path to match, it must either be the prefix exactly, or\r
+ be followed by a path separator character. Thus, with a volume\r
+ prefix of "/foo", both "/foo" and "/foo/bar" are matches, but\r
+ "/foobar" is not.\r
+ */\r
+ else if( (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0)\r
+ && ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR)))\r
+ {\r
+ /* The length of this match should never exactly equal the\r
+ length of a previous match: that would require a duplicate\r
+ volume name, which should have been detected during init.\r
+ */\r
+ REDASSERT(ulPrefixLen != ulMatchLen);\r
+\r
+ /* If multiple prefixes match, the longest takes precedence.\r
+ Thus, if there are two prefixes "Flash" and "Flash/Backup",\r
+ the path "Flash/Backup/" will not be erroneously matched\r
+ with the "Flash" volume.\r
+ */\r
+ if(ulPrefixLen > ulMatchLen)\r
+ {\r
+ bMatchVol = bVolNum;\r
+ ulMatchLen = ulPrefixLen;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* No match, keep looking.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(bMatchVol != UINT8_MAX)\r
+ {\r
+ /* The path matched a volume path prefix.\r
+ */\r
+ bVolNum = bMatchVol;\r
+ pszLocalPath = &pszPath[ulMatchLen];\r
+ }\r
+ else if(bDefaultVolNum != UINT8_MAX)\r
+ {\r
+ /* The path didn't match any of the prefixes, but one of the\r
+ volumes has a path prefix of "", so an unprefixed path is\r
+ assigned to that volume.\r
+ */\r
+ bVolNum = bDefaultVolNum;\r
+ REDASSERT(pszLocalPath == pszPath);\r
+ }\r
+ else\r
+ {\r
+ /* The path cannot be assigned a volume.\r
+ */\r
+ ret = -RED_ENOENT;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(pbVolNum != NULL)\r
+ {\r
+ *pbVolNum = bVolNum;\r
+ }\r
+\r
+ if(ppszLocalPath != NULL)\r
+ {\r
+ *ppszLocalPath = pszLocalPath;\r
+ }\r
+ else\r
+ {\r
+ /* If no local path is expected, then the string should either\r
+ terminate after the path prefix or the local path should name\r
+ the root directory. Allowing path separators here means that\r
+ red_mount("/data/") is OK with a path prefix of "/data".\r
+ */\r
+ if(pszLocalPath[0U] != '\0')\r
+ {\r
+ if(!IsRootDir(pszLocalPath))\r
+ {\r
+ ret = -RED_ENOENT;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Lookup the inode named by the given path.\r
+\r
+ @param pszLocalPath The path to lookup; this is a local path, without any\r
+ volume prefix.\r
+ @param pulInode On successful return, populated with the number of the\r
+ inode named by @p pszLocalPath.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulInode is\r
+ `NULL`.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT @p pszLocalPath is an empty string; or\r
+ @p pszLocalPath does not name an existing file\r
+ or directory.\r
+ @retval -RED_ENOTDIR A component of the path other than the last is\r
+ not a directory.\r
+ @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is\r
+ longer than #REDCONF_NAME_MAX.\r
+*/\r
+REDSTATUS RedPathLookup(\r
+ const char *pszLocalPath,\r
+ uint32_t *pulInode)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((pszLocalPath == NULL) || (pulInode == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(pszLocalPath[0U] == '\0')\r
+ {\r
+ ret = -RED_ENOENT;\r
+ }\r
+ else if(IsRootDir(pszLocalPath))\r
+ {\r
+ ret = 0;\r
+ *pulInode = INODE_ROOTDIR;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulPInode;\r
+ const char *pszName;\r
+\r
+ ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreLookup(ulPInode, pszName, pulInode);\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Given a path, return the parent inode number and a pointer to the\r
+ last component in the path (the name).\r
+\r
+ @param pszLocalPath The path to examine; this is a local path, without any\r
+ volume prefix.\r
+ @param pulPInode On successful return, populated with the inode number of\r
+ the parent directory of the last component in the path.\r
+ For example, with the path "a/b/c", populated with the\r
+ inode number of "b".\r
+ @param ppszName On successful return, populated with a pointer to the\r
+ last component in the path. For example, with the path\r
+ "a/b/c", populated with a pointer to "c".\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulPInode is\r
+ `NULL`; or @p ppszName is `NULL`; or the path\r
+ names the root directory.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENOENT @p pszLocalPath is an empty string; or a\r
+ component of the path other than the last does\r
+ not exist.\r
+ @retval -RED_ENOTDIR A component of the path other than the last is\r
+ not a directory.\r
+ @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is\r
+ longer than #REDCONF_NAME_MAX.\r
+*/\r
+REDSTATUS RedPathToName(\r
+ const char *pszLocalPath,\r
+ uint32_t *pulPInode,\r
+ const char **ppszName)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((pszLocalPath == NULL) || (pulPInode == NULL) || (ppszName == NULL))\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(IsRootDir(pszLocalPath))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(pszLocalPath[0U] == '\0')\r
+ {\r
+ ret = -RED_ENOENT;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulInode = INODE_ROOTDIR;\r
+ uint32_t ulPInode = INODE_INVALID;\r
+ uint32_t ulPathIdx = 0U;\r
+ uint32_t ulLastNameIdx = 0U;\r
+\r
+ ret = 0;\r
+\r
+ do\r
+ {\r
+ uint32_t ulNameLen;\r
+\r
+ /* Skip over path separators, to get pszLocalPath[ulPathIdx]\r
+ pointing at the next name.\r
+ */\r
+ while(pszLocalPath[ulPathIdx] == REDCONF_PATH_SEPARATOR)\r
+ {\r
+ ulPathIdx++;\r
+ }\r
+\r
+ if(pszLocalPath[ulPathIdx] == '\0')\r
+ {\r
+ break;\r
+ }\r
+\r
+ /* Point ulLastNameIdx at the first character of the name; after\r
+ we exit the loop, it will point at the first character of the\r
+ last name in the path.\r
+ */\r
+ ulLastNameIdx = ulPathIdx;\r
+\r
+ /* Point ulPInode at the parent inode: either the root inode\r
+ (first pass) or the inode of the previous name. After we exit\r
+ the loop, this will point at the parent inode of the last name.\r
+ */\r
+ ulPInode = ulInode;\r
+\r
+ ulNameLen = RedNameLen(&pszLocalPath[ulPathIdx]);\r
+\r
+ /* Lookup the inode of the name, unless we are at the last name in\r
+ the path: we don't care whether the last name exists or not.\r
+ */\r
+ if(PathHasMoreNames(&pszLocalPath[ulPathIdx + ulNameLen]))\r
+ {\r
+ ret = RedCoreLookup(ulPInode, &pszLocalPath[ulPathIdx], &ulInode);\r
+ }\r
+\r
+ /* Move on to the next path element.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ulPathIdx += ulNameLen;\r
+ }\r
+ }\r
+ while(ret == 0);\r
+\r
+ if(ret == 0)\r
+ {\r
+ *pulPInode = ulPInode;\r
+ *ppszName = &pszLocalPath[ulLastNameIdx];\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Determine whether a path names the root directory.\r
+\r
+ @param pszLocalPath The path to examine; this is a local path, without any\r
+ volume prefix.\r
+\r
+ @return Returns whether @p pszLocalPath names the root directory.\r
+\r
+ @retval true @p pszLocalPath names the root directory.\r
+ @retval false @p pszLocalPath does not name the root directory.\r
+*/\r
+static bool IsRootDir(\r
+ const char *pszLocalPath)\r
+{\r
+ bool fRet;\r
+\r
+ if(pszLocalPath == NULL)\r
+ {\r
+ REDERROR();\r
+ fRet = false;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx = 0U;\r
+\r
+ /* A string containing nothing but path separators (usually only one)\r
+ names the root directory. An empty string does *not* name the root\r
+ directory, since in POSIX empty strings typically elicit -RED_ENOENT\r
+ errors.\r
+ */\r
+ while(pszLocalPath[ulIdx] == REDCONF_PATH_SEPARATOR)\r
+ {\r
+ ulIdx++;\r
+ }\r
+\r
+ fRet = (ulIdx > 0U) && (pszLocalPath[ulIdx] == '\0');\r
+ }\r
+\r
+ return fRet;\r
+}\r
+\r
+\r
+/** @brief Determine whether there are more names in a path.\r
+\r
+ Example | Result\r
+ ------- | ------\r
+ "" false\r
+ "\" false\r
+ "\\" false\r
+ "a" true\r
+ "\a" true\r
+ "\\a" true\r
+\r
+ @param pszPathIdx The path to examine, incremented to the point of\r
+ interest.\r
+\r
+ @return Returns whether there are more names in @p pszPathIdx.\r
+\r
+ @retval true @p pszPathIdx has more names.\r
+ @retval false @p pszPathIdx has no more names.\r
+*/\r
+static bool PathHasMoreNames(\r
+ const char *pszPathIdx)\r
+{\r
+ bool fRet;\r
+\r
+ if(pszPathIdx == NULL)\r
+ {\r
+ REDERROR();\r
+ fRet = false;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulIdx = 0U;\r
+\r
+ while(pszPathIdx[ulIdx] == REDCONF_PATH_SEPARATOR)\r
+ {\r
+ ulIdx++;\r
+ }\r
+\r
+ fRet = pszPathIdx[ulIdx] != '\0';\r
+ }\r
+\r
+ return fRet;\r
+}\r
+\r
+#endif /* REDCONF_API_POSIX */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implementation of the the Reliance Edge POSIX-like API.\r
+*/\r
+\r
+#include <redfs.h>\r
+\r
+#if REDCONF_API_POSIX == 1\r
+\r
+/** @defgroup red_group_posix The POSIX-like File System Interface\r
+ @{\r
+*/\r
+\r
+#include <redvolume.h>\r
+#include <redcoreapi.h>\r
+#include <redposix.h>\r
+#include "redpath.h"\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+ File Descriptors\r
+-------------------------------------------------------------------*/\r
+\r
+#define FD_GEN_BITS 11U /* File descriptor bits for mount generation. */\r
+#define FD_VOL_BITS 8U /* File descriptor bits for volume number. */\r
+#define FD_IDX_BITS 12U /* File descriptor bits for handle index. */\r
+\r
+/* 31 bits available: file descriptors are int32_t, but the sign bit must\r
+ always be zero.\r
+*/\r
+#if (FD_GEN_BITS + FD_VOL_BITS + FD_IDX_BITS) > 31U\r
+ #error "Internal error: too many file descriptor bits!"\r
+#endif\r
+\r
+/* Maximum values for file descriptor components.\r
+*/\r
+#define FD_GEN_MAX ((1UL << FD_GEN_BITS) - 1U)\r
+#define FD_VOL_MAX ((1UL << FD_VOL_BITS) - 1U)\r
+#define FD_IDX_MAX ((1UL << FD_IDX_BITS) - 1U)\r
+\r
+#if REDCONF_VOLUME_COUNT > FD_VOL_MAX\r
+ #error "Error: Too many file system volumes!"\r
+#endif\r
+#if REDCONF_HANDLE_COUNT > (FD_IDX_MAX + 1U)\r
+ #error "Error: Too many file system handles!"\r
+#endif\r
+\r
+/* File descriptors must never be negative; and must never be zero, one, or\r
+ two, to avoid confusion with STDIN, STDOUT, and STDERR.\r
+*/\r
+#define FD_MIN (3)\r
+\r
+/*-------------------------------------------------------------------\r
+ Handles\r
+-------------------------------------------------------------------*/\r
+\r
+/* Mask of all RED_O_* values.\r
+*/\r
+#define RED_O_MASK (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR|RED_O_APPEND|RED_O_CREAT|RED_O_EXCL|RED_O_TRUNC)\r
+\r
+#define HFLAG_DIRECTORY 0x01U /* Handle is for a directory. */\r
+#define HFLAG_READABLE 0x02U /* Handle is readable. */\r
+#define HFLAG_WRITEABLE 0x04U /* Handle is writeable. */\r
+#define HFLAG_APPENDING 0x08U /* Handle was opened in append mode. */\r
+\r
+/* @brief Handle structure, used to implement file descriptors and directory\r
+ streams.\r
+*/\r
+typedef struct sREDHANDLE\r
+{\r
+ uint32_t ulInode; /**< Inode number; 0 if handle is available. */\r
+ uint8_t bVolNum; /**< Volume containing the inode. */\r
+ uint8_t bFlags; /**< Handle flags (type and mode). */\r
+ uint64_t ullOffset; /**< File or directory offset. */\r
+ #if REDCONF_API_POSIX_READDIR == 1\r
+ REDDIRENT dirent; /**< Dirent structure returned by red_readdir(). */\r
+ #endif\r
+} REDHANDLE;\r
+\r
+/*-------------------------------------------------------------------\r
+ Tasks\r
+-------------------------------------------------------------------*/\r
+\r
+#if REDCONF_TASK_COUNT > 1U\r
+/* @brief Per-task information.\r
+*/\r
+typedef struct\r
+{\r
+ uint32_t ulTaskId; /**< ID of the task which owns this slot; 0 if free. */\r
+ REDSTATUS iErrno; /**< Last error value. */\r
+} TASKSLOT;\r
+#endif\r
+\r
+/*-------------------------------------------------------------------\r
+ Local Prototypes\r
+-------------------------------------------------------------------*/\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+static REDSTATUS UnlinkSub(const char *pszPath, FTYPE type);\r
+#endif\r
+static REDSTATUS FildesOpen(const char *pszPath, uint32_t ulOpenMode, FTYPE type, int32_t *piFildes);\r
+static REDSTATUS FildesClose(int32_t iFildes);\r
+static REDSTATUS FildesToHandle(int32_t iFildes, FTYPE expectedType, REDHANDLE **ppHandle);\r
+static int32_t FildesPack(uint16_t uHandleIdx, uint8_t bVolNum);\r
+static void FildesUnpack(int32_t iFildes, uint16_t *puHandleIdx, uint8_t *pbVolNum, uint16_t *puGeneration);\r
+#if REDCONF_API_POSIX_READDIR == 1\r
+static bool DirStreamIsValid(const REDDIR *pDirStream);\r
+#endif\r
+static REDSTATUS PosixEnter(void);\r
+static void PosixLeave(void);\r
+static REDSTATUS ModeTypeCheck(uint16_t uMode, FTYPE expectedType);\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))\r
+static REDSTATUS InodeUnlinkCheck(uint32_t ulInode);\r
+#endif\r
+#if REDCONF_TASK_COUNT > 1U\r
+static REDSTATUS TaskRegister(uint32_t *pulTaskIdx);\r
+#endif\r
+static int32_t PosixReturn(REDSTATUS iError);\r
+\r
+/*-------------------------------------------------------------------\r
+ Globals\r
+-------------------------------------------------------------------*/\r
+\r
+static bool gfPosixInited; /* Whether driver is initialized. */\r
+static REDHANDLE gaHandle[REDCONF_HANDLE_COUNT]; /* Array of all handles. */\r
+#if REDCONF_TASK_COUNT > 1U\r
+static TASKSLOT gaTask[REDCONF_TASK_COUNT]; /* Array of task slots. */\r
+#endif\r
+\r
+/* Array of volume mount "generations". These are incremented for a volume\r
+ each time that volume is mounted. The generation number (along with the\r
+ volume number) is incorporated into the file descriptors; a stale file\r
+ descriptor from a previous mount can be detected since it will include a\r
+ stale generation number.\r
+*/\r
+static uint16_t gauGeneration[REDCONF_VOLUME_COUNT];\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+ Public API\r
+-------------------------------------------------------------------*/\r
+\r
+/** @brief Initialize the Reliance Edge file system driver.\r
+\r
+ Prepares the Reliance Edge file system driver to be used. Must be the first\r
+ Reliance Edge function to be invoked: no volumes can be mounted or formatted\r
+ until the driver has been initialized.\r
+\r
+ If this function is called when the Reliance Edge driver is already\r
+ initialized, it does nothing and returns success.\r
+\r
+ This function is not thread safe: attempting to initialize from multiple\r
+ threads could leave things in a bad state.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: The volume path prefix configuration is invalid.\r
+*/\r
+int32_t red_init(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gfPosixInited)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ ret = RedCoreInit();\r
+ if(ret == 0)\r
+ {\r
+ RedMemSet(gaHandle, 0U, sizeof(gaHandle));\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedMemSet(gaTask, 0U, sizeof(gaTask));\r
+ #endif\r
+\r
+ gfPosixInited = true;\r
+ }\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Uninitialize the Reliance Edge file system driver.\r
+\r
+ Tears down the Reliance Edge file system driver. Cannot be used until all\r
+ Reliance Edge volumes are unmounted. A subsequent call to red_init() will\r
+ initialize the driver again.\r
+\r
+ If this function is called when the Reliance Edge driver is already\r
+ uninitialized, it does nothing and returns success.\r
+\r
+ This function is not thread safe: attempting to uninitialize from multiple\r
+ threads could leave things in a bad state.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: At least one volume is still mounted.\r
+*/\r
+int32_t red_uninit(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gfPosixInited)\r
+ {\r
+ ret = PosixEnter();\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)\r
+ {\r
+ if(gaRedVolume[bVolNum].fMounted)\r
+ {\r
+ ret = -RED_EBUSY;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* All volumes are unmounted. Mark the driver as\r
+ uninitialized before releasing the FS mutex, to avoid any\r
+ race condition where a volume could be mounted and then the\r
+ driver uninitialized with a mounted volume.\r
+ */\r
+ gfPosixInited = false;\r
+ }\r
+\r
+ /* The FS mutex must be released before we uninitialize the core,\r
+ since the FS mutex needs to be in the released state when it\r
+ gets uninitialized.\r
+\r
+ Don't use PosixLeave(), since it asserts gfPosixInited is true.\r
+ */\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexRelease();\r
+ #endif\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreUninit();\r
+\r
+ /* Not good if the above fails, since things might be partly, but\r
+ not entirely, torn down, and there might not be a way back to\r
+ a valid driver state.\r
+ */\r
+ REDASSERT(ret == 0);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ret = 0;\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Mount a file system volume.\r
+\r
+ Prepares the file system volume to be accessed. Mount will fail if the\r
+ volume has never been formatted, or if the on-disk format is inconsistent\r
+ with the compile-time configuration.\r
+\r
+ An error is returned if the volume is already mounted.\r
+\r
+ @param pszVolume A path prefix identifying the volume to mount.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: Volume is already mounted.\r
+ - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized.\r
+ - #RED_EIO: Volume not formatted, improperly formatted, or corrupt.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_mount(\r
+ const char *pszVolume)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ /* The core will return success if the volume is already mounted, so\r
+ check for that condition here to propagate the error.\r
+ */\r
+ if((ret == 0) && gaRedVolume[bVolNum].fMounted)\r
+ {\r
+ ret = -RED_EBUSY;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolMount();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Increment the mount generation, invalidating file descriptors\r
+ from previous mounts. Note that while the generation numbers\r
+ are stored in 16-bit values, we have less than 16-bits to store\r
+ generations in the file descriptors, so we must wrap-around\r
+ manually.\r
+ */\r
+ gauGeneration[bVolNum]++;\r
+ if(gauGeneration[bVolNum] > FD_GEN_MAX)\r
+ {\r
+ /* Wrap-around to one, rather than zero. The generation is\r
+ stored in the top bits of the file descriptor, and doing\r
+ this means that low numbers are never valid file\r
+ descriptors. This implements the requirement that 0, 1,\r
+ and 2 are never valid file descriptors, thereby avoiding\r
+ confusion with STDIN, STDOUT, and STDERR.\r
+ */\r
+ gauGeneration[bVolNum] = 1U;\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Unmount a file system volume.\r
+\r
+ This function discards the in-memory state for the file system and marks it\r
+ as unmounted. Subsequent attempts to access the volume will fail until the\r
+ volume is mounted again.\r
+\r
+ If unmount automatic transaction points are enabled, this function will\r
+ commit a transaction point prior to unmounting. If unmount automatic\r
+ transaction points are disabled, this function will unmount without\r
+ transacting, effectively discarding the working state.\r
+\r
+ Before unmounting, this function will wait for any active file system\r
+ thread to complete by acquiring the FS mutex. The volume will be marked as\r
+ unmounted before the FS mutex is released, so subsequent FS threads will\r
+ possibly block and then see an error when attempting to access a volume\r
+ which is unmounting or unmounted. If the volume has open handles, the\r
+ unmount will fail.\r
+\r
+ An error is returned if the volume is already unmounted.\r
+\r
+ @param pszVolume A path prefix identifying the volume to unmount.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: There are still open handles for this file system volume.\r
+ - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized; or\r
+ the volume is already unmounted.\r
+ - #RED_EIO: I/O error during unmount automatic transaction point.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_umount(\r
+ const char *pszVolume)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ /* The core will return success if the volume is already unmounted, so\r
+ check for that condition here to propagate the error.\r
+ */\r
+ if((ret == 0) && !gaRedVolume[bVolNum].fMounted)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint16_t uHandleIdx;\r
+\r
+ /* Do not unmount the volume if it still has open handles.\r
+ */\r
+ for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++)\r
+ {\r
+ const REDHANDLE *pHandle = &gaHandle[uHandleIdx];\r
+\r
+ if((pHandle->ulInode != INODE_INVALID) && (pHandle->bVolNum == bVolNum))\r
+ {\r
+ ret = -RED_EBUSY;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolUnmount();\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)\r
+/** @brief Format a file system volume.\r
+\r
+ Uses the statically defined volume configuration. After calling this\r
+ function, the volume needs to be mounted -- see red_mount().\r
+\r
+ An error is returned if the volume is mounted.\r
+\r
+ @param pszVolume A path prefix identifying the volume to format.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: Volume is mounted.\r
+ - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized.\r
+ - #RED_EIO: I/O error formatting the volume.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_format(\r
+ const char *pszVolume)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolFormat();\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Commit a transaction point.\r
+\r
+ Reliance Edge is a transactional file system. All modifications, of both\r
+ metadata and filedata, are initially working state. A transaction point\r
+ is a process whereby the working state atomically becomes the committed\r
+ state, replacing the previous committed state. Whenever Reliance Edge is\r
+ mounted, including after power loss, the state of the file system after\r
+ mount is the most recent committed state. Nothing from the committed\r
+ state is ever missing, and nothing from the working state is ever included.\r
+\r
+ @param pszVolume A path prefix identifying the volume to transact.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`.\r
+ - #RED_EIO: I/O error during the transaction point.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_transact(\r
+ const char *pszVolume)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolTransact();\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Update the transaction mask.\r
+\r
+ The following events are available:\r
+\r
+ - #RED_TRANSACT_UMOUNT\r
+ - #RED_TRANSACT_CREAT\r
+ - #RED_TRANSACT_UNLINK\r
+ - #RED_TRANSACT_MKDIR\r
+ - #RED_TRANSACT_RENAME\r
+ - #RED_TRANSACT_LINK\r
+ - #RED_TRANSACT_CLOSE\r
+ - #RED_TRANSACT_WRITE\r
+ - #RED_TRANSACT_FSYNC\r
+ - #RED_TRANSACT_TRUNCATE\r
+ - #RED_TRANSACT_VOLFULL\r
+\r
+ The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all\r
+ automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask\r
+ of all transaction flags, excluding those representing excluded\r
+ functionality.\r
+\r
+ Attempting to enable events for excluded functionality will result in an\r
+ error.\r
+\r
+ @param pszVolume The path prefix of the volume whose transaction mask is\r
+ being changed.\r
+ @param ulEventMask A bitwise-OR'd mask of automatic transaction events to\r
+ be set as the current transaction mode.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or\r
+ @p ulEventMask contains invalid bits.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_settransmask(\r
+ const char *pszVolume,\r
+ uint32_t ulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreTransMaskSet(ulEventMask);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Read the transaction mask.\r
+\r
+ If the volume is read-only, the returned event mask is always zero.\r
+\r
+ @param pszVolume The path prefix of the volume whose transaction mask is\r
+ being retrieved.\r
+ @param pulEventMask Populated with a bitwise-OR'd mask of automatic\r
+ transaction events which represent the current\r
+ transaction mode for the volume.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or\r
+ @p pulEventMask is `NULL`.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_gettransmask(\r
+ const char *pszVolume,\r
+ uint32_t *pulEventMask)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreTransMaskGet(pulEventMask);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Query file system status information.\r
+\r
+ @p pszVolume should name a valid volume prefix or a valid root directory;\r
+ this differs from POSIX statvfs, where any existing file or directory is a\r
+ valid path.\r
+\r
+ @param pszVolume The path prefix of the volume to query.\r
+ @param pStatvfs The buffer to populate with volume information.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or\r
+ @p pStatvfs is `NULL`.\r
+ - #RED_ENOENT: @p pszVolume is not a valid volume path prefix.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_statvfs(\r
+ const char *pszVolume,\r
+ REDSTATFS *pStatvfs)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszVolume, &bVolNum, NULL);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolStat(pStatvfs);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Open a file or directory.\r
+\r
+ Exactly one file access mode must be specified:\r
+\r
+ - #RED_O_RDONLY: Open for reading only.\r
+ - #RED_O_WRONLY: Open for writing only.\r
+ - #RED_O_RDWR: Open for reading and writing.\r
+\r
+ Directories can only be opened with `RED_O_RDONLY`.\r
+\r
+ The following flags may also be used:\r
+\r
+ - #RED_O_APPEND: Set the file offset to the end-of-file prior to each\r
+ write.\r
+ - #RED_O_CREAT: Create the named file if it does not exist.\r
+ - #RED_O_EXCL: In combination with `RED_O_CREAT`, return an error if the\r
+ path already exists.\r
+ - #RED_O_TRUNC: Truncate the opened file to size zero. Only supported when\r
+ #REDCONF_API_POSIX_FTRUNCATE is true.\r
+\r
+ #RED_O_CREAT, #RED_O_EXCL, and #RED_O_TRUNC are invalid with #RED_O_RDONLY.\r
+ #RED_O_EXCL is invalid without #RED_O_CREAT.\r
+\r
+ If the volume is read-only, #RED_O_RDONLY is the only valid open flag; use\r
+ of any other flag will result in an error.\r
+\r
+ If #RED_O_TRUNC frees data which is in the committed state, it will not\r
+ return to free space until after a transaction point.\r
+\r
+ The returned file descriptor must later be closed with red_close().\r
+\r
+ Unlike POSIX open, there is no optional third argument for the permissions\r
+ (which Reliance Edge does not use) and other open flags (like `O_SYNC`) are\r
+ not supported.\r
+\r
+ @param pszPath The path to the file or directory.\r
+ @param ulOpenMode The open flags (mask of `RED_O_` values).\r
+\r
+ @return On success, a nonnegative file descriptor is returned. On error,\r
+ -1 is returned and #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EEXIST: Using #RED_O_CREAT and #RED_O_EXCL, and the indicated path\r
+ already exists.\r
+ - #RED_EINVAL: @p ulOpenMode is invalid; or @p pszPath is `NULL`; or the\r
+ volume containing the path is not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EISDIR: The path names a directory and @p ulOpenMode includes\r
+ #RED_O_WRONLY or #RED_O_RDWR.\r
+ - #RED_EMFILE: There are no available file descriptors.\r
+ - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than\r
+ #REDCONF_NAME_MAX.\r
+ - #RED_ENFILE: Attempting to create a file but the file system has used all\r
+ available inode slots.\r
+ - #RED_ENOENT: #RED_O_CREAT is not set and the named file does not exist; or\r
+ #RED_O_CREAT is set and the parent directory does not exist; or the\r
+ volume does not exist; or the @p pszPath argument, after removing the\r
+ volume prefix, points to an empty string.\r
+ - #RED_ENOSPC: The file does not exist and #RED_O_CREAT was specified, but\r
+ there is insufficient free space to expand the directory or to create the\r
+ new file.\r
+ - #RED_ENOTDIR: A component of the prefix in @p pszPath does not name a\r
+ directory.\r
+ - #RED_EROFS: The path resides on a read-only file system and a write\r
+ operation was requested.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_open(\r
+ const char *pszPath,\r
+ uint32_t ulOpenMode)\r
+{\r
+ int32_t iFildes = -1; /* Init'd to quiet warnings. */\r
+ REDSTATUS ret;\r
+\r
+ #if REDCONF_READ_ONLY == 1\r
+ if(ulOpenMode != RED_O_RDONLY)\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ #else\r
+ if( (ulOpenMode != (ulOpenMode & RED_O_MASK))\r
+ || ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR)) == 0U)\r
+ || (((ulOpenMode & RED_O_RDONLY) != 0U) && ((ulOpenMode & (RED_O_WRONLY|RED_O_RDWR)) != 0U))\r
+ || (((ulOpenMode & RED_O_WRONLY) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_RDWR)) != 0U))\r
+ || (((ulOpenMode & RED_O_RDWR) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY)) != 0U))\r
+ || (((ulOpenMode & (RED_O_TRUNC|RED_O_CREAT|RED_O_EXCL)) != 0U) && ((ulOpenMode & RED_O_RDONLY) != 0U))\r
+ || (((ulOpenMode & RED_O_EXCL) != 0U) && ((ulOpenMode & RED_O_CREAT) == 0U)))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #if REDCONF_API_POSIX_FTRUNCATE == 0\r
+ else if((ulOpenMode & RED_O_TRUNC) != 0U)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #endif\r
+ #endif\r
+ else\r
+ {\r
+ ret = PosixEnter();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = FildesOpen(pszPath, ulOpenMode, FTYPE_EITHER, &iFildes);\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ iFildes = PosixReturn(ret);\r
+ }\r
+\r
+ return iFildes;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1)\r
+/** @brief Delete a file or directory.\r
+\r
+ The given name is deleted and the link count of the corresponding inode is\r
+ decremented. If the link count falls to zero (no remaining hard links),\r
+ the inode will be deleted.\r
+\r
+ Unlike POSIX unlink, deleting a file or directory with open handles (file\r
+ descriptors or directory streams) will fail with an #RED_EBUSY error. This\r
+ only applies when deleting an inode with a link count of one; if a file has\r
+ multiple names (hard links), all but the last name may be deleted even if\r
+ the file is open.\r
+\r
+ If the path names a directory which is not empty, the unlink will fail.\r
+\r
+ If the deletion frees data in the committed state, it will not return to\r
+ free space until after a transaction point.\r
+\r
+ Unlike POSIX unlink, this function can fail when the disk is full. To fix\r
+ this, transact and try again: Reliance Edge guarantees that it is possible\r
+ to delete at least one file or directory after a transaction point. If disk\r
+ full automatic transactions are enabled, this will happen automatically.\r
+\r
+ @param pszPath The path of the file or directory to delete.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: @p pszPath points to an inode with open handles and a link\r
+ count of one.\r
+ - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is\r
+ not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than\r
+ #REDCONF_NAME_MAX.\r
+ - #RED_ENOENT: The path does not name an existing file; or the @p pszPath\r
+ argument, after removing the volume prefix, points to an empty string.\r
+ - #RED_ENOTDIR: A component of the path prefix is not a directory.\r
+ - #RED_ENOTEMPTY: The path names a directory which is not empty.\r
+ - #RED_ENOSPC: The file system does not have enough space to modify the\r
+ parent directory to perform the deletion.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_unlink(\r
+ const char *pszPath)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ ret = UnlinkSub(pszPath, FTYPE_EITHER);\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1)\r
+/** @brief Create a new directory.\r
+\r
+ Unlike POSIX mkdir, this function has no second argument for the\r
+ permissions (which Reliance Edge does not use).\r
+\r
+ @param pszPath The name and location of the directory to create.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EEXIST: @p pszPath points to an existing file or directory.\r
+ - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is\r
+ not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than\r
+ #REDCONF_NAME_MAX.\r
+ - #RED_ENOENT: A component of the path prefix does not name an existing\r
+ directory; or the @p pszPath argument, after removing the volume prefix,\r
+ points to an empty string.\r
+ - #RED_ENOSPC: The file system does not have enough space for the new\r
+ directory or to extend the parent directory of the new directory.\r
+ - #RED_ENOTDIR: A component of the path prefix is not a directory.\r
+ - #RED_EROFS: The parent directory resides on a read-only file system.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_mkdir(\r
+ const char *pszPath)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ const char *pszLocalPath;\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszName;\r
+ uint32_t ulPInode;\r
+\r
+ ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulInode;\r
+\r
+ ret = RedCoreCreate(ulPInode, pszName, true, &ulInode);\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1)\r
+/** @brief Delete a directory.\r
+\r
+ The given directory name is deleted and the corresponding directory inode\r
+ will be deleted.\r
+\r
+ Unlike POSIX rmdir, deleting a directory with open handles (file\r
+ descriptors or directory streams) will fail with an #RED_EBUSY error.\r
+\r
+ If the path names a directory which is not empty, the deletion will fail.\r
+ If the path names the root directory of a file system volume, the deletion\r
+ will fail.\r
+\r
+ If the path names a regular file, the deletion will fail. This provides\r
+ type checking and may be useful in cases where an application knows the\r
+ path to be deleted should name a directory.\r
+\r
+ If the deletion frees data in the committed state, it will not return to\r
+ free space until after a transaction point.\r
+\r
+ Unlike POSIX rmdir, this function can fail when the disk is full. To fix\r
+ this, transact and try again: Reliance Edge guarantees that it is possible\r
+ to delete at least one file or directory after a transaction point. If disk\r
+ full automatic transactions are enabled, this will happen automatically.\r
+\r
+ @param pszPath The path of the directory to delete.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: @p pszPath points to a directory with open handles.\r
+ - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is\r
+ not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than\r
+ #REDCONF_NAME_MAX.\r
+ - #RED_ENOENT: The path does not name an existing directory; or the\r
+ @p pszPath argument, after removing the volume prefix, points to an empty\r
+ string.\r
+ - #RED_ENOTDIR: A component of the path is not a directory.\r
+ - #RED_ENOTEMPTY: The path names a directory which is not empty.\r
+ - #RED_ENOSPC: The file system does not have enough space to modify the\r
+ parent directory to perform the deletion.\r
+ - #RED_EROFS: The directory to be removed resides on a read-only file\r
+ system.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_rmdir(\r
+ const char *pszPath)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ ret = UnlinkSub(pszPath, FTYPE_DIR);\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)\r
+/** @brief Rename a file or directory.\r
+\r
+ Both paths must reside on the same file system volume. Attempting to use\r
+ this API to move a file to a different volume will result in an error.\r
+\r
+ If @p pszNewPath names an existing file or directory, the behavior depends\r
+ on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the\r
+ destination name exists, this function always fails and sets #red_errno to\r
+ #RED_EEXIST. This behavior is contrary to POSIX.\r
+\r
+ If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one\r
+ atomic operation, @p pszNewPath is unlinked and @p pszOldPath is renamed to\r
+ @p pszNewPath. Both @p pszNewPath and @p pszOldPath must be of the same\r
+ type (both files or both directories). As with red_unlink(), if\r
+ @p pszNewPath is a directory, it must be empty. The major exception to this\r
+ behavior is that if both @p pszOldPath and @p pszNewPath are links to the\r
+ same inode, then the rename does nothing and both names continue to exist.\r
+ Unlike POSIX rename, if @p pszNewPath points to an inode with a link count\r
+ of one and open handles (file descriptors or directory streams), the\r
+ rename will fail with #RED_EBUSY.\r
+\r
+ If the rename deletes the old destination, it may free data in the\r
+ committed state, which will not return to free space until after a\r
+ transaction point. Similarly, if the deleted inode was part of the\r
+ committed state, the inode slot will not be available until after a\r
+ transaction point.\r
+\r
+ @param pszOldPath The path of the file or directory to rename.\r
+ @param pszNewPath The new name and location after the rename.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBUSY: #REDCONF_RENAME_ATOMIC is true and @p pszNewPath points to an\r
+ inode with open handles and a link count of one.\r
+ - #RED_EEXIST: #REDCONF_RENAME_ATOMIC is false and @p pszNewPath exists.\r
+ - #RED_EINVAL: @p pszOldPath is `NULL`; or @p pszNewPath is `NULL`; or the\r
+ volume containing the path is not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EISDIR: The @p pszNewPath argument names a directory and the\r
+ @p pszOldPath argument names a non-directory.\r
+ - #RED_ENAMETOOLONG: The length of a component of either @p pszOldPath or\r
+ @p pszNewPath is longer than #REDCONF_NAME_MAX.\r
+ - #RED_ENOENT: The link named by @p pszOldPath does not name an existing\r
+ entry; or either @p pszOldPath or @p pszNewPath, after removing the volume\r
+ prefix, point to an empty string.\r
+ - #RED_ENOTDIR: A component of either path prefix is not a directory; or\r
+ @p pszOldPath names a directory and @p pszNewPath names a file.\r
+ - #RED_ENOTEMPTY: The path named by @p pszNewPath is a directory which is\r
+ not empty.\r
+ - #RED_ENOSPC: The file system does not have enough space to extend the\r
+ directory that would contain @p pszNewPath.\r
+ - #RED_EROFS: The directory to be removed resides on a read-only file\r
+ system.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+ - #RED_EXDEV: @p pszOldPath and @p pszNewPath are on different file system\r
+ volumes.\r
+*/\r
+int32_t red_rename(\r
+ const char *pszOldPath,\r
+ const char *pszNewPath)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ const char *pszOldLocalPath;\r
+ uint8_t bOldVolNum;\r
+\r
+ ret = RedPathSplit(pszOldPath, &bOldVolNum, &pszOldLocalPath);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszNewLocalPath;\r
+ uint8_t bNewVolNum;\r
+\r
+ ret = RedPathSplit(pszNewPath, &bNewVolNum, &pszNewLocalPath);\r
+\r
+ if((ret == 0) && (bOldVolNum != bNewVolNum))\r
+ {\r
+ ret = -RED_EXDEV;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bOldVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszOldName;\r
+ uint32_t ulOldPInode;\r
+\r
+ ret = RedPathToName(pszOldLocalPath, &ulOldPInode, &pszOldName);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszNewName;\r
+ uint32_t ulNewPInode;\r
+\r
+ ret = RedPathToName(pszNewLocalPath, &ulNewPInode, &pszNewName);\r
+\r
+ #if REDCONF_RENAME_ATOMIC == 1\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulDestInode;\r
+\r
+ ret = RedCoreLookup(ulNewPInode, pszNewName, &ulDestInode);\r
+ if(ret == 0)\r
+ {\r
+ ret = InodeUnlinkCheck(ulDestInode);\r
+ }\r
+ else if(ret == -RED_ENOENT)\r
+ {\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ /* Unexpected error, nothing to do.\r
+ */\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreRename(ulOldPInode, pszOldName, ulNewPInode, pszNewName);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1)\r
+/** @brief Create a hard link.\r
+\r
+ This creates an additional name (link) for the file named by @p pszPath.\r
+ The new name refers to the same file with the same contents. If a name is\r
+ deleted, but the underlying file has other names, the file continues to\r
+ exist. The link count (accessible via red_fstat()) indicates the number of\r
+ names that a file has. All of a file's names are on equal footing: there\r
+ is nothing special about the original name.\r
+\r
+ If @p pszPath names a directory, the operation will fail.\r
+\r
+ @param pszPath The path indicating the inode for the new link.\r
+ @param pszHardLink The name and location for the new link.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EEXIST: @p pszHardLink resolves to an existing file.\r
+ - #RED_EINVAL: @p pszPath or @p pszHardLink is `NULL`; or the volume\r
+ containing the paths is not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EMLINK: Creating the link would exceed the maximum link count of the\r
+ inode named by @p pszPath.\r
+ - #RED_ENAMETOOLONG: The length of a component of either @p pszPath or\r
+ @p pszHardLink is longer than #REDCONF_NAME_MAX.\r
+ - #RED_ENOENT: A component of either path prefix does not exist; or the file\r
+ named by @p pszPath does not exist; or either @p pszPath or\r
+ @p pszHardLink, after removing the volume prefix, point to an empty\r
+ string.\r
+ - #RED_ENOSPC: There is insufficient free space to expand the directory that\r
+ would contain the link.\r
+ - #RED_ENOTDIR: A component of either path prefix is not a directory.\r
+ - #RED_EPERM: The @p pszPath argument names a directory.\r
+ - #RED_EROFS: The requested link requires writing in a directory on a\r
+ read-only file system.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+ - #RED_EXDEV: @p pszPath and @p pszHardLink are on different file system\r
+ volumes.\r
+*/\r
+int32_t red_link(\r
+ const char *pszPath,\r
+ const char *pszHardLink)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ const char *pszLocalPath;\r
+ uint8_t bVolNum;\r
+\r
+ ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszLinkLocalPath;\r
+ uint8_t bLinkVolNum;\r
+\r
+ ret = RedPathSplit(pszHardLink, &bLinkVolNum, &pszLinkLocalPath);\r
+\r
+ if((ret == 0) && (bVolNum != bLinkVolNum))\r
+ {\r
+ ret = -RED_EXDEV;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulInode;\r
+\r
+ ret = RedPathLookup(pszLocalPath, &ulInode);\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszLinkName;\r
+ uint32_t ulLinkPInode;\r
+\r
+ ret = RedPathToName(pszLinkLocalPath, &ulLinkPInode, &pszLinkName);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreLink(ulLinkPInode, pszLinkName, ulInode);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Close a file descriptor.\r
+\r
+ @param iFildes The file descriptor to close.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: @p iFildes is not a valid file descriptor.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_close(\r
+ int32_t iFildes)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ ret = FildesClose(iFildes);\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+/** @brief Read from an open file.\r
+\r
+ The read takes place at the file offset associated with @p iFildes and\r
+ advances the file offset by the number of bytes actually read.\r
+\r
+ Data which has not yet been written, but which is before the end-of-file\r
+ (sparse data), will read as zeroes. A short read -- where the number of\r
+ bytes read is less than requested -- indicates that the requested read was\r
+ partially or, if zero bytes were read, entirely beyond the end-of-file.\r
+\r
+ @param iFildes The file descriptor from which to read.\r
+ @param pBuffer The buffer to populate with data read. Must be at least\r
+ @p ulLength bytes in size.\r
+ @param ulLength Number of bytes to attempt to read.\r
+\r
+ @return On success, returns a nonnegative value indicating the number of\r
+ bytes actually read. On error, -1 is returned and #red_errno is\r
+ set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open\r
+ for reading.\r
+ - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and\r
+ cannot be returned properly.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EISDIR: The @p iFildes is a file descriptor for a directory.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_read(\r
+ int32_t iFildes,\r
+ void *pBuffer,\r
+ uint32_t ulLength)\r
+{\r
+ uint32_t ulLenRead = 0U;\r
+ REDSTATUS ret;\r
+ int32_t iReturn;\r
+\r
+ if(ulLength > (uint32_t)INT32_MAX)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = PosixEnter();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDHANDLE *pHandle;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle);\r
+\r
+ if((ret == 0) && ((pHandle->bFlags & HFLAG_READABLE) == 0U))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulLenRead = ulLength;\r
+ ret = RedCoreFileRead(pHandle->ulInode, pHandle->ullOffset, &ulLenRead, pBuffer);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDASSERT(ulLenRead <= ulLength);\r
+\r
+ pHandle->ullOffset += ulLenRead;\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ iReturn = (int32_t)ulLenRead;\r
+ }\r
+ else\r
+ {\r
+ iReturn = PosixReturn(ret);\r
+ }\r
+\r
+ return iReturn;\r
+}\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Write to an open file.\r
+\r
+ The write takes place at the file offset associated with @p iFildes and\r
+ advances the file offset by the number of bytes actually written.\r
+ Alternatively, if @p iFildes was opened with #RED_O_APPEND, the file offset\r
+ is set to the end-of-file before the write begins, and likewise advances by\r
+ the number of bytes actually written.\r
+\r
+ A short write -- where the number of bytes written is less than requested\r
+ -- indicates either that the file system ran out of space but was still\r
+ able to write some of the request; or that the request would have caused\r
+ the file to exceed the maximum file size, but some of the data could be\r
+ written prior to the file size limit.\r
+\r
+ If an error is returned (-1), either none of the data was written or a\r
+ critical error occurred (like an I/O error) and the file system volume will\r
+ be read-only.\r
+\r
+ @param iFildes The file descriptor to write to.\r
+ @param pBuffer The buffer containing the data to be written. Must be at\r
+ least @p ulLength bytes in size.\r
+ @param ulLength Number of bytes to attempt to write.\r
+\r
+ @return On success, returns a nonnegative value indicating the number of\r
+ bytes actually written. On error, -1 is returned and #red_errno is\r
+ set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open\r
+ for writing. This includes the case where the file descriptor is for a\r
+ directory.\r
+ - #RED_EFBIG: No data can be written to the current file offset since the\r
+ resulting file size would exceed the maximum file size.\r
+ - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and\r
+ cannot be returned properly.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENOSPC: No data can be written because there is insufficient free\r
+ space.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_write(\r
+ int32_t iFildes,\r
+ const void *pBuffer,\r
+ uint32_t ulLength)\r
+{\r
+ uint32_t ulLenWrote = 0U;\r
+ REDSTATUS ret;\r
+ int32_t iReturn;\r
+\r
+ if(ulLength > (uint32_t)INT32_MAX)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ ret = PosixEnter();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDHANDLE *pHandle;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle);\r
+ if(ret == -RED_EISDIR)\r
+ {\r
+ /* POSIX says that if a file descriptor is not writable, the\r
+ errno should be -RED_EBADF. Directory file descriptors are\r
+ never writable, and unlike for read(), the spec does not\r
+ list -RED_EISDIR as an allowed errno. Therefore -RED_EBADF\r
+ takes precedence.\r
+ */\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if((ret == 0) && ((pHandle->bFlags & HFLAG_APPENDING) != 0U))\r
+ {\r
+ REDSTAT s;\r
+\r
+ ret = RedCoreStat(pHandle->ulInode, &s);\r
+ if(ret == 0)\r
+ {\r
+ pHandle->ullOffset = s.st_size;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ulLenWrote = ulLength;\r
+ ret = RedCoreFileWrite(pHandle->ulInode, pHandle->ullOffset, &ulLenWrote, pBuffer);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDASSERT(ulLenWrote <= ulLength);\r
+\r
+ pHandle->ullOffset += ulLenWrote;\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ iReturn = (int32_t)ulLenWrote;\r
+ }\r
+ else\r
+ {\r
+ iReturn = PosixReturn(ret);\r
+ }\r
+\r
+ return iReturn;\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_READ_ONLY == 0\r
+/** @brief Synchronizes changes to a file.\r
+\r
+ Commits all changes associated with a file or directory (including file\r
+ data, directory contents, and metadata) to permanent storage. This\r
+ function will not return until the operation is complete.\r
+\r
+ In the current implementation, this function has global effect. All dirty\r
+ buffers are flushed and a transaction point is committed. Fsyncing one\r
+ file effectively fsyncs all files.\r
+\r
+ If fsync automatic transactions have been disabled, this function does\r
+ nothing and returns success. In the current implementation, this is the\r
+ only real difference between this function and red_transact(): this\r
+ function can be configured to do nothing, whereas red_transact() is\r
+ unconditional.\r
+\r
+ Applications written for portability should avoid assuming red_fsync()\r
+ effects all files, and use red_fsync() on each file that needs to be\r
+ synchronized.\r
+\r
+ Passing read-only file descriptors to this function is permitted.\r
+\r
+ @param iFildes The file descriptor to synchronize.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not a valid file descriptor.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_fsync(\r
+ int32_t iFildes)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ REDHANDLE *pHandle;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ /* No core event for fsync, so this transaction flag needs to be\r
+ implemented here.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulTransMask;\r
+\r
+ ret = RedCoreTransMaskGet(&ulTransMask);\r
+\r
+ if((ret == 0) && ((ulTransMask & RED_TRANSACT_FSYNC) != 0U))\r
+ {\r
+ ret = RedCoreVolTransact();\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Move the read/write file offset.\r
+\r
+ The file offset of the @p iFildes file descriptor is set to @p llOffset,\r
+ relative to some starting position. The available positions are:\r
+\r
+ - ::RED_SEEK_SET Seek from the start of the file. In other words,\r
+ @p llOffset becomes the new file offset.\r
+ - ::RED_SEEK_CUR Seek from the current file offset. In other words,\r
+ @p llOffset is added to the current file offset.\r
+ - ::RED_SEEK_END Seek from the end-of-file. In other words, the new file\r
+ offset is the file size plus @p llOffset.\r
+\r
+ Since @p llOffset is signed (can be negative), it is possible to seek\r
+ backward with ::RED_SEEK_CUR or ::RED_SEEK_END.\r
+\r
+ It is permitted to seek beyond the end-of-file; this does not increase the\r
+ file size (a subsequent red_write() call would).\r
+\r
+ Unlike POSIX lseek, this function cannot be used with directory file\r
+ descriptors.\r
+\r
+ @param iFildes The file descriptor whose offset is to be updated.\r
+ @param llOffset The new file offset, relative to @p whence.\r
+ @param whence The location from which @p llOffset should be applied.\r
+\r
+ @return On success, returns the new file position, measured in bytes from\r
+ the beginning of the file. On error, -1 is returned and #red_errno\r
+ is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not an open file descriptor.\r
+ - #RED_EINVAL: @p whence is not a valid `RED_SEEK_` value; or the resulting\r
+ file offset would be negative or beyond the maximum file size.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EISDIR: The @p iFildes argument is a file descriptor for a directory.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int64_t red_lseek(\r
+ int32_t iFildes,\r
+ int64_t llOffset,\r
+ REDWHENCE whence)\r
+{\r
+ REDSTATUS ret;\r
+ int64_t llReturn = -1; /* Init'd to quiet warnings. */\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ int64_t llFrom = 0; /* Init'd to quiet warnings. */\r
+ REDHANDLE *pHandle;\r
+\r
+ /* Unlike POSIX, we disallow lseek() on directory handles.\r
+ */\r
+ ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ switch(whence)\r
+ {\r
+ /* Seek from the beginning of the file.\r
+ */\r
+ case RED_SEEK_SET:\r
+ llFrom = 0;\r
+ break;\r
+\r
+ /* Seek from the current file offset.\r
+ */\r
+ case RED_SEEK_CUR:\r
+ REDASSERT(pHandle->ullOffset <= (uint64_t)INT64_MAX);\r
+ llFrom = (int64_t)pHandle->ullOffset;\r
+ break;\r
+\r
+ /* Seek from the end of the file.\r
+ */\r
+ case RED_SEEK_END:\r
+ {\r
+ REDSTAT s;\r
+\r
+ ret = RedCoreStat(pHandle->ulInode, &s);\r
+ if(ret == 0)\r
+ {\r
+ REDASSERT(s.st_size <= (uint64_t)INT64_MAX);\r
+ llFrom = (int64_t)s.st_size;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ default:\r
+ ret = -RED_EINVAL;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDASSERT(llFrom >= 0);\r
+\r
+ /* Avoid signed integer overflow from llFrom + llOffset with large\r
+ values of llOffset and nonzero llFrom values. Underflow isn't\r
+ possible since llFrom is nonnegative.\r
+ */\r
+ if((llOffset > 0) && (((uint64_t)llFrom + (uint64_t)llOffset) > (uint64_t)INT64_MAX))\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ int64_t llNewOffset = llFrom + llOffset;\r
+\r
+ if((llNewOffset < 0) || ((uint64_t)llNewOffset > gpRedVolume->ullMaxInodeSize))\r
+ {\r
+ /* Invalid file offset.\r
+ */\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else\r
+ {\r
+ pHandle->ullOffset = (uint64_t)llNewOffset;\r
+ llReturn = llNewOffset;\r
+ }\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ llReturn = PosixReturn(ret);\r
+ }\r
+\r
+ return llReturn;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)\r
+/** @brief Truncate a file to a specified length.\r
+\r
+ Allows the file size to be increased, decreased, or to remain the same. If\r
+ the file size is increased, the new area is sparse (will read as zeroes).\r
+ If the file size is decreased, the data beyond the new end-of-file will\r
+ return to free space once it is no longer part of the committed state\r
+ (either immediately or after the next transaction point).\r
+\r
+ The value of the file offset is not modified by this function.\r
+\r
+ Unlike POSIX ftruncate, this function can fail when the disk is full if\r
+ @p ullSize is non-zero. If decreasing the file size, this can be fixed by\r
+ transacting and trying again: Reliance Edge guarantees that it is possible\r
+ to perform a truncate of at least one file that decreases the file size\r
+ after a transaction point. If disk full transactions are enabled, this will\r
+ happen automatically.\r
+\r
+ @param iFildes The file descriptor of the file to truncate.\r
+ @param ullSize The new size of the file.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open\r
+ for writing. This includes the case where the file descriptor is for a\r
+ directory.\r
+ - #RED_EFBIG: @p ullSize exceeds the maximum file size.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENOSPC: Insufficient free space to perform the truncate.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_ftruncate(\r
+ int32_t iFildes,\r
+ uint64_t ullSize)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ REDHANDLE *pHandle;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle);\r
+ if(ret == -RED_EISDIR)\r
+ {\r
+ /* Similar to red_write() (see comment there), the RED_EBADF error\r
+ for a non-writable file descriptor takes precedence.\r
+ */\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreFileTruncate(pHandle->ulInode, ullSize);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Get the status of a file or directory.\r
+\r
+ See the ::REDSTAT type for the details of the information returned.\r
+\r
+ @param iFildes An open file descriptor for the file whose information is\r
+ to be retrieved.\r
+ @param pStat Pointer to a ::REDSTAT buffer to populate.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: The @p iFildes argument is not a valid file descriptor.\r
+ - #RED_EINVAL: @p pStat is `NULL`.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_fstat(\r
+ int32_t iFildes,\r
+ REDSTAT *pStat)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ REDHANDLE *pHandle;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreStat(pHandle->ulInode, pStat);\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+\r
+\r
+#if REDCONF_API_POSIX_READDIR == 1\r
+/** @brief Open a directory stream for reading.\r
+\r
+ @param pszPath The path of the directory to open.\r
+\r
+ @return On success, returns a pointer to a ::REDDIR object that can be used\r
+ with red_readdir() and red_closedir(). On error, returns `NULL`\r
+ and #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is\r
+ not mounted.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_ENOENT: A component of @p pszPath does not exist; or the @p pszPath\r
+ argument, after removing the volume prefix, points to an empty string.\r
+ - #RED_ENOTDIR: A component of @p pszPath is a not a directory.\r
+ - #RED_EMFILE: There are no available file descriptors.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+REDDIR *red_opendir(\r
+ const char *pszPath)\r
+{\r
+ int32_t iFildes;\r
+ REDSTATUS ret;\r
+ REDDIR *pDir = NULL;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ ret = FildesOpen(pszPath, RED_O_RDONLY, FTYPE_DIR, &iFildes);\r
+ if(ret == 0)\r
+ {\r
+ uint16_t uHandleIdx;\r
+\r
+ FildesUnpack(iFildes, &uHandleIdx, NULL, NULL);\r
+ pDir = &gaHandle[uHandleIdx];\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ REDASSERT((pDir == NULL) == (ret != 0));\r
+\r
+ if(pDir == NULL)\r
+ {\r
+ red_errno = -ret;\r
+ }\r
+\r
+ return pDir;\r
+}\r
+\r
+\r
+/** @brief Read from a directory stream.\r
+\r
+ The ::REDDIRENT pointer returned by this function will be overwritten by\r
+ subsequent calls on the same @p pDir. Calls with other ::REDDIR objects\r
+ will *not* modify the returned ::REDDIRENT.\r
+\r
+ If files are added to the directory after it is opened, the new files may\r
+ or may not be returned by this function. If files are deleted, the deleted\r
+ files will not be returned.\r
+\r
+ This function (like its POSIX equivalent) returns `NULL` in two cases: on\r
+ error and when the end of the directory is reached. To distinguish between\r
+ these two cases, the application should set #red_errno to zero before\r
+ calling this function, and if `NULL` is returned, check if #red_errno is\r
+ still zero. If it is, the end of the directory was reached; otherwise,\r
+ there was an error.\r
+\r
+ @param pDirStream The directory stream to read from.\r
+\r
+ @return On success, returns a pointer to a ::REDDIRENT object which is\r
+ populated with directory entry information read from the directory.\r
+ On error, returns `NULL` and #red_errno is set appropriately. If at\r
+ the end of the directory, returns `NULL` but #red_errno is not\r
+ modified.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: @p pDirStream is not an open directory stream.\r
+ - #RED_EIO: A disk I/O error occurred.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+REDDIRENT *red_readdir(\r
+ REDDIR *pDirStream)\r
+{\r
+ REDSTATUS ret;\r
+ REDDIRENT *pDirEnt = NULL;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ if(!DirStreamIsValid(pDirStream))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ else\r
+ {\r
+ ret = RedCoreVolSetCurrent(pDirStream->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulDirPosition;\r
+\r
+ /* To save memory, the directory position is stored in the same\r
+ location as the file offset. This would be a bit cleaner using\r
+ a union, but MISRA-C:2012 Rule 19.2 disallows unions.\r
+ */\r
+ REDASSERT(pDirStream->ullOffset <= UINT32_MAX);\r
+ ulDirPosition = (uint32_t)pDirStream->ullOffset;\r
+\r
+ ret = RedCoreDirRead(pDirStream->ulInode, &ulDirPosition, pDirStream->dirent.d_name, &pDirStream->dirent.d_ino);\r
+\r
+ pDirStream->ullOffset = ulDirPosition;\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* POSIX extension: return stat information with the dirent.\r
+ */\r
+ ret = RedCoreStat(pDirStream->dirent.d_ino, &pDirStream->dirent.d_stat);\r
+ if(ret == 0)\r
+ {\r
+ pDirEnt = &pDirStream->dirent;\r
+ }\r
+ }\r
+ else if(ret == -RED_ENOENT)\r
+ {\r
+ /* Reached the end of the directory; return NULL but do not set\r
+ errno.\r
+ */\r
+ ret = 0;\r
+ }\r
+ else\r
+ {\r
+ /* Miscellaneous error; return NULL and set errno (done below).\r
+ */\r
+ }\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ if(ret != 0)\r
+ {\r
+ REDASSERT(pDirEnt == NULL);\r
+\r
+ red_errno = -ret;\r
+ }\r
+\r
+ return pDirEnt;\r
+}\r
+\r
+\r
+/** @brief Rewind a directory stream to read it from the beginning.\r
+\r
+ Similar to closing the directory object and opening it again, but without\r
+ the need for the path.\r
+\r
+ Since this function (like its POSIX equivalent) cannot return an error,\r
+ it takes no action in error conditions, such as when @p pDirStream is\r
+ invalid.\r
+\r
+ @param pDirStream The directory stream to rewind.\r
+*/\r
+void red_rewinddir(\r
+ REDDIR *pDirStream)\r
+{\r
+ if(PosixEnter() == 0)\r
+ {\r
+ if(DirStreamIsValid(pDirStream))\r
+ {\r
+ pDirStream->ullOffset = 0U;\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+}\r
+\r
+\r
+/** @brief Close a directory stream.\r
+\r
+ After calling this function, @p pDirStream should no longer be used.\r
+\r
+ @param pDirStream The directory stream to close.\r
+\r
+ @return On success, zero is returned. On error, -1 is returned and\r
+ #red_errno is set appropriately.\r
+\r
+ <b>Errno values</b>\r
+ - #RED_EBADF: @p pDirStream is not an open directory stream.\r
+ - #RED_EUSERS: Cannot become a file system user: too many users.\r
+*/\r
+int32_t red_closedir(\r
+ REDDIR *pDirStream)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ ret = PosixEnter();\r
+ if(ret == 0)\r
+ {\r
+ if(DirStreamIsValid(pDirStream))\r
+ {\r
+ /* Mark this handle as unused.\r
+ */\r
+ pDirStream->ulInode = INODE_INVALID;\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+\r
+ PosixLeave();\r
+ }\r
+\r
+ return PosixReturn(ret);\r
+}\r
+#endif /* REDCONF_API_POSIX_READDIR */\r
+\r
+\r
+/** @brief Pointer to where the last file system error (errno) is stored.\r
+\r
+ This function is intended to be used via the #red_errno macro, or a similar\r
+ user-defined macro, that can be used both as an lvalue (writable) and an\r
+ rvalue (readable).\r
+\r
+ Under normal circumstances, the errno for each task is stored in a\r
+ different location. Applications do not need to worry about one task\r
+ obliterating an error value that another task needed to read. This task\r
+ errno for is initially zero. When one of the POSIX-like APIs returns an\r
+ indication of error, the location for the calling task will be populated\r
+ with the error value.\r
+\r
+ In some circumstances, this function will return a pointer to a global\r
+ errno location which is shared by multiple tasks. If the calling task is\r
+ not registered as a file system user and all of the task slots are full,\r
+ there can be no task-specific errno, so the global pointer is returned.\r
+ Likewise, if the file system driver is uninitialized, there are no\r
+ registered file system users and this function always returns the pointer\r
+ to the global errno. Under these circumstances, multiple tasks\r
+ manipulating errno could be problematic.\r
+\r
+ This function never returns `NULL` under any circumstances. The #red_errno\r
+ macro unconditionally dereferences the return value from this function, so\r
+ returning `NULL` could result in a fault.\r
+\r
+ @return Pointer to where the errno value is stored for this task.\r
+*/\r
+REDSTATUS *red_errnoptr(void)\r
+{\r
+ /* The global errno value, used in single-task configurations and when the\r
+ caller is not (and cannot become) a file system user (which includes\r
+ when the driver is uninitialized).\r
+ */\r
+ static REDSTATUS iGlobalErrno = 0;\r
+\r
+ #if REDCONF_TASK_COUNT == 1U\r
+\r
+ return &iGlobalErrno;\r
+\r
+ #else\r
+\r
+ REDSTATUS *piErrno;\r
+\r
+ if(gfPosixInited)\r
+ {\r
+ uint32_t ulTaskId = RedOsTaskId();\r
+ uint32_t ulIdx;\r
+\r
+ REDASSERT(ulTaskId != 0U);\r
+\r
+ /* If this task has used the file system before, it will already have\r
+ a task slot, which includes the task-specific errno.\r
+ */\r
+ RedOsMutexAcquire();\r
+\r
+ for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++)\r
+ {\r
+ if(gaTask[ulIdx].ulTaskId == ulTaskId)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ RedOsMutexRelease();\r
+\r
+ if(ulIdx == REDCONF_TASK_COUNT)\r
+ {\r
+ REDSTATUS ret;\r
+\r
+ /* This task is not a file system user, so try to register it as\r
+ one. This FS mutex must be held in order to register.\r
+ */\r
+ RedOsMutexAcquire();\r
+\r
+ ret = TaskRegister(&ulIdx);\r
+\r
+ RedOsMutexRelease();\r
+\r
+ if(ret == 0)\r
+ {\r
+ REDASSERT(gaTask[ulIdx].ulTaskId == RedOsTaskId());\r
+ REDASSERT(gaTask[ulIdx].iErrno == 0);\r
+\r
+ piErrno = &gaTask[ulIdx].iErrno;\r
+ }\r
+ else\r
+ {\r
+ /* Unable to register; use the global errno.\r
+ */\r
+ piErrno = &iGlobalErrno;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ piErrno = &gaTask[ulIdx].iErrno;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* There are no registered file system tasks when the driver is\r
+ uninitialized, so use the global errno.\r
+ */\r
+ piErrno = &iGlobalErrno;\r
+ }\r
+\r
+ /* This function is not allowed to return NULL.\r
+ */\r
+ REDASSERT(piErrno != NULL);\r
+ return piErrno;\r
+\r
+ #endif\r
+}\r
+/** @} */\r
+\r
+/*-------------------------------------------------------------------\r
+ Helper Functions\r
+-------------------------------------------------------------------*/\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))\r
+\r
+/** @brief Remove a link to a file or directory.\r
+\r
+ If the link count becomes zero, the file or directory is deleted.\r
+\r
+ @param pszPath Path of the link to remove.\r
+ @param type The expected type of the path: file, directory, or either.\r
+ An error is returned if the expected type is file or\r
+ directory and does not match the path.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval -RED_EBUSY @p pszPath points to an inode with open handles\r
+ and a link count of one.\r
+ @retval -RED_EINVAL @p pszPath is `NULL`; or the volume containing\r
+ the path is not mounted.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_EISDIR @p type is ::FTYPE_FILE and the path names a\r
+ directory.\r
+ @retval -RED_ENAMETOOLONG @p pszName is too long.\r
+ @retval -RED_ENOENT The path does not name an existing file; or\r
+ @p pszPath, after removing the volume prefix,\r
+ points to an empty string.\r
+ @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the path does not\r
+ name a directory.\r
+ @retval -RED_ENOTEMPTY @p pszPath is a directory which is not empty.\r
+ @retval -RED_ENOSPC The file system does not have enough space to\r
+ modify the parent directory to perform the\r
+ deletion.\r
+*/\r
+static REDSTATUS UnlinkSub(\r
+ const char *pszPath,\r
+ FTYPE type)\r
+{\r
+ uint8_t bVolNum;\r
+ const char *pszLocalPath;\r
+ REDSTATUS ret;\r
+\r
+ ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath);\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ const char *pszName;\r
+ uint32_t ulPInode;\r
+\r
+ ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);\r
+\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulInode;\r
+\r
+ ret = RedCoreLookup(ulPInode, pszName, &ulInode);\r
+\r
+ /* ModeTypeCheck() always passes when the type is FTYPE_EITHER, so\r
+ skip stat'ing the inode in that case.\r
+ */\r
+ if((ret == 0) && (type != FTYPE_EITHER))\r
+ {\r
+ REDSTAT InodeStat;\r
+\r
+ ret = RedCoreStat(ulInode, &InodeStat);\r
+ if(ret == 0)\r
+ {\r
+ ret = ModeTypeCheck(InodeStat.st_mode, type);\r
+ }\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = InodeUnlinkCheck(ulInode);\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreUnlink(ulPInode, pszName);\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* (REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) */\r
+\r
+\r
+/** @brief Get a file descriptor for a path.\r
+\r
+ @param pszPath Path to a file to open.\r
+ @param ulOpenMode The RED_O_* flags the descriptor is opened with.\r
+ @param type Indicates the expected descriptor type: file, directory,\r
+ or either.\r
+ @param piFildes On successful return, populated with the file\r
+ descriptor.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL @p piFildes is `NULL`; or @p pszPath is `NULL`;\r
+ or the volume is not mounted.\r
+ @retval -RED_EMFILE There are no available handles.\r
+ @retval -RED_EEXIST Using #RED_O_CREAT and #RED_O_EXCL, and the\r
+ indicated path already exists.\r
+ @retval -RED_EISDIR The path names a directory and @p ulOpenMode\r
+ includes #RED_O_WRONLY or #RED_O_RDWR.\r
+ @retval -RED_ENOENT #RED_O_CREAT is not set and the named file does\r
+ not exist; or #RED_O_CREAT is set and the parent\r
+ directory does not exist; or the volume does not\r
+ exist; or the @p pszPath argument, after\r
+ removing the volume prefix, points to an empty\r
+ string.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+ @retval -RED_ENAMETOOLONG The length of a component of @p pszPath is\r
+ longer than #REDCONF_NAME_MAX.\r
+ @retval -RED_ENFILE Attempting to create a file but the file system\r
+ has used all available inode slots.\r
+ @retval -RED_ENOSPC The file does not exist and #RED_O_CREAT was\r
+ specified, but there is insufficient free space\r
+ to expand the directory or to create the new\r
+ file.\r
+ @retval -RED_ENOTDIR A component of the prefix in @p pszPath does not\r
+ name a directory.\r
+ @retval -RED_EROFS The path resides on a read-only file system and\r
+ a write operation was requested.\r
+*/\r
+static REDSTATUS FildesOpen(\r
+ const char *pszPath,\r
+ uint32_t ulOpenMode,\r
+ FTYPE type,\r
+ int32_t *piFildes)\r
+{\r
+ uint8_t bVolNum;\r
+ const char *pszLocalPath;\r
+ REDSTATUS ret;\r
+\r
+ ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath);\r
+\r
+ if(ret == 0)\r
+ {\r
+ if(piFildes == NULL)\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+ #if REDCONF_READ_ONLY == 0\r
+ else if(gaRedVolume[bVolNum].fReadOnly && (ulOpenMode != RED_O_RDONLY))\r
+ {\r
+ ret = -RED_EROFS;\r
+ }\r
+ #endif\r
+ else\r
+ {\r
+ uint16_t uHandleIdx;\r
+ REDHANDLE *pHandle = NULL;\r
+\r
+ /* Search for an unused handle.\r
+ */\r
+ for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++)\r
+ {\r
+ if(gaHandle[uHandleIdx].ulInode == INODE_INVALID)\r
+ {\r
+ pHandle = &gaHandle[uHandleIdx];\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* Error if all the handles are in use.\r
+ */\r
+ if(pHandle == NULL)\r
+ {\r
+ ret = -RED_EMFILE;\r
+ }\r
+ else\r
+ {\r
+ bool fCreated = false;\r
+ uint16_t uMode = 0U;\r
+ uint32_t ulInode = 0U; /* Init'd to quiet warnings. */\r
+\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ ret = RedCoreVolSetCurrent(bVolNum);\r
+ if(ret == 0)\r
+ #endif\r
+ {\r
+ #if REDCONF_READ_ONLY == 0\r
+ if((ulOpenMode & RED_O_CREAT) != 0U)\r
+ {\r
+ uint32_t ulPInode;\r
+ const char *pszName;\r
+\r
+ ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreCreate(ulPInode, pszName, false, &ulInode);\r
+ if(ret == 0)\r
+ {\r
+ fCreated = true;\r
+ }\r
+ else if((ret == -RED_EEXIST) && ((ulOpenMode & RED_O_EXCL) == 0U))\r
+ {\r
+ /* If the path already exists and that's OK,\r
+ lookup its inode number.\r
+ */\r
+ ret = RedCoreLookup(ulPInode, pszName, &ulInode);\r
+ }\r
+ else\r
+ {\r
+ /* No action, just propagate the error.\r
+ */\r
+ }\r
+ }\r
+ }\r
+ else\r
+ #endif\r
+ {\r
+ ret = RedPathLookup(pszLocalPath, &ulInode);\r
+ }\r
+ }\r
+\r
+ /* If we created the inode, none of the below stuff is\r
+ necessary. This is important from an error handling\r
+ perspective -- we do not need code to delete the created\r
+ inode on error.\r
+ */\r
+ if(!fCreated)\r
+ {\r
+ if(ret == 0)\r
+ {\r
+ REDSTAT s;\r
+\r
+ ret = RedCoreStat(ulInode, &s);\r
+ if(ret == 0)\r
+ {\r
+ uMode = s.st_mode;\r
+ }\r
+ }\r
+\r
+ /* Error if the inode is not of the expected type.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ ret = ModeTypeCheck(uMode, type);\r
+ }\r
+\r
+ /* Directories must always be opened with O_RDONLY.\r
+ */\r
+ if((ret == 0) && RED_S_ISDIR(uMode) && ((ulOpenMode & RED_O_RDONLY) == 0U))\r
+ {\r
+ ret = -RED_EISDIR;\r
+ }\r
+\r
+ #if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)\r
+ if((ret == 0) && ((ulOpenMode & RED_O_TRUNC) != 0U))\r
+ {\r
+ ret = RedCoreFileTruncate(ulInode, UINT64_SUFFIX(0));\r
+ }\r
+ #endif\r
+ }\r
+\r
+ if(ret == 0)\r
+ {\r
+ int32_t iFildes;\r
+\r
+ RedMemSet(pHandle, 0U, sizeof(*pHandle));\r
+\r
+ /* Populate this handle, marking it as in use.\r
+ */\r
+ pHandle->ulInode = ulInode;\r
+ pHandle->bVolNum = bVolNum;\r
+\r
+ if(RED_S_ISDIR(uMode))\r
+ {\r
+ pHandle->bFlags |= HFLAG_DIRECTORY;\r
+ }\r
+\r
+ if(((ulOpenMode & RED_O_RDONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U))\r
+ {\r
+ pHandle->bFlags |= HFLAG_READABLE;\r
+ }\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ if(((ulOpenMode & RED_O_WRONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U))\r
+ {\r
+ pHandle->bFlags |= HFLAG_WRITEABLE;\r
+ }\r
+\r
+ if((ulOpenMode & RED_O_APPEND) != 0U)\r
+ {\r
+ pHandle->bFlags |= HFLAG_APPENDING;\r
+ }\r
+ #endif\r
+\r
+ iFildes = FildesPack(uHandleIdx, bVolNum);\r
+ if(iFildes == -1)\r
+ {\r
+ /* It should be impossible to get here, unless there\r
+ is memory corruption.\r
+ */\r
+ REDERROR();\r
+ ret = -RED_EFUBAR;\r
+ }\r
+ else\r
+ {\r
+ *piFildes = iFildes;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Close a file descriptor.\r
+\r
+ @param iFildes The file descriptor to close.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p iFildes is not a valid file descriptor.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS FildesClose(\r
+ int32_t iFildes)\r
+{\r
+ REDHANDLE *pHandle;\r
+ REDSTATUS ret;\r
+\r
+ ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle);\r
+\r
+ #if REDCONF_READ_ONLY == 0\r
+ #if REDCONF_VOLUME_COUNT > 1U\r
+ if(ret == 0)\r
+ {\r
+ ret = RedCoreVolSetCurrent(pHandle->bVolNum);\r
+ }\r
+ #endif\r
+\r
+ /* No core event for close, so this transaction flag needs to be\r
+ implemented here.\r
+ */\r
+ if(ret == 0)\r
+ {\r
+ uint32_t ulTransMask;\r
+\r
+ ret = RedCoreTransMaskGet(&ulTransMask);\r
+\r
+ if((ret == 0) && ((ulTransMask & RED_TRANSACT_CLOSE) != 0U))\r
+ {\r
+ ret = RedCoreVolTransact();\r
+ }\r
+ }\r
+ #endif\r
+\r
+ if(ret == 0)\r
+ {\r
+ /* Mark this handle as unused.\r
+ */\r
+ pHandle->ulInode = INODE_INVALID;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Convert a file descriptor into a handle pointer.\r
+\r
+ Also validates the file descriptor.\r
+\r
+ @param iFildes The file descriptor for which to get a handle.\r
+ @param expectedType The expected type of the file descriptor: ::FTYPE_DIR,\r
+ ::FTYPE_FILE, or ::FTYPE_EITHER.\r
+ @param ppHandle On successful return, populated with a pointer to the\r
+ handle associated with @p iFildes.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p iFildes is not a valid file descriptor.\r
+ @retval -RED_EINVAL @p ppHandle is `NULL`.\r
+ @retval -RED_EISDIR Expected a file, but the file descriptor is for a\r
+ directory.\r
+ @retval -RED_ENOTDIR Expected a directory, but the file descriptor is for\r
+ a file.\r
+*/\r
+static REDSTATUS FildesToHandle(\r
+ int32_t iFildes,\r
+ FTYPE expectedType,\r
+ REDHANDLE **ppHandle)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(ppHandle == NULL)\r
+ {\r
+ REDERROR();\r
+ ret = -RED_EINVAL;\r
+ }\r
+ else if(iFildes < FD_MIN)\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+ else\r
+ {\r
+ uint16_t uHandleIdx;\r
+ uint8_t bVolNum;\r
+ uint16_t uGeneration;\r
+\r
+ FildesUnpack(iFildes, &uHandleIdx, &bVolNum, &uGeneration);\r
+\r
+ if( (uHandleIdx >= REDCONF_HANDLE_COUNT)\r
+ || (bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || (gaHandle[uHandleIdx].ulInode == INODE_INVALID)\r
+ || (gaHandle[uHandleIdx].bVolNum != bVolNum)\r
+ || (gauGeneration[bVolNum] != uGeneration))\r
+ {\r
+ ret = -RED_EBADF;\r
+ }\r
+ else if((expectedType == FTYPE_FILE) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) != 0U))\r
+ {\r
+ ret = -RED_EISDIR;\r
+ }\r
+ else if((expectedType == FTYPE_DIR) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) == 0U))\r
+ {\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ *ppHandle = &gaHandle[uHandleIdx];\r
+ ret = 0;\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Pack a file descriptor.\r
+\r
+ @param uHandleIdx The index of the file handle that will be associated\r
+ with this file descriptor.\r
+ @param bVolNum The volume which contains the file or directory this\r
+ file descriptor was opened against.\r
+\r
+ @return The packed file descriptor.\r
+*/\r
+static int32_t FildesPack(\r
+ uint16_t uHandleIdx,\r
+ uint8_t bVolNum)\r
+{\r
+ int32_t iFildes;\r
+\r
+ if((uHandleIdx >= REDCONF_HANDLE_COUNT) || (bVolNum >= REDCONF_VOLUME_COUNT))\r
+ {\r
+ REDERROR();\r
+ iFildes = -1;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulFdBits;\r
+\r
+ REDASSERT(gauGeneration[bVolNum] <= FD_GEN_MAX);\r
+ REDASSERT(gauGeneration[bVolNum] != 0U);\r
+\r
+ ulFdBits = gauGeneration[bVolNum];\r
+ ulFdBits <<= FD_VOL_BITS;\r
+ ulFdBits |= bVolNum;\r
+ ulFdBits <<= FD_IDX_BITS;\r
+ ulFdBits |= uHandleIdx;\r
+\r
+ iFildes = (int32_t)ulFdBits;\r
+\r
+ if(iFildes < FD_MIN)\r
+ {\r
+ REDERROR();\r
+ iFildes = -1;\r
+ }\r
+ }\r
+\r
+ return iFildes;\r
+}\r
+\r
+\r
+/** @brief Unpack a file descriptor.\r
+\r
+ @param iFildes The file descriptor to unpack.\r
+ @param puHandleIdx If non-NULL, populated with the handle index extracted\r
+ from the file descriptor.\r
+ @param pbVolNum If non-NULL, populated with the volume number extracted\r
+ from the file descriptor.\r
+ @param puGeneration If non-NULL, populated with the generation number\r
+ extracted from the file descriptor.\r
+*/\r
+static void FildesUnpack(\r
+ int32_t iFildes,\r
+ uint16_t *puHandleIdx,\r
+ uint8_t *pbVolNum,\r
+ uint16_t *puGeneration)\r
+{\r
+ uint32_t ulFdBits = (uint32_t)iFildes;\r
+\r
+ REDASSERT(iFildes >= FD_MIN);\r
+\r
+ if(puHandleIdx != NULL)\r
+ {\r
+ *puHandleIdx = (uint16_t)(ulFdBits & FD_IDX_MAX);\r
+ }\r
+\r
+ ulFdBits >>= FD_IDX_BITS;\r
+\r
+ if(pbVolNum != NULL)\r
+ {\r
+ *pbVolNum = (uint8_t)(ulFdBits & FD_VOL_MAX);\r
+ }\r
+\r
+ ulFdBits >>= FD_VOL_BITS;\r
+\r
+ if(puGeneration != NULL)\r
+ {\r
+ *puGeneration = (uint16_t)(ulFdBits & FD_GEN_MAX);\r
+ }\r
+}\r
+\r
+\r
+#if REDCONF_API_POSIX_READDIR == 1\r
+/** @brief Validate a directory stream object.\r
+\r
+ @param pDirStream The directory stream to validate.\r
+\r
+ @return Whether the directory stream is valid.\r
+\r
+ @retval true The directory stream object appears valid.\r
+ @retval false The directory stream object is invalid.\r
+*/\r
+static bool DirStreamIsValid(\r
+ const REDDIR *pDirStream)\r
+{\r
+ bool fRet = true;\r
+\r
+ if(pDirStream == NULL)\r
+ {\r
+ fRet = false;\r
+ }\r
+ else\r
+ {\r
+ uint16_t uHandleIdx;\r
+\r
+ /* pDirStream should be a pointer to one of the handles.\r
+\r
+ A good compiler will optimize this loop into a bounds check and an\r
+ alignment check.\r
+ */\r
+ for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++)\r
+ {\r
+ if(pDirStream == &gaHandle[uHandleIdx])\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(uHandleIdx < REDCONF_HANDLE_COUNT)\r
+ {\r
+ /* The handle must be in use, have a valid volume number, and be a\r
+ directory handle.\r
+ */\r
+ if( (pDirStream->ulInode == INODE_INVALID)\r
+ || (pDirStream->bVolNum >= REDCONF_VOLUME_COUNT)\r
+ || ((pDirStream->bFlags & HFLAG_DIRECTORY) == 0U))\r
+ {\r
+ fRet = false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* pDirStream is a non-null pointer, but it is not a pointer to one\r
+ of our handles.\r
+ */\r
+ fRet = false;\r
+ }\r
+ }\r
+\r
+ return fRet;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Enter the file system driver.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EINVAL The file system driver is uninitialized.\r
+ @retval -RED_EUSERS Cannot become a file system user: too many users.\r
+*/\r
+static REDSTATUS PosixEnter(void)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if(gfPosixInited)\r
+ {\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexAcquire();\r
+\r
+ ret = TaskRegister(NULL);\r
+ if(ret != 0)\r
+ {\r
+ RedOsMutexRelease();\r
+ }\r
+ #else\r
+ ret = 0;\r
+ #endif\r
+ }\r
+ else\r
+ {\r
+ ret = -RED_EINVAL;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/** @brief Leave the file system driver.\r
+*/\r
+static void PosixLeave(void)\r
+{\r
+ /* If the driver was uninitialized, PosixEnter() should have failed and we\r
+ should not be calling PosixLeave().\r
+ */\r
+ REDASSERT(gfPosixInited);\r
+\r
+ #if REDCONF_TASK_COUNT > 1U\r
+ RedOsMutexRelease();\r
+ #endif\r
+}\r
+\r
+\r
+/** @brief Check that a mode is consistent with the given expected type.\r
+\r
+ @param uMode An inode mode, indicating whether the inode is a file\r
+ or a directory.\r
+ @param expectedType The expected type: ::FTYPE_FILE, ::FTYPE_DIR, or\r
+ ::FTYPE_EITHER.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EISDIR Expected type is file, actual type is directory.\r
+ @retval -RED_ENOTDIR Expected type is directory, actual type is file.\r
+*/\r
+static REDSTATUS ModeTypeCheck(\r
+ uint16_t uMode,\r
+ FTYPE expectedType)\r
+{\r
+ REDSTATUS ret;\r
+\r
+ if((expectedType == FTYPE_FILE) && RED_S_ISDIR(uMode))\r
+ {\r
+ /* Expected file, found directory.\r
+ */\r
+ ret = -RED_EISDIR;\r
+ }\r
+ else if((expectedType == FTYPE_DIR) && RED_S_ISREG(uMode))\r
+ {\r
+ /* Expected directory, found file.\r
+ */\r
+ ret = -RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ /* No expected type or found what we expected.\r
+ */\r
+ ret = 0;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))\r
+/** @brief Check whether an inode can be unlinked.\r
+\r
+ If an inode has a link count of 1 (meaning unlinking another name would\r
+ result in the deletion of the inode) and open handles, it cannot be deleted\r
+ since this would break open handles.\r
+\r
+ @param ulInode The inode whose name is to be unlinked.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EBADF @p ulInode is not a valid inode.\r
+ @retval -RED_EBUSY The inode has a link count of one and open handles.\r
+ @retval -RED_EIO A disk I/O error occurred.\r
+*/\r
+static REDSTATUS InodeUnlinkCheck(\r
+ uint32_t ulInode)\r
+{\r
+ uint16_t uHandleIdx;\r
+ REDSTATUS ret;\r
+\r
+ #if REDCONF_API_POSIX_LINK == 0\r
+ ret = 0;\r
+ #else\r
+ REDSTAT InodeStat;\r
+\r
+ ret = RedCoreStat(ulInode, &InodeStat);\r
+\r
+ /* We only need to check for open handles if the inode is down to its last\r
+ link. If it has multiple links, the inode will continue to exist, so\r
+ deleting the name will not break the open handles.\r
+ */\r
+ if((ret == 0) && (InodeStat.st_nlink == 1U))\r
+ #endif\r
+ {\r
+ for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++)\r
+ {\r
+ if((gaHandle[uHandleIdx].ulInode == ulInode) && (gaHandle[uHandleIdx].bVolNum == gbRedVolNum))\r
+ {\r
+ ret = -RED_EBUSY;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if REDCONF_TASK_COUNT > 1U\r
+/** @brief Register a task as a file system user, if it is not already\r
+ registered as one.\r
+\r
+ The caller must hold the FS mutex.\r
+\r
+ @param pulTaskIdx On successful return, if non-NULL, populated with the\r
+ index of the task slot assigned to the calling task.\r
+ This is populated whether or not the task had already\r
+ been registered.\r
+\r
+ @return A negated ::REDSTATUS code indicating the operation result.\r
+\r
+ @retval 0 Operation was successful.\r
+ @retval -RED_EUSERS Cannot become a file system user: too many users.\r
+*/\r
+static REDSTATUS TaskRegister(\r
+ uint32_t *pulTaskIdx)\r
+{\r
+ uint32_t ulTaskId = RedOsTaskId();\r
+ uint32_t ulFirstFreeIdx = REDCONF_TASK_COUNT;\r
+ uint32_t ulIdx;\r
+ REDSTATUS ret;\r
+\r
+ REDASSERT(ulTaskId != 0U);\r
+\r
+ /* Scan the task slots to determine if the task is registered as a file\r
+ system task.\r
+ */\r
+ for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++)\r
+ {\r
+ if(gaTask[ulIdx].ulTaskId == ulTaskId)\r
+ {\r
+ break;\r
+ }\r
+\r
+ if((ulFirstFreeIdx == REDCONF_TASK_COUNT) && (gaTask[ulIdx].ulTaskId == 0U))\r
+ {\r
+ ulFirstFreeIdx = ulIdx;\r
+ }\r
+ }\r
+\r
+ if(ulIdx == REDCONF_TASK_COUNT)\r
+ {\r
+ /* Task not already registered.\r
+ */\r
+ if(ulFirstFreeIdx == REDCONF_TASK_COUNT)\r
+ {\r
+ /* Cannot register task, no more slots.\r
+ */\r
+ ret = -RED_EUSERS;\r
+ }\r
+ else\r
+ {\r
+ /* Registering task.\r
+ */\r
+ ulIdx = ulFirstFreeIdx;\r
+ gaTask[ulIdx].ulTaskId = ulTaskId;\r
+ ret = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Task already registered.\r
+ */\r
+ ret = 0;\r
+ }\r
+\r
+ if((ret == 0) && (pulTaskIdx != NULL))\r
+ {\r
+ *pulTaskIdx = ulIdx;\r
+ }\r
+\r
+ return ret;\r
+}\r
+#endif /* REDCONF_TASK_COUNT > 1U */\r
+\r
+\r
+/** @brief Convert an error value into a simple 0 or -1 return.\r
+\r
+ This function is simple, but what it does is needed in many places. It\r
+ returns zero if @p iError is zero (meaning success) or it returns -1 if\r
+ @p iError is nonzero (meaning error). Also, if @p iError is nonzero, it\r
+ is saved in red_errno.\r
+\r
+ @param iError The error value.\r
+\r
+ @return Returns 0 if @p iError is 0; otherwise, returns -1.\r
+*/\r
+static int32_t PosixReturn(\r
+ REDSTATUS iError)\r
+{\r
+ int32_t iReturn;\r
+\r
+ if(iError == 0)\r
+ {\r
+ iReturn = 0;\r
+ }\r
+ else\r
+ {\r
+ iReturn = -1;\r
+\r
+ /* The errors should be negative, and errno positive.\r
+ */\r
+ REDASSERT(iError < 0);\r
+ red_errno = -iError;\r
+ }\r
+\r
+ return iReturn;\r
+}\r
+\r
+\r
+#endif /* REDCONF_API_POSIX == 1 */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Interfaces of path utilities for the POSIX-like API layer.\r
+*/\r
+#ifndef REDPATH_H\r
+#define REDPATH_H\r
+\r
+\r
+REDSTATUS RedPathSplit(const char *pszPath, uint8_t *pbVolNum, const char **ppszLocalPath);\r
+REDSTATUS RedPathLookup(const char *pszLocalPath, uint32_t *pulInode);\r
+REDSTATUS RedPathToName(const char *pszLocalPath, uint32_t *pulPInode, const char **ppszName);\r
+\r
+\r
+#endif\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms of version 2 of the GNU General Public License as\r
+ * published by the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope that it would be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+ *\r
+ * Further, this software is distributed without any warranty that it is\r
+ * free of the rightful claim of any third person regarding infringement\r
+ * or the like. Any license provided herein, whether implied or\r
+ * otherwise, applies only to this software file. Patent licenses, if\r
+ * any, provided herein do not apply to combinations of this program with\r
+ * other software, or any other product whatsoever.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ *\r
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,\r
+ * Mountain View, CA 94043, or:\r
+ *\r
+ * http://www.sgi.com\r
+ *\r
+ * For further information regarding this notice, see:\r
+ *\r
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/\r
+ */\r
+/** @file\r
+ @brief File system stress test.\r
+\r
+ This version of SGI fsstress has been modified to be single-threaded and to\r
+ work with the Reliance Edge POSIX-like API.\r
+*/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <limits.h>\r
+#include <string.h>\r
+#include <stdarg.h>\r
+#include <time.h>\r
+\r
+#include <redposix.h>\r
+#include <redtests.h>\r
+\r
+#if FSSTRESS_SUPPORTED\r
+\r
+#include "redposixcompat.h"\r
+\r
+#include <redosserv.h>\r
+#include <redutils.h>\r
+#include <redmacs.h>\r
+#include <redvolume.h>\r
+#include <redgetopt.h>\r
+#include <redtoolcmn.h>\r
+\r
+#if REDCONF_CHECKER == 1\r
+#include <redcoreapi.h>\r
+#endif\r
+\r
+\r
+/* Create POSIX types. Use #define to avoid name conflicts in those\r
+ environments where the type names already exist.\r
+*/\r
+#define off_t int64_t\r
+#define off64_t off_t\r
+#define ino_t uint32_t\r
+#define mode_t uint16_t\r
+#define __int64_t int64_t\r
+\r
+\r
+/** @brief Generate a random number.\r
+\r
+ @return A nonnegative random number.\r
+*/\r
+#define random() ((int)(RedRand32(NULL) & 0x7FFFFFFF))\r
+\r
+\r
+/** @brief Seed the random number generator.\r
+*/\r
+#define srandom(seed) RedRandSeed(seed)\r
+\r
+\r
+#define _exit(status) exit(status)\r
+#define getpagesize() 4096U\r
+#define getpid() 1\r
+\r
+\r
+/** @brief Determine the maximum file size.\r
+\r
+ This is used for the MAXFSSIZE macro.\r
+*/\r
+static uint64_t MaxFileSize(void)\r
+{\r
+ REDSTATFS info;\r
+ int32_t iStatus;\r
+ REDSTATUS errnoSave = errno;\r
+ uint64_t ullMaxFileSize;\r
+\r
+ iStatus = red_statvfs("", &info);\r
+ if(iStatus == 0)\r
+ {\r
+ ullMaxFileSize = info.f_maxfsize;\r
+ }\r
+ else\r
+ {\r
+ /* This function does not change errno.\r
+ */\r
+ errno = errnoSave;\r
+\r
+ ullMaxFileSize = 0x7FFFFFFFU;\r
+ }\r
+\r
+ return ullMaxFileSize;\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+ Simulated current working directory support\r
+-------------------------------------------------------------------*/\r
+\r
+\r
+/* Forward declaration for red_chdir().\r
+*/\r
+static int red_stat(const char *pszPath, REDSTAT *pStat);\r
+\r
+/* The simulated CWD functions.\r
+*/\r
+#undef chdir\r
+#undef getcwd\r
+#define chdir(path) red_chdir(path)\r
+#define getcwd(buf, size) red_getcwd(buf, size)\r
+\r
+\r
+/* Redefine the path-based APIs to call MakeFullPath() on their arguments\r
+ since there is no CWD support in the red_*() APIs.\r
+*/\r
+#undef open\r
+#undef unlink\r
+#undef mkdir\r
+#undef rmdir\r
+#undef rename\r
+#undef link\r
+#undef opendir\r
+#define open(path, oflag) red_open(MakeFullPath(path), oflag)\r
+#define unlink(path) red_unlink(MakeFullPath(path))\r
+#define mkdir(path) red_mkdir(MakeFullPath(path))\r
+#define rmdir(path) red_rmdir(MakeFullPath(path))\r
+#define rename(old, new) red_rename(MakeFullPath(old), MakeFullPath(new))\r
+#define link(path, hardlink) red_link(MakeFullPath(path), MakeFullPath(hardlink))\r
+#define opendir(path) red_opendir(MakeFullPath(path))\r
+\r
+\r
+/* Stores the simulated current working directory.\r
+*/\r
+static char szLocalCwd[1024U] = "/";\r
+\r
+\r
+/** @brief Change the current working directory.\r
+\r
+ This function only supports a subset of what is possible with POSIX chdir().\r
+\r
+ @param pszPath The new current working directory.\r
+\r
+ @return Upon successful completion, 0 shall be returned. Otherwise, -1\r
+ shall be returned, and errno shall be set to indicate the error.\r
+*/\r
+static int red_chdir(\r
+ const char *pszPath)\r
+{\r
+ uint32_t ulIdx;\r
+ int iErrno = 0;\r
+\r
+ if(strcmp(pszPath, "..") == 0)\r
+ {\r
+ uint32_t ulLastSlashIdx = 0U;\r
+\r
+ /* Chop off the last path separator and everything after it, so that\r
+ "/foo/bar/baz" becomes "/foo/bar", moving the CWD up one directory.\r
+ */\r
+ for(ulIdx = 0U; szLocalCwd[ulIdx] != '\0'; ulIdx++)\r
+ {\r
+ if(szLocalCwd[ulIdx] == '/')\r
+ {\r
+ ulLastSlashIdx = ulIdx;\r
+ }\r
+ }\r
+\r
+ if(ulLastSlashIdx != 0U)\r
+ {\r
+ szLocalCwd[ulLastSlashIdx] = '\0';\r
+ }\r
+ }\r
+ else\r
+ {\r
+ char szOldCwd[1024U];\r
+\r
+ /* chdir() must have no effect on the CWD if it fails, so save the CWD\r
+ so we can revert it if necessary.\r
+ */\r
+ strcpy(szOldCwd, szLocalCwd);\r
+\r
+ if(pszPath[0U] == '/')\r
+ {\r
+ if(strlen(pszPath) >= sizeof(szLocalCwd))\r
+ {\r
+ iErrno = RED_ENAMETOOLONG;\r
+ }\r
+ else\r
+ {\r
+ strcpy(szLocalCwd, pszPath);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ulIdx = strlen(szLocalCwd);\r
+\r
+ if((ulIdx + 1U + strlen(pszPath)) >= sizeof(szLocalCwd))\r
+ {\r
+ iErrno = RED_ENAMETOOLONG;\r
+ }\r
+ else\r
+ {\r
+ if(szLocalCwd[1U] != '\0')\r
+ {\r
+ szLocalCwd[ulIdx] = '/';\r
+ ulIdx++;\r
+ }\r
+\r
+ strcpy(&szLocalCwd[ulIdx], pszPath);\r
+ }\r
+ }\r
+\r
+ if(iErrno == 0)\r
+ {\r
+ REDSTAT s;\r
+ int iStatus;\r
+\r
+ iStatus = red_stat(szLocalCwd, &s);\r
+ if(iStatus != 0)\r
+ {\r
+ iErrno = errno;\r
+ }\r
+ else if(!S_ISDIR(s.st_mode))\r
+ {\r
+ iErrno = RED_ENOTDIR;\r
+ }\r
+ else\r
+ {\r
+ /* No error, new CWD checks out.\r
+ */\r
+ }\r
+ }\r
+\r
+ if(iErrno != 0)\r
+ {\r
+ strcpy(szLocalCwd, szOldCwd);\r
+ }\r
+ }\r
+\r
+ if(iErrno != 0)\r
+ {\r
+ errno = iErrno;\r
+ }\r
+\r
+ return iErrno == 0 ? 0 : -1;\r
+}\r
+\r
+\r
+/** @brief Retrieve the current working directory.\r
+\r
+ @param pszBuf On successful return, populated with the current working\r
+ directory. If NULL, memory will be allocated for the CWD\r
+ and returned by this function.\r
+ @param nSize The size of @p pszBuf.\r
+\r
+ @return On success, if @p pszBuf was non-NULL, returns @p pszBuf; if\r
+ @p pszBuf was NULL, returns an allocated buffer populated with the\r
+ CWD which must be freed by the caller. On failure, returns NULL\r
+ and errno will be set.\r
+*/\r
+static char *red_getcwd(\r
+ char *pszBuf,\r
+ size_t nSize)\r
+{\r
+ char *pszRet;\r
+\r
+ if(pszBuf == NULL)\r
+ {\r
+ pszRet = malloc(strlen(szLocalCwd) + 1U);\r
+ if(pszRet == NULL)\r
+ {\r
+ errno = RED_ENOMEM;\r
+ }\r
+ else\r
+ {\r
+ strcpy(pszRet, szLocalCwd);\r
+ }\r
+ }\r
+ else if(nSize < strlen(szLocalCwd) + 1U)\r
+ {\r
+ errno = RED_ERANGE;\r
+ pszRet = NULL;\r
+ }\r
+ else\r
+ {\r
+ strcpy(pszBuf, szLocalCwd);\r
+ pszRet = pszBuf;\r
+ }\r
+\r
+ return pszRet;\r
+}\r
+\r
+\r
+/** @brief Make a relative path into a fully qualified path.\r
+\r
+ @param pszName The relative path.\r
+\r
+ @return On success, a pointer to a fully qualified path. On error, NULL.\r
+*/\r
+static const char *MakeFullPath(\r
+ const char *pszName)\r
+{\r
+ #define MAXVOLNAME 64U /* Enough for most configs. */\r
+ static char aszFullPath[2U][MAXVOLNAME + 1U + 1024U];\r
+ static uint32_t ulWhich = 0U;\r
+\r
+ char *pszFullPath = aszFullPath[ulWhich];\r
+ const char *pszVolume = gpRedVolConf->pszPathPrefix;\r
+ int32_t iLen;\r
+\r
+ if(pszName[0U] == '/')\r
+ {\r
+ iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, pszName);\r
+ }\r
+ else if(strcmp(pszName, ".") == 0U)\r
+ {\r
+ iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, szLocalCwd);\r
+ }\r
+ else if((szLocalCwd[0U] == '/') && (szLocalCwd[1U] == '\0'))\r
+ {\r
+ iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s/%s", pszVolume, pszName);\r
+ }\r
+ else\r
+ {\r
+ iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s/%s", pszVolume, szLocalCwd, pszName);\r
+ }\r
+\r
+ if(iLen == -1)\r
+ {\r
+ /* Insufficient path buffer space.\r
+ */\r
+ pszFullPath = NULL;\r
+ }\r
+ else\r
+ {\r
+ /* Toggle between two full path arrays; a kluge to make rename() and\r
+ link() work correctly.\r
+ */\r
+ ulWhich ^= 1U;\r
+ }\r
+\r
+ return pszFullPath;\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+ POSIX functions not implemented by the RED POSIX-like API\r
+-------------------------------------------------------------------*/\r
+\r
+#define stat(p, s) red_stat(p, s)\r
+#define stat64(p, s) stat(p, s)\r
+#define lstat(p, s) stat(p, s)\r
+#define lstat64(p, s) stat(p, s)\r
+#define truncate(p, s) red_truncate(p, s)\r
+#define truncate64(p, s) truncate(p, s)\r
+\r
+\r
+/** @brief Get the status of a file or directory.\r
+*/\r
+static int red_stat(\r
+ const char *pszPath,\r
+ REDSTAT *pStat)\r
+{\r
+ int iFd;\r
+ int iRet;\r
+\r
+ iFd = open(pszPath, O_RDONLY);\r
+ iRet = iFd;\r
+ if(iFd != -1)\r
+ {\r
+ iRet = fstat(iFd, pStat);\r
+\r
+ (void)close(iFd);\r
+ }\r
+\r
+ return iRet;\r
+}\r
+\r
+\r
+/** @brief Truncate a file to a specified length.\r
+*/\r
+static int red_truncate(\r
+ const char *pszPath,\r
+ off_t llSize)\r
+{\r
+ int iFd;\r
+ int iRet;\r
+\r
+ iFd = open(pszPath, O_WRONLY);\r
+ iRet = iFd;\r
+ if(iFd != -1)\r
+ {\r
+ iRet = ftruncate(iFd, llSize);\r
+\r
+ (void)close(iFd);\r
+ }\r
+\r
+ return iRet;\r
+}\r
+\r
+\r
+/*-------------------------------------------------------------------\r
+ Begin ported fsstress code\r
+-------------------------------------------------------------------*/\r
+\r
+/* Stuff from xfscompat.h */\r
+\r
+#define MAXNAMELEN (REDCONF_NAME_MAX+1U) /* Assumed to include NUL */\r
+\r
+struct dioattr {\r
+ int d_miniosz, d_maxiosz, d_mem;\r
+};\r
+\r
+#define MIN(a,b) ((a)<(b) ? (a):(b))\r
+#define MAX(a,b) ((a)>(b) ? (a):(b))\r
+\r
+/* End xfscompat.h */\r
+\r
+\r
+typedef enum {\r
+ OP_CREAT,\r
+ OP_FDATASYNC,\r
+ OP_FSYNC,\r
+ OP_GETDENTS,\r
+ OP_LINK,\r
+ OP_MKDIR,\r
+ OP_READ,\r
+ OP_RENAME,\r
+ OP_RMDIR,\r
+ OP_STAT,\r
+ OP_TRUNCATE,\r
+ OP_UNLINK,\r
+ OP_WRITE,\r
+ #if REDCONF_CHECKER == 1\r
+ OP_CHECK,\r
+ #endif\r
+ OP_LAST\r
+} opty_t;\r
+\r
+typedef void (*opfnc_t) (int, long);\r
+\r
+typedef struct opdesc {\r
+ opty_t op;\r
+ const char *name;\r
+ opfnc_t func;\r
+ int freq;\r
+ int iswrite;\r
+} opdesc_t;\r
+\r
+typedef struct fent {\r
+ int id;\r
+ int parent;\r
+} fent_t;\r
+\r
+typedef struct flist {\r
+ int nfiles;\r
+ int nslots;\r
+ int tag;\r
+ fent_t *fents;\r
+} flist_t;\r
+\r
+typedef struct pathname {\r
+ int len;\r
+ char *path;\r
+} pathname_t;\r
+\r
+#define FT_DIR 0\r
+#define FT_DIRm (1 << FT_DIR)\r
+#define FT_REG 1\r
+#define FT_REGm (1 << FT_REG)\r
+#define FT_SYM 2\r
+#define FT_SYMm (1 << FT_SYM)\r
+#define FT_DEV 3\r
+#define FT_DEVm (1 << FT_DEV)\r
+#define FT_RTF 4\r
+#define FT_RTFm (1 << FT_RTF)\r
+#define FT_nft 5\r
+#define FT_ANYm ((1 << FT_nft) - 1)\r
+#define FT_REGFILE (FT_REGm | FT_RTFm)\r
+#define FT_NOTDIR (FT_ANYm & ~FT_DIRm)\r
+\r
+#define FLIST_SLOT_INCR 16\r
+#define NDCACHE 64\r
+\r
+#define MAXFSIZE MaxFileSize()\r
+\r
+static void creat_f(int opno, long r);\r
+static void fdatasync_f(int opno, long r);\r
+static void fsync_f(int opno, long r);\r
+static void getdents_f(int opno, long r);\r
+static void link_f(int opno, long r);\r
+static void mkdir_f(int opno, long r);\r
+static void read_f(int opno, long r);\r
+static void rename_f(int opno, long r);\r
+static void rmdir_f(int opno, long r);\r
+static void stat_f(int opno, long r);\r
+static void truncate_f(int opno, long r);\r
+static void unlink_f(int opno, long r);\r
+static void write_f(int opno, long r);\r
+#if REDCONF_CHECKER == 1\r
+static void check_f(int opno, long r);\r
+#endif\r
+\r
+static opdesc_t ops[] = {\r
+ {OP_CREAT, "creat", creat_f, 4, 1},\r
+ {OP_FDATASYNC, "fdatasync", fdatasync_f, 1, 1},\r
+ {OP_FSYNC, "fsync", fsync_f, 1, 1},\r
+ {OP_GETDENTS, "getdents", getdents_f, 1, 0},\r
+ {OP_LINK, "link", link_f, 1, 1},\r
+ {OP_MKDIR, "mkdir", mkdir_f, 2, 1},\r
+ {OP_READ, "read", read_f, 1, 0},\r
+ {OP_RENAME, "rename", rename_f, 2, 1},\r
+ {OP_RMDIR, "rmdir", rmdir_f, 1, 1},\r
+ {OP_STAT, "stat", stat_f, 1, 0},\r
+ {OP_TRUNCATE, "truncate", truncate_f, 2, 1},\r
+ {OP_UNLINK, "unlink", unlink_f, 1, 1},\r
+ {OP_WRITE, "write", write_f, 4, 1},\r
+ #if REDCONF_CHECKER == 1\r
+ {OP_CHECK, "check", check_f, 1, 1},\r
+ #endif\r
+}, *ops_end;\r
+\r
+static flist_t flist[FT_nft] = {\r
+ {0, 0, 'd', NULL},\r
+ {0, 0, 'f', NULL},\r
+ {0, 0, 'l', NULL},\r
+ {0, 0, 'c', NULL},\r
+ {0, 0, 'r', NULL},\r
+};\r
+\r
+static int dcache[NDCACHE];\r
+static opty_t *freq_table;\r
+static int freq_table_size;\r
+static char *homedir;\r
+static int *ilist;\r
+static int ilistlen;\r
+static off64_t maxfsize;\r
+static int namerand;\r
+static int nameseq;\r
+static int nops;\r
+static int operations = 1;\r
+static int procid;\r
+static int rtpct;\r
+static unsigned long seed = 0;\r
+static ino_t top_ino;\r
+static int verbose = 0;\r
+\r
+static int delete_tree(const char *path);\r
+static void add_to_flist(int fd, int it, int parent);\r
+static void append_pathname(pathname_t *name, const char *str);\r
+static void check_cwd(void);\r
+static int creat_path(pathname_t *name, mode_t mode);\r
+static void dcache_enter(int dirid, int slot);\r
+static void dcache_init(void);\r
+static fent_t *dcache_lookup(int dirid);\r
+static void dcache_purge(int dirid);\r
+static void del_from_flist(int ft, int slot);\r
+static void doproc(void);\r
+static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep);\r
+static void fix_parent(int oldid, int newid);\r
+static void free_pathname(pathname_t *name);\r
+static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v);\r
+static int get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v);\r
+static void init_pathname(pathname_t *name);\r
+static int link_path(pathname_t *name1, pathname_t *name2);\r
+static int lstat64_path(pathname_t *name, REDSTAT *sbuf);\r
+static void make_freq_table(void);\r
+static int mkdir_path(pathname_t *name, mode_t mode);\r
+static void namerandpad(int id, char *buf, int len);\r
+static int open_path(pathname_t *name, int oflag);\r
+static DIR *opendir_path(pathname_t *name);\r
+static int rename_path(pathname_t *name1, pathname_t *name2);\r
+static int rmdir_path(pathname_t *name);\r
+static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname);\r
+static int stat64_path(pathname_t *name, REDSTAT *sbuf);\r
+static int truncate64_path(pathname_t *name, off64_t length);\r
+static int unlink_path(pathname_t *name);\r
+static void usage(const char *progname);\r
+\r
+\r
+/** @brief Parse parameters for fsstress.\r
+\r
+ @param argc The number of arguments from main().\r
+ @param argv The vector of arguments from main().\r
+ @param pParam Populated with the fsstress parameters.\r
+ @param pbVolNum If non-NULL, populated with the volume number.\r
+ @param ppszDevice If non-NULL, populated with the device name argument or\r
+ NULL if no device argument is provided.\r
+\r
+ @return The result of parsing the parameters.\r
+*/\r
+PARAMSTATUS FsstressParseParams(\r
+ int argc,\r
+ char *argv[],\r
+ FSSTRESSPARAM *pParam,\r
+ uint8_t *pbVolNum,\r
+ const char **ppszDevice)\r
+{\r
+ int c;\r
+ uint8_t bVolNum;\r
+ const REDOPTION aLongopts[] =\r
+ {\r
+ { "no-cleanup", red_no_argument, NULL, 'c' },\r
+ { "loops", red_required_argument, NULL, 'l' },\r
+ { "nops", red_required_argument, NULL, 'n' },\r
+ { "namepad", red_no_argument, NULL, 'r' },\r
+ { "seed", red_required_argument, NULL, 's' },\r
+ { "verbose", red_no_argument, NULL, 'v' },\r
+ { "dev", red_required_argument, NULL, 'D' },\r
+ { "help", red_no_argument, NULL, 'H' },\r
+ { NULL }\r
+ };\r
+\r
+ /* If run without parameters, treat as a help request.\r
+ */\r
+ if(argc <= 1)\r
+ {\r
+ goto Help;\r
+ }\r
+\r
+ /* Assume no device argument to start with.\r
+ */\r
+ if(ppszDevice != NULL)\r
+ {\r
+ *ppszDevice = NULL;\r
+ }\r
+\r
+ /* Set default parameters.\r
+ */\r
+ FsstressDefaultParams(pParam);\r
+\r
+ while((c = RedGetoptLong(argc, argv, "cl:n:rs:vD:H", aLongopts, NULL)) != -1)\r
+ {\r
+ switch(c)\r
+ {\r
+ case 'c': /* --no-cleanup */\r
+ pParam->fNoCleanup = true;\r
+ break;\r
+ case 'l': /* --loops */\r
+ pParam->ulLoops = RedAtoI(red_optarg);\r
+ break;\r
+ case 'n': /* --nops */\r
+ pParam->ulNops = RedAtoI(red_optarg);\r
+ break;\r
+ case 'r': /* --namepad */\r
+ pParam->fNamePad = true;\r
+ break;\r
+ case 's': /* --seed */\r
+ pParam->ulSeed = RedAtoI(red_optarg);\r
+ break;\r
+ case 'v': /* --verbose */\r
+ pParam->fVerbose = true;\r
+ break;\r
+ case 'D': /* --dev */\r
+ if(ppszDevice != NULL)\r
+ {\r
+ *ppszDevice = red_optarg;\r
+ }\r
+ break;\r
+ case 'H': /* --help */\r
+ goto Help;\r
+ case '?': /* Unknown or ambiguous option */\r
+ case ':': /* Option missing required argument */\r
+ default:\r
+ goto BadOpt;\r
+ }\r
+ }\r
+\r
+ /* RedGetoptLong() has permuted argv to move all non-option arguments to\r
+ the end. We expect to find a volume identifier.\r
+ */\r
+ if(red_optind >= argc)\r
+ {\r
+ RedPrintf("Missing volume argument\n");\r
+ goto BadOpt;\r
+ }\r
+\r
+ bVolNum = RedFindVolumeNumber(argv[red_optind]);\r
+ if(bVolNum == REDCONF_VOLUME_COUNT)\r
+ {\r
+ RedPrintf("Error: \"%s\" is not a valid volume identifier.\n", argv[red_optind]);\r
+ goto BadOpt;\r
+ }\r
+\r
+ if(pbVolNum != NULL)\r
+ {\r
+ *pbVolNum = bVolNum;\r
+ }\r
+\r
+ red_optind++; /* Move past volume parameter. */\r
+ if(red_optind < argc)\r
+ {\r
+ int32_t ii;\r
+\r
+ for(ii = red_optind; ii < argc; ii++)\r
+ {\r
+ RedPrintf("Error: Unexpected command-line argument \"%s\".\n", argv[ii]);\r
+ }\r
+\r
+ goto BadOpt;\r
+ }\r
+\r
+ return PARAMSTATUS_OK;\r
+\r
+ BadOpt:\r
+\r
+ RedPrintf("%s - invalid parameters\n", argv[0U]);\r
+ usage(argv[0U]);\r
+ return PARAMSTATUS_BAD;\r
+\r
+ Help:\r
+\r
+ usage(argv[0U]);\r
+ return PARAMSTATUS_HELP;\r
+}\r
+\r
+\r
+/** @brief Set default fsstress parameters.\r
+\r
+ @param pParam Populated with the default fsstress parameters.\r
+*/\r
+void FsstressDefaultParams(\r
+ FSSTRESSPARAM *pParam)\r
+{\r
+ RedMemSet(pParam, 0U, sizeof(*pParam));\r
+ pParam->ulLoops = 1U;\r
+ pParam->ulNops = 10000U;\r
+}\r
+\r
+\r
+/** @brief Start fsstress.\r
+\r
+ @param pParam fsstress parameters, either from FsstressParseParams() or\r
+ constructed programatically.\r
+\r
+ @return Zero on success, otherwise nonzero.\r
+*/\r
+int FsstressStart(\r
+ const FSSTRESSPARAM *pParam)\r
+{\r
+ char buf[10];\r
+ int fd;\r
+ int i;\r
+ int cleanup;\r
+ int loops;\r
+ int loopcntr = 1;\r
+\r
+ nops = sizeof(ops) / sizeof(ops[0]);\r
+ ops_end = &ops[nops];\r
+\r
+ /* Copy the already-parsed parameters into the traditional variables.\r
+ */\r
+ cleanup = pParam->fNoCleanup ? 1 : 0;\r
+ loops = pParam->ulLoops;\r
+ operations = pParam->ulNops;\r
+ namerand = pParam->fNamePad ? 1 : 0;\r
+ seed = pParam->ulSeed;\r
+ verbose = pParam->fVerbose ? 1 : 0;\r
+\r
+ make_freq_table();\r
+\r
+ while ((loopcntr <= loops) || (loops == 0)) {\r
+ RedSNPrintf(buf, sizeof(buf), "fss%x", getpid());\r
+ fd = creat(buf, 0666);\r
+ maxfsize = (off64_t) MAXFSIZE;\r
+ dcache_init();\r
+ if (!seed) {\r
+ seed = (unsigned long)RedOsClockGetTime();\r
+ RedPrintf("seed = %ld\n", seed);\r
+ }\r
+ close(fd);\r
+ unlink(buf);\r
+ procid = 0;\r
+ doproc();\r
+ if (cleanup == 0) {\r
+ delete_tree("/");\r
+ for (i = 0; i < FT_nft; i++) {\r
+ flist[i].nslots = 0;\r
+ flist[i].nfiles = 0;\r
+ free(flist[i].fents);\r
+ flist[i].fents = NULL;\r
+ }\r
+ }\r
+ loopcntr++;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int delete_tree(const char *path)\r
+{\r
+ REDSTAT sb;\r
+ DIR *dp;\r
+ REDDIRENT *dep;\r
+ char *childpath;\r
+ size_t len;\r
+ int e;\r
+\r
+ e = stat(path, &sb);\r
+ if (e)\r
+ return errno;\r
+\r
+ if (!S_ISDIR(sb.st_mode))\r
+ return unlink(path) ? errno : 0;\r
+\r
+ dp = opendir(path);\r
+ if (dp == NULL)\r
+ return errno;\r
+\r
+ while((dep = readdir(dp)) != NULL) {\r
+ len = strlen(path) + 1 + strlen(dep->d_name) + 1;\r
+ childpath = malloc(len);\r
+\r
+ strcpy(childpath, path);\r
+ if (childpath[strlen(childpath) - 1] != '/')\r
+ strcat(childpath, "/");\r
+ strcat(childpath, dep->d_name);\r
+\r
+ e = delete_tree(childpath);\r
+\r
+ free(childpath);\r
+\r
+ if (e)\r
+ break;\r
+ }\r
+\r
+ if (e == 0 && strcmp(path, "/") != 0) {\r
+ e = rmdir(path) ? errno : 0;\r
+ }\r
+ closedir(dp);\r
+ return e;\r
+}\r
+\r
+static void add_to_flist(int ft, int id, int parent)\r
+{\r
+ fent_t *fep;\r
+ flist_t *ftp;\r
+\r
+ ftp = &flist[ft];\r
+ if (ftp->nfiles == ftp->nslots) {\r
+ ftp->nslots += FLIST_SLOT_INCR;\r
+ ftp->fents = realloc(ftp->fents, ftp->nslots * sizeof(fent_t));\r
+ }\r
+ fep = &ftp->fents[ftp->nfiles++];\r
+ fep->id = id;\r
+ fep->parent = parent;\r
+}\r
+\r
+static void append_pathname(pathname_t *name, const char *str)\r
+{\r
+ int len;\r
+\r
+ len = strlen(str);\r
+#ifdef DEBUG\r
+ if (len && *str == '/' && name->len == 0) {\r
+ RedPrintf("fsstress: append_pathname failure\n");\r
+ chdir(homedir);\r
+ abort();\r
+\r
+ }\r
+#endif\r
+ name->path = realloc(name->path, name->len + 1 + len);\r
+ strcpy(&name->path[name->len], str);\r
+ name->len += len;\r
+}\r
+\r
+static void check_cwd(void)\r
+{\r
+#ifdef DEBUG\r
+ REDSTAT statbuf;\r
+\r
+ if (stat64(".", &statbuf) == 0 && statbuf.st_ino == top_ino)\r
+ return;\r
+ chdir(homedir);\r
+ RedPrintf("fsstress: check_cwd failure\n");\r
+ abort();\r
+\r
+#endif\r
+}\r
+\r
+static int creat_path(pathname_t *name, mode_t mode)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = creat(name->path, mode);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = creat_path(&newname, mode);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static void dcache_enter(int dirid, int slot)\r
+{\r
+ dcache[dirid % NDCACHE] = slot;\r
+}\r
+\r
+static void dcache_init(void)\r
+{\r
+ int i;\r
+\r
+ for (i = 0; i < NDCACHE; i++)\r
+ dcache[i] = -1;\r
+}\r
+\r
+static fent_t *dcache_lookup(int dirid)\r
+{\r
+ fent_t *fep;\r
+ int i;\r
+\r
+ i = dcache[dirid % NDCACHE];\r
+ if (i >= 0 && (fep = &flist[FT_DIR].fents[i])->id == dirid)\r
+ return fep;\r
+ return NULL;\r
+}\r
+\r
+static void dcache_purge(int dirid)\r
+{\r
+ int *dcp;\r
+\r
+ dcp = &dcache[dirid % NDCACHE];\r
+ if (*dcp >= 0 && flist[FT_DIR].fents[*dcp].id == dirid)\r
+ *dcp = -1;\r
+}\r
+\r
+static void del_from_flist(int ft, int slot)\r
+{\r
+ flist_t *ftp;\r
+\r
+ ftp = &flist[ft];\r
+ if (ft == FT_DIR)\r
+ dcache_purge(ftp->fents[slot].id);\r
+ if (slot != ftp->nfiles - 1) {\r
+ if (ft == FT_DIR)\r
+ dcache_purge(ftp->fents[ftp->nfiles - 1].id);\r
+ ftp->fents[slot] = ftp->fents[--ftp->nfiles];\r
+ } else\r
+ ftp->nfiles--;\r
+}\r
+\r
+static fent_t *dirid_to_fent(int dirid)\r
+{\r
+ fent_t *efep;\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+\r
+ if ((fep = dcache_lookup(dirid)))\r
+ return fep;\r
+ flp = &flist[FT_DIR];\r
+ for (fep = flp->fents, efep = &fep[flp->nfiles]; fep < efep; fep++) {\r
+ if (fep->id == dirid) {\r
+ dcache_enter(dirid, (int)(fep - flp->fents));\r
+ return fep;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+static void doproc(void)\r
+{\r
+ REDSTAT statbuf;\r
+ char buf[10];\r
+ int opno;\r
+ opdesc_t *p;\r
+\r
+ RedSNPrintf(buf, sizeof(buf), "p%x", procid);\r
+ (void)mkdir(buf);\r
+ if (chdir(buf) < 0 || stat64(".", &statbuf) < 0) {\r
+ perror(buf);\r
+ _exit(1);\r
+ }\r
+ top_ino = statbuf.st_ino;\r
+ homedir = getcwd(NULL, 0);\r
+ seed += procid;\r
+ srandom(seed);\r
+ if (namerand)\r
+ namerand = random();\r
+ for (opno = 0; opno < operations; opno++) {\r
+ p = &ops[freq_table[random() % freq_table_size]];\r
+ if ((unsigned long)p->func < 4096)\r
+ abort();\r
+\r
+ p->func(opno, random());\r
+ }\r
+ free(homedir);\r
+}\r
+\r
+static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ int i;\r
+ fent_t *pfep;\r
+\r
+ if (fep == NULL)\r
+ return;\r
+ if (fep->parent != -1) {\r
+ pfep = dirid_to_fent(fep->parent);\r
+ fent_to_name(name, &flist[FT_DIR], pfep);\r
+ append_pathname(name, "/");\r
+ }\r
+ i = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, fep->id);\r
+ namerandpad(fep->id, buf, i);\r
+ append_pathname(name, buf);\r
+}\r
+\r
+static void fix_parent(int oldid, int newid)\r
+{\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+ int i;\r
+ int j;\r
+\r
+ for (i = 0, flp = flist; i < FT_nft; i++, flp++) {\r
+ for (j = 0, fep = flp->fents; j < flp->nfiles; j++, fep++) {\r
+ if (fep->parent == oldid)\r
+ fep->parent = newid;\r
+ }\r
+ }\r
+}\r
+\r
+static void free_pathname(pathname_t *name)\r
+{\r
+ if (name->path) {\r
+ free(name->path);\r
+ name->path = NULL;\r
+ name->len = 0;\r
+ }\r
+}\r
+\r
+static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ flist_t *flp;\r
+ int id;\r
+ int j;\r
+ int len;\r
+\r
+ flp = &flist[ft];\r
+ len = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, id = nameseq++);\r
+ namerandpad(id, buf, len);\r
+ if (fep) {\r
+ fent_to_name(name, &flist[FT_DIR], fep);\r
+ append_pathname(name, "/");\r
+ }\r
+ append_pathname(name, buf);\r
+ *idp = id;\r
+ *v = verbose;\r
+ for (j = 0; !*v && j < ilistlen; j++) {\r
+ if (ilist[j] == id) {\r
+ *v = 1;\r
+ break;\r
+ }\r
+ }\r
+ return 1;\r
+}\r
+\r
+static int\r
+get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v)\r
+{\r
+ int c;\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+ int i;\r
+ int j;\r
+ int x;\r
+\r
+ for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) {\r
+ if (which & (1 << i))\r
+ c += flp->nfiles;\r
+ }\r
+ if (c == 0) {\r
+ if (flpp)\r
+ *flpp = NULL;\r
+ if (fepp)\r
+ *fepp = NULL;\r
+ *v = verbose;\r
+ return 0;\r
+ }\r
+ x = (int)(r % c);\r
+ for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) {\r
+ if (which & (1 << i)) {\r
+ if (x < c + flp->nfiles) {\r
+ fep = &flp->fents[x - c];\r
+ if (name)\r
+ fent_to_name(name, flp, fep);\r
+ if (flpp)\r
+ *flpp = flp;\r
+ if (fepp)\r
+ *fepp = fep;\r
+ *v = verbose;\r
+ for (j = 0; !*v && j < ilistlen; j++) {\r
+ if (ilist[j] == fep->id) {\r
+ *v = 1;\r
+ break;\r
+ }\r
+ }\r
+ return 1;\r
+ }\r
+ c += flp->nfiles;\r
+ }\r
+ }\r
+#ifdef DEBUG\r
+ RedPrintf("fsstress: get_fname failure\n");\r
+ abort();\r
+#endif\r
+ return -1;\r
+\r
+}\r
+\r
+static void init_pathname(pathname_t *name)\r
+{\r
+ name->len = 0;\r
+ name->path = NULL;\r
+}\r
+\r
+static int link_path(pathname_t *name1, pathname_t *name2)\r
+{\r
+ char buf1[MAXNAMELEN];\r
+ char buf2[MAXNAMELEN];\r
+ int down1;\r
+ pathname_t newname1;\r
+ pathname_t newname2;\r
+ int rval;\r
+\r
+ rval = link(name1->path, name2->path);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name1, buf1, &newname1);\r
+ separate_pathname(name2, buf2, &newname2);\r
+ if (strcmp(buf1, buf2) == 0) {\r
+ if (chdir(buf1) == 0) {\r
+ rval = link_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ } else {\r
+ if (strcmp(buf1, "..") == 0)\r
+ down1 = 0;\r
+ else if (strcmp(buf2, "..") == 0)\r
+ down1 = 1;\r
+ else if (strlen(buf1) == 0)\r
+ down1 = 0;\r
+ else if (strlen(buf2) == 0)\r
+ down1 = 1;\r
+ else\r
+ down1 = MAX(newname1.len, 3 + name2->len) <=\r
+ MAX(3 + name1->len, newname2.len);\r
+ if (down1) {\r
+ free_pathname(&newname2);\r
+ append_pathname(&newname2, "../");\r
+ append_pathname(&newname2, name2->path);\r
+ if (chdir(buf1) == 0) {\r
+ rval = link_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ } else {\r
+ free_pathname(&newname1);\r
+ append_pathname(&newname1, "../");\r
+ append_pathname(&newname1, name1->path);\r
+ if (chdir(buf2) == 0) {\r
+ rval = link_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ }\r
+ }\r
+ free_pathname(&newname1);\r
+ free_pathname(&newname2);\r
+ return rval;\r
+}\r
+\r
+static int lstat64_path(pathname_t *name, REDSTAT *sbuf)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = lstat64(name->path, sbuf);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = lstat64_path(&newname, sbuf);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static void make_freq_table(void)\r
+{\r
+ int f;\r
+ int i;\r
+ opdesc_t *p;\r
+\r
+ for (p = ops, f = 0; p < ops_end; p++)\r
+ f += p->freq;\r
+ freq_table = malloc(f * sizeof(*freq_table));\r
+ freq_table_size = f;\r
+ for (p = ops, i = 0; p < ops_end; p++) {\r
+ for (f = 0; f < p->freq; f++, i++)\r
+ freq_table[i] = p->op;\r
+ }\r
+}\r
+\r
+static int mkdir_path(pathname_t *name, mode_t mode)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = mkdir(name->path);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = mkdir_path(&newname, mode);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static void namerandpad(int id, char *buf, int len)\r
+{\r
+ int bucket;\r
+ static int buckets[8] = {0};\r
+ static int bucket_count = 0;\r
+ int bucket_value;\r
+ int i;\r
+ int padlen;\r
+ int padmod;\r
+\r
+ if (namerand == 0)\r
+ return;\r
+\r
+ /* buckets[] used to be a statically initialized array with the following\r
+ initializer: { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN - 1 }\r
+\r
+ The problem is that with Reliance Edge, the maximum name length might be\r
+ less than 128. So the below code populates buckets[] in a similar\r
+ fashion but avoids name lengths longer than the maximum. For example,\r
+ if the max name is 20, the resulting array is { 2, 4, 8, 16, 20 }.\r
+ */\r
+ if (!bucket_count) {\r
+ bucket_count = sizeof(buckets) / sizeof(buckets[0]);\r
+ bucket_value = 2;\r
+ for (i = 0; i < bucket_count; i++) {\r
+ if (bucket_value > 128 || bucket_value >= (int)MAXNAMELEN - 1)\r
+ break;\r
+ buckets[i] = bucket_value;\r
+ bucket_value *= 2;\r
+ }\r
+ if (i < bucket_count) {\r
+ buckets[i] = MAXNAMELEN - 1;\r
+ i++;\r
+ }\r
+ bucket_count = i;\r
+ }\r
+\r
+ bucket = (id ^ namerand) % bucket_count;\r
+ padmod = buckets[bucket] + 1 - len;\r
+ if (padmod <= 0)\r
+ return;\r
+ padlen = (id ^ namerand) % padmod;\r
+ if (padlen) {\r
+ memset(&buf[len], 'X', padlen);\r
+ buf[len + padlen] = '\0';\r
+ }\r
+}\r
+\r
+static int open_path(pathname_t *name, int oflag)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = open(name->path, oflag);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = open_path(&newname, oflag);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static DIR *opendir_path(pathname_t *name)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ DIR *rval;\r
+\r
+ rval = opendir(name->path);\r
+ if (rval || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = opendir_path(&newname);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static int rename_path(pathname_t *name1, pathname_t *name2)\r
+{\r
+ char buf1[MAXNAMELEN];\r
+ char buf2[MAXNAMELEN];\r
+ int down1;\r
+ pathname_t newname1;\r
+ pathname_t newname2;\r
+ int rval;\r
+\r
+ rval = rename(name1->path, name2->path);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name1, buf1, &newname1);\r
+ separate_pathname(name2, buf2, &newname2);\r
+ if (strcmp(buf1, buf2) == 0) {\r
+ if (chdir(buf1) == 0) {\r
+ rval = rename_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ } else {\r
+ if (strcmp(buf1, "..") == 0)\r
+ down1 = 0;\r
+ else if (strcmp(buf2, "..") == 0)\r
+ down1 = 1;\r
+ else if (strlen(buf1) == 0)\r
+ down1 = 0;\r
+ else if (strlen(buf2) == 0)\r
+ down1 = 1;\r
+ else\r
+ down1 = MAX(newname1.len, 3 + name2->len) <=\r
+ MAX(3 + name1->len, newname2.len);\r
+ if (down1) {\r
+ free_pathname(&newname2);\r
+ append_pathname(&newname2, "../");\r
+ append_pathname(&newname2, name2->path);\r
+ if (chdir(buf1) == 0) {\r
+ rval = rename_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ } else {\r
+ free_pathname(&newname1);\r
+ append_pathname(&newname1, "../");\r
+ append_pathname(&newname1, name1->path);\r
+ if (chdir(buf2) == 0) {\r
+ rval = rename_path(&newname1, &newname2);\r
+ chdir("..");\r
+ }\r
+ }\r
+ }\r
+ free_pathname(&newname1);\r
+ free_pathname(&newname2);\r
+ return rval;\r
+}\r
+\r
+static int rmdir_path(pathname_t *name)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = rmdir(name->path);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = rmdir_path(&newname);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname)\r
+{\r
+ char *slash;\r
+\r
+ init_pathname(newname);\r
+ slash = strchr(name->path, '/');\r
+ if (slash == NULL) {\r
+ buf[0] = '\0';\r
+ return;\r
+ }\r
+ *slash = '\0';\r
+ strcpy(buf, name->path);\r
+ *slash = '/';\r
+ append_pathname(newname, slash + 1);\r
+}\r
+\r
+static int stat64_path(pathname_t *name, REDSTAT *sbuf)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = stat64(name->path, sbuf);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = stat64_path(&newname, sbuf);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static int truncate64_path(pathname_t *name, off64_t length)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = truncate64(name->path, length);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = truncate64_path(&newname, length);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static int unlink_path(pathname_t *name)\r
+{\r
+ char buf[MAXNAMELEN];\r
+ pathname_t newname;\r
+ int rval;\r
+\r
+ rval = unlink(name->path);\r
+ if (rval >= 0 || errno != RED_ENAMETOOLONG)\r
+ return rval;\r
+ separate_pathname(name, buf, &newname);\r
+ if (chdir(buf) == 0) {\r
+ rval = unlink_path(&newname);\r
+ chdir("..");\r
+ }\r
+ free_pathname(&newname);\r
+ return rval;\r
+}\r
+\r
+static void usage(const char *progname)\r
+{\r
+ RedPrintf("usage: %s VolumeID [Options]\n", progname);\r
+ RedPrintf("File system stress test.\n\n");\r
+ RedPrintf("Where:\n");\r
+ RedPrintf(" VolumeID\n");\r
+ RedPrintf(" A volume number (e.g., 2) or a volume path prefix (e.g., VOL1: or /data)\n");\r
+ RedPrintf(" of the volume to test.\n");\r
+ RedPrintf("And 'Options' are any of the following:\n");\r
+ RedPrintf(" --no-cleanup, -c\n");\r
+ RedPrintf(" Specifies not to remove files (cleanup) after execution\n");\r
+ RedPrintf(" --loops=count, -l count\n");\r
+ RedPrintf(" Specifies the number of times the entire test should loop. Use 0 for\n");\r
+ RedPrintf(" infinite. Default 1.\n");\r
+ RedPrintf(" --nops=count, -n count\n");\r
+ RedPrintf(" Specifies the number of operations to run (default 10000).\n");\r
+ RedPrintf(" --namepad, -r\n");\r
+ RedPrintf(" Specifies to use random name padding (resulting in longer names).\n");\r
+ RedPrintf(" --seed=value, -s value\n");\r
+ RedPrintf(" Specifies the seed for the random number generator (default timestamp).\n");\r
+ RedPrintf(" --verbose, -v\n");\r
+ RedPrintf(" Specifies verbose mode (without this, test is very quiet).\n");\r
+ RedPrintf(" --dev=devname, -D devname\n");\r
+ RedPrintf(" Specifies the device name. This is typically only meaningful when\n");\r
+ RedPrintf(" running the test on a host machine. This can be \"ram\" to test on a RAM\n");\r
+ RedPrintf(" disk, the path and name of a file disk (e.g., red.bin); or an OS-specific\n");\r
+ RedPrintf(" reference to a device (on Windows, a drive letter like G: or a device name\n");\r
+ RedPrintf(" like \\\\.\\PhysicalDrive7).\n");\r
+ RedPrintf(" --help, -H\n");\r
+ RedPrintf(" Prints this usage text and exits.\n\n");\r
+ RedPrintf("Warning: This test will format the volume -- destroying all existing data.\n\n");\r
+}\r
+\r
+static void creat_f(int opno, long r)\r
+{\r
+ int e;\r
+ int e1;\r
+ pathname_t f;\r
+ int fd;\r
+ fent_t *fep;\r
+ int id;\r
+ int parid;\r
+ int type;\r
+ int v;\r
+ int v1;\r
+ int esz = 0;\r
+\r
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v1))\r
+ parid = -1;\r
+ else\r
+ parid = fep->id;\r
+ init_pathname(&f);\r
+ type = rtpct ? ((int)(random() % 100) > rtpct ? FT_REG : FT_RTF) : FT_REG;\r
+ e = generate_fname(fep, type, &f, &id, &v);\r
+ v |= v1;\r
+ if (!e) {\r
+ if (v) {\r
+ fent_to_name(&f, &flist[FT_DIR], fep);\r
+ RedPrintf("%d/%d: creat - no filename from %s\n",\r
+ procid, opno, f.path);\r
+ }\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ fd = creat_path(&f, 0666);\r
+ e = fd < 0 ? errno : 0;\r
+ e1 = 0;\r
+ check_cwd();\r
+ esz = 0;\r
+ if (fd >= 0) {\r
+ add_to_flist(type, id, parid);\r
+ close(fd);\r
+ }\r
+ if (v)\r
+ RedPrintf("%d/%d: creat %s x:%d %d %d\n", procid, opno, f.path,\r
+ esz, e, e1);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void fdatasync_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ int fd;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: fdatasync - no filename\n",\r
+ procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ fd = open_path(&f, O_WRONLY);\r
+ e = fd < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (fd < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: fdatasync - open %s failed %d\n",\r
+ procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = fdatasync(fd) < 0 ? errno : 0;\r
+ if (v)\r
+ RedPrintf("%d/%d: fdatasync %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ close(fd);\r
+}\r
+\r
+static void fsync_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ int fd;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: fsync - no filename\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ fd = open_path(&f, O_WRONLY);\r
+ e = fd < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (fd < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: fsync - open %s failed %d\n",\r
+ procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = fsync(fd) < 0 ? errno : 0;\r
+ if (v)\r
+ RedPrintf("%d/%d: fsync %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ close(fd);\r
+}\r
+\r
+static void getdents_f(int opno, long r)\r
+{\r
+ DIR *dir;\r
+ pathname_t f;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_DIRm, r, &f, NULL, NULL, &v))\r
+ append_pathname(&f, ".");\r
+ dir = opendir_path(&f);\r
+ check_cwd();\r
+ if (dir == NULL) {\r
+ if (v)\r
+ RedPrintf("%d/%d: getdents - can't open %s\n",\r
+ procid, opno, f.path);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ while (readdir64(dir) != NULL)\r
+ continue;\r
+ if (v)\r
+ RedPrintf("%d/%d: getdents %s 0\n", procid, opno, f.path);\r
+ free_pathname(&f);\r
+ closedir(dir);\r
+}\r
+\r
+static void link_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+ int id;\r
+ pathname_t l;\r
+ int parid;\r
+ int v;\r
+ int v1;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_NOTDIR, r, &f, &flp, NULL, &v1)) {\r
+ if (v1)\r
+ RedPrintf("%d/%d: link - no file\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ if (!get_fname(FT_DIRm, random(), NULL, NULL, &fep, &v))\r
+ parid = -1;\r
+ else\r
+ parid = fep->id;\r
+ v |= v1;\r
+ init_pathname(&l);\r
+ e = generate_fname(fep, (int)(flp - flist), &l, &id, &v1);\r
+ v |= v1;\r
+ if (!e) {\r
+ if (v) {\r
+ fent_to_name(&l, &flist[FT_DIR], fep);\r
+ RedPrintf("%d/%d: link - no filename from %s\n",\r
+ procid, opno, l.path);\r
+ }\r
+ free_pathname(&l);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = link_path(&f, &l) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e == 0)\r
+ add_to_flist((int)(flp - flist), id, parid);\r
+ if (v)\r
+ RedPrintf("%d/%d: link %s %s %d\n", procid, opno, f.path, l.path,\r
+ e);\r
+ free_pathname(&l);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void mkdir_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ fent_t *fep;\r
+ int id;\r
+ int parid;\r
+ int v;\r
+ int v1;\r
+\r
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v))\r
+ parid = -1;\r
+ else\r
+ parid = fep->id;\r
+ init_pathname(&f);\r
+ e = generate_fname(fep, FT_DIR, &f, &id, &v1);\r
+ v |= v1;\r
+ if (!e) {\r
+ if (v) {\r
+ fent_to_name(&f, &flist[FT_DIR], fep);\r
+ RedPrintf("%d/%d: mkdir - no filename from %s\n",\r
+ procid, opno, f.path);\r
+ }\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = mkdir_path(&f, 0777) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e == 0)\r
+ add_to_flist(FT_DIR, id, parid);\r
+ if (v)\r
+ RedPrintf("%d/%d: mkdir %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void read_f(int opno, long r)\r
+{\r
+ char *buf;\r
+ int e;\r
+ pathname_t f;\r
+ int fd;\r
+ uint32_t len;\r
+ __int64_t lr;\r
+ off64_t off;\r
+ REDSTAT stb;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: read - no filename\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ fd = open_path(&f, O_RDONLY);\r
+ e = fd < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (fd < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: read - open %s failed %d\n",\r
+ procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ if (fstat64(fd, &stb) < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: read - fstat64 %s failed %d\n",\r
+ procid, opno, f.path, errno);\r
+ free_pathname(&f);\r
+ close(fd);\r
+ return;\r
+ }\r
+ if (stb.st_size == 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: read - %s zero size\n", procid, opno,\r
+ f.path);\r
+ free_pathname(&f);\r
+ close(fd);\r
+ return;\r
+ }\r
+ lr = ((__int64_t) random() << 32) + random();\r
+ off = (off64_t) (lr % stb.st_size);\r
+ lseek64(fd, off, SEEK_SET);\r
+ len = (random() % (getpagesize() * 4)) + 1;\r
+ buf = malloc(len);\r
+ e = read(fd, buf, len) < 0 ? errno : 0;\r
+ free(buf);\r
+ if (v)\r
+ RedPrintf("%d/%d: read %s [%lld,%ld] %d\n",\r
+ procid, opno, f.path, (long long)off, (long int)len, e);\r
+ free_pathname(&f);\r
+ close(fd);\r
+}\r
+\r
+static void rename_f(int opno, long r)\r
+{\r
+ fent_t *dfep;\r
+ int e;\r
+ pathname_t f;\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+ int id;\r
+ pathname_t newf;\r
+ int oldid;\r
+ int parid;\r
+ int v;\r
+ int v1;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_ANYm, r, &f, &flp, &fep, &v1)) {\r
+ if (v1)\r
+ RedPrintf("%d/%d: rename - no filename\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ if (!get_fname(FT_DIRm, random(), NULL, NULL, &dfep, &v))\r
+ parid = -1;\r
+ else\r
+ parid = dfep->id;\r
+ v |= v1;\r
+ init_pathname(&newf);\r
+ e = generate_fname(dfep, (int)(flp - flist), &newf, &id, &v1);\r
+ v |= v1;\r
+ if (!e) {\r
+ if (v) {\r
+ fent_to_name(&f, &flist[FT_DIR], dfep);\r
+ RedPrintf("%d/%d: rename - no filename from %s\n",\r
+ procid, opno, f.path);\r
+ }\r
+ free_pathname(&newf);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = rename_path(&f, &newf) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e == 0) {\r
+ if (flp - flist == FT_DIR) {\r
+ oldid = fep->id;\r
+ fix_parent(oldid, id);\r
+ }\r
+ del_from_flist((int)(flp - flist), (int)(fep - flp->fents));\r
+ add_to_flist((int)(flp - flist), id, parid);\r
+ }\r
+ if (v)\r
+ RedPrintf("%d/%d: rename %s to %s %d\n", procid, opno, f.path,\r
+ newf.path, e);\r
+ free_pathname(&newf);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void rmdir_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ fent_t *fep;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_DIRm, r, &f, NULL, &fep, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: rmdir - no directory\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = rmdir_path(&f) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e == 0)\r
+ del_from_flist(FT_DIR, (int)(fep - flist[FT_DIR].fents));\r
+ if (v)\r
+ RedPrintf("%d/%d: rmdir %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void stat_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ REDSTAT stb;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: stat - no entries\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = lstat64_path(&f, &stb) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (v)\r
+ RedPrintf("%d/%d: stat %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void truncate_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ __int64_t lr;\r
+ off64_t off;\r
+ REDSTAT stb;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: truncate - no filename\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = stat64_path(&f, &stb) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e > 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: truncate - stat64 %s failed %d\n",\r
+ procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ lr = ((__int64_t) random() << 32) + random();\r
+ off = lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE);\r
+ off %= maxfsize;\r
+ e = truncate64_path(&f, off) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (v)\r
+ RedPrintf("%d/%d: truncate %s %lld %d\n", procid, opno, f.path,\r
+ (long long)off, e);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void unlink_f(int opno, long r)\r
+{\r
+ int e;\r
+ pathname_t f;\r
+ fent_t *fep;\r
+ flist_t *flp;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_NOTDIR, r, &f, &flp, &fep, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: unlink - no file\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ e = unlink_path(&f) < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (e == 0)\r
+ del_from_flist((int)(flp - flist), (int)(fep - flp->fents));\r
+ if (v)\r
+ RedPrintf("%d/%d: unlink %s %d\n", procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+}\r
+\r
+static void write_f(int opno, long r)\r
+{\r
+ char *buf;\r
+ int e;\r
+ pathname_t f;\r
+ int fd;\r
+ uint32_t len;\r
+ __int64_t lr;\r
+ off64_t off;\r
+ REDSTAT stb;\r
+ int v;\r
+\r
+ init_pathname(&f);\r
+ if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) {\r
+ if (v)\r
+ RedPrintf("%d/%d: write - no filename\n", procid, opno);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ fd = open_path(&f, O_WRONLY);\r
+ e = fd < 0 ? errno : 0;\r
+ check_cwd();\r
+ if (fd < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: write - open %s failed %d\n",\r
+ procid, opno, f.path, e);\r
+ free_pathname(&f);\r
+ return;\r
+ }\r
+ if (fstat64(fd, &stb) < 0) {\r
+ if (v)\r
+ RedPrintf("%d/%d: write - fstat64 %s failed %d\n",\r
+ procid, opno, f.path, errno);\r
+ free_pathname(&f);\r
+ close(fd);\r
+ return;\r
+ }\r
+ lr = ((__int64_t) random() << 32) + random();\r
+ off = (off64_t) (lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));\r
+ off %= maxfsize;\r
+ lseek64(fd, off, SEEK_SET);\r
+ len = (random() % (getpagesize() * 4)) + 1;\r
+ buf = malloc(len);\r
+ memset(buf, nameseq & 0xff, len);\r
+ e = write(fd, buf, len) < 0 ? errno : 0;\r
+ free(buf);\r
+ if (v)\r
+ RedPrintf("%d/%d: write %s [%lld,%ld] %d\n",\r
+ procid, opno, f.path, (long long)off, (long int)len, e);\r
+ free_pathname(&f);\r
+ close(fd);\r
+}\r
+\r
+\r
+#if REDCONF_CHECKER == 1\r
+static void check_f(int opno, long r)\r
+{\r
+ int32_t ret;\r
+ const char *pszVolume = gpRedVolConf->pszPathPrefix;\r
+\r
+ (void)r;\r
+\r
+ errno = 0;\r
+\r
+ ret = red_transact(pszVolume);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = red_umount(pszVolume);\r
+\r
+ if(ret == 0)\r
+ {\r
+ int32_t ret2;\r
+\r
+ errno = -RedCoreVolCheck();\r
+ if(errno != 0)\r
+ {\r
+ ret = -1;\r
+ }\r
+\r
+ ret2 = red_mount(pszVolume);\r
+\r
+ if(ret == 0)\r
+ {\r
+ ret = ret2;\r
+ }\r
+\r
+ if(ret2 != 0)\r
+ {\r
+ exit(1);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (verbose)\r
+ {\r
+ RedPrintf("%d/%d: check %s %d\n", procid, opno, pszVolume, errno);\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+#endif /* FSSTRESS_SUPPORTED */\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Defines macros which make the Reliance Edge POSIX-like API look more\r
+ like the actual POSIX API.\r
+\r
+ This file is intended for porting POSIX file system tests; it is not\r
+ intended for application use.\r
+*/\r
+#ifndef REDPOSIXCOMPAT_H\r
+#define REDPOSIXCOMPAT_H\r
+\r
+\r
+#ifndef assert\r
+#define assert(x) REDASSERT(x)\r
+#endif\r
+\r
+\r
+#undef O_RDONLY\r
+#undef O_WRONLY\r
+#undef O_RDWR\r
+#undef O_APPEND\r
+#undef O_CREAT\r
+#undef O_EXCL\r
+#undef O_TRUNC\r
+#define O_RDONLY RED_O_RDONLY\r
+#define O_WRONLY RED_O_WRONLY\r
+#define O_RDWR RED_O_RDWR\r
+#define O_APPEND RED_O_APPEND\r
+#define O_CREAT RED_O_CREAT\r
+#define O_EXCL RED_O_EXCL\r
+#define O_TRUNC RED_O_TRUNC\r
+\r
+#undef SEEK_SET\r
+#undef SEEK_CUR\r
+#undef SEEK_END\r
+#define SEEK_SET RED_SEEK_SET\r
+#define SEEK_CUR RED_SEEK_CUR\r
+#define SEEK_END RED_SEEK_END\r
+\r
+/* Old-fashioned Linux seek names.\r
+*/\r
+#undef L_SET\r
+#undef L_INCR\r
+#undef L_XTND\r
+#define L_SET SEEK_SET\r
+#define L_INCR SEEK_CUR\r
+#define L_XTND SEEK_END\r
+\r
+#undef S_IFDIR\r
+#undef S_IFREG\r
+#undef S_ISDIR\r
+#undef S_ISREG\r
+#define S_IFDIR RED_S_IFDIR\r
+#define S_IFREG RED_S_IFREG\r
+#define S_ISDIR(m) RED_S_ISDIR(m)\r
+#define S_ISREG(m) RED_S_ISREG(m)\r
+\r
+#undef ST_RDONLY\r
+#undef ST_NOSUID\r
+#define ST_RDONLY RED_ST_RDONLY\r
+#define ST_NOSUID RED_ST_NOSUID\r
+\r
+#undef open\r
+#undef creat\r
+#undef unlink\r
+#undef mkdir\r
+#undef rmdir\r
+#undef rename\r
+#undef link\r
+#undef close\r
+#undef read\r
+#undef write\r
+#undef fsync\r
+#undef fdatasync\r
+#undef lseek\r
+#undef ftruncate\r
+#undef fstat\r
+#undef opendir\r
+#undef readdir\r
+#undef rewinddir\r
+#undef closedir\r
+#define open(path, oflag) red_open(path, oflag)\r
+#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC)\r
+#define unlink(path) red_unlink(path)\r
+#define mkdir(path) red_mkdir(path)\r
+#define rmdir(path) red_rmdir(path)\r
+#define rename(old, new) red_rename(old, new)\r
+#define link(path, hardlink) red_link(path, hardlink)\r
+#define close(fd) red_close(fd)\r
+#define read(fd, buf, len) red_read(fd, buf, len)\r
+#define write(fd, buf, len) red_write(fd, buf, len)\r
+#define fsync(fd) red_fsync(fd)\r
+#define fdatasync(fd) fsync(fd)\r
+#define lseek(fd, offset, whence) red_lseek(fd, offset, whence)\r
+#define lseek64(fd, offset, whence) lseek(fd, offset, whence)\r
+#define ftruncate(fd, size) red_ftruncate(fd, size)\r
+#define fstat(fd, stat) red_fstat(fd, stat)\r
+#define fstat64(fd, stat) fstat(fd, stat)\r
+#define opendir(path) red_opendir(path)\r
+#define readdir(dirp) red_readdir(dirp)\r
+#define readdir64(dirp) readdir(dirp)\r
+#define rewinddir(dirp) red_rewinddir(dirp)\r
+#define closedir(dirp) red_closedir(dirp)\r
+\r
+#undef DIR\r
+#define DIR REDDIR\r
+\r
+#undef errno\r
+#define errno (*(int *)red_errnoptr())\r
+\r
+#undef memcpy\r
+#undef memmove\r
+#undef memset\r
+#undef strlen\r
+#undef strncmp\r
+#undef strcmp\r
+#undef strncpy\r
+#define memcpy(d, s, l) RedMemCpy(d, s, (uint32_t)(l))\r
+#define memmove(d, s, l) RedMemMove(d, s, (uint32_t)(l))\r
+#define memset(d, c, l) RedMemSet(d, (uint8_t)(c), (uint32_t)(l))\r
+#define strlen(s) RedStrLen(s)\r
+#define strncmp(s1, s2, l) RedStrNCmp(s1, s2, (uint32_t)(l))\r
+#define strcmp(s1, s2) RedStrCmp(s1, s2)\r
+#define strncpy(d, s, l) RedStrNCpy(d, s, (uint32_t)(l))\r
+\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements utilities that convert strings to numbers.\r
+*/\r
+#include <redfs.h>\r
+#include <redtestutils.h>\r
+\r
+\r
+#define ISHEXDIGITU(c) (((c) >= 'A') && ((c) <= 'F'))\r
+#define ISHEXDIGITL(c) (((c) >= 'a') && ((c) <= 'f'))\r
+#define ISHEXDIGIT(c) (ISHEXDIGITL(c) || ISHEXDIGITU(c))\r
+\r
+\r
+/** @brief Converts an ASCII number into an int32_t.\r
+\r
+ Converts all decimal digit numbers up to the end of the string or to the\r
+ first non-numerical character.\r
+\r
+ @note This function does *not* ignore leading white space.\r
+\r
+ @param pszNum Pointer to a constant array of characters.\r
+\r
+ @return The integer represented in the string.\r
+*/\r
+int32_t RedAtoI(\r
+ const char *pszNum)\r
+{\r
+ int32_t lValue = 0;\r
+ int32_t lNegative = 1;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ if(pszNum[ulIdx] == '+')\r
+ {\r
+ ulIdx++;\r
+ }\r
+ else if(pszNum[ulIdx] == '-')\r
+ {\r
+ ulIdx++;\r
+ lNegative = -1;\r
+ }\r
+ else\r
+ {\r
+ /* No sign, implicitly positive.\r
+ */\r
+ }\r
+\r
+ while(ISDIGIT(pszNum[ulIdx]))\r
+ {\r
+ lValue *= 10;\r
+ lValue += pszNum[ulIdx] - '0';\r
+ ulIdx++;\r
+ }\r
+\r
+ lValue *= lNegative;\r
+\r
+ return lValue;\r
+}\r
+\r
+\r
+/** @brief Convert a hexadecimal ASCII number into a uint32_t value.\r
+\r
+ The function processes all hex digits up to a NUL-terminator, or to the\r
+ first non-hex character. Only hexadecimal digits are processed, so leading\r
+ white space, or a leading "0x" prefix are not allowed.\r
+\r
+ If pachNum points to an empty string (points to a NUL), this function will\r
+ return NULL, and the value at *pulNum will not be modified.\r
+\r
+ @note This function does not check for overflow. If there are more\r
+ significant digits than can be represented in a uint32_t variable, the\r
+ output is unspecified.\r
+\r
+ @param pachNum A pointer to a constant array of hex characters.\r
+ @param pulNum A pointer to the location in which to store the uint32_t\r
+ result. Upon return, this value will be modified ONLY if\r
+ the function succeeds and the returned pointer is valid (not\r
+ NULL).\r
+\r
+ @return A pointer to the byte following the converted number or NULL to\r
+ indicate failure.\r
+*/\r
+const char *RedHtoUL(\r
+ const char *pszNum,\r
+ uint32_t *pulNum)\r
+{\r
+ uint64_t ullValue;\r
+ const char *pszReturn;\r
+\r
+ pszReturn = RedHtoULL(pszNum, &ullValue);\r
+ if(pszReturn != NULL)\r
+ {\r
+ if(ullValue < UINT32_MAX)\r
+ {\r
+ *pulNum = (uint32_t)ullValue;\r
+ }\r
+ else\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ }\r
+\r
+ return pszReturn;\r
+}\r
+\r
+\r
+/** @brief Convert a hexadecimal ASCII number into a D_UINT64 value.\r
+\r
+ The function processes all hex digits up to a NUL-terminator, or to the\r
+ first non-hex character. Only hexadecimal digits are processed, so leading\r
+ white space, or a leading "0x" prefix are not allowed.\r
+\r
+ If pachNum points to an empty string (points to a NUL), this function will\r
+ return NULL, and the value at *pulNum will not be modified.\r
+\r
+ @note This function does not check for overflow. If there are more\r
+ significant digits than can be represented in a uint64_t variable, the\r
+ output is unspecified.\r
+\r
+ @param pszNum A pointer to a constant array of hex characters.\r
+ @param pullNum A pointer to the location in which to store the uint64_t\r
+ result. Upon return, this value will be modified ONLY if\r
+ the function succeeds and the returned pointer is valid (not\r
+ NULL).\r
+\r
+ @return A pointer to the byte following the converted number, or NULL to\r
+ indicate failure.\r
+*/\r
+const char *RedHtoULL(\r
+ const char *pszNum,\r
+ uint64_t *pullNum)\r
+{\r
+ uint64_t ullValue = 0U;\r
+ const char *pszReturn = NULL;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ REDASSERT(pszNum != NULL);\r
+ REDASSERT(pullNum != NULL);\r
+\r
+ while(pszNum[ulIdx] != '\0')\r
+ {\r
+ char cDigit = pszNum[ulIdx];\r
+\r
+ if(ISDIGIT(cDigit))\r
+ {\r
+ cDigit -= '0';\r
+ }\r
+ else if(ISHEXDIGITU(cDigit))\r
+ {\r
+ cDigit -= ('A' - 10);\r
+ }\r
+ else if(ISHEXDIGITL(cDigit))\r
+ {\r
+ cDigit -= ('a' - 10);\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+\r
+ REDASSERT((ullValue & UINT64_SUFFIX(0xF000000000000000)) == 0U);\r
+\r
+ ullValue <<= 4U;\r
+ ullValue += cDigit;\r
+\r
+ ulIdx++;\r
+ pszReturn = &pszNum[ulIdx];\r
+ }\r
+\r
+ /* Modify the number returned only if we found one or more valid hex\r
+ digits.\r
+ */\r
+ if(pszReturn != NULL)\r
+ {\r
+ *pullNum = ullValue;\r
+ }\r
+\r
+ return pszReturn;\r
+}\r
+\r
+\r
+/** @brief Convert the ASCII number to a uint32_t value.\r
+\r
+ The number may be hex or decimal. Hex numbers must be prefixed by '0x', and\r
+ they may be upper or lower case. The conversion process will stop with the\r
+ first non hex or decimal digit.\r
+\r
+ If the number is negative (the first character is a '-' sign), the value\r
+ will be range checked and returned as the equivalent unsigned value.\r
+\r
+ @note This function will NOT fail for numbers which exceed the size of a\r
+ uint32_t value.\r
+\r
+ @param pszNum A pointer to the ASCII number to convert\r
+ @param pulNum A pointer to the uint32_t location to store the result.\r
+ This value will be modified on return only if the function\r
+ succeeds and the returned pointer is valid (not NULL).\r
+\r
+ @return A pointer to the byte following the converted number, or NULL to\r
+ indicate failure.\r
+*/\r
+const char *RedNtoUL(\r
+ const char *pszNum,\r
+ uint32_t *pulNum)\r
+{\r
+ bool fNegative = false;\r
+ uint32_t ulIdx = 0U;\r
+ const char *pszReturn;\r
+\r
+ REDASSERT(pszNum != NULL);\r
+ REDASSERT(pulNum != NULL);\r
+\r
+ if(pszNum[ulIdx] == '-')\r
+ {\r
+ fNegative = true;\r
+ ulIdx++;\r
+ }\r
+\r
+ /* Hex numbers must be prefixed with '0x'.\r
+ */\r
+ if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))\r
+ {\r
+ ulIdx += 2U;\r
+\r
+ if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))\r
+ {\r
+ pszReturn = RedHtoUL(&pszNum[ulIdx], pulNum);\r
+ }\r
+ else\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ }\r
+ else if(ISDIGIT(pszNum[ulIdx]))\r
+ {\r
+ uint32_t ulTemp;\r
+\r
+ ulTemp = RedAtoI(&pszNum[ulIdx]);\r
+\r
+ while(ISDIGIT(pszNum[ulIdx]))\r
+ {\r
+ ulIdx++;\r
+ }\r
+\r
+ if(fNegative)\r
+ {\r
+ /* Fail if the number is out of range.\r
+ */\r
+ if(ulTemp > INT32_MAX)\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ else\r
+ {\r
+ *pulNum = -((int32_t)ulTemp);\r
+ pszReturn = &pszNum[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ *pulNum = ulTemp;\r
+ pszReturn = &pszNum[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Return an error if there is not at least one hex or decimal digit.\r
+ */\r
+ pszReturn = NULL;\r
+ }\r
+\r
+ return pszReturn;\r
+}\r
+\r
+\r
+/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value.\r
+\r
+ The number may be hex or decimal. Hex numbers must be prefixed by '0x', and\r
+ they may be upper or lower case. The conversion process will stop with the\r
+ first non hex or decimal digit.\r
+\r
+ If the number is negative (the first character is a '-' sign), the value\r
+ will be range checked and returned as the equivalent unsigned value.\r
+\r
+ @param pszNum A pointer to the ASCII number to convert.\r
+ @param pullNum A pointer to the uint64_t location to store the result.\r
+ This value will be modified on return only if the function\r
+ succeeds and the returned pointer is valid (not NULL).\r
+\r
+ @return A pointer to the byte following the converted number, or NULL to\r
+ indicate failure.\r
+*/\r
+const char *RedNtoULL(\r
+ const char *pszNum,\r
+ uint64_t *pullNum)\r
+{\r
+ bool fNegative = false;\r
+ uint32_t ulIdx = 0U;\r
+ const char *pszReturn;\r
+\r
+ REDASSERT(pszNum != NULL);\r
+ REDASSERT(pullNum != NULL);\r
+\r
+ if(pszNum[ulIdx] == '-')\r
+ {\r
+ fNegative = true;\r
+ ulIdx++;\r
+ }\r
+\r
+ /* Hex numbers must be prefixed with '0x'.\r
+ */\r
+ if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))\r
+ {\r
+ ulIdx += 2U;\r
+\r
+ if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))\r
+ {\r
+ pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum);\r
+ }\r
+ else\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ }\r
+ else if(ISDIGIT(pszNum[ulIdx]))\r
+ {\r
+ uint64_t ullTemp = 0U;\r
+\r
+ while(ISDIGIT(pszNum[ulIdx]))\r
+ {\r
+ ullTemp *= 10U;\r
+ ullTemp += pszNum[ulIdx] - '0';\r
+ ulIdx++;\r
+ }\r
+\r
+ if(fNegative)\r
+ {\r
+ /* Fail if the number is out of range.\r
+ */\r
+ if(ullTemp > INT64_MAX)\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ else\r
+ {\r
+ *pullNum = (uint64_t)(-((int64_t)ullTemp));\r
+ pszReturn = &pszNum[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ *pullNum = ullTemp;\r
+ pszReturn = &pszNum[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Return an error if there is not at least one hex or decimal digit.\r
+ */\r
+ pszReturn = NULL;\r
+ }\r
+\r
+ return pszReturn;\r
+}\r
+\r
+\r
+/** @brief Convert an ASCII hex or decimal number, which may may have a "B",\r
+ "KB", or "MB" suffix (case insensitive), to a binary value.\r
+\r
+ Hex numbers must be prefixed with "0x".\r
+\r
+ @note If there is no postfix, KB is assumed!\r
+\r
+ May fail due to bad formatting or overflow.\r
+\r
+ @param pszNum A pointer to the ASCII number to convert.\r
+ @param pulResult A pointer to a uint32_t in which to place the result.\r
+\r
+ @return A pointer to the byte following the string, or NULL to indicate an\r
+ error. In the event of an error, *pulResult will not be modified.\r
+*/\r
+const char *RedSizeToUL(\r
+ const char *pszNum,\r
+ uint32_t *pulResult)\r
+{\r
+ uint32_t ulResult;\r
+ const char *pszSuffix;\r
+ const char *pszReturn;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ REDASSERT(pszNum != NULL);\r
+ REDASSERT(pulResult != NULL);\r
+\r
+ /* Do the basic hex/decimal conversion\r
+ */\r
+ pszSuffix = RedNtoUL(pszNum, &ulResult);\r
+ if(pszSuffix != NULL)\r
+ {\r
+ if((pszSuffix[ulIdx] == 'B') || (pszSuffix[ulIdx] == 'b'))\r
+ {\r
+ ulIdx++;\r
+ pszReturn = &pszSuffix[ulIdx];\r
+ }\r
+ else if( ((pszSuffix[ulIdx] == 'M') || (pszSuffix[ulIdx] == 'm'))\r
+ && ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))\r
+ {\r
+ ulIdx += 2U;\r
+\r
+ if(ulResult > (UINT32_MAX / (1024U * 1024U)))\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ else\r
+ {\r
+ ulResult *= 1024U * 1024U;\r
+ pszReturn = &pszSuffix[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* The number is either postfixed with "KB" or something\r
+ else (we don't care), but we must increment the pointer\r
+ if it is something recognize.\r
+ */\r
+ if( ((pszSuffix[ulIdx] == 'K') || (pszSuffix[ulIdx] == 'k'))\r
+ && ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))\r
+ {\r
+ ulIdx += 2U;\r
+ }\r
+\r
+ /* "B" or "MB" were not specified, so it must be "KB"\r
+ */\r
+ if(ulResult > (UINT32_MAX / 1024U))\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+ else\r
+ {\r
+ ulResult *= 1024UL;\r
+ pszReturn = &pszSuffix[ulIdx];\r
+ }\r
+ }\r
+\r
+ if(pszReturn != NULL)\r
+ {\r
+ *pulResult = ulResult;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pszReturn = NULL;\r
+ }\r
+\r
+ return pszReturn;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements routines for certain 64-bit math operations and simulated\r
+ floating point.\r
+\r
+ RedUint64DivMod32() and RedUint64DivMod64() are derived from code at\r
+ http://www.hackersdelight.org. This web site states explicitly that "You\r
+ are free to use, copy, and distribute any of the code on this web site,\r
+ whether modified by you or not. You need not give attribution."\r
+*/\r
+#include <redfs.h>\r
+#include <redtestutils.h>\r
+\r
+\r
+static uint32_t nlz64(uint64_t ullValue);\r
+\r
+\r
+/** @brief Return a ratio value formatted as a floating point string accurate to\r
+ the specified number of decimal places.\r
+\r
+ The function exists to provide floating point style output without using\r
+ any actual floating point types.\r
+\r
+ This function may scale the numbers down to avoid overflow at the high end.\r
+ Likewise, potential divide-by-zero errors are internally avoided. Here are\r
+ some examples:\r
+\r
+ Dividend | Divisor | DecPlaces | Result\r
+ -------- | ------- | --------- | ------\r
+ 12133 | 28545 | 2 | "0.42"\r
+ 1539 | 506 | 2 | "3.04"\r
+\r
+ To get a number formatted as a percentage, take the take the portion of the\r
+ total (normally the smaller part), multiply it by 100, and pass it to this\r
+ function as the Dividend, pass the "total" value to this function as the\r
+ Divisor, and specify the desired number of decimal places.\r
+\r
+ For example, if you have a disk format overhead value of N blocks out of a\r
+ total of Y blocks on the disk, and you want to display the format overhead\r
+ as a percentage, you would use a function call\r
+ similar to:\r
+\r
+ ~~~{.c}\r
+ RedRatio(szBuffer, sizeof(szBuffer), N*100U, Y, 2U);\r
+ ~~~\r
+\r
+ If N=145, Y=4096, and decimal places is 2, the resulting output would be\r
+ "3.54".\r
+\r
+ The string returned will always be null-terminated, even if it means\r
+ stomping on the least significant decimal digit.\r
+\r
+ If either the dividend or divisor values are zero, the string "0.0" will be\r
+ returned, with the prescribed number of decimal places.\r
+\r
+ @note This function has "reasonable" limits which meet the needs of the\r
+ various supplemental utilities which use this function. Extremely\r
+ large ratios, or using many decimal places may not function as\r
+ desired.\r
+\r
+ Parameters:\r
+ @param pBuffer A pointer to the buffer in which to store the null\r
+ terminated results.\r
+ @param ulBufferLen The length of the output buffer.\r
+ @param ullDividend The "total" value to divide.\r
+ @param ullDivisor The portion of ullDividend for which to calculate the\r
+ ratio (may be greater than ulDividend).\r
+ @param ulDecPlaces The number of decimal places to use, from 0 to 9.\r
+\r
+ @return @p pBuffer.\r
+*/\r
+char *RedRatio(\r
+ char *pBuffer,\r
+ uint32_t ulBufferLen,\r
+ uint64_t ullDividend,\r
+ uint64_t ullDivisor,\r
+ uint32_t ulDecPlaces)\r
+{\r
+ REDASSERT(pBuffer != NULL);\r
+ REDASSERT(ulBufferLen > 0U);\r
+ REDASSERT(ulDecPlaces <= 9U); /* arbitrary */\r
+\r
+ if((ullDivisor > 0U) && (ullDividend > 0U))\r
+ {\r
+ uint32_t ii;\r
+ uint32_t ulFactor = 1U;\r
+ uint64_t ullDecimal;\r
+ uint64_t ullTemp;\r
+\r
+ for(ii = 1U; ii <= ulDecPlaces; ii++)\r
+ {\r
+ ulFactor *= 10U;\r
+ }\r
+\r
+ ullDecimal = RedMulDiv64(ullDividend, ulFactor, ullDivisor);\r
+\r
+ /* Shouldn't really be calling this function in a situation where we\r
+ can overflow at this point...\r
+ */\r
+ REDASSERT(ullDecimal != UINT64_MAX);\r
+\r
+ if(ullDivisor <= ullDividend)\r
+ {\r
+ uint32_t ulDecimal;\r
+\r
+ (void)RedUint64DivMod32(ullDecimal, ulFactor, &ulDecimal);\r
+ ullDecimal = ulDecimal;\r
+ }\r
+\r
+ ullTemp = RedUint64DivMod64(ullDividend, ullDivisor, NULL);\r
+\r
+ if(ulDecPlaces > 0U)\r
+ {\r
+ RedSNPrintf(pBuffer, ulBufferLen, "%llu.%0*llu", (unsigned long long)ullTemp,\r
+ (unsigned)ulDecPlaces, (unsigned long long)ullDecimal);\r
+ }\r
+ else\r
+ {\r
+ RedSNPrintf(pBuffer, ulBufferLen, "%llu", (unsigned long long)ullTemp);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* If either the dividend or divisor is zero, then just output a "0.0"\r
+ string with the prescribed number of decimal places.\r
+ */\r
+ if(ulDecPlaces > 0U)\r
+ {\r
+ RedSNPrintf(pBuffer, ulBufferLen, "0.%0*u", (unsigned)ulDecPlaces, 0U);\r
+ }\r
+ else\r
+ {\r
+ RedStrNCpy(pBuffer, "0", ulBufferLen);\r
+ }\r
+ }\r
+\r
+ /* Ensure the returned buffer is always null-terminated\r
+ */\r
+ pBuffer[ulBufferLen - 1U] = '\0';\r
+\r
+ return pBuffer;\r
+}\r
+\r
+\r
+/** @brief Multiply 64-bit and 32-bit numbers, and divide by a 64-bit number,\r
+ returning a 64-bit result.\r
+\r
+ @note This function may return an approximate value if multiplying\r
+ @p ullBase and @p ulMultplier results in a number larger than 64-bits\r
+ _and_ this cannot be avoided by scaling.\r
+\r
+ @param ullBase The base 64-bit number number.\r
+ @param ulMultiplier The 32-bit number by which to multiply.\r
+ @param ullDivisor The 64-bit number by which to divide.\r
+\r
+ @return The 64-bit unsigned integer result. Always returns zero if either\r
+ @p ullBase or @p ulMultiplier are zero (regardless what\r
+ @p ullDivisor is). Returns UINT64_MAX if an overflow condition\r
+ occurred, or if @p ullDivisor is zero.\r
+*/\r
+uint64_t RedMulDiv64(\r
+ uint64_t ullBase,\r
+ uint32_t ulMultiplier,\r
+ uint64_t ullDivisor)\r
+{\r
+ uint64_t ullTemp;\r
+\r
+ /* Result would always be zero if either of these are zero. Specifically\r
+ test this case before looking for a zero divisor.\r
+ */\r
+ if((ullBase == 0U) || (ulMultiplier == 0U))\r
+ {\r
+ return 0U;\r
+ }\r
+\r
+ if(ullDivisor == 0U)\r
+ {\r
+ return UINT64_MAX;\r
+ }\r
+\r
+ /* Since we don't have the ability (yet) to use 128-bit numbers, we jump\r
+ through the following hoops (in order) to try to determine the proper\r
+ results without losing precision:\r
+\r
+ 1) Shift the divisor and one of the multiplicands as many times as is\r
+ necessary to reduce the scale -- only if it can be done without\r
+ losing precision.\r
+ 2) Divide one of the multiplicands by the divisor first, but only if it\r
+ divides evenly, preserving precision.\r
+ 3) Same as #2, but try it for the other multiplicand.\r
+ 4) Last ditch, divide the larger multiplicand by the divisor first, then\r
+ do the multiply. This <WILL> lose precision.\r
+\r
+ These solutions are identified as CODE-PATHs #1-4 which are used to\r
+ identify the matching tests in dltmain.c.\r
+\r
+ Note that execution might partially include CODE-PATH #1 up until\r
+ shifting can no longer be done without losing precision. In that case,\r
+ one of the three remaining options will be used.\r
+ */\r
+\r
+ ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL);\r
+ while(ullBase > ullTemp)\r
+ {\r
+ uint64_t ullMod;\r
+ uint64_t ullBaseTemp;\r
+ uint64_t ullWideMultiplier;\r
+\r
+ /* CODE-PATH #1\r
+ */\r
+ /* So long as ulDivisor, and at least one of the other numbers, are\r
+ evenly divisible by 2, we can scale the numbers so the result does\r
+ not overflow the intermediate 64-bit value.\r
+ */\r
+ if((ullDivisor & 1U) == 0U)\r
+ {\r
+ if((ullBase & 1U) == 0U)\r
+ {\r
+ /* CODE-PATH #1a\r
+ */\r
+ ullDivisor >>= 1U;\r
+ ullBase >>= 1U;\r
+ continue;\r
+ }\r
+\r
+ if(((ulMultiplier & 1U) == 0U) && ((ullTemp & UINT64_SUFFIX(0x8000000000000000)) == 0U))\r
+ {\r
+ /* CODE-PATH #1b\r
+ */\r
+ ullDivisor >>= 1U;\r
+ ulMultiplier >>= 1U;\r
+ ullTemp <<= 1U;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ /* If we get to this point, the above method (#1) cannot be used\r
+ because not enough of the numbers are even long enough to scale the\r
+ operands down. We'll see if either multiplicand is evenly divisble\r
+ by ulDivisor, and if so, do the divide first, then the multiply.\r
+ (Note that once we get to this point, we will never exercise the\r
+ while{} loop anymore.)\r
+ */\r
+\r
+ /* CODE-PATH #2\r
+ */\r
+ ullBaseTemp = RedUint64DivMod64(ullBase, ullDivisor, &ullMod);\r
+ if(ullMod == 0U)\r
+ {\r
+ /* Evenly divides, so check that we won't overflow, and finish up.\r
+ */\r
+ ullBase = ullBaseTemp;\r
+ if(ullBase > ullTemp)\r
+ {\r
+ return UINT64_MAX;\r
+ }\r
+ else\r
+ {\r
+ /* We've validated that this will not overflow.\r
+ */\r
+ ullBase *= ulMultiplier;\r
+ return ullBase;\r
+ }\r
+ }\r
+\r
+ /* CODE-PATH #3\r
+ */\r
+ ullWideMultiplier = RedUint64DivMod64(ulMultiplier, ullDivisor, &ullMod);\r
+ if(ullMod == 0U)\r
+ {\r
+ /* Evenly divides, so check that we won't overflow, and finish up.\r
+ */\r
+\r
+ /* Must recalculate ullTemp relative to ullBase\r
+ */\r
+ ullTemp = RedUint64DivMod64(UINT64_MAX, ullBase, NULL);\r
+ if(ullWideMultiplier > ullTemp)\r
+ {\r
+ return UINT64_MAX;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulNarrowMultiplier = (uint32_t)ullWideMultiplier;\r
+\r
+ /* We've validated that this will not overflow.\r
+ */\r
+ ullBase *= ulNarrowMultiplier;\r
+ return ullBase;\r
+ }\r
+ }\r
+\r
+ /* CODE-PATH #4\r
+\r
+ Neither of the multipliers is evenly divisible by the divisor, so\r
+ just punt and divide the larger number first, then do the final\r
+ multiply.\r
+\r
+ All the other attempts above would preserve precision -- this is the\r
+ only case where precision may be lost.\r
+ */\r
+\r
+ /* If necessary reverse the ullBase and ulMultiplier operands so that\r
+ ullBase contains the larger of the two values.\r
+ */\r
+ if(ullBase < ulMultiplier)\r
+ {\r
+ uint32_t ulTemp = ulMultiplier;\r
+\r
+ ulMultiplier = (uint32_t)ullBase;\r
+ ullBase = ulTemp;\r
+ }\r
+\r
+ ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL);\r
+ ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL);\r
+ if(ullBase > ullTemp)\r
+ {\r
+ return UINT64_MAX;\r
+ }\r
+ else\r
+ {\r
+ ullBase *= ulMultiplier;\r
+ return ullBase;\r
+ }\r
+ }\r
+\r
+ /* We only get to this point if either there was never any chance of\r
+ overflow, or if the pure shifting mechanism succeeded in reducing\r
+ the scale so overflow is not a problem.\r
+ */\r
+\r
+ ullBase *= ulMultiplier;\r
+ ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL);\r
+\r
+ return ullBase;\r
+}\r
+\r
+\r
+/** @brief Divide a 64-bit value by a 32-bit value, returning the quotient and\r
+ the remainder.\r
+\r
+ Essentially this function does the following:\r
+\r
+ ~~~{.c}\r
+ if(pulRemainder != NULL)\r
+ {\r
+ *pulRemainder = (uint32_t)(ullDividend % ulDivisor);\r
+ }\r
+ return ullDividend / ulDivisor;\r
+ ~~~\r
+\r
+ However, it does so without ever actually dividing/modulating a 64-bit\r
+ value, since such operations are not allowed in all environments.\r
+\r
+ @param ullDividend The value to divide.\r
+ @param ulDivisor The value to divide by.\r
+ @param pulRemander Populated with the remainder; may be NULL.\r
+\r
+ @return The quotient (result of the division).\r
+*/\r
+uint64_t RedUint64DivMod32(\r
+ uint64_t ullDividend,\r
+ uint32_t ulDivisor,\r
+ uint32_t *pulRemainder)\r
+{\r
+ uint64_t ullQuotient;\r
+ uint32_t ulResultRemainder;\r
+\r
+ /* Check for divide by zero.\r
+ */\r
+ if(ulDivisor == 0U)\r
+ {\r
+ REDERROR();\r
+\r
+ /* Nonsense value if no asserts.\r
+ */\r
+ ullQuotient = UINT64_SUFFIX(0xFFFFFFFFFFFFFBAD);\r
+ ulResultRemainder = 0xFFFFFBADU;\r
+ }\r
+ else if(ullDividend <= UINT32_MAX)\r
+ {\r
+ uint32_t ulDividend = (uint32_t)ullDividend;\r
+\r
+ ullQuotient = ulDividend / ulDivisor;\r
+ ulResultRemainder = ulDividend % ulDivisor;\r
+ }\r
+ else\r
+ {\r
+ uint32_t ulResultHi;\r
+ uint32_t ulResultLo;\r
+ uint32_t ulRemainder;\r
+ uint8_t bIndex;\r
+ uint32_t ulThisDivision;\r
+ uint32_t ulMask;\r
+ uint8_t ucNextValue;\r
+ uint32_t ulInterimHi, ulInterimLo;\r
+ uint32_t ulLowDword = (uint32_t)ullDividend;\r
+ uint32_t ulHighDword = (uint32_t)(ullDividend >> 32U);\r
+\r
+ /* Compute the high part and get the remainder\r
+ */\r
+ ulResultHi = ulHighDword / ulDivisor;\r
+ ulResultLo = 0U;\r
+ ulRemainder = ulHighDword % ulDivisor;\r
+\r
+ /* Compute the low part\r
+ */\r
+ ulMask = 0xFF000000U;\r
+ for(bIndex = 0U; bIndex < sizeof(uint32_t); bIndex++)\r
+ {\r
+ ucNextValue = (uint8_t)((ulLowDword & ulMask) >> ((sizeof(uint32_t) - 1U - bIndex) * 8U));\r
+ ulInterimHi = ulRemainder >> 24U;\r
+ ulInterimLo = (ulRemainder << 8U) | ucNextValue;\r
+ ulThisDivision = 0U;\r
+ while(ulInterimHi != 0U)\r
+ {\r
+ uint64_t ullInterim = ((uint64_t)ulInterimHi << 32U) + ulInterimLo;\r
+\r
+ ullInterim -= ulDivisor;\r
+ ulThisDivision++;\r
+\r
+ ulInterimHi = (uint32_t)(ullInterim >> 32U);\r
+ ulInterimLo = (uint32_t)ullInterim;\r
+ }\r
+ ulThisDivision += ulInterimLo / ulDivisor;\r
+ ulRemainder = ulInterimLo % ulDivisor;\r
+ ulResultLo <<= 8U;\r
+ ulResultLo += ulThisDivision;\r
+ ulMask >>= 8U;\r
+ }\r
+\r
+ ullQuotient = ((uint64_t)ulResultHi << 32U) + ulResultLo;\r
+ ulResultRemainder = (uint32_t)(ullDividend - (ullQuotient * ulDivisor));\r
+ }\r
+\r
+ if(pulRemainder != NULL)\r
+ {\r
+ *pulRemainder = ulResultRemainder;\r
+ }\r
+\r
+ return ullQuotient;\r
+}\r
+\r
+\r
+/** @brief Divide a 64-bit value by a 64-bit value, returning the quotient and\r
+ the remainder.\r
+\r
+ Essentially this function does the following:\r
+\r
+ ~~~{.c}\r
+ if(pullRemainder != NULL)\r
+ {\r
+ *pullRemainder = ullDividend % ullDivisor;\r
+ }\r
+ return ullDividend / ullDivisor;\r
+ ~~~\r
+\r
+ However, it does so without ever actually dividing/modulating a 64-bit\r
+ value, since such operations are not allowed in all environments.\r
+\r
+ @param ullDividend The value to divide.\r
+ @param ullDivisor The value to divide by.\r
+ @param pullRemander Populated with the remainder; may be NULL.\r
+\r
+ @return The quotient (result of the division).\r
+*/\r
+uint64_t RedUint64DivMod64(\r
+ uint64_t ullDividend,\r
+ uint64_t ullDivisor,\r
+ uint64_t *pullRemainder)\r
+{\r
+ /* The variables u0, u1, etc. take on only 32-bit values, but they are\r
+ declared uint64_t to avoid some compiler warning messages and to avoid\r
+ some unnecessary EXTRs that the compiler would put in, to convert\r
+ uint64_ts to ints.\r
+ */\r
+ uint64_t u0;\r
+ uint64_t u1;\r
+ uint64_t q0;\r
+ uint64_t q1;\r
+ uint64_t ullQuotient;\r
+\r
+ /* First the procedure takes care of the case in which the divisor is a\r
+ 32-bit quantity. There are two subcases: (1) If the left half of the\r
+ dividend is less than the divisor, one execution of RedUint64DivMod32()\r
+ is all that is required (overflow is not possible). (2) Otherwise it\r
+ does two divisions, using the grade school method.\r
+ */\r
+\r
+ if((ullDivisor >> 32U) == 0U)\r
+ {\r
+ if((ullDividend >> 32U) < ullDivisor)\r
+ {\r
+ /* If ullDividend/ullDivisor cannot overflow, just do one division.\r
+ */\r
+ ullQuotient = RedUint64DivMod32(ullDividend, (uint32_t)ullDivisor, NULL);\r
+ }\r
+ else\r
+ {\r
+ uint32_t k;\r
+\r
+ /* If ullDividend/ullDivisor would overflow:\r
+ */\r
+\r
+ /* Break ullDividend up into two halves.\r
+ */\r
+ u1 = ullDividend >> 32U;\r
+ u0 = ullDividend & 0xFFFFFFFFU;\r
+\r
+ /* First quotient digit and first remainder.\r
+ */\r
+ q1 = RedUint64DivMod32(u1, (uint32_t)ullDivisor, &k);\r
+\r
+ /* 2nd quot. digit.\r
+ */\r
+ q0 = RedUint64DivMod32(((uint64_t)k << 32U) + u0, (uint32_t)ullDivisor, NULL);\r
+\r
+ ullQuotient = (q1 << 32U) + q0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ uint64_t n;\r
+ uint64_t v1;\r
+\r
+ n = nlz64(ullDivisor); /* 0 <= n <= 31. */\r
+ v1 = (ullDivisor << n) >> 32U; /* Normalize the divisor so its MSB is 1. */\r
+ u1 = ullDividend >> 1U; /* To ensure no overflow. */\r
+\r
+ /* Get quotient from divide unsigned insn.\r
+ */\r
+ q1 = RedUint64DivMod32(u1, (uint32_t)v1, NULL);\r
+\r
+ q0 = (q1 << n) >> 31U; /* Undo normalization and division of ullDividend by 2. */\r
+\r
+ /* Make q0 correct or too small by 1.\r
+ */\r
+ if(q0 != 0U)\r
+ {\r
+ q0--;\r
+ }\r
+\r
+ if((ullDividend - (q0 * ullDivisor)) >= ullDivisor)\r
+ {\r
+ q0++; /* Now q0 is correct. */\r
+ }\r
+\r
+ ullQuotient = q0;\r
+ }\r
+\r
+ if(pullRemainder != NULL)\r
+ {\r
+ *pullRemainder = ullDividend - (ullQuotient * ullDivisor);\r
+ }\r
+\r
+ return ullQuotient;\r
+}\r
+\r
+\r
+/** @brief Compute the number of leading zeroes in a 64-bit value.\r
+\r
+ @param ullValue The value for which to compute the NLZ.\r
+\r
+ @return The number of leading zeroes in @p ullValue.\r
+*/\r
+static uint32_t nlz64(\r
+ uint64_t ullValue)\r
+{\r
+ uint32_t n;\r
+\r
+ if(ullValue == 0U)\r
+ {\r
+ n = 64U;\r
+ }\r
+ else\r
+ {\r
+ uint64_t x = ullValue;\r
+\r
+ n = 0U;\r
+\r
+ if(x <= UINT64_SUFFIX(0x00000000FFFFFFFF))\r
+ {\r
+ n += 32U;\r
+ x <<= 32U;\r
+ }\r
+\r
+ if(x <= UINT64_SUFFIX(0x0000FFFFFFFFFFFF))\r
+ {\r
+ n += 16U;\r
+ x <<= 16U;\r
+ }\r
+\r
+ if(x <= UINT64_SUFFIX(0x00FFFFFFFFFFFFFF))\r
+ {\r
+ n += 8U;\r
+ x <<= 8U;\r
+ }\r
+\r
+ if(x <= UINT64_SUFFIX(0x0FFFFFFFFFFFFFFF))\r
+ {\r
+ n += 4U;\r
+ x <<= 4U;\r
+ }\r
+\r
+ if(x <= UINT64_SUFFIX(0x3FFFFFFFFFFFFFFF))\r
+ {\r
+ n += 2U;\r
+ x <<= 2U;\r
+ }\r
+\r
+ if(x <= UINT64_SUFFIX(0x7FFFFFFFFFFFFFFF))\r
+ {\r
+ n += 1;\r
+ }\r
+ }\r
+\r
+ return n;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements functions for printing.\r
+\r
+ These functions are intended to be used in portable test code, which cannot\r
+ assume the standard I/O functions will be available. Similar to their ANSI\r
+ C counterparts, these functions allow formatting text strings and (if the\r
+ configuration allows it) outputing formatted text. The latter ability\r
+ relies on the RedOsOutputString() OS service function.\r
+\r
+ Do *not* use these functions in code which can safely assume the standard\r
+ I/O functions are available (e.g., in host tools code).\r
+\r
+ Do *not* use these functions from within the file system driver. These\r
+ functions use variable arguments and thus are not MISRA-C:2012 compliant.\r
+*/\r
+#include <redfs.h>\r
+#include <redtestutils.h>\r
+#include <limits.h>\r
+#include <stdarg.h>\r
+\r
+\r
+/** @brief Maximum number of bytes of output supported by RedPrintf().\r
+\r
+ Typically only Datalight code uses these functions, and that could should be\r
+ written to respect this limit, so it should not normally be necessary to\r
+ adjust this value.\r
+*/\r
+#define OUTPUT_BUFFER_SIZE 256U\r
+\r
+\r
+typedef enum\r
+{\r
+ PRFMT_UNKNOWN = 0,\r
+ PRFMT_CHAR,\r
+ PRFMT_ANSISTRING,\r
+ PRFMT_SIGNED8BIT,\r
+ PRFMT_UNSIGNED8BIT,\r
+ PRFMT_SIGNED16BIT,\r
+ PRFMT_UNSIGNED16BIT,\r
+ PRFMT_SIGNED32BIT,\r
+ PRFMT_UNSIGNED32BIT,\r
+ PRFMT_SIGNED64BIT,\r
+ PRFMT_UNSIGNED64BIT,\r
+ PRFMT_HEX8BIT,\r
+ PRFMT_HEX16BIT,\r
+ PRFMT_HEX32BIT,\r
+ PRFMT_HEX64BIT,\r
+ PRFMT_POINTER,\r
+ PRFMT_DOUBLEPERCENT\r
+} PRINTTYPE;\r
+\r
+typedef struct\r
+{\r
+ PRINTTYPE type; /* The PRFMT_* type found */\r
+ uint32_t ulSpecifierIdx; /* Returns a pointer to the % sign */\r
+ uint32_t ulFillLen;\r
+ char cFillChar;\r
+ bool fLeftJustified;\r
+ bool fHasIllegalType; /* TRUE if an illegal sequence was skipped over */\r
+ bool fHasVarWidth;\r
+} PRINTFORMAT;\r
+\r
+\r
+/* Our output handlers are written for standard fixed width data types. Map\r
+ the standard ANSI C data types onto our handlers. Currently this code has\r
+ the following requirements:\r
+\r
+ 1) shorts must be either 16 or 32 bits\r
+ 2) ints must be either 16 or 32 bits\r
+ 3) longs must be between 32 or 64 bits\r
+ 4) long longs must be 64 bits\r
+*/\r
+#if (USHRT_MAX == 0xFFFFU)\r
+ #define MAPSHORT PRFMT_SIGNED16BIT\r
+ #define MAPUSHORT PRFMT_UNSIGNED16BIT\r
+ #define MAPHEXUSHORT PRFMT_HEX16BIT\r
+#elif (USHRT_MAX == 0xFFFFFFFFU)\r
+ #define MAPSHORT PRFMT_SIGNED32BIT\r
+ #define MAPUSHORT PRFMT_UNSIGNED32BIT\r
+ #define MAPHEXUSHORT PRFMT_HEX32BIT\r
+#else\r
+ #error "The 'short' data type does not have a 16 or 32-bit width"\r
+#endif\r
+\r
+#if (UINT_MAX == 0xFFFFU)\r
+ #define MAPINT PRFMT_SIGNED16BIT\r
+ #define MAPUINT PRFMT_UNSIGNED16BIT\r
+ #define MAPHEXUINT PRFMT_HEX16BIT\r
+#elif (UINT_MAX == 0xFFFFFFFFU)\r
+ #define MAPINT PRFMT_SIGNED32BIT\r
+ #define MAPUINT PRFMT_UNSIGNED32BIT\r
+ #define MAPHEXUINT PRFMT_HEX32BIT\r
+#else\r
+ #error "The 'int' data type does not have a 16 or 32-bit width"\r
+#endif\r
+\r
+#if (ULONG_MAX == 0xFFFFFFFFU)\r
+ #define MAPLONG PRFMT_SIGNED32BIT\r
+ #define MAPULONG PRFMT_UNSIGNED32BIT\r
+ #define MAPHEXULONG PRFMT_HEX32BIT\r
+#elif (ULONG_MAX <= UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF))\r
+ /* We've run into unusual environments where "longs" are 40-bits wide.\r
+ In this event, map them to 64-bit types so no data is lost.\r
+ */\r
+ #define MAPLONG PRFMT_SIGNED64BIT\r
+ #define MAPULONG PRFMT_UNSIGNED64BIT\r
+ #define MAPHEXULONG PRFMT_HEX64BIT\r
+#else\r
+ #error "The 'long' data type is not between 32 and 64 bits wide"\r
+#endif\r
+\r
+#if defined(ULLONG_MAX) && (ULLONG_MAX != UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF))\r
+ #error "The 'long long' data type is not 64 bits wide"\r
+#else\r
+ #define MAPLONGLONG PRFMT_SIGNED64BIT\r
+ #define MAPULONGLONG PRFMT_UNSIGNED64BIT\r
+ #define MAPHEXULONGLONG PRFMT_HEX64BIT\r
+#endif\r
+\r
+\r
+static uint32_t ProcessFormatSegment(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, PRINTFORMAT *pFormat, uint32_t *pulSpecifierLen);\r
+static uint32_t ParseFormatSpecifier(char const *pszFomat, PRINTFORMAT *pFormatType);\r
+static PRINTTYPE ParseFormatType(const char *pszFormat, uint32_t *pulTypeLen);\r
+static uint32_t LtoA(char *pcBuffer, uint32_t ulBufferLen, int32_t lNum, uint32_t ulFillLen, char cFill);\r
+static uint32_t LLtoA(char *pcBuffer, uint32_t ulBufferLen, int64_t llNum, uint32_t ulFillLen, char cFill);\r
+static uint32_t ULtoA(char *pcBuffer, uint32_t ulBufferLen, uint32_t ulNum, bool fHex, uint32_t ulFillLen, char cFill);\r
+static uint32_t ULLtoA(char *pcBuffer, uint32_t ulBufferLen, uint64_t ullNum, bool fHex, uint32_t ulFillLen, char cFill);\r
+static uint32_t FinishToA(const char *pcDigits, uint32_t ulDigits, char *pcOutBuffer, uint32_t ulBufferLen, uint32_t ulFillLen, char cFill);\r
+\r
+\r
+/* Digits for the *LtoA() routines.\r
+*/\r
+static const char gacDigits[] = "0123456789ABCDEF";\r
+\r
+\r
+#if REDCONF_OUTPUT == 1\r
+/** @brief Print formatted data with a variable length argument list.\r
+\r
+ This function provides a subset of the ANSI C printf() functionality with\r
+ several extensions to support fixed size data types.\r
+\r
+ See RedVSNPrintf() for the list of supported types.\r
+\r
+ @param pszFormat A pointer to the null-terminated format string.\r
+ @param ... The variable length argument list.\r
+*/\r
+void RedPrintf(\r
+ const char *pszFormat,\r
+ ...)\r
+{\r
+ va_list arglist;\r
+\r
+ va_start(arglist, pszFormat);\r
+\r
+ RedVPrintf(pszFormat, arglist);\r
+\r
+ va_end(arglist);\r
+}\r
+\r
+\r
+/** @brief Print formatted data using a pointer to a variable length argument\r
+ list.\r
+\r
+ This function provides a subset of the ANSI C vprintf() functionality.\r
+\r
+ See RedVSNPrintf() for the list of supported types.\r
+\r
+ This function accommodates a maximum output length of #OUTPUT_BUFFER_SIZE.\r
+ If this function must truncate the output, and the original string was\r
+ \n terminated, the truncated output will be \n terminated as well.\r
+\r
+ @param pszFormat A pointer to the null-terminated format string.\r
+ @param arglist The variable length argument list.\r
+*/\r
+void RedVPrintf(\r
+ const char *pszFormat,\r
+ va_list arglist)\r
+{\r
+ char achBuffer[OUTPUT_BUFFER_SIZE];\r
+\r
+ if(RedVSNPrintf(achBuffer, sizeof(achBuffer), pszFormat, arglist) == -1)\r
+ {\r
+ /* Ensture the buffer is null terminated.\r
+ */\r
+ achBuffer[sizeof(achBuffer) - 1U] = '\0';\r
+\r
+ /* If the original string was \n terminated and the new one is not, due to\r
+ truncation, stuff a \n into the new one.\r
+ */\r
+ if(pszFormat[RedStrLen(pszFormat) - 1U] == '\n')\r
+ {\r
+ achBuffer[sizeof(achBuffer) - 2U] = '\n';\r
+ }\r
+ }\r
+\r
+ RedOsOutputString(achBuffer);\r
+}\r
+#endif /* #if REDCONF_OUTPUT == 1 */\r
+\r
+\r
+/** @brief Format arguments into a string using a subset of the ANSI C\r
+ vsprintf() functionality.\r
+\r
+ This function is modeled after the Microsoft _snprint() extension to the\r
+ ANSI C sprintf() function, and allows a buffer length to be specified so\r
+ that overflow is avoided.\r
+\r
+ See RedVSNPrintf() for the list of supported types.\r
+\r
+ @param pcBuffer A pointer to the output buffer\r
+ @param ulBufferLen The output buffer length\r
+ @param pszFormat A pointer to the null terminated format string\r
+ @param ... Variable argument list\r
+\r
+ @return The length output, or -1 if the buffer filled up. If -1 is\r
+ returned, the output buffer may not be null-terminated.\r
+*/\r
+int32_t RedSNPrintf(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ const char *pszFormat,\r
+ ...)\r
+{\r
+ int32_t iLen;\r
+ va_list arglist;\r
+\r
+ va_start(arglist, pszFormat);\r
+\r
+ iLen = RedVSNPrintf(pcBuffer, ulBufferLen, pszFormat, arglist);\r
+\r
+ va_end(arglist);\r
+\r
+ return iLen;\r
+}\r
+\r
+\r
+/** @brief Format arguments into a string using a subset of the ANSI C\r
+ vsprintf() functionality.\r
+\r
+ This function is modeled after the Microsoft _vsnprint() extension to the\r
+ ANSI C vsprintf() function, and requires a buffer length to be specified so\r
+ that overflow is avoided.\r
+\r
+ The following ANSI C standard formatting codes are supported:\r
+\r
+ | Code | Meaning |\r
+ | ---- | ---------------------------------- |\r
+ | %c | Format a character |\r
+ | %s | Format a null-terminated C string |\r
+ | %hd | Format a signed short |\r
+ | %hu | Format an unsigned short |\r
+ | %d | Format a signed integer |\r
+ | %u | Format an unsigned integer |\r
+ | %ld | Format a signed long |\r
+ | %lu | Format an unsigned long |\r
+ | %lld | Format a signed long long |\r
+ | %llu | Format an unsigned long long |\r
+ | %hx | Format a short in hex |\r
+ | %x | Format an integer in hex |\r
+ | %lx | Format a long in hex |\r
+ | %llx | Format a long long in hex |\r
+ | %p | Format a pointer (hex value) |\r
+\r
+ @note All formatting codes are case-sensitive.\r
+\r
+ Fill characters and field widths are supported per the ANSI standard, as is\r
+ left justification with the '-' character.\r
+\r
+ The only supported fill characters are '0', ' ', and '_'.\r
+\r
+ '*' is supported to specify variable length field widths.\r
+\r
+ Hexidecimal numbers are always displayed in upper case. Formatting codes\r
+ which specifically request upper case (e.g., "%lX") are not supported.\r
+\r
+ Unsupported behaviors:\r
+ - Precision is not supported.\r
+ - Floating point is not supported.\r
+\r
+ Errata:\r
+ - There is a subtle difference in the return value for this function versus\r
+ the Microsoft implementation. In the Microsoft version, if the buffer\r
+ exactly fills up, but there is no room for a null-terminator, the return\r
+ value will be the length of the buffer. In this code, -1 will be returned\r
+ when this happens.\r
+ - When using left justified strings, the only supported fill character is a\r
+ space, regardless of what may be specified. It is not clear if this is\r
+ ANSI standard or just the way the Microsoft function works, but we emulate\r
+ the Microsoft behavior.\r
+\r
+ @param pcBuffer A pointer to the output buffer.\r
+ @param ulBufferLen The output buffer length.\r
+ @param pszFormat A pointer to the null terminated ANSI format string.\r
+ @param arglist Variable argument list.\r
+\r
+ @return The length output, or -1 if the buffer filled up. If -1 is\r
+ returned, the output buffer may not be null-terminated.\r
+*/\r
+int32_t RedVSNPrintf(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ const char *pszFormat,\r
+ va_list arglist)\r
+{\r
+ uint32_t ulBufIdx = 0U;\r
+ uint32_t ulFmtIdx = 0U;\r
+ int32_t iLen;\r
+\r
+ while((pszFormat[ulFmtIdx] != '\0') && (ulBufIdx < ulBufferLen))\r
+ {\r
+ PRINTFORMAT fmt;\r
+ uint32_t ulSpecifierLen;\r
+ uint32_t ulWidth;\r
+\r
+ /* Process the next segment of the format string, outputting\r
+ any non-format specifiers, as output buffer space allows,\r
+ and return information about the next format specifier.\r
+ */\r
+ ulWidth = ProcessFormatSegment(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, &pszFormat[ulFmtIdx], &fmt, &ulSpecifierLen);\r
+ if(ulWidth)\r
+ {\r
+ REDASSERT(ulWidth <= (ulBufferLen - ulBufIdx));\r
+\r
+ ulBufIdx += ulWidth;\r
+ }\r
+\r
+ /* If no specifier was found, or if the output buffer is\r
+ full, we're done -- get out.\r
+ */\r
+ if((ulSpecifierLen == 0U) || (ulBufIdx == ulBufferLen))\r
+ {\r
+ break;\r
+ }\r
+\r
+ /* Otherwise, the math should add up for these things...\r
+ */\r
+ REDASSERT(&pszFormat[fmt.ulSpecifierIdx] == &pszFormat[ulWidth]);\r
+\r
+ /* Point past the specifier, to the next piece of the format string.\r
+ */\r
+ ulFmtIdx = ulFmtIdx + fmt.ulSpecifierIdx + ulSpecifierLen;\r
+\r
+ if(fmt.fHasVarWidth)\r
+ {\r
+ int iFillLen = va_arg(arglist, int);\r
+\r
+ if(iFillLen >= 0)\r
+ {\r
+ fmt.ulFillLen = (uint32_t)iFillLen;\r
+ }\r
+ else\r
+ {\r
+ /* Bogus fill length. Ignore.\r
+ */\r
+ fmt.ulFillLen = 0U;\r
+ }\r
+ }\r
+\r
+ switch(fmt.type)\r
+ {\r
+ case PRFMT_DOUBLEPERCENT:\r
+ {\r
+ /* Nothing to do. A single percent has already been output,\r
+ and we just finished skipping past the second percent.\r
+ */\r
+ break;\r
+ }\r
+\r
+ /*-----------------> Small int handling <------------------\r
+ *\r
+ * Values smaller than "int" will be promoted to "int" by\r
+ * the compiler, so we must retrieve them using "int" when\r
+ * calling va_arg(). Once we've done that, we immediately\r
+ * put the value into the desired data type.\r
+ *---------------------------------------------------------*/\r
+\r
+ case PRFMT_CHAR:\r
+ {\r
+ pcBuffer[ulBufIdx] = (char)va_arg(arglist, int);\r
+ ulBufIdx++;\r
+ break;\r
+ }\r
+ case PRFMT_SIGNED8BIT:\r
+ {\r
+ int8_t num = (int8_t)va_arg(arglist, int);\r
+\r
+ ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_UNSIGNED8BIT:\r
+ {\r
+ uint8_t bNum = (uint8_t)va_arg(arglist, unsigned);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, false, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_HEX8BIT:\r
+ {\r
+ uint8_t bNum = (uint8_t)va_arg(arglist, unsigned);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, true, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_SIGNED16BIT:\r
+ {\r
+ int16_t num = (int16_t)va_arg(arglist, int);\r
+\r
+ ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_UNSIGNED16BIT:\r
+ {\r
+ uint16_t uNum = (uint16_t)va_arg(arglist, unsigned);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, false, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_HEX16BIT:\r
+ {\r
+ uint16_t uNum = (uint16_t)va_arg(arglist, unsigned);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, true, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_SIGNED32BIT:\r
+ {\r
+ int32_t lNum = va_arg(arglist, int32_t);\r
+\r
+ ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, lNum, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_UNSIGNED32BIT:\r
+ {\r
+ uint32_t ulNum = va_arg(arglist, uint32_t);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, false, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_HEX32BIT:\r
+ {\r
+ uint32_t ulNum = va_arg(arglist, uint32_t);\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, true, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_SIGNED64BIT:\r
+ {\r
+ int64_t llNum = va_arg(arglist, int64_t);\r
+\r
+ ulBufIdx += LLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, llNum, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_UNSIGNED64BIT:\r
+ {\r
+ uint64_t ullNum = va_arg(arglist, uint64_t);\r
+\r
+ ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, false, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_HEX64BIT:\r
+ {\r
+ uint64_t ullNum = va_arg(arglist, uint64_t);\r
+\r
+ ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, true, fmt.ulFillLen, fmt.cFillChar);\r
+ break;\r
+ }\r
+ case PRFMT_POINTER:\r
+ {\r
+ const void *ptr = va_arg(arglist, const void *);\r
+\r
+ /* Assert our assumption.\r
+ */\r
+ REDASSERT(sizeof(void *) <= 8U);\r
+\r
+ /* Format as either a 64-bit or a 32-bit value.\r
+ */\r
+ if(sizeof(void *) > 4U)\r
+ {\r
+ /* Attempt to quiet warnings.\r
+ */\r
+ uintptr_t ptrval = (uintptr_t)ptr;\r
+ uint64_t ullPtrVal = (uint64_t)ptrval;\r
+\r
+ ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullPtrVal, true, fmt.ulFillLen, fmt.cFillChar);\r
+ }\r
+ else\r
+ {\r
+ /* Attempt to quiet warnings.\r
+ */\r
+ uintptr_t ptrval = (uintptr_t)ptr;\r
+ uint32_t ulPtrVal = (uint32_t)ptrval;\r
+\r
+ ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulPtrVal, true, fmt.ulFillLen, fmt.cFillChar);\r
+ }\r
+\r
+ break;\r
+ }\r
+ case PRFMT_ANSISTRING:\r
+ {\r
+ const char *pszArg = va_arg(arglist, const char *);\r
+ uint32_t ulArgIdx = 0U;\r
+\r
+ if(pszArg == NULL)\r
+ {\r
+ pszArg = "null";\r
+ }\r
+\r
+ if(fmt.ulFillLen > 0U)\r
+ {\r
+ if(!fmt.fLeftJustified)\r
+ {\r
+ uint32_t ulLen = RedStrLen(pszArg);\r
+\r
+ /* So long as we are not left justifying, fill as many\r
+ characters as is necessary to make the string right\r
+ justified.\r
+ */\r
+ while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > ulLen))\r
+ {\r
+ pcBuffer[ulBufIdx] = fmt.cFillChar;\r
+ ulBufIdx++;\r
+ fmt.ulFillLen--;\r
+ }\r
+ }\r
+\r
+ /* Move as many characters as we have space for into the\r
+ output buffer.\r
+ */\r
+ while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0'))\r
+ {\r
+ pcBuffer[ulBufIdx] = pszArg[ulArgIdx];\r
+ ulBufIdx++;\r
+ ulArgIdx++;\r
+ if(fmt.ulFillLen > 0U)\r
+ {\r
+ fmt.ulFillLen--;\r
+ }\r
+ }\r
+\r
+ /* If there is any space left to fill, do it (the string\r
+ must have been left justified).\r
+ */\r
+ while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > 0U))\r
+ {\r
+ /* This is NOT a typo -- when using left justified\r
+ strings, spaces are the only allowed fill character.\r
+ See the errata.\r
+ */\r
+ pcBuffer[ulBufIdx] = ' ';\r
+ ulBufIdx++;\r
+ fmt.ulFillLen--;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* No fill characters, just move up to as many\r
+ characters as we have space for in the output\r
+ buffer.\r
+ */\r
+ while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0'))\r
+ {\r
+ pcBuffer[ulBufIdx] = pszArg[ulArgIdx];\r
+ ulBufIdx++;\r
+ ulArgIdx++;\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ {\r
+ REDERROR();\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* If there is space, tack on a null and return the output length\r
+ processed, not including the null.\r
+ */\r
+ if(ulBufIdx < ulBufferLen)\r
+ {\r
+ pcBuffer[ulBufIdx] = '\0';\r
+ iLen = (int32_t)ulBufIdx;\r
+ }\r
+ else\r
+ {\r
+ /* Not enough space, just return -1, with no null termination\r
+ */\r
+ iLen = -1;\r
+ }\r
+\r
+ return iLen;\r
+}\r
+\r
+\r
+/** @brief Process the next segment of the format string, outputting any\r
+ non-format specifiers, as output buffer space allows, and return\r
+ information about the next format specifier.\r
+\r
+ @note If the returned value is the same as the supplied @p ulBufferLen,\r
+ the output buffer will not be null-terminated. In all other cases,\r
+ the result will be null-terminated. The returned length will never\r
+ include the null in the count.\r
+\r
+ @param pcBuffer The output buffer.\r
+ @param ulBufferLen The output buffer length.\r
+ @param pszFormat The format string to process.\r
+ @param pFormat The PRINTFORMAT structure to fill.\r
+ @param pulSpecifierLen Returns the length of any format specifier string,\r
+ or zero if no specifier was found.\r
+\r
+ @return The count of characters from pszFormatt which were processed and\r
+ copied to pcBuffer.\r
+ - If zero is returned and *pulSpecifierLen is non-zero, then\r
+ a format specifier string was found at the start of pszFmt.\r
+ - If non-zero is returned and *pulSpecifierLen is zero, then\r
+ no format specifier string was found, and the entire pszFmt\r
+ string was copied to pBuffer (or as much as will fit).\r
+*/\r
+static uint32_t ProcessFormatSegment(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ const char *pszFormat,\r
+ PRINTFORMAT *pFormat,\r
+ uint32_t *pulSpecifierLen)\r
+{\r
+ uint32_t ulWidth = 0U;\r
+\r
+ /* Find the next format specifier string, and information about it.\r
+ */\r
+ *pulSpecifierLen = ParseFormatSpecifier(pszFormat, pFormat);\r
+\r
+ if(*pulSpecifierLen == 0U)\r
+ {\r
+ /* If no specifier was found at all, then simply output the full length\r
+ of the string, or as much as will fit.\r
+ */\r
+ ulWidth = REDMIN(ulBufferLen, RedStrLen(pszFormat));\r
+\r
+ RedMemCpy(pcBuffer, pszFormat, ulWidth);\r
+ }\r
+ else\r
+ {\r
+ /* If we encountered a double percent, skip past one of them so it is\r
+ copied into the output buffer.\r
+ */\r
+ if(pFormat->type == PRFMT_DOUBLEPERCENT)\r
+ {\r
+ pFormat->ulSpecifierIdx++;\r
+\r
+ /* A double percent specifier always has a length of two. Since\r
+ we're processing one of those percent signs, reduce the length\r
+ to one. Assert it so.\r
+ */\r
+ REDASSERT(*pulSpecifierLen == 2U);\r
+\r
+ (*pulSpecifierLen)--;\r
+ }\r
+\r
+ /* So long as the specifier is not the very first thing in the format\r
+ string...\r
+ */\r
+ if(pFormat->ulSpecifierIdx != 0U)\r
+ {\r
+ /* A specifier was found, but there is other data preceding it.\r
+ Copy as much as allowed to the output buffer.\r
+ */\r
+ ulWidth = REDMIN(ulBufferLen, pFormat->ulSpecifierIdx);\r
+\r
+ RedMemCpy(pcBuffer, pszFormat, ulWidth);\r
+ }\r
+ }\r
+\r
+ /* If there is room in the output buffer, null-terminate whatever is there.\r
+ But note that the returned length never includes the null.\r
+ */\r
+ if(ulWidth < ulBufferLen)\r
+ {\r
+ pcBuffer[ulWidth] = 0U;\r
+ }\r
+\r
+ return ulWidth;\r
+}\r
+\r
+\r
+/** @brief Parse the specified format string for a valid RedVSNPrintf() format\r
+ sequence, and return information about it.\r
+\r
+ @param pszFormat The format string to process.\r
+ @param pFormatType The PRINTFORMAT structure to fill. The data is only\r
+ valid if a non-zero length is returned.\r
+\r
+ @return The length of the full format specifier string, starting at\r
+ pFormat->ulSpecifierIdx. Returns zero if a valid specifier was\r
+ not found.\r
+*/\r
+static uint32_t ParseFormatSpecifier(\r
+ char const *pszFomat,\r
+ PRINTFORMAT *pFormatType)\r
+{\r
+ bool fContainsIllegalSequence = false;\r
+ uint32_t ulLen = 0U;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ while(pszFomat[ulIdx] != '\0')\r
+ {\r
+ uint32_t ulTypeLen;\r
+\r
+ /* general output\r
+ */\r
+ if(pszFomat[ulIdx] != '%')\r
+ {\r
+ ulIdx++;\r
+ }\r
+ else\r
+ {\r
+ RedMemSet(pFormatType, 0U, sizeof(*pFormatType));\r
+\r
+ /* Record the location of the start of the format sequence\r
+ */\r
+ pFormatType->ulSpecifierIdx = ulIdx;\r
+ ulIdx++;\r
+\r
+ if(pszFomat[ulIdx] == '-')\r
+ {\r
+ pFormatType->fLeftJustified = true;\r
+ ulIdx++;\r
+ }\r
+\r
+ if((pszFomat[ulIdx] == '0') || (pszFomat[ulIdx] == '_'))\r
+ {\r
+ pFormatType->cFillChar = pszFomat[ulIdx];\r
+ ulIdx++;\r
+ }\r
+ else\r
+ {\r
+ pFormatType->cFillChar = ' ';\r
+ }\r
+\r
+ if(pszFomat[ulIdx] == '*')\r
+ {\r
+ pFormatType->fHasVarWidth = true;\r
+ ulIdx++;\r
+ }\r
+ else if(ISDIGIT(pszFomat[ulIdx]))\r
+ {\r
+ pFormatType->ulFillLen = (uint32_t)RedAtoI(&pszFomat[ulIdx]);\r
+ while(ISDIGIT(pszFomat[ulIdx]))\r
+ {\r
+ ulIdx++;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* No fill length.\r
+ */\r
+ }\r
+\r
+ pFormatType->type = ParseFormatType(&pszFomat[ulIdx], &ulTypeLen);\r
+ if(pFormatType->type != PRFMT_UNKNOWN)\r
+ {\r
+ /* Even though we are returning successfully, keep track of\r
+ whether an illegal sequence was encountered and skipped.\r
+ */\r
+ pFormatType->fHasIllegalType = fContainsIllegalSequence;\r
+\r
+ ulLen = (ulIdx - pFormatType->ulSpecifierIdx) + ulTypeLen;\r
+ break;\r
+ }\r
+\r
+ /* In the case of an unrecognized type string, simply ignore\r
+ it entirely. Reset the pointer to the position following\r
+ the percent sign, so it is not found again.\r
+ */\r
+ fContainsIllegalSequence = false;\r
+ ulIdx = pFormatType->ulSpecifierIdx + 1U;\r
+ }\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+/** @brief Parse a RedPrintf() format type string to determine the proper data\r
+ type.\r
+\r
+ @param pszFormat The format string to process. This must be a pointer to\r
+ the character following any width or justification\r
+ characters.\r
+ @param pulTypeLen The location in which to store the type length. The\r
+ value will be 0 if PRFMT_UNKNOWN is returned.\r
+\r
+ @return Rhe PRFMT_* type value, or PRFMT_UNKNOWN if the type is not\r
+ recognized.\r
+*/\r
+static PRINTTYPE ParseFormatType(\r
+ const char *pszFormat,\r
+ uint32_t *pulTypeLen)\r
+{\r
+ PRINTTYPE fmtType = PRFMT_UNKNOWN;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ switch(pszFormat[ulIdx])\r
+ {\r
+ case '%':\r
+ fmtType = PRFMT_DOUBLEPERCENT;\r
+ break;\r
+ case 'c':\r
+ fmtType = PRFMT_CHAR;\r
+ break;\r
+ case 's':\r
+ fmtType = PRFMT_ANSISTRING;\r
+ break;\r
+ case 'p':\r
+ fmtType = PRFMT_POINTER;\r
+ break;\r
+ case 'd':\r
+ fmtType = MAPINT;\r
+ break;\r
+ case 'u':\r
+ fmtType = MAPUINT;\r
+ break;\r
+ case 'x':\r
+ fmtType = MAPHEXUINT;\r
+ break;\r
+ case 'h':\r
+ {\r
+ ulIdx++;\r
+ switch(pszFormat[ulIdx])\r
+ {\r
+ case 'd':\r
+ fmtType = MAPSHORT;\r
+ break;\r
+ case 'u':\r
+ fmtType = MAPUSHORT;\r
+ break;\r
+ case 'x':\r
+ fmtType = MAPHEXUSHORT;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ case 'l':\r
+ {\r
+ ulIdx++;\r
+ switch(pszFormat[ulIdx])\r
+ {\r
+ case 'd':\r
+ fmtType = MAPLONG;\r
+ break;\r
+ case 'u':\r
+ fmtType = MAPULONG;\r
+ break;\r
+ case 'x':\r
+ fmtType = MAPHEXULONG;\r
+ break;\r
+ case 'l':\r
+ {\r
+ ulIdx++;\r
+ switch(pszFormat[ulIdx])\r
+ {\r
+ case 'd':\r
+ fmtType = MAPLONGLONG;\r
+ break;\r
+ case 'u':\r
+ fmtType = MAPULONGLONG;\r
+ break;\r
+ case 'X':\r
+ fmtType = MAPHEXULONGLONG;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if(fmtType != PRFMT_UNKNOWN)\r
+ {\r
+ *pulTypeLen = ulIdx + 1U;\r
+ }\r
+ else\r
+ {\r
+ *pulTypeLen = 0U;\r
+ }\r
+\r
+ return fmtType;\r
+}\r
+\r
+\r
+/** @brief Format a signed 32-bit integer as a base 10 ASCII string.\r
+\r
+ @note If the output buffer length is exhausted, the result will *not* be\r
+ null-terminated.\r
+\r
+ @note If the @p ulFillLen value is greater than or equal to the buffer\r
+ length, the result will not be null-terminated, even if the\r
+ formatted portion of the data is shorter than the buffer length.\r
+\r
+ @param pcBuffer The output buffer\r
+ @param ulBufferLen A pointer to the output buffer length\r
+ @param lNum The 32-bit signed number to convert\r
+ @param ulFillLen The fill length, if any\r
+ @param cFill The fill character to use\r
+\r
+ @return The length of the string.\r
+*/\r
+static uint32_t LtoA(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ int32_t lNum,\r
+ uint32_t ulFillLen,\r
+ char cFill)\r
+{\r
+ uint32_t ulLen;\r
+\r
+ if(pcBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulLen = 0U;\r
+ }\r
+ else\r
+ {\r
+ char ach[12U]; /* big enough for a int32_t in base 10 */\r
+ uint32_t ulDigits = 0U;\r
+ uint32_t ulNum;\r
+ bool fSign;\r
+\r
+ if(lNum < 0)\r
+ {\r
+ fSign = true;\r
+ ulNum = (uint32_t)-lNum;\r
+ }\r
+ else\r
+ {\r
+ fSign = false;\r
+ ulNum = (uint32_t)lNum;\r
+ }\r
+\r
+ do\r
+ {\r
+ ach[ulDigits] = gacDigits[ulNum % 10U];\r
+ ulNum = ulNum / 10U;\r
+ ulDigits++;\r
+ }\r
+ while(ulNum);\r
+\r
+ if(fSign)\r
+ {\r
+ ach[ulDigits] = '-';\r
+ ulDigits++;\r
+ }\r
+\r
+ ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill);\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+/** @brief Format a signed 64-bit integer as a base 10 ASCII string.\r
+\r
+ @note If the output buffer length is exhausted, the result will *not* be\r
+ null-terminated.\r
+\r
+ @note If the @p ulFillLen value is greater than or equal to the buffer\r
+ length, the result will not be null-terminated, even if the\r
+ formatted portion of the data is shorter than the buffer length.\r
+\r
+ @param pcBuffer The output buffer\r
+ @param ulBufferLen A pointer to the output buffer length\r
+ @param llNum The 64-bit signed number to convert\r
+ @param ulFillLen The fill length, if any\r
+ @param cFill The fill character to use\r
+\r
+ @return The length of the string.\r
+*/\r
+static uint32_t LLtoA(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ int64_t llNum,\r
+ uint32_t ulFillLen,\r
+ char cFill)\r
+{\r
+ uint32_t ulLen;\r
+\r
+ if(pcBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulLen = 0U;\r
+ }\r
+ else\r
+ {\r
+ char ach[12U]; /* big enough for a int32_t in base 10 */\r
+ uint32_t ulDigits = 0U;\r
+ uint64_t ullNum;\r
+ bool fSign;\r
+\r
+ if(llNum < 0)\r
+ {\r
+ fSign = true;\r
+ ullNum = (uint64_t)-llNum;\r
+ }\r
+ else\r
+ {\r
+ fSign = false;\r
+ ullNum = (uint64_t)llNum;\r
+ }\r
+\r
+ /* Not allowed to assume that 64-bit division is OK, so use a\r
+ software division routine.\r
+ */\r
+ do\r
+ {\r
+ uint64_t ullQuotient;\r
+ uint32_t ulRemainder;\r
+\r
+ /* Note: RedUint64DivMod32() is smart enough to use normal division\r
+ once ullNumericVal <= UINT32_MAX.\r
+ */\r
+ ullQuotient = RedUint64DivMod32(ullNum, 10U, &ulRemainder);\r
+\r
+ ach[ulDigits] = gacDigits[ulRemainder];\r
+ ullNum = ullQuotient;\r
+ ulDigits++;\r
+ }\r
+ while(ullNum > 0U);\r
+\r
+ if(fSign)\r
+ {\r
+ ach[ulDigits] = '-';\r
+ ulDigits++;\r
+ }\r
+\r
+ ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill);\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+/** @brief Format an unsigned 32-bit integer as an ASCII string as decimal or\r
+ hex.\r
+\r
+ @note If the output buffer length is exhausted, the result will *not* be\r
+ null-terminated.\r
+\r
+ @param pcBuffer The output buffer\r
+ @param ulBufferLen The output buffer length\r
+ @param ulNum The 32-bit unsigned number to convert\r
+ @param fHex If true, format as hex; if false, decimal.\r
+ @param ulFillLen The fill length, if any\r
+ @param cFill The fill character to use\r
+\r
+ @return The length of the string.\r
+*/\r
+static uint32_t ULtoA(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ uint32_t ulNum,\r
+ bool fHex,\r
+ uint32_t ulFillLen,\r
+ char cFill)\r
+{\r
+ uint32_t ulLen;\r
+\r
+ if(pcBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulLen = 0U;\r
+ }\r
+ else\r
+ {\r
+ char ach[11U]; /* Big enough for a uint32_t in radix 10 */\r
+ uint32_t ulDigits = 0U;\r
+ uint32_t ulNumericVal = ulNum;\r
+ uint32_t ulRadix = fHex ? 16U : 10U;\r
+\r
+ do\r
+ {\r
+ ach[ulDigits] = gacDigits[ulNumericVal % ulRadix];\r
+ ulNumericVal = ulNumericVal / ulRadix;\r
+ ulDigits++;\r
+ }\r
+ while(ulNumericVal > 0U);\r
+\r
+ ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill);\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+/** @brief Format an unsigned 64-bit integer as an ASCII string as decimal or\r
+ hex.\r
+\r
+ @note If the output buffer length is exhausted, the result will *not* be\r
+ null-terminated.\r
+\r
+ @param pcBuffer The output buffer.\r
+ @param ulBufferLen The output buffer length.\r
+ @param ullNum The unsigned 64-bit number to convert.\r
+ @param fHex If true, format as hex; if false, decimal.\r
+ @param ulFillLen The fill length, if any.\r
+ @param cFill The fill character to use.\r
+\r
+ @return The length of the string.\r
+*/\r
+static uint32_t ULLtoA(\r
+ char *pcBuffer,\r
+ uint32_t ulBufferLen,\r
+ uint64_t ullNum,\r
+ bool fHex,\r
+ uint32_t ulFillLen,\r
+ char cFill)\r
+{\r
+ uint32_t ulLen;\r
+\r
+ if(pcBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulLen = 0U;\r
+ }\r
+ else\r
+ {\r
+\r
+ char ach[21U]; /* Big enough for a uint64_t in radix 10 */\r
+ uint32_t ulDigits = 0U;\r
+ uint64_t ullNumericVal = ullNum;\r
+\r
+ if(fHex)\r
+ {\r
+ /* We can figure out the digits using bit operations.\r
+ */\r
+ do\r
+ {\r
+ ach[ulDigits] = gacDigits[ullNumericVal & 15U];\r
+ ullNumericVal >>= 4U;\r
+ ulDigits++;\r
+ }\r
+ while(ullNumericVal > 0U);\r
+ }\r
+ else\r
+ {\r
+ /* Not allowed to assume that 64-bit division is OK, so use a\r
+ software division routine.\r
+ */\r
+ do\r
+ {\r
+ uint64_t ullQuotient;\r
+ uint32_t ulRemainder;\r
+\r
+ /* Note: RedUint64DivMod32() is smart enough to use normal division\r
+ once ullNumericVal <= UINT32_MAX.\r
+ */\r
+ ullQuotient = RedUint64DivMod32(ullNumericVal, 10U, &ulRemainder);\r
+\r
+ ach[ulDigits] = gacDigits[ulRemainder];\r
+ ullNumericVal = ullQuotient;\r
+ ulDigits++;\r
+ }\r
+ while(ullNumericVal > 0U);\r
+ }\r
+\r
+ ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill);\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+/** @brief Finish converting a number into an ASCII string representing that\r
+ number.\r
+\r
+ This helper function contains common logic that needs to run at the end of\r
+ all the "toA" functions. It adds the fill character and reverses the digits\r
+ string.\r
+\r
+ @param pcDigits The digits (and sign) for the ASCII string, in reverse\r
+ order as they were computed.\r
+ @param ulDigits The number of digit characters.\r
+ @param pcOutBuffer The output buffer.\r
+ @param ulBufferLen The length of the output buffer.\r
+ @param ulFillLen The fill length. If the number string is shorter than\r
+ this, the remaining bytes are filled with @p cFill.\r
+ @param cFill The fill character.\r
+\r
+ @return The length of @p pcOutBuffer.\r
+*/\r
+static uint32_t FinishToA(\r
+ const char *pcDigits,\r
+ uint32_t ulDigits,\r
+ char *pcOutBuffer,\r
+ uint32_t ulBufferLen,\r
+ uint32_t ulFillLen,\r
+ char cFill)\r
+{\r
+ uint32_t ulIdx = 0U;\r
+ uint32_t ulDigitIdx = ulDigits;\r
+\r
+ /* user may have asked for a fill char\r
+ */\r
+ if(ulFillLen > ulDigits)\r
+ {\r
+ uint32_t ulFillRem = ulFillLen - ulDigits;\r
+\r
+ while((ulFillRem > 0U) && (ulIdx < ulBufferLen))\r
+ {\r
+ pcOutBuffer[ulIdx] = cFill;\r
+ ulIdx++;\r
+ ulFillRem--;\r
+ }\r
+ }\r
+\r
+ /* reverse the string\r
+ */\r
+ while((ulDigitIdx > 0) && (ulIdx < ulBufferLen))\r
+ {\r
+ ulDigitIdx--;\r
+ pcOutBuffer[ulIdx] = pcDigits[ulDigitIdx];\r
+ ulIdx++;\r
+ }\r
+\r
+ if(ulIdx < ulBufferLen)\r
+ {\r
+ pcOutBuffer[ulIdx] = '\0';\r
+ }\r
+\r
+ return ulIdx;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements a random number generator.\r
+*/\r
+#include <redfs.h>\r
+#include <redtestutils.h>\r
+\r
+\r
+/* This is the global seed used by the random number generator when the caller\r
+ has not provided a seed to either the RedRand32() or RedRand64() functions.\r
+*/\r
+static uint64_t ullGlobalRandomNumberSeed;\r
+\r
+/* Whether the above seed has been initialized.\r
+*/\r
+static bool fGlobalSeedInited;\r
+\r
+\r
+/** @brief Set the global seed used by the random number generator.\r
+\r
+ The global seed gets used when RedRand64() or RedRand32() are called with\r
+ a NULL seed argument.\r
+\r
+ @param ullSeed The value to use as the global RNG seed.\r
+*/\r
+void RedRandSeed(\r
+ uint64_t ullSeed)\r
+{\r
+ ullGlobalRandomNumberSeed = ullSeed;\r
+ fGlobalSeedInited = true;\r
+}\r
+\r
+\r
+/** @brief Generate a 64-bit pseudo-random number.\r
+\r
+ The period of this random number generator is 2^64 (1.8 x 1019). These\r
+ parameters are the same as the default one-stream SPRNG lcg64 generator and\r
+ it satisfies the requirements for a maximal period.\r
+\r
+ The tempering value is used and an AND mask and is specifically selected to\r
+ favor the distribution of lower bits.\r
+\r
+ @param pullSeed A pointer to the seed to use. Set this value to NULL to\r
+ use the internal global seed value.\r
+\r
+ @return A pseudo-random number in the range [0, UINT64_MAX].\r
+*/\r
+uint64_t RedRand64(\r
+ uint64_t *pullSeed)\r
+{\r
+ const uint64_t ullA = UINT64_SUFFIX(2862933555777941757);\r
+ const uint64_t ullC = UINT64_SUFFIX(3037000493);\r
+ const uint64_t ullT = UINT64_SUFFIX(4921441182957829599);\r
+ uint64_t ullN;\r
+ uint64_t *pullSeedPtr;\r
+ uint64_t ullLocalSeed;\r
+\r
+ if(pullSeed != NULL)\r
+ {\r
+ ullLocalSeed = *pullSeed;\r
+ pullSeedPtr = pullSeed;\r
+ }\r
+ else\r
+ {\r
+ if(!fGlobalSeedInited)\r
+ {\r
+ /* Unfortunately, the Reliance Edge OS services don't give us much\r
+ to work with to initialize the global seed. There is no entropy\r
+ abstraction, no tick count abstraction, and the timestamp\r
+ abstraction uses an opaque type which is not guaranteed to be an\r
+ integer. The best we can do is use the RTC.\r
+\r
+ Tests using the RNG should be supplying a seed anyway, for\r
+ reproducibility.\r
+ */\r
+ RedRandSeed((uint64_t)RedOsClockGetTime());\r
+ }\r
+\r
+ ullLocalSeed = ullGlobalRandomNumberSeed;\r
+ pullSeedPtr = &ullGlobalRandomNumberSeed;\r
+ }\r
+\r
+ ullN = (ullLocalSeed * ullA) + ullC;\r
+\r
+ *pullSeedPtr = ullN;\r
+\r
+ /* The linear congruential generator used above produces good psuedo-random\r
+ 64-bit number sequences, however, as with any LCG, the period of the\r
+ lower order bits is much shorter resulting in alternately odd/even pairs\r
+ in bit zero.\r
+\r
+ The result of the LGC above is tempered below with a series of XOR and\r
+ shift operations to produce a more acceptable equidistribution of bits\r
+ throughout the 64-bit range.\r
+ */\r
+ ullN ^= (ullN >> 21U) & ullT;\r
+ ullN ^= (ullN >> 43U) & ullT;\r
+ ullN ^= (ullN << 23U) & ~ullT;\r
+ ullN ^= (ullN << 31U) & ~ullT;\r
+\r
+ return ullN;\r
+}\r
+\r
+\r
+/** @brief Generate a 32-bit pseudo-random number.\r
+\r
+ @note The 32-bit random number generator internally uses the 64-bit random\r
+ number generator, returning the low 32-bits of the pseudo-random\r
+ 64-bit value.\r
+\r
+ @param pulSeed A pointer to the seed to use. Set this value to NULL to use\r
+ the internal global seed value.\r
+\r
+ @return A pseudo-random number in the range [0, UINT32_MAX].\r
+*/\r
+uint32_t RedRand32(\r
+ uint32_t *pulSeed)\r
+{\r
+ uint64_t ullN;\r
+\r
+ if(pulSeed != NULL)\r
+ {\r
+ uint64_t ullLocalSeed;\r
+\r
+ ullLocalSeed = *pulSeed;\r
+ ullN = RedRand64(&ullLocalSeed);\r
+ *pulSeed = (uint32_t)ullLocalSeed;\r
+ }\r
+ else\r
+ {\r
+ ullN = RedRand64(NULL);\r
+ }\r
+\r
+ return (uint32_t)ullN;\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>\r
+ *\r
+ * Permission to use, copy, modify, and distribute this software for any\r
+ * purpose with or without fee is hereby granted, provided that the above\r
+ * copyright notice and this permission notice appear in all copies.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\r
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\r
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\r
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\r
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+ *\r
+ * Sponsored in part by the Defense Advanced Research Projects\r
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force\r
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.\r
+ */\r
+/*-\r
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.\r
+ * All rights reserved.\r
+ *\r
+ * This code is derived from software contributed to The NetBSD Foundation\r
+ * by Dieter Baron and Thomas Klausner.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS\r
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+/** @file\r
+ @brief Implementations of getopt() and getopt_long() work-alike functions.\r
+\r
+ This code was taken from FreeBSD and slightly modified, mostly to rename\r
+ symbols with external linkage to avoid naming conflicts in systems where\r
+ there are real getopt()/getopt_long() implementations, and for portability.\r
+*/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include <redfs.h>\r
+#include <redgetopt.h>\r
+#include <redtestutils.h>\r
+#include <rederrno.h>\r
+\r
+\r
+int32_t red_opterr = 1; /* if error message should be printed */\r
+int32_t red_optind = 1; /* index into parent argv vector */\r
+int32_t red_optopt = '?'; /* character checked for validity */\r
+int32_t red_optreset; /* reset RedGetopt */\r
+const char *red_optarg; /* argument associated with option */\r
+\r
+#define PRINT_ERROR ((red_opterr) && (*options != ':'))\r
+\r
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */\r
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */\r
+#define FLAG_LONGONLY 0x04 /* operate as RedGetoptLongOnly */\r
+\r
+/* return values */\r
+#define BADCH (int)'?'\r
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')\r
+#define INORDER (int)1\r
+\r
+#define EMSG ""\r
+\r
+#define NO_PREFIX (-1)\r
+#define D_PREFIX 0\r
+#define DD_PREFIX 1\r
+#define W_PREFIX 2\r
+\r
+static int gcd(int a, int b);\r
+static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv);\r
+static int parse_long_options(char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int short_too, int flags);\r
+static int getopt_internal(int nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int flags);\r
+\r
+static const char *place = EMSG; /* option letter processing */\r
+\r
+/* XXX: set red_optreset to 1 rather than these two */\r
+static int nonopt_start = -1; /* first non option argument (for permute) */\r
+static int nonopt_end = -1; /* first option after non options (for permute) */\r
+\r
+/* Error messages */\r
+static const char recargchar[] = "option requires an argument -- %c\n";\r
+static const char illoptchar[] = "illegal option -- %c\n"; /* From P1003.2 */\r
+static int dash_prefix = NO_PREFIX;\r
+static const char gnuoptchar[] = "invalid option -- %c\n";\r
+\r
+static const char recargstring[] = "option `%s%s' requires an argument\n";\r
+static const char ambig[] = "option `%s%s' is ambiguous\n";\r
+static const char noarg[] = "option `%s%s' doesn't allow an argument\n";\r
+static const char illoptstring[] = "unrecognized option `%s%s'\n";\r
+\r
+/*\r
+ * Compute the greatest common divisor of a and b.\r
+ */\r
+static int\r
+gcd(int a, int b)\r
+{\r
+ int c;\r
+\r
+ c = a % b;\r
+ while (c != 0) {\r
+ a = b;\r
+ b = c;\r
+ c = a % b;\r
+ }\r
+\r
+ return (b);\r
+}\r
+\r
+/*\r
+ * Exchange the block from nonopt_start to nonopt_end with the block\r
+ * from nonopt_end to opt_end (keeping the same order of arguments\r
+ * in each block).\r
+ */\r
+static void\r
+permute_args(int panonopt_start, int panonopt_end, int opt_end,\r
+ char * const *nargv)\r
+{\r
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;\r
+ char *swap;\r
+\r
+ /*\r
+ * compute lengths of blocks and number and size of cycles\r
+ */\r
+ nnonopts = panonopt_end - panonopt_start;\r
+ nopts = opt_end - panonopt_end;\r
+ ncycle = gcd(nnonopts, nopts);\r
+ cyclelen = (opt_end - panonopt_start) / ncycle;\r
+\r
+ for (i = 0; i < ncycle; i++) {\r
+ cstart = panonopt_end+i;\r
+ pos = cstart;\r
+ for (j = 0; j < cyclelen; j++) {\r
+ if (pos >= panonopt_end)\r
+ pos -= nnonopts;\r
+ else\r
+ pos += nopts;\r
+ swap = nargv[pos];\r
+ ((char **) nargv)[pos] = nargv[cstart];\r
+ ((char **)nargv)[cstart] = swap;\r
+ }\r
+ }\r
+}\r
+\r
+/*\r
+ * parse_long_options --\r
+ * Parse long options in argc/argv argument vector.\r
+ * Returns -1 if short_too is set and the option does not match long_options.\r
+ */\r
+static int\r
+parse_long_options(char * const *nargv, const char *options,\r
+ const REDOPTION *long_options, int32_t *idx, int short_too, int flags)\r
+{\r
+ const char *current_argv, *has_equal, *current_dash;\r
+ size_t current_argv_len;\r
+ int i, match, exact_match, second_partial_match;\r
+\r
+ current_argv = place;\r
+ switch (dash_prefix) {\r
+ case D_PREFIX:\r
+ current_dash = "-";\r
+ break;\r
+ case DD_PREFIX:\r
+ current_dash = "--";\r
+ break;\r
+ case W_PREFIX:\r
+ current_dash = "-W ";\r
+ break;\r
+ default:\r
+ current_dash = "";\r
+ break;\r
+ }\r
+ match = -1;\r
+ exact_match = 0;\r
+ second_partial_match = 0;\r
+\r
+ red_optind++;\r
+\r
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {\r
+ /* argument found (--option=arg) */\r
+ current_argv_len = has_equal - current_argv;\r
+ has_equal++;\r
+ } else\r
+ current_argv_len = strlen(current_argv);\r
+\r
+ for (i = 0; long_options[i].name; i++) {\r
+ /* find matching long option */\r
+ if (strncmp(current_argv, long_options[i].name,\r
+ current_argv_len))\r
+ continue;\r
+\r
+ if (strlen(long_options[i].name) == current_argv_len) {\r
+ /* exact match */\r
+ match = i;\r
+ exact_match = 1;\r
+ break;\r
+ }\r
+ /*\r
+ * If this is a known short option, don't allow\r
+ * a partial match of a single character.\r
+ */\r
+ if (short_too && current_argv_len == 1)\r
+ continue;\r
+\r
+ if (match == -1) /* first partial match */\r
+ match = i;\r
+ else if ((flags & FLAG_LONGONLY) ||\r
+ long_options[i].has_arg !=\r
+ long_options[match].has_arg ||\r
+ long_options[i].flag != long_options[match].flag ||\r
+ long_options[i].val != long_options[match].val)\r
+ second_partial_match = 1;\r
+ }\r
+ if (!exact_match && second_partial_match) {\r
+ /* ambiguous abbreviation */\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr,\r
+ ambig,\r
+ current_dash,\r
+ current_argv);\r
+ red_optopt = 0;\r
+ return (BADCH);\r
+ }\r
+ if (match != -1) { /* option found */\r
+ if (long_options[match].has_arg == red_no_argument\r
+ && has_equal) {\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr,\r
+ noarg,\r
+ current_dash,\r
+ current_argv);\r
+ /*\r
+ * XXX: GNU sets red_optopt to val regardless of flag\r
+ */\r
+ if (long_options[match].flag == NULL)\r
+ red_optopt = long_options[match].val;\r
+ else\r
+ red_optopt = 0;\r
+ return (BADCH);\r
+ }\r
+ if (long_options[match].has_arg == red_required_argument ||\r
+ long_options[match].has_arg == red_optional_argument) {\r
+ if (has_equal)\r
+ red_optarg = has_equal;\r
+ else if (long_options[match].has_arg ==\r
+ red_required_argument) {\r
+ /*\r
+ * optional argument doesn't use next nargv\r
+ */\r
+ red_optarg = nargv[red_optind++];\r
+ }\r
+ }\r
+ if ((long_options[match].has_arg == red_required_argument)\r
+ && (red_optarg == NULL)) {\r
+ /*\r
+ * Missing argument; leading ':' indicates no error\r
+ * should be generated.\r
+ */\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr,\r
+ recargstring,\r
+ current_dash,\r
+ current_argv);\r
+ /*\r
+ * XXX: GNU sets red_optopt to val regardless of flag\r
+ */\r
+ if (long_options[match].flag == NULL)\r
+ red_optopt = long_options[match].val;\r
+ else\r
+ red_optopt = 0;\r
+ --red_optind;\r
+ return (BADARG);\r
+ }\r
+ } else { /* unknown option */\r
+ if (short_too) {\r
+ --red_optind;\r
+ return (-1);\r
+ }\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr,\r
+ illoptstring,\r
+ current_dash,\r
+ current_argv);\r
+ red_optopt = 0;\r
+ return (BADCH);\r
+ }\r
+ if (idx)\r
+ *idx = match;\r
+ if (long_options[match].flag) {\r
+ *long_options[match].flag = long_options[match].val;\r
+ return (0);\r
+ } else\r
+ return (long_options[match].val);\r
+}\r
+\r
+/*\r
+ * getopt_internal --\r
+ * Parse argc/argv argument vector. Called by user level routines.\r
+ */\r
+static int\r
+getopt_internal(int nargc, char * const *nargv, const char *options,\r
+ const REDOPTION *long_options, int32_t *idx, int flags)\r
+{\r
+ char *oli; /* option letter list index */\r
+ int optchar, short_too;\r
+\r
+ if (options == NULL)\r
+ return (-1);\r
+\r
+ /*\r
+ * XXX Some GNU programs (like cvs) set red_optind to 0 instead of\r
+ * XXX using red_optreset. Work around this braindamage.\r
+ */\r
+ if (red_optind == 0)\r
+ red_optind = red_optreset = 1;\r
+\r
+ /*\r
+ * Disable GNU extensions if options string begins with a '+'.\r
+ */\r
+ if (*options == '-')\r
+ flags |= FLAG_ALLARGS;\r
+ else if (*options == '+')\r
+ flags &= ~FLAG_PERMUTE;\r
+ if (*options == '+' || *options == '-')\r
+ options++;\r
+\r
+ red_optarg = NULL;\r
+ if (red_optreset)\r
+ nonopt_start = nonopt_end = -1;\r
+start:\r
+ if (red_optreset || !*place) { /* update scanning pointer */\r
+ red_optreset = 0;\r
+ if (red_optind >= nargc) { /* end of argument vector */\r
+ place = EMSG;\r
+ if (nonopt_end != -1) {\r
+ /* do permutation, if we have to */\r
+ permute_args(nonopt_start, nonopt_end,\r
+ red_optind, nargv);\r
+ red_optind -= nonopt_end - nonopt_start;\r
+ }\r
+ else if (nonopt_start != -1) {\r
+ /*\r
+ * If we skipped non-options, set red_optind\r
+ * to the first of them.\r
+ */\r
+ red_optind = nonopt_start;\r
+ }\r
+ nonopt_start = nonopt_end = -1;\r
+ return (-1);\r
+ }\r
+ if (*(place = nargv[red_optind]) != '-' || place[1] == '\0') {\r
+ place = EMSG; /* found non-option */\r
+ if (flags & FLAG_ALLARGS) {\r
+ /*\r
+ * GNU extension:\r
+ * return non-option as argument to option 1\r
+ */\r
+ red_optarg = nargv[red_optind++];\r
+ return (INORDER);\r
+ }\r
+ if (!(flags & FLAG_PERMUTE)) {\r
+ /*\r
+ * If no permutation wanted, stop parsing\r
+ * at first non-option.\r
+ */\r
+ return (-1);\r
+ }\r
+ /* do permutation */\r
+ if (nonopt_start == -1)\r
+ nonopt_start = red_optind;\r
+ else if (nonopt_end != -1) {\r
+ permute_args(nonopt_start, nonopt_end,\r
+ red_optind, nargv);\r
+ nonopt_start = red_optind -\r
+ (nonopt_end - nonopt_start);\r
+ nonopt_end = -1;\r
+ }\r
+ red_optind++;\r
+ /* process next argument */\r
+ goto start;\r
+ }\r
+ if (nonopt_start != -1 && nonopt_end == -1)\r
+ nonopt_end = red_optind;\r
+\r
+ /*\r
+ * If we have "-" do nothing, if "--" we are done.\r
+ */\r
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {\r
+ red_optind++;\r
+ place = EMSG;\r
+ /*\r
+ * We found an option (--), so if we skipped\r
+ * non-options, we have to permute.\r
+ */\r
+ if (nonopt_end != -1) {\r
+ permute_args(nonopt_start, nonopt_end,\r
+ red_optind, nargv);\r
+ red_optind -= nonopt_end - nonopt_start;\r
+ }\r
+ nonopt_start = nonopt_end = -1;\r
+ return (-1);\r
+ }\r
+ }\r
+\r
+ /*\r
+ * Check long options if:\r
+ * 1) we were passed some\r
+ * 2) the arg is not just "-"\r
+ * 3) either the arg starts with -- we are RedGetoptLongOnly()\r
+ */\r
+ if (long_options != NULL && place != nargv[red_optind] &&\r
+ (*place == '-' || (flags & FLAG_LONGONLY))) {\r
+ short_too = 0;\r
+ dash_prefix = D_PREFIX;\r
+ if (*place == '-') {\r
+ place++; /* --foo long option */\r
+ dash_prefix = DD_PREFIX;\r
+ } else if (*place != ':' && strchr(options, *place) != NULL)\r
+ short_too = 1; /* could be short option too */\r
+\r
+ optchar = parse_long_options(nargv, options, long_options,\r
+ idx, short_too, flags);\r
+ if (optchar != -1) {\r
+ place = EMSG;\r
+ return (optchar);\r
+ }\r
+ }\r
+\r
+ if ((optchar = (int)*place++) == (int)':' ||\r
+ (optchar == (int)'-' && *place != '\0') ||\r
+ (oli = strchr(options, optchar)) == NULL) {\r
+ /*\r
+ * If the user specified "-" and '-' isn't listed in\r
+ * options, return -1 (non-option) as per POSIX.\r
+ * Otherwise, it is an unknown option character (or ':').\r
+ */\r
+ if (optchar == (int)'-' && *place == '\0')\r
+ return (-1);\r
+ if (!*place)\r
+ ++red_optind;\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr, gnuoptchar, optchar);\r
+ red_optopt = optchar;\r
+ return (BADCH);\r
+ }\r
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {\r
+ /* -W long-option */\r
+ if (*place) /* no space */\r
+ /* NOTHING */;\r
+ else if (++red_optind >= nargc) { /* no arg */\r
+ place = EMSG;\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr, recargchar, optchar);\r
+ red_optopt = optchar;\r
+ return (BADARG);\r
+ } else /* white space */\r
+ place = nargv[red_optind];\r
+ dash_prefix = W_PREFIX;\r
+ optchar = parse_long_options(nargv, options, long_options,\r
+ idx, 0, flags);\r
+ place = EMSG;\r
+ return (optchar);\r
+ }\r
+ if (*++oli != ':') { /* doesn't take argument */\r
+ if (!*place)\r
+ ++red_optind;\r
+ } else { /* takes (optional) argument */\r
+ red_optarg = NULL;\r
+ if (*place) /* no white space */\r
+ red_optarg = place;\r
+ else if (oli[1] != ':') { /* arg not optional */\r
+ if (++red_optind >= nargc) { /* no arg */\r
+ place = EMSG;\r
+ if (PRINT_ERROR)\r
+ fprintf(stderr, recargchar, optchar);\r
+ red_optopt = optchar;\r
+ return (BADARG);\r
+ } else\r
+ red_optarg = nargv[red_optind];\r
+ }\r
+ place = EMSG;\r
+ ++red_optind;\r
+ }\r
+ /* dump back option letter */\r
+ return (optchar);\r
+}\r
+\r
+\r
+/** @brief Get option character from command line argument list.\r
+\r
+ For more details, consult the getopt() man pages, since this function is\r
+ generally similar.\r
+\r
+ @param nargc Number of arguments (argc passed into main()).\r
+ @param nargv Argument vector (argv passed into main()).\r
+ @param options String of option characters.\r
+\r
+ @return The next known option character in @p options. If a character not\r
+ found in @p options is found or if an option is missing an argument,\r
+ it returns '?'. Returns -1 when the argument list is exhausted.\r
+*/\r
+int32_t RedGetopt(\r
+ int32_t nargc,\r
+ char * const *nargv,\r
+ const char *options)\r
+{\r
+ return getopt_internal(nargc, nargv, options, NULL, NULL, FLAG_PERMUTE);\r
+}\r
+\r
+\r
+/** @brief Get long options from command line argument list.\r
+\r
+ For more details, consult the getopt_long() man pages, since this function\r
+ is generally similar.\r
+\r
+ @param nargc Number of arguments (argc passed into main()).\r
+ @param nargv Argument vector (argv passed into main()).\r
+ @param options String of option characters.\r
+ @param long_options The long options; the last element of this array must be\r
+ filled with zeroes.\r
+ @param idx If non-NULL, then populated with the index of the long\r
+ option relative to @p long_options.\r
+\r
+ @return If the flag field in REDOPTION is NULL, returns the value specified\r
+ in the val field, which is usually just the corresponding short\r
+ option. If flag is non-NULL, returns zero and stores val in the\r
+ location pointed to by flag. Returns ':' if an option was missing\r
+ its argument, '?' for an unknown option, and -1 when the argument\r
+ list is exhausted.\r
+*/\r
+int32_t RedGetoptLong(\r
+ int32_t nargc,\r
+ char * const *nargv,\r
+ const char *options,\r
+ const REDOPTION *long_options,\r
+ int32_t *idx)\r
+{\r
+ return getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE);\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements common-code utilities for tools and tests.\r
+*/\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <errno.h>\r
+#include <limits.h>\r
+\r
+#include <redfs.h>\r
+#include <redcoreapi.h>\r
+#include <redvolume.h>\r
+#include <redtoolcmn.h>\r
+\r
+\r
+/** @brief Convert a string into a volume number.\r
+\r
+ In a POSIX-like configuration, @p pszVolume can either be a volume number or\r
+ a volume path prefix. In case of ambiguity, the volume number of a matching\r
+ path prefix takes precedence.\r
+\r
+ In an FSE configuration, @p pszVolume can be a volume number.\r
+\r
+ @param pszVolume The volume string.\r
+\r
+ @return On success, returns the volume number; on failure, returns\r
+ #REDCONF_VOLUME_COUNT.\r
+*/\r
+uint8_t RedFindVolumeNumber(\r
+ const char *pszVolume)\r
+{\r
+ unsigned long ulNumber;\r
+ const char *pszEndPtr;\r
+ uint8_t bVolNum = REDCONF_VOLUME_COUNT;\r
+ #if REDCONF_API_POSIX == 1\r
+ uint8_t bIndex;\r
+ #endif\r
+\r
+ /* Determine if pszVolume can be interpreted as a volume number.\r
+ */\r
+ errno = 0;\r
+ ulNumber = strtoul(pszVolume, (char **)&pszEndPtr, 10);\r
+ if((errno == 0) && (ulNumber != ULONG_MAX) && (pszEndPtr[0U] == '\0') && (ulNumber < REDCONF_VOLUME_COUNT))\r
+ {\r
+ bVolNum = (uint8_t)ulNumber;\r
+ }\r
+\r
+ #if REDCONF_API_POSIX == 1\r
+ /* Determine if pszVolume is a valid path prefix.\r
+ */\r
+ for(bIndex = 0U; bIndex < REDCONF_VOLUME_COUNT; bIndex++)\r
+ {\r
+ if(strcmp(gaRedVolConf[bIndex].pszPathPrefix, pszVolume) == 0)\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(bIndex < REDCONF_VOLUME_COUNT)\r
+ {\r
+ /* Edge case: It is technically possible for pszVolume to be both a\r
+ valid volume number and a valid volume prefix, for different\r
+ volumes. For example, if pszVolume is "2", that would be recognized\r
+ as volume number 2 above. But if "2" is the (poorly chosen) path\r
+ prefix for volume number 4, that would also be matched. Since the\r
+ POSIX-like API is primarily name based, and the ability to use\r
+ volume numbers with this tool is just a convenience, the volume\r
+ prefix takes precedence.\r
+ */\r
+ bVolNum = bIndex;\r
+ }\r
+ #endif\r
+\r
+ return bVolNum;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements utilities for working with bitmaps.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+/** @brief Query the state of a bit in a bitmap.\r
+\r
+ Bits are counted from most significant to least significant. Thus, the mask\r
+ for bit zero is 0x80 applied to the first byte in the bitmap.\r
+\r
+ @param pbBitmap Pointer to the bitmap.\r
+ @param ulBit The bit to query.\r
+\r
+ @retval Whether the bit is set (true) or clear (false.\r
+*/\r
+bool RedBitGet(\r
+ const uint8_t *pbBitmap,\r
+ uint32_t ulBit)\r
+{\r
+ bool fRet;\r
+\r
+ if(pbBitmap == NULL)\r
+ {\r
+ REDERROR();\r
+ fRet = false;\r
+ }\r
+ else\r
+ {\r
+ fRet = (pbBitmap[ulBit >> 3U] & (0x80U >> (ulBit & 7U))) != 0U;\r
+ }\r
+\r
+ return fRet;\r
+}\r
+\r
+\r
+/** @brief Set a bit in a bitmap to one.\r
+\r
+ Bits are counted from most significant to least significant. Thus, the mask\r
+ for bit zero is 0x80 applied to the first byte in the bitmap.\r
+\r
+ @param pbBitmap Pointer to the bitmap.\r
+ @param ulBit The bit to set.\r
+*/\r
+void RedBitSet(\r
+ uint8_t *pbBitmap,\r
+ uint32_t ulBit)\r
+{\r
+ REDASSERT(pbBitmap != NULL);\r
+\r
+ if(pbBitmap != NULL)\r
+ {\r
+ pbBitmap[ulBit >> 3U] |= (0x80U >> (ulBit & 7U));\r
+ }\r
+}\r
+\r
+\r
+/** @brief Clear a bit in a bitmap to zero.\r
+\r
+ Bits are counted from most significant to least significant. Thus, the mask\r
+ for bit zero is 0x80 applied to the first byte in the bitmap.\r
+\r
+ @param pbBitmap Pointer to the bitmap.\r
+ @param ulBit The bit to clear.\r
+*/\r
+void RedBitClear(\r
+ uint8_t *pbBitmap,\r
+ uint32_t ulBit)\r
+{\r
+ REDASSERT(pbBitmap != NULL);\r
+\r
+ if(pbBitmap != NULL)\r
+ {\r
+ pbBitmap[ulBit >> 3U] &= ~(0x80U >> (ulBit & 7U));\r
+ }\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements utilities for calculating CRC-32 checksums.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+/* The CRC functions do not return errors since the only detectable error\r
+ condition is a NULL buffer pointer. If such a condition does arise, the\r
+ functions assert and return the below CRC, which, although a legal CRC,\r
+ is nonetheless suspicious and could provide a clue that something has\r
+ gone wrong.\r
+*/\r
+#define SUSPICIOUS_CRC_VALUE (0xBAADC0DEU)\r
+\r
+#define CRC_BITWISE (0U)\r
+#define CRC_SARWATE (1U)\r
+#define CRC_SLICEBY8 (2U)\r
+\r
+\r
+#if REDCONF_CRC_ALGORITHM == CRC_BITWISE\r
+\r
+/* The following is representative of the polynomial accepted by CCITT 32-bit\r
+ and in IEEE 802.3, Ethernet 2 specification.\r
+\r
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1\r
+ (reverse order)\r
+ 1110 1101 1011 1000 1000 0011 0010 0000 1\r
+ (E) (D) (B) (8) (8) (3) (2) (0)\r
+*/\r
+#define CCITT_32_POLYNOMIAL (0xEDB88320U)\r
+\r
+\r
+/** @brief Compute a CRC32 for the given data buffer.\r
+\r
+ For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple\r
+ buffers, call this function with the previously returned CRC value.\r
+\r
+ @param ulInitCrc32 Starting CRC value.\r
+ @param pBuffer Data buffer to calculate the CRC from.\r
+ @param ulLength Number of bytes of data in the given buffer.\r
+\r
+ @return The updated CRC value.\r
+*/\r
+uint32_t RedCrc32Update(\r
+ uint32_t ulInitCrc32,\r
+ const void *pBuffer,\r
+ uint32_t ulLength)\r
+{\r
+ uint32_t ulCrc32;\r
+\r
+ if(pBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulCrc32 = SUSPICIOUS_CRC_VALUE;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+ uint32_t ulIdx;\r
+\r
+ ulCrc32 = ~ulInitCrc32;\r
+\r
+ for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx)\r
+ {\r
+ uint32_t ulBit;\r
+\r
+ ulCrc32 ^= pbBuffer[ulIdx];\r
+\r
+ /* Branchless inner loop (greatly improves performance).\r
+ */\r
+ for(ulBit = 0U; ulBit < 8U; ulBit++)\r
+ {\r
+ ulCrc32 = ((ulCrc32 & 1U) * CCITT_32_POLYNOMIAL) ^ (ulCrc32 >> 1U);\r
+ }\r
+ }\r
+\r
+ ulCrc32 = ~ulCrc32;\r
+ }\r
+\r
+ return ulCrc32;\r
+}\r
+\r
+#elif REDCONF_CRC_ALGORITHM == CRC_SARWATE\r
+\r
+/** @brief Compute a CRC32 for the given data buffer.\r
+\r
+ For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple\r
+ buffers, call this function with the previously returned CRC value.\r
+\r
+ @param ulInitCrc32 Starting CRC value.\r
+ @param pBuffer Data buffer to calculate the CRC from.\r
+ @param ulLength Number of bytes of data in the given buffer.\r
+\r
+ @return The updated CRC value.\r
+*/\r
+uint32_t RedCrc32Update(\r
+ uint32_t ulInitCrc32,\r
+ const void *pBuffer,\r
+ uint32_t ulLength)\r
+{\r
+ static const uint32_t aulCrc32Table[] =\r
+ {\r
+ 0x00000000U, 0x77073096U, 0xEE0E612CU, 0x990951BAU, 0x076DC419U, 0x706AF48FU, 0xE963A535U, 0x9E6495A3U,\r
+ 0x0EDB8832U, 0x79DCB8A4U, 0xE0D5E91EU, 0x97D2D988U, 0x09B64C2BU, 0x7EB17CBDU, 0xE7B82D07U, 0x90BF1D91U,\r
+ 0x1DB71064U, 0x6AB020F2U, 0xF3B97148U, 0x84BE41DEU, 0x1ADAD47DU, 0x6DDDE4EBU, 0xF4D4B551U, 0x83D385C7U,\r
+ 0x136C9856U, 0x646BA8C0U, 0xFD62F97AU, 0x8A65C9ECU, 0x14015C4FU, 0x63066CD9U, 0xFA0F3D63U, 0x8D080DF5U,\r
+ 0x3B6E20C8U, 0x4C69105EU, 0xD56041E4U, 0xA2677172U, 0x3C03E4D1U, 0x4B04D447U, 0xD20D85FDU, 0xA50AB56BU,\r
+ 0x35B5A8FAU, 0x42B2986CU, 0xDBBBC9D6U, 0xACBCF940U, 0x32D86CE3U, 0x45DF5C75U, 0xDCD60DCFU, 0xABD13D59U,\r
+ 0x26D930ACU, 0x51DE003AU, 0xC8D75180U, 0xBFD06116U, 0x21B4F4B5U, 0x56B3C423U, 0xCFBA9599U, 0xB8BDA50FU,\r
+ 0x2802B89EU, 0x5F058808U, 0xC60CD9B2U, 0xB10BE924U, 0x2F6F7C87U, 0x58684C11U, 0xC1611DABU, 0xB6662D3DU,\r
+ 0x76DC4190U, 0x01DB7106U, 0x98D220BCU, 0xEFD5102AU, 0x71B18589U, 0x06B6B51FU, 0x9FBFE4A5U, 0xE8B8D433U,\r
+ 0x7807C9A2U, 0x0F00F934U, 0x9609A88EU, 0xE10E9818U, 0x7F6A0DBBU, 0x086D3D2DU, 0x91646C97U, 0xE6635C01U,\r
+ 0x6B6B51F4U, 0x1C6C6162U, 0x856530D8U, 0xF262004EU, 0x6C0695EDU, 0x1B01A57BU, 0x8208F4C1U, 0xF50FC457U,\r
+ 0x65B0D9C6U, 0x12B7E950U, 0x8BBEB8EAU, 0xFCB9887CU, 0x62DD1DDFU, 0x15DA2D49U, 0x8CD37CF3U, 0xFBD44C65U,\r
+ 0x4DB26158U, 0x3AB551CEU, 0xA3BC0074U, 0xD4BB30E2U, 0x4ADFA541U, 0x3DD895D7U, 0xA4D1C46DU, 0xD3D6F4FBU,\r
+ 0x4369E96AU, 0x346ED9FCU, 0xAD678846U, 0xDA60B8D0U, 0x44042D73U, 0x33031DE5U, 0xAA0A4C5FU, 0xDD0D7CC9U,\r
+ 0x5005713CU, 0x270241AAU, 0xBE0B1010U, 0xC90C2086U, 0x5768B525U, 0x206F85B3U, 0xB966D409U, 0xCE61E49FU,\r
+ 0x5EDEF90EU, 0x29D9C998U, 0xB0D09822U, 0xC7D7A8B4U, 0x59B33D17U, 0x2EB40D81U, 0xB7BD5C3BU, 0xC0BA6CADU,\r
+ 0xEDB88320U, 0x9ABFB3B6U, 0x03B6E20CU, 0x74B1D29AU, 0xEAD54739U, 0x9DD277AFU, 0x04DB2615U, 0x73DC1683U,\r
+ 0xE3630B12U, 0x94643B84U, 0x0D6D6A3EU, 0x7A6A5AA8U, 0xE40ECF0BU, 0x9309FF9DU, 0x0A00AE27U, 0x7D079EB1U,\r
+ 0xF00F9344U, 0x8708A3D2U, 0x1E01F268U, 0x6906C2FEU, 0xF762575DU, 0x806567CBU, 0x196C3671U, 0x6E6B06E7U,\r
+ 0xFED41B76U, 0x89D32BE0U, 0x10DA7A5AU, 0x67DD4ACCU, 0xF9B9DF6FU, 0x8EBEEFF9U, 0x17B7BE43U, 0x60B08ED5U,\r
+ 0xD6D6A3E8U, 0xA1D1937EU, 0x38D8C2C4U, 0x4FDFF252U, 0xD1BB67F1U, 0xA6BC5767U, 0x3FB506DDU, 0x48B2364BU,\r
+ 0xD80D2BDAU, 0xAF0A1B4CU, 0x36034AF6U, 0x41047A60U, 0xDF60EFC3U, 0xA867DF55U, 0x316E8EEFU, 0x4669BE79U,\r
+ 0xCB61B38CU, 0xBC66831AU, 0x256FD2A0U, 0x5268E236U, 0xCC0C7795U, 0xBB0B4703U, 0x220216B9U, 0x5505262FU,\r
+ 0xC5BA3BBEU, 0xB2BD0B28U, 0x2BB45A92U, 0x5CB36A04U, 0xC2D7FFA7U, 0xB5D0CF31U, 0x2CD99E8BU, 0x5BDEAE1DU,\r
+ 0x9B64C2B0U, 0xEC63F226U, 0x756AA39CU, 0x026D930AU, 0x9C0906A9U, 0xEB0E363FU, 0x72076785U, 0x05005713U,\r
+ 0x95BF4A82U, 0xE2B87A14U, 0x7BB12BAEU, 0x0CB61B38U, 0x92D28E9BU, 0xE5D5BE0DU, 0x7CDCEFB7U, 0x0BDBDF21U,\r
+ 0x86D3D2D4U, 0xF1D4E242U, 0x68DDB3F8U, 0x1FDA836EU, 0x81BE16CDU, 0xF6B9265BU, 0x6FB077E1U, 0x18B74777U,\r
+ 0x88085AE6U, 0xFF0F6A70U, 0x66063BCAU, 0x11010B5CU, 0x8F659EFFU, 0xF862AE69U, 0x616BFFD3U, 0x166CCF45U,\r
+ 0xA00AE278U, 0xD70DD2EEU, 0x4E048354U, 0x3903B3C2U, 0xA7672661U, 0xD06016F7U, 0x4969474DU, 0x3E6E77DBU,\r
+ 0xAED16A4AU, 0xD9D65ADCU, 0x40DF0B66U, 0x37D83BF0U, 0xA9BCAE53U, 0xDEBB9EC5U, 0x47B2CF7FU, 0x30B5FFE9U,\r
+ 0xBDBDF21CU, 0xCABAC28AU, 0x53B39330U, 0x24B4A3A6U, 0xBAD03605U, 0xCDD70693U, 0x54DE5729U, 0x23D967BFU,\r
+ 0xB3667A2EU, 0xC4614AB8U, 0x5D681B02U, 0x2A6F2B94U, 0xB40BBE37U, 0xC30C8EA1U, 0x5A05DF1BU, 0x2D02EF8DU,\r
+ };\r
+\r
+ uint32_t ulCrc32;\r
+\r
+ if(pBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulCrc32 = SUSPICIOUS_CRC_VALUE;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+ uint32_t ulIdx;\r
+\r
+ ulCrc32 = ~ulInitCrc32;\r
+\r
+ for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx)\r
+ {\r
+ ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[(ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU];\r
+ }\r
+\r
+ ulCrc32 = ~ulCrc32;\r
+ }\r
+\r
+ return ulCrc32;\r
+}\r
+\r
+#elif REDCONF_CRC_ALGORITHM == CRC_SLICEBY8\r
+\r
+\r
+/** @brief Compute a CRC32 for the given data buffer.\r
+\r
+ For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple\r
+ buffers, call this function with the previously returned CRC value.\r
+\r
+ @param ulInitCrc32 Starting CRC value.\r
+ @param pBuffer Data buffer to calculate the CRC from.\r
+ @param ulLength Number of bytes of data in the given buffer.\r
+\r
+ @return The updated CRC value.\r
+*/\r
+uint32_t RedCrc32Update(\r
+ uint32_t ulInitCrc32,\r
+ const void *pBuffer,\r
+ uint32_t ulLength)\r
+{\r
+ /* CRC32 XOR table, with slicing-by-8 extensions.\r
+\r
+ This first column of the table contains the same XOR values as used in\r
+ the classic byte-at-a-time Sarwate algorithm. The other seven columns\r
+ are derived from the first, and are used in Intel's slicing-by-eight CRC\r
+ algorithm.\r
+\r
+ The layout of this array in memory is novel and deserves explanation.\r
+ In other implementations, including Intel's example, each of the below\r
+ columns is an array. The first column is a 256-entry array, followed by\r
+ another 256-entry array for the second column, etc. Testing on both ARM\r
+ and x86 has shown the below mixed arrangement to be about 5-9% faster.\r
+ One possible explanation: With the array-per-table approach, each of the\r
+ eight table lookups is guaranteed to be in a separate 1 KB chunk of\r
+ memory. With the below array, sometimes multiple table lookups will, by\r
+ coincidence, be close together, making better use of the cache.\r
+ */\r
+ static const uint32_t aulCrc32Table[] =\r
+ {\r
+ 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,\r
+ 0x77073096U, 0x191B3141U, 0x01C26A37U, 0xB8BC6765U, 0x3D6029B0U, 0xCB5CD3A5U, 0xA6770BB4U, 0xCCAA009EU,\r
+ 0xEE0E612CU, 0x32366282U, 0x0384D46EU, 0xAA09C88BU, 0x7AC05360U, 0x4DC8A10BU, 0x979F1129U, 0x4225077DU,\r
+ 0x990951BAU, 0x2B2D53C3U, 0x0246BE59U, 0x12B5AFEEU, 0x47A07AD0U, 0x869472AEU, 0x31E81A9DU, 0x8E8F07E3U,\r
+ 0x076DC419U, 0x646CC504U, 0x0709A8DCU, 0x8F629757U, 0xF580A6C0U, 0x9B914216U, 0xF44F2413U, 0x844A0EFAU,\r
+ 0x706AF48FU, 0x7D77F445U, 0x06CBC2EBU, 0x37DEF032U, 0xC8E08F70U, 0x50CD91B3U, 0x52382FA7U, 0x48E00E64U,\r
+ 0xE963A535U, 0x565AA786U, 0x048D7CB2U, 0x256B5FDCU, 0x8F40F5A0U, 0xD659E31DU, 0x63D0353AU, 0xC66F0987U,\r
+ 0x9E6495A3U, 0x4F4196C7U, 0x054F1685U, 0x9DD738B9U, 0xB220DC10U, 0x1D0530B8U, 0xC5A73E8EU, 0x0AC50919U,\r
+ 0x0EDB8832U, 0xC8D98A08U, 0x0E1351B8U, 0xC5B428EFU, 0x30704BC1U, 0xEC53826DU, 0x33EF4E67U, 0xD3E51BB5U,\r
+ 0x79DCB8A4U, 0xD1C2BB49U, 0x0FD13B8FU, 0x7D084F8AU, 0x0D106271U, 0x270F51C8U, 0x959845D3U, 0x1F4F1B2BU,\r
+ 0xE0D5E91EU, 0xFAEFE88AU, 0x0D9785D6U, 0x6FBDE064U, 0x4AB018A1U, 0xA19B2366U, 0xA4705F4EU, 0x91C01CC8U,\r
+ 0x97D2D988U, 0xE3F4D9CBU, 0x0C55EFE1U, 0xD7018701U, 0x77D03111U, 0x6AC7F0C3U, 0x020754FAU, 0x5D6A1C56U,\r
+ 0x09B64C2BU, 0xACB54F0CU, 0x091AF964U, 0x4AD6BFB8U, 0xC5F0ED01U, 0x77C2C07BU, 0xC7A06A74U, 0x57AF154FU,\r
+ 0x7EB17CBDU, 0xB5AE7E4DU, 0x08D89353U, 0xF26AD8DDU, 0xF890C4B1U, 0xBC9E13DEU, 0x61D761C0U, 0x9B0515D1U,\r
+ 0xE7B82D07U, 0x9E832D8EU, 0x0A9E2D0AU, 0xE0DF7733U, 0xBF30BE61U, 0x3A0A6170U, 0x503F7B5DU, 0x158A1232U,\r
+ 0x90BF1D91U, 0x87981CCFU, 0x0B5C473DU, 0x58631056U, 0x825097D1U, 0xF156B2D5U, 0xF64870E9U, 0xD92012ACU,\r
+ 0x1DB71064U, 0x4AC21251U, 0x1C26A370U, 0x5019579FU, 0x60E09782U, 0x03D6029BU, 0x67DE9CCEU, 0x7CBB312BU,\r
+ 0x6AB020F2U, 0x53D92310U, 0x1DE4C947U, 0xE8A530FAU, 0x5D80BE32U, 0xC88AD13EU, 0xC1A9977AU, 0xB01131B5U,\r
+ 0xF3B97148U, 0x78F470D3U, 0x1FA2771EU, 0xFA109F14U, 0x1A20C4E2U, 0x4E1EA390U, 0xF0418DE7U, 0x3E9E3656U,\r
+ 0x84BE41DEU, 0x61EF4192U, 0x1E601D29U, 0x42ACF871U, 0x2740ED52U, 0x85427035U, 0x56368653U, 0xF23436C8U,\r
+ 0x1ADAD47DU, 0x2EAED755U, 0x1B2F0BACU, 0xDF7BC0C8U, 0x95603142U, 0x9847408DU, 0x9391B8DDU, 0xF8F13FD1U,\r
+ 0x6DDDE4EBU, 0x37B5E614U, 0x1AED619BU, 0x67C7A7ADU, 0xA80018F2U, 0x531B9328U, 0x35E6B369U, 0x345B3F4FU,\r
+ 0xF4D4B551U, 0x1C98B5D7U, 0x18ABDFC2U, 0x75720843U, 0xEFA06222U, 0xD58FE186U, 0x040EA9F4U, 0xBAD438ACU,\r
+ 0x83D385C7U, 0x05838496U, 0x1969B5F5U, 0xCDCE6F26U, 0xD2C04B92U, 0x1ED33223U, 0xA279A240U, 0x767E3832U,\r
+ 0x136C9856U, 0x821B9859U, 0x1235F2C8U, 0x95AD7F70U, 0x5090DC43U, 0xEF8580F6U, 0x5431D2A9U, 0xAF5E2A9EU,\r
+ 0x646BA8C0U, 0x9B00A918U, 0x13F798FFU, 0x2D111815U, 0x6DF0F5F3U, 0x24D95353U, 0xF246D91DU, 0x63F42A00U,\r
+ 0xFD62F97AU, 0xB02DFADBU, 0x11B126A6U, 0x3FA4B7FBU, 0x2A508F23U, 0xA24D21FDU, 0xC3AEC380U, 0xED7B2DE3U,\r
+ 0x8A65C9ECU, 0xA936CB9AU, 0x10734C91U, 0x8718D09EU, 0x1730A693U, 0x6911F258U, 0x65D9C834U, 0x21D12D7DU,\r
+ 0x14015C4FU, 0xE6775D5DU, 0x153C5A14U, 0x1ACFE827U, 0xA5107A83U, 0x7414C2E0U, 0xA07EF6BAU, 0x2B142464U,\r
+ 0x63066CD9U, 0xFF6C6C1CU, 0x14FE3023U, 0xA2738F42U, 0x98705333U, 0xBF481145U, 0x0609FD0EU, 0xE7BE24FAU,\r
+ 0xFA0F3D63U, 0xD4413FDFU, 0x16B88E7AU, 0xB0C620ACU, 0xDFD029E3U, 0x39DC63EBU, 0x37E1E793U, 0x69312319U,\r
+ 0x8D080DF5U, 0xCD5A0E9EU, 0x177AE44DU, 0x087A47C9U, 0xE2B00053U, 0xF280B04EU, 0x9196EC27U, 0xA59B2387U,\r
+ 0x3B6E20C8U, 0x958424A2U, 0x384D46E0U, 0xA032AF3EU, 0xC1C12F04U, 0x07AC0536U, 0xCFBD399CU, 0xF9766256U,\r
+ 0x4C69105EU, 0x8C9F15E3U, 0x398F2CD7U, 0x188EC85BU, 0xFCA106B4U, 0xCCF0D693U, 0x69CA3228U, 0x35DC62C8U,\r
+ 0xD56041E4U, 0xA7B24620U, 0x3BC9928EU, 0x0A3B67B5U, 0xBB017C64U, 0x4A64A43DU, 0x582228B5U, 0xBB53652BU,\r
+ 0xA2677172U, 0xBEA97761U, 0x3A0BF8B9U, 0xB28700D0U, 0x866155D4U, 0x81387798U, 0xFE552301U, 0x77F965B5U,\r
+ 0x3C03E4D1U, 0xF1E8E1A6U, 0x3F44EE3CU, 0x2F503869U, 0x344189C4U, 0x9C3D4720U, 0x3BF21D8FU, 0x7D3C6CACU,\r
+ 0x4B04D447U, 0xE8F3D0E7U, 0x3E86840BU, 0x97EC5F0CU, 0x0921A074U, 0x57619485U, 0x9D85163BU, 0xB1966C32U,\r
+ 0xD20D85FDU, 0xC3DE8324U, 0x3CC03A52U, 0x8559F0E2U, 0x4E81DAA4U, 0xD1F5E62BU, 0xAC6D0CA6U, 0x3F196BD1U,\r
+ 0xA50AB56BU, 0xDAC5B265U, 0x3D025065U, 0x3DE59787U, 0x73E1F314U, 0x1AA9358EU, 0x0A1A0712U, 0xF3B36B4FU,\r
+ 0x35B5A8FAU, 0x5D5DAEAAU, 0x365E1758U, 0x658687D1U, 0xF1B164C5U, 0xEBFF875BU, 0xFC5277FBU, 0x2A9379E3U,\r
+ 0x42B2986CU, 0x44469FEBU, 0x379C7D6FU, 0xDD3AE0B4U, 0xCCD14D75U, 0x20A354FEU, 0x5A257C4FU, 0xE639797DU,\r
+ 0xDBBBC9D6U, 0x6F6BCC28U, 0x35DAC336U, 0xCF8F4F5AU, 0x8B7137A5U, 0xA6372650U, 0x6BCD66D2U, 0x68B67E9EU,\r
+ 0xACBCF940U, 0x7670FD69U, 0x3418A901U, 0x7733283FU, 0xB6111E15U, 0x6D6BF5F5U, 0xCDBA6D66U, 0xA41C7E00U,\r
+ 0x32D86CE3U, 0x39316BAEU, 0x3157BF84U, 0xEAE41086U, 0x0431C205U, 0x706EC54DU, 0x081D53E8U, 0xAED97719U,\r
+ 0x45DF5C75U, 0x202A5AEFU, 0x3095D5B3U, 0x525877E3U, 0x3951EBB5U, 0xBB3216E8U, 0xAE6A585CU, 0x62737787U,\r
+ 0xDCD60DCFU, 0x0B07092CU, 0x32D36BEAU, 0x40EDD80DU, 0x7EF19165U, 0x3DA66446U, 0x9F8242C1U, 0xECFC7064U,\r
+ 0xABD13D59U, 0x121C386DU, 0x331101DDU, 0xF851BF68U, 0x4391B8D5U, 0xF6FAB7E3U, 0x39F54975U, 0x205670FAU,\r
+ 0x26D930ACU, 0xDF4636F3U, 0x246BE590U, 0xF02BF8A1U, 0xA121B886U, 0x047A07ADU, 0xA863A552U, 0x85CD537DU,\r
+ 0x51DE003AU, 0xC65D07B2U, 0x25A98FA7U, 0x48979FC4U, 0x9C419136U, 0xCF26D408U, 0x0E14AEE6U, 0x496753E3U,\r
+ 0xC8D75180U, 0xED705471U, 0x27EF31FEU, 0x5A22302AU, 0xDBE1EBE6U, 0x49B2A6A6U, 0x3FFCB47BU, 0xC7E85400U,\r
+ 0xBFD06116U, 0xF46B6530U, 0x262D5BC9U, 0xE29E574FU, 0xE681C256U, 0x82EE7503U, 0x998BBFCFU, 0x0B42549EU,\r
+ 0x21B4F4B5U, 0xBB2AF3F7U, 0x23624D4CU, 0x7F496FF6U, 0x54A11E46U, 0x9FEB45BBU, 0x5C2C8141U, 0x01875D87U,\r
+ 0x56B3C423U, 0xA231C2B6U, 0x22A0277BU, 0xC7F50893U, 0x69C137F6U, 0x54B7961EU, 0xFA5B8AF5U, 0xCD2D5D19U,\r
+ 0xCFBA9599U, 0x891C9175U, 0x20E69922U, 0xD540A77DU, 0x2E614D26U, 0xD223E4B0U, 0xCBB39068U, 0x43A25AFAU,\r
+ 0xB8BDA50FU, 0x9007A034U, 0x2124F315U, 0x6DFCC018U, 0x13016496U, 0x197F3715U, 0x6DC49BDCU, 0x8F085A64U,\r
+ 0x2802B89EU, 0x179FBCFBU, 0x2A78B428U, 0x359FD04EU, 0x9151F347U, 0xE82985C0U, 0x9B8CEB35U, 0x562848C8U,\r
+ 0x5F058808U, 0x0E848DBAU, 0x2BBADE1FU, 0x8D23B72BU, 0xAC31DAF7U, 0x23755665U, 0x3DFBE081U, 0x9A824856U,\r
+ 0xC60CD9B2U, 0x25A9DE79U, 0x29FC6046U, 0x9F9618C5U, 0xEB91A027U, 0xA5E124CBU, 0x0C13FA1CU, 0x140D4FB5U,\r
+ 0xB10BE924U, 0x3CB2EF38U, 0x283E0A71U, 0x272A7FA0U, 0xD6F18997U, 0x6EBDF76EU, 0xAA64F1A8U, 0xD8A74F2BU,\r
+ 0x2F6F7C87U, 0x73F379FFU, 0x2D711CF4U, 0xBAFD4719U, 0x64D15587U, 0x73B8C7D6U, 0x6FC3CF26U, 0xD2624632U,\r
+ 0x58684C11U, 0x6AE848BEU, 0x2CB376C3U, 0x0241207CU, 0x59B17C37U, 0xB8E41473U, 0xC9B4C492U, 0x1EC846ACU,\r
+ 0xC1611DABU, 0x41C51B7DU, 0x2EF5C89AU, 0x10F48F92U, 0x1E1106E7U, 0x3E7066DDU, 0xF85CDE0FU, 0x9047414FU,\r
+ 0xB6662D3DU, 0x58DE2A3CU, 0x2F37A2ADU, 0xA848E8F7U, 0x23712F57U, 0xF52CB578U, 0x5E2BD5BBU, 0x5CED41D1U,\r
+ 0x76DC4190U, 0xF0794F05U, 0x709A8DC0U, 0x9B14583DU, 0x58F35849U, 0x0F580A6CU, 0x440B7579U, 0x299DC2EDU,\r
+ 0x01DB7106U, 0xE9627E44U, 0x7158E7F7U, 0x23A83F58U, 0x659371F9U, 0xC404D9C9U, 0xE27C7ECDU, 0xE537C273U,\r
+ 0x98D220BCU, 0xC24F2D87U, 0x731E59AEU, 0x311D90B6U, 0x22330B29U, 0x4290AB67U, 0xD3946450U, 0x6BB8C590U,\r
+ 0xEFD5102AU, 0xDB541CC6U, 0x72DC3399U, 0x89A1F7D3U, 0x1F532299U, 0x89CC78C2U, 0x75E36FE4U, 0xA712C50EU,\r
+ 0x71B18589U, 0x94158A01U, 0x7793251CU, 0x1476CF6AU, 0xAD73FE89U, 0x94C9487AU, 0xB044516AU, 0xADD7CC17U,\r
+ 0x06B6B51FU, 0x8D0EBB40U, 0x76514F2BU, 0xACCAA80FU, 0x9013D739U, 0x5F959BDFU, 0x16335ADEU, 0x617DCC89U,\r
+ 0x9FBFE4A5U, 0xA623E883U, 0x7417F172U, 0xBE7F07E1U, 0xD7B3ADE9U, 0xD901E971U, 0x27DB4043U, 0xEFF2CB6AU,\r
+ 0xE8B8D433U, 0xBF38D9C2U, 0x75D59B45U, 0x06C36084U, 0xEAD38459U, 0x125D3AD4U, 0x81AC4BF7U, 0x2358CBF4U,\r
+ 0x7807C9A2U, 0x38A0C50DU, 0x7E89DC78U, 0x5EA070D2U, 0x68831388U, 0xE30B8801U, 0x77E43B1EU, 0xFA78D958U,\r
+ 0x0F00F934U, 0x21BBF44CU, 0x7F4BB64FU, 0xE61C17B7U, 0x55E33A38U, 0x28575BA4U, 0xD19330AAU, 0x36D2D9C6U,\r
+ 0x9609A88EU, 0x0A96A78FU, 0x7D0D0816U, 0xF4A9B859U, 0x124340E8U, 0xAEC3290AU, 0xE07B2A37U, 0xB85DDE25U,\r
+ 0xE10E9818U, 0x138D96CEU, 0x7CCF6221U, 0x4C15DF3CU, 0x2F236958U, 0x659FFAAFU, 0x460C2183U, 0x74F7DEBBU,\r
+ 0x7F6A0DBBU, 0x5CCC0009U, 0x798074A4U, 0xD1C2E785U, 0x9D03B548U, 0x789ACA17U, 0x83AB1F0DU, 0x7E32D7A2U,\r
+ 0x086D3D2DU, 0x45D73148U, 0x78421E93U, 0x697E80E0U, 0xA0639CF8U, 0xB3C619B2U, 0x25DC14B9U, 0xB298D73CU,\r
+ 0x91646C97U, 0x6EFA628BU, 0x7A04A0CAU, 0x7BCB2F0EU, 0xE7C3E628U, 0x35526B1CU, 0x14340E24U, 0x3C17D0DFU,\r
+ 0xE6635C01U, 0x77E153CAU, 0x7BC6CAFDU, 0xC377486BU, 0xDAA3CF98U, 0xFE0EB8B9U, 0xB2430590U, 0xF0BDD041U,\r
+ 0x6B6B51F4U, 0xBABB5D54U, 0x6CBC2EB0U, 0xCB0D0FA2U, 0x3813CFCBU, 0x0C8E08F7U, 0x23D5E9B7U, 0x5526F3C6U,\r
+ 0x1C6C6162U, 0xA3A06C15U, 0x6D7E4487U, 0x73B168C7U, 0x0573E67BU, 0xC7D2DB52U, 0x85A2E203U, 0x998CF358U,\r
+ 0x856530D8U, 0x888D3FD6U, 0x6F38FADEU, 0x6104C729U, 0x42D39CABU, 0x4146A9FCU, 0xB44AF89EU, 0x1703F4BBU,\r
+ 0xF262004EU, 0x91960E97U, 0x6EFA90E9U, 0xD9B8A04CU, 0x7FB3B51BU, 0x8A1A7A59U, 0x123DF32AU, 0xDBA9F425U,\r
+ 0x6C0695EDU, 0xDED79850U, 0x6BB5866CU, 0x446F98F5U, 0xCD93690BU, 0x971F4AE1U, 0xD79ACDA4U, 0xD16CFD3CU,\r
+ 0x1B01A57BU, 0xC7CCA911U, 0x6A77EC5BU, 0xFCD3FF90U, 0xF0F340BBU, 0x5C439944U, 0x71EDC610U, 0x1DC6FDA2U,\r
+ 0x8208F4C1U, 0xECE1FAD2U, 0x68315202U, 0xEE66507EU, 0xB7533A6BU, 0xDAD7EBEAU, 0x4005DC8DU, 0x9349FA41U,\r
+ 0xF50FC457U, 0xF5FACB93U, 0x69F33835U, 0x56DA371BU, 0x8A3313DBU, 0x118B384FU, 0xE672D739U, 0x5FE3FADFU,\r
+ 0x65B0D9C6U, 0x7262D75CU, 0x62AF7F08U, 0x0EB9274DU, 0x0863840AU, 0xE0DD8A9AU, 0x103AA7D0U, 0x86C3E873U,\r
+ 0x12B7E950U, 0x6B79E61DU, 0x636D153FU, 0xB6054028U, 0x3503ADBAU, 0x2B81593FU, 0xB64DAC64U, 0x4A69E8EDU,\r
+ 0x8BBEB8EAU, 0x4054B5DEU, 0x612BAB66U, 0xA4B0EFC6U, 0x72A3D76AU, 0xAD152B91U, 0x87A5B6F9U, 0xC4E6EF0EU,\r
+ 0xFCB9887CU, 0x594F849FU, 0x60E9C151U, 0x1C0C88A3U, 0x4FC3FEDAU, 0x6649F834U, 0x21D2BD4DU, 0x084CEF90U,\r
+ 0x62DD1DDFU, 0x160E1258U, 0x65A6D7D4U, 0x81DBB01AU, 0xFDE322CAU, 0x7B4CC88CU, 0xE47583C3U, 0x0289E689U,\r
+ 0x15DA2D49U, 0x0F152319U, 0x6464BDE3U, 0x3967D77FU, 0xC0830B7AU, 0xB0101B29U, 0x42028877U, 0xCE23E617U,\r
+ 0x8CD37CF3U, 0x243870DAU, 0x662203BAU, 0x2BD27891U, 0x872371AAU, 0x36846987U, 0x73EA92EAU, 0x40ACE1F4U,\r
+ 0xFBD44C65U, 0x3D23419BU, 0x67E0698DU, 0x936E1FF4U, 0xBA43581AU, 0xFDD8BA22U, 0xD59D995EU, 0x8C06E16AU,\r
+ 0x4DB26158U, 0x65FD6BA7U, 0x48D7CB20U, 0x3B26F703U, 0x9932774DU, 0x08F40F5AU, 0x8BB64CE5U, 0xD0EBA0BBU,\r
+ 0x3AB551CEU, 0x7CE65AE6U, 0x4915A117U, 0x839A9066U, 0xA4525EFDU, 0xC3A8DCFFU, 0x2DC14751U, 0x1C41A025U,\r
+ 0xA3BC0074U, 0x57CB0925U, 0x4B531F4EU, 0x912F3F88U, 0xE3F2242DU, 0x453CAE51U, 0x1C295DCCU, 0x92CEA7C6U,\r
+ 0xD4BB30E2U, 0x4ED03864U, 0x4A917579U, 0x299358EDU, 0xDE920D9DU, 0x8E607DF4U, 0xBA5E5678U, 0x5E64A758U,\r
+ 0x4ADFA541U, 0x0191AEA3U, 0x4FDE63FCU, 0xB4446054U, 0x6CB2D18DU, 0x93654D4CU, 0x7FF968F6U, 0x54A1AE41U,\r
+ 0x3DD895D7U, 0x188A9FE2U, 0x4E1C09CBU, 0x0CF80731U, 0x51D2F83DU, 0x58399EE9U, 0xD98E6342U, 0x980BAEDFU,\r
+ 0xA4D1C46DU, 0x33A7CC21U, 0x4C5AB792U, 0x1E4DA8DFU, 0x167282EDU, 0xDEADEC47U, 0xE86679DFU, 0x1684A93CU,\r
+ 0xD3D6F4FBU, 0x2ABCFD60U, 0x4D98DDA5U, 0xA6F1CFBAU, 0x2B12AB5DU, 0x15F13FE2U, 0x4E11726BU, 0xDA2EA9A2U,\r
+ 0x4369E96AU, 0xAD24E1AFU, 0x46C49A98U, 0xFE92DFECU, 0xA9423C8CU, 0xE4A78D37U, 0xB8590282U, 0x030EBB0EU,\r
+ 0x346ED9FCU, 0xB43FD0EEU, 0x4706F0AFU, 0x462EB889U, 0x9422153CU, 0x2FFB5E92U, 0x1E2E0936U, 0xCFA4BB90U,\r
+ 0xAD678846U, 0x9F12832DU, 0x45404EF6U, 0x549B1767U, 0xD3826FECU, 0xA96F2C3CU, 0x2FC613ABU, 0x412BBC73U,\r
+ 0xDA60B8D0U, 0x8609B26CU, 0x448224C1U, 0xEC277002U, 0xEEE2465CU, 0x6233FF99U, 0x89B1181FU, 0x8D81BCEDU,\r
+ 0x44042D73U, 0xC94824ABU, 0x41CD3244U, 0x71F048BBU, 0x5CC29A4CU, 0x7F36CF21U, 0x4C162691U, 0x8744B5F4U,\r
+ 0x33031DE5U, 0xD05315EAU, 0x400F5873U, 0xC94C2FDEU, 0x61A2B3FCU, 0xB46A1C84U, 0xEA612D25U, 0x4BEEB56AU,\r
+ 0xAA0A4C5FU, 0xFB7E4629U, 0x4249E62AU, 0xDBF98030U, 0x2602C92CU, 0x32FE6E2AU, 0xDB8937B8U, 0xC561B289U,\r
+ 0xDD0D7CC9U, 0xE2657768U, 0x438B8C1DU, 0x6345E755U, 0x1B62E09CU, 0xF9A2BD8FU, 0x7DFE3C0CU, 0x09CBB217U,\r
+ 0x5005713CU, 0x2F3F79F6U, 0x54F16850U, 0x6B3FA09CU, 0xF9D2E0CFU, 0x0B220DC1U, 0xEC68D02BU, 0xAC509190U,\r
+ 0x270241AAU, 0x362448B7U, 0x55330267U, 0xD383C7F9U, 0xC4B2C97FU, 0xC07EDE64U, 0x4A1FDB9FU, 0x60FA910EU,\r
+ 0xBE0B1010U, 0x1D091B74U, 0x5775BC3EU, 0xC1366817U, 0x8312B3AFU, 0x46EAACCAU, 0x7BF7C102U, 0xEE7596EDU,\r
+ 0xC90C2086U, 0x04122A35U, 0x56B7D609U, 0x798A0F72U, 0xBE729A1FU, 0x8DB67F6FU, 0xDD80CAB6U, 0x22DF9673U,\r
+ 0x5768B525U, 0x4B53BCF2U, 0x53F8C08CU, 0xE45D37CBU, 0x0C52460FU, 0x90B34FD7U, 0x1827F438U, 0x281A9F6AU,\r
+ 0x206F85B3U, 0x52488DB3U, 0x523AAABBU, 0x5CE150AEU, 0x31326FBFU, 0x5BEF9C72U, 0xBE50FF8CU, 0xE4B09FF4U,\r
+ 0xB966D409U, 0x7965DE70U, 0x507C14E2U, 0x4E54FF40U, 0x7692156FU, 0xDD7BEEDCU, 0x8FB8E511U, 0x6A3F9817U,\r
+ 0xCE61E49FU, 0x607EEF31U, 0x51BE7ED5U, 0xF6E89825U, 0x4BF23CDFU, 0x16273D79U, 0x29CFEEA5U, 0xA6959889U,\r
+ 0x5EDEF90EU, 0xE7E6F3FEU, 0x5AE239E8U, 0xAE8B8873U, 0xC9A2AB0EU, 0xE7718FACU, 0xDF879E4CU, 0x7FB58A25U,\r
+ 0x29D9C998U, 0xFEFDC2BFU, 0x5B2053DFU, 0x1637EF16U, 0xF4C282BEU, 0x2C2D5C09U, 0x79F095F8U, 0xB31F8ABBU,\r
+ 0xB0D09822U, 0xD5D0917CU, 0x5966ED86U, 0x048240F8U, 0xB362F86EU, 0xAAB92EA7U, 0x48188F65U, 0x3D908D58U,\r
+ 0xC7D7A8B4U, 0xCCCBA03DU, 0x58A487B1U, 0xBC3E279DU, 0x8E02D1DEU, 0x61E5FD02U, 0xEE6F84D1U, 0xF13A8DC6U,\r
+ 0x59B33D17U, 0x838A36FAU, 0x5DEB9134U, 0x21E91F24U, 0x3C220DCEU, 0x7CE0CDBAU, 0x2BC8BA5FU, 0xFBFF84DFU,\r
+ 0x2EB40D81U, 0x9A9107BBU, 0x5C29FB03U, 0x99557841U, 0x0142247EU, 0xB7BC1E1FU, 0x8DBFB1EBU, 0x37558441U,\r
+ 0xB7BD5C3BU, 0xB1BC5478U, 0x5E6F455AU, 0x8BE0D7AFU, 0x46E25EAEU, 0x31286CB1U, 0xBC57AB76U, 0xB9DA83A2U,\r
+ 0xC0BA6CADU, 0xA8A76539U, 0x5FAD2F6DU, 0x335CB0CAU, 0x7B82771EU, 0xFA74BF14U, 0x1A20A0C2U, 0x7570833CU,\r
+ 0xEDB88320U, 0x3B83984BU, 0xE1351B80U, 0xED59B63BU, 0xB1E6B092U, 0x1EB014D8U, 0x8816EAF2U, 0x533B85DAU,\r
+ 0x9ABFB3B6U, 0x2298A90AU, 0xE0F771B7U, 0x55E5D15EU, 0x8C869922U, 0xD5ECC77DU, 0x2E61E146U, 0x9F918544U,\r
+ 0x03B6E20CU, 0x09B5FAC9U, 0xE2B1CFEEU, 0x47507EB0U, 0xCB26E3F2U, 0x5378B5D3U, 0x1F89FBDBU, 0x111E82A7U,\r
+ 0x74B1D29AU, 0x10AECB88U, 0xE373A5D9U, 0xFFEC19D5U, 0xF646CA42U, 0x98246676U, 0xB9FEF06FU, 0xDDB48239U,\r
+ 0xEAD54739U, 0x5FEF5D4FU, 0xE63CB35CU, 0x623B216CU, 0x44661652U, 0x852156CEU, 0x7C59CEE1U, 0xD7718B20U,\r
+ 0x9DD277AFU, 0x46F46C0EU, 0xE7FED96BU, 0xDA874609U, 0x79063FE2U, 0x4E7D856BU, 0xDA2EC555U, 0x1BDB8BBEU,\r
+ 0x04DB2615U, 0x6DD93FCDU, 0xE5B86732U, 0xC832E9E7U, 0x3EA64532U, 0xC8E9F7C5U, 0xEBC6DFC8U, 0x95548C5DU,\r
+ 0x73DC1683U, 0x74C20E8CU, 0xE47A0D05U, 0x708E8E82U, 0x03C66C82U, 0x03B52460U, 0x4DB1D47CU, 0x59FE8CC3U,\r
+ 0xE3630B12U, 0xF35A1243U, 0xEF264A38U, 0x28ED9ED4U, 0x8196FB53U, 0xF2E396B5U, 0xBBF9A495U, 0x80DE9E6FU,\r
+ 0x94643B84U, 0xEA412302U, 0xEEE4200FU, 0x9051F9B1U, 0xBCF6D2E3U, 0x39BF4510U, 0x1D8EAF21U, 0x4C749EF1U,\r
+ 0x0D6D6A3EU, 0xC16C70C1U, 0xECA29E56U, 0x82E4565FU, 0xFB56A833U, 0xBF2B37BEU, 0x2C66B5BCU, 0xC2FB9912U,\r
+ 0x7A6A5AA8U, 0xD8774180U, 0xED60F461U, 0x3A58313AU, 0xC6368183U, 0x7477E41BU, 0x8A11BE08U, 0x0E51998CU,\r
+ 0xE40ECF0BU, 0x9736D747U, 0xE82FE2E4U, 0xA78F0983U, 0x74165D93U, 0x6972D4A3U, 0x4FB68086U, 0x04949095U,\r
+ 0x9309FF9DU, 0x8E2DE606U, 0xE9ED88D3U, 0x1F336EE6U, 0x49767423U, 0xA22E0706U, 0xE9C18B32U, 0xC83E900BU,\r
+ 0x0A00AE27U, 0xA500B5C5U, 0xEBAB368AU, 0x0D86C108U, 0x0ED60EF3U, 0x24BA75A8U, 0xD82991AFU, 0x46B197E8U,\r
+ 0x7D079EB1U, 0xBC1B8484U, 0xEA695CBDU, 0xB53AA66DU, 0x33B62743U, 0xEFE6A60DU, 0x7E5E9A1BU, 0x8A1B9776U,\r
+ 0xF00F9344U, 0x71418A1AU, 0xFD13B8F0U, 0xBD40E1A4U, 0xD1062710U, 0x1D661643U, 0xEFC8763CU, 0x2F80B4F1U,\r
+ 0x8708A3D2U, 0x685ABB5BU, 0xFCD1D2C7U, 0x05FC86C1U, 0xEC660EA0U, 0xD63AC5E6U, 0x49BF7D88U, 0xE32AB46FU,\r
+ 0x1E01F268U, 0x4377E898U, 0xFE976C9EU, 0x1749292FU, 0xABC67470U, 0x50AEB748U, 0x78576715U, 0x6DA5B38CU,\r
+ 0x6906C2FEU, 0x5A6CD9D9U, 0xFF5506A9U, 0xAFF54E4AU, 0x96A65DC0U, 0x9BF264EDU, 0xDE206CA1U, 0xA10FB312U,\r
+ 0xF762575DU, 0x152D4F1EU, 0xFA1A102CU, 0x322276F3U, 0x248681D0U, 0x86F75455U, 0x1B87522FU, 0xABCABA0BU,\r
+ 0x806567CBU, 0x0C367E5FU, 0xFBD87A1BU, 0x8A9E1196U, 0x19E6A860U, 0x4DAB87F0U, 0xBDF0599BU, 0x6760BA95U,\r
+ 0x196C3671U, 0x271B2D9CU, 0xF99EC442U, 0x982BBE78U, 0x5E46D2B0U, 0xCB3FF55EU, 0x8C184306U, 0xE9EFBD76U,\r
+ 0x6E6B06E7U, 0x3E001CDDU, 0xF85CAE75U, 0x2097D91DU, 0x6326FB00U, 0x006326FBU, 0x2A6F48B2U, 0x2545BDE8U,\r
+ 0xFED41B76U, 0xB9980012U, 0xF300E948U, 0x78F4C94BU, 0xE1766CD1U, 0xF135942EU, 0xDC27385BU, 0xFC65AF44U,\r
+ 0x89D32BE0U, 0xA0833153U, 0xF2C2837FU, 0xC048AE2EU, 0xDC164561U, 0x3A69478BU, 0x7A5033EFU, 0x30CFAFDAU,\r
+ 0x10DA7A5AU, 0x8BAE6290U, 0xF0843D26U, 0xD2FD01C0U, 0x9BB63FB1U, 0xBCFD3525U, 0x4BB82972U, 0xBE40A839U,\r
+ 0x67DD4ACCU, 0x92B553D1U, 0xF1465711U, 0x6A4166A5U, 0xA6D61601U, 0x77A1E680U, 0xEDCF22C6U, 0x72EAA8A7U,\r
+ 0xF9B9DF6FU, 0xDDF4C516U, 0xF4094194U, 0xF7965E1CU, 0x14F6CA11U, 0x6AA4D638U, 0x28681C48U, 0x782FA1BEU,\r
+ 0x8EBEEFF9U, 0xC4EFF457U, 0xF5CB2BA3U, 0x4F2A3979U, 0x2996E3A1U, 0xA1F8059DU, 0x8E1F17FCU, 0xB485A120U,\r
+ 0x17B7BE43U, 0xEFC2A794U, 0xF78D95FAU, 0x5D9F9697U, 0x6E369971U, 0x276C7733U, 0xBFF70D61U, 0x3A0AA6C3U,\r
+ 0x60B08ED5U, 0xF6D996D5U, 0xF64FFFCDU, 0xE523F1F2U, 0x5356B0C1U, 0xEC30A496U, 0x198006D5U, 0xF6A0A65DU,\r
+ 0xD6D6A3E8U, 0xAE07BCE9U, 0xD9785D60U, 0x4D6B1905U, 0x70279F96U, 0x191C11EEU, 0x47ABD36EU, 0xAA4DE78CU,\r
+ 0xA1D1937EU, 0xB71C8DA8U, 0xD8BA3757U, 0xF5D77E60U, 0x4D47B626U, 0xD240C24BU, 0xE1DCD8DAU, 0x66E7E712U,\r
+ 0x38D8C2C4U, 0x9C31DE6BU, 0xDAFC890EU, 0xE762D18EU, 0x0AE7CCF6U, 0x54D4B0E5U, 0xD034C247U, 0xE868E0F1U,\r
+ 0x4FDFF252U, 0x852AEF2AU, 0xDB3EE339U, 0x5FDEB6EBU, 0x3787E546U, 0x9F886340U, 0x7643C9F3U, 0x24C2E06FU,\r
+ 0xD1BB67F1U, 0xCA6B79EDU, 0xDE71F5BCU, 0xC2098E52U, 0x85A73956U, 0x828D53F8U, 0xB3E4F77DU, 0x2E07E976U,\r
+ 0xA6BC5767U, 0xD37048ACU, 0xDFB39F8BU, 0x7AB5E937U, 0xB8C710E6U, 0x49D1805DU, 0x1593FCC9U, 0xE2ADE9E8U,\r
+ 0x3FB506DDU, 0xF85D1B6FU, 0xDDF521D2U, 0x680046D9U, 0xFF676A36U, 0xCF45F2F3U, 0x247BE654U, 0x6C22EE0BU,\r
+ 0x48B2364BU, 0xE1462A2EU, 0xDC374BE5U, 0xD0BC21BCU, 0xC2074386U, 0x04192156U, 0x820CEDE0U, 0xA088EE95U,\r
+ 0xD80D2BDAU, 0x66DE36E1U, 0xD76B0CD8U, 0x88DF31EAU, 0x4057D457U, 0xF54F9383U, 0x74449D09U, 0x79A8FC39U,\r
+ 0xAF0A1B4CU, 0x7FC507A0U, 0xD6A966EFU, 0x3063568FU, 0x7D37FDE7U, 0x3E134026U, 0xD23396BDU, 0xB502FCA7U,\r
+ 0x36034AF6U, 0x54E85463U, 0xD4EFD8B6U, 0x22D6F961U, 0x3A978737U, 0xB8873288U, 0xE3DB8C20U, 0x3B8DFB44U,\r
+ 0x41047A60U, 0x4DF36522U, 0xD52DB281U, 0x9A6A9E04U, 0x07F7AE87U, 0x73DBE12DU, 0x45AC8794U, 0xF727FBDAU,\r
+ 0xDF60EFC3U, 0x02B2F3E5U, 0xD062A404U, 0x07BDA6BDU, 0xB5D77297U, 0x6EDED195U, 0x800BB91AU, 0xFDE2F2C3U,\r
+ 0xA867DF55U, 0x1BA9C2A4U, 0xD1A0CE33U, 0xBF01C1D8U, 0x88B75B27U, 0xA5820230U, 0x267CB2AEU, 0x3148F25DU,\r
+ 0x316E8EEFU, 0x30849167U, 0xD3E6706AU, 0xADB46E36U, 0xCF1721F7U, 0x2316709EU, 0x1794A833U, 0xBFC7F5BEU,\r
+ 0x4669BE79U, 0x299FA026U, 0xD2241A5DU, 0x15080953U, 0xF2770847U, 0xE84AA33BU, 0xB1E3A387U, 0x736DF520U,\r
+ 0xCB61B38CU, 0xE4C5AEB8U, 0xC55EFE10U, 0x1D724E9AU, 0x10C70814U, 0x1ACA1375U, 0x20754FA0U, 0xD6F6D6A7U,\r
+ 0xBC66831AU, 0xFDDE9FF9U, 0xC49C9427U, 0xA5CE29FFU, 0x2DA721A4U, 0xD196C0D0U, 0x86024414U, 0x1A5CD639U,\r
+ 0x256FD2A0U, 0xD6F3CC3AU, 0xC6DA2A7EU, 0xB77B8611U, 0x6A075B74U, 0x5702B27EU, 0xB7EA5E89U, 0x94D3D1DAU,\r
+ 0x5268E236U, 0xCFE8FD7BU, 0xC7184049U, 0x0FC7E174U, 0x576772C4U, 0x9C5E61DBU, 0x119D553DU, 0x5879D144U,\r
+ 0xCC0C7795U, 0x80A96BBCU, 0xC25756CCU, 0x9210D9CDU, 0xE547AED4U, 0x815B5163U, 0xD43A6BB3U, 0x52BCD85DU,\r
+ 0xBB0B4703U, 0x99B25AFDU, 0xC3953CFBU, 0x2AACBEA8U, 0xD8278764U, 0x4A0782C6U, 0x724D6007U, 0x9E16D8C3U,\r
+ 0x220216B9U, 0xB29F093EU, 0xC1D382A2U, 0x38191146U, 0x9F87FDB4U, 0xCC93F068U, 0x43A57A9AU, 0x1099DF20U,\r
+ 0x5505262FU, 0xAB84387FU, 0xC011E895U, 0x80A57623U, 0xA2E7D404U, 0x07CF23CDU, 0xE5D2712EU, 0xDC33DFBEU,\r
+ 0xC5BA3BBEU, 0x2C1C24B0U, 0xCB4DAFA8U, 0xD8C66675U, 0x20B743D5U, 0xF6999118U, 0x139A01C7U, 0x0513CD12U,\r
+ 0xB2BD0B28U, 0x350715F1U, 0xCA8FC59FU, 0x607A0110U, 0x1DD76A65U, 0x3DC542BDU, 0xB5ED0A73U, 0xC9B9CD8CU,\r
+ 0x2BB45A92U, 0x1E2A4632U, 0xC8C97BC6U, 0x72CFAEFEU, 0x5A7710B5U, 0xBB513013U, 0x840510EEU, 0x4736CA6FU,\r
+ 0x5CB36A04U, 0x07317773U, 0xC90B11F1U, 0xCA73C99BU, 0x67173905U, 0x700DE3B6U, 0x22721B5AU, 0x8B9CCAF1U,\r
+ 0xC2D7FFA7U, 0x4870E1B4U, 0xCC440774U, 0x57A4F122U, 0xD537E515U, 0x6D08D30EU, 0xE7D525D4U, 0x8159C3E8U,\r
+ 0xB5D0CF31U, 0x516BD0F5U, 0xCD866D43U, 0xEF189647U, 0xE857CCA5U, 0xA65400ABU, 0x41A22E60U, 0x4DF3C376U,\r
+ 0x2CD99E8BU, 0x7A468336U, 0xCFC0D31AU, 0xFDAD39A9U, 0xAFF7B675U, 0x20C07205U, 0x704A34FDU, 0xC37CC495U,\r
+ 0x5BDEAE1DU, 0x635DB277U, 0xCE02B92DU, 0x45115ECCU, 0x92979FC5U, 0xEB9CA1A0U, 0xD63D3F49U, 0x0FD6C40BU,\r
+ 0x9B64C2B0U, 0xCBFAD74EU, 0x91AF9640U, 0x764DEE06U, 0xE915E8DBU, 0x11E81EB4U, 0xCC1D9F8BU, 0x7AA64737U,\r
+ 0xEC63F226U, 0xD2E1E60FU, 0x906DFC77U, 0xCEF18963U, 0xD475C16BU, 0xDAB4CD11U, 0x6A6A943FU, 0xB60C47A9U,\r
+ 0x756AA39CU, 0xF9CCB5CCU, 0x922B422EU, 0xDC44268DU, 0x93D5BBBBU, 0x5C20BFBFU, 0x5B828EA2U, 0x3883404AU,\r
+ 0x026D930AU, 0xE0D7848DU, 0x93E92819U, 0x64F841E8U, 0xAEB5920BU, 0x977C6C1AU, 0xFDF58516U, 0xF42940D4U,\r
+ 0x9C0906A9U, 0xAF96124AU, 0x96A63E9CU, 0xF92F7951U, 0x1C954E1BU, 0x8A795CA2U, 0x3852BB98U, 0xFEEC49CDU,\r
+ 0xEB0E363FU, 0xB68D230BU, 0x976454ABU, 0x41931E34U, 0x21F567ABU, 0x41258F07U, 0x9E25B02CU, 0x32464953U,\r
+ 0x72076785U, 0x9DA070C8U, 0x9522EAF2U, 0x5326B1DAU, 0x66551D7BU, 0xC7B1FDA9U, 0xAFCDAAB1U, 0xBCC94EB0U,\r
+ 0x05005713U, 0x84BB4189U, 0x94E080C5U, 0xEB9AD6BFU, 0x5B3534CBU, 0x0CED2E0CU, 0x09BAA105U, 0x70634E2EU,\r
+ 0x95BF4A82U, 0x03235D46U, 0x9FBCC7F8U, 0xB3F9C6E9U, 0xD965A31AU, 0xFDBB9CD9U, 0xFFF2D1ECU, 0xA9435C82U,\r
+ 0xE2B87A14U, 0x1A386C07U, 0x9E7EADCFU, 0x0B45A18CU, 0xE4058AAAU, 0x36E74F7CU, 0x5985DA58U, 0x65E95C1CU,\r
+ 0x7BB12BAEU, 0x31153FC4U, 0x9C381396U, 0x19F00E62U, 0xA3A5F07AU, 0xB0733DD2U, 0x686DC0C5U, 0xEB665BFFU,\r
+ 0x0CB61B38U, 0x280E0E85U, 0x9DFA79A1U, 0xA14C6907U, 0x9EC5D9CAU, 0x7B2FEE77U, 0xCE1ACB71U, 0x27CC5B61U,\r
+ 0x92D28E9BU, 0x674F9842U, 0x98B56F24U, 0x3C9B51BEU, 0x2CE505DAU, 0x662ADECFU, 0x0BBDF5FFU, 0x2D095278U,\r
+ 0xE5D5BE0DU, 0x7E54A903U, 0x99770513U, 0x842736DBU, 0x11852C6AU, 0xAD760D6AU, 0xADCAFE4BU, 0xE1A352E6U,\r
+ 0x7CDCEFB7U, 0x5579FAC0U, 0x9B31BB4AU, 0x96929935U, 0x562556BAU, 0x2BE27FC4U, 0x9C22E4D6U, 0x6F2C5505U,\r
+ 0x0BDBDF21U, 0x4C62CB81U, 0x9AF3D17DU, 0x2E2EFE50U, 0x6B457F0AU, 0xE0BEAC61U, 0x3A55EF62U, 0xA386559BU,\r
+ 0x86D3D2D4U, 0x8138C51FU, 0x8D893530U, 0x2654B999U, 0x89F57F59U, 0x123E1C2FU, 0xABC30345U, 0x061D761CU,\r
+ 0xF1D4E242U, 0x9823F45EU, 0x8C4B5F07U, 0x9EE8DEFCU, 0xB49556E9U, 0xD962CF8AU, 0x0DB408F1U, 0xCAB77682U,\r
+ 0x68DDB3F8U, 0xB30EA79DU, 0x8E0DE15EU, 0x8C5D7112U, 0xF3352C39U, 0x5FF6BD24U, 0x3C5C126CU, 0x44387161U,\r
+ 0x1FDA836EU, 0xAA1596DCU, 0x8FCF8B69U, 0x34E11677U, 0xCE550589U, 0x94AA6E81U, 0x9A2B19D8U, 0x889271FFU,\r
+ 0x81BE16CDU, 0xE554001BU, 0x8A809DECU, 0xA9362ECEU, 0x7C75D999U, 0x89AF5E39U, 0x5F8C2756U, 0x825778E6U,\r
+ 0xF6B9265BU, 0xFC4F315AU, 0x8B42F7DBU, 0x118A49ABU, 0x4115F029U, 0x42F38D9CU, 0xF9FB2CE2U, 0x4EFD7878U,\r
+ 0x6FB077E1U, 0xD7626299U, 0x89044982U, 0x033FE645U, 0x06B58AF9U, 0xC467FF32U, 0xC813367FU, 0xC0727F9BU,\r
+ 0x18B74777U, 0xCE7953D8U, 0x88C623B5U, 0xBB838120U, 0x3BD5A349U, 0x0F3B2C97U, 0x6E643DCBU, 0x0CD87F05U,\r
+ 0x88085AE6U, 0x49E14F17U, 0x839A6488U, 0xE3E09176U, 0xB9853498U, 0xFE6D9E42U, 0x982C4D22U, 0xD5F86DA9U,\r
+ 0xFF0F6A70U, 0x50FA7E56U, 0x82580EBFU, 0x5B5CF613U, 0x84E51D28U, 0x35314DE7U, 0x3E5B4696U, 0x19526D37U,\r
+ 0x66063BCAU, 0x7BD72D95U, 0x801EB0E6U, 0x49E959FDU, 0xC34567F8U, 0xB3A53F49U, 0x0FB35C0BU, 0x97DD6AD4U,\r
+ 0x11010B5CU, 0x62CC1CD4U, 0x81DCDAD1U, 0xF1553E98U, 0xFE254E48U, 0x78F9ECECU, 0xA9C457BFU, 0x5B776A4AU,\r
+ 0x8F659EFFU, 0x2D8D8A13U, 0x8493CC54U, 0x6C820621U, 0x4C059258U, 0x65FCDC54U, 0x6C636931U, 0x51B26353U,\r
+ 0xF862AE69U, 0x3496BB52U, 0x8551A663U, 0xD43E6144U, 0x7165BBE8U, 0xAEA00FF1U, 0xCA146285U, 0x9D1863CDU,\r
+ 0x616BFFD3U, 0x1FBBE891U, 0x8717183AU, 0xC68BCEAAU, 0x36C5C138U, 0x28347D5FU, 0xFBFC7818U, 0x1397642EU,\r
+ 0x166CCF45U, 0x06A0D9D0U, 0x86D5720DU, 0x7E37A9CFU, 0x0BA5E888U, 0xE368AEFAU, 0x5D8B73ACU, 0xDF3D64B0U,\r
+ 0xA00AE278U, 0x5E7EF3ECU, 0xA9E2D0A0U, 0xD67F4138U, 0x28D4C7DFU, 0x16441B82U, 0x03A0A617U, 0x83D02561U,\r
+ 0xD70DD2EEU, 0x4765C2ADU, 0xA820BA97U, 0x6EC3265DU, 0x15B4EE6FU, 0xDD18C827U, 0xA5D7ADA3U, 0x4F7A25FFU,\r
+ 0x4E048354U, 0x6C48916EU, 0xAA6604CEU, 0x7C7689B3U, 0x521494BFU, 0x5B8CBA89U, 0x943FB73EU, 0xC1F5221CU,\r
+ 0x3903B3C2U, 0x7553A02FU, 0xABA46EF9U, 0xC4CAEED6U, 0x6F74BD0FU, 0x90D0692CU, 0x3248BC8AU, 0x0D5F2282U,\r
+ 0xA7672661U, 0x3A1236E8U, 0xAEEB787CU, 0x591DD66FU, 0xDD54611FU, 0x8DD55994U, 0xF7EF8204U, 0x079A2B9BU,\r
+ 0xD06016F7U, 0x230907A9U, 0xAF29124BU, 0xE1A1B10AU, 0xE03448AFU, 0x46898A31U, 0x519889B0U, 0xCB302B05U,\r
+ 0x4969474DU, 0x0824546AU, 0xAD6FAC12U, 0xF3141EE4U, 0xA794327FU, 0xC01DF89FU, 0x6070932DU, 0x45BF2CE6U,\r
+ 0x3E6E77DBU, 0x113F652BU, 0xACADC625U, 0x4BA87981U, 0x9AF41BCFU, 0x0B412B3AU, 0xC6079899U, 0x89152C78U,\r
+ 0xAED16A4AU, 0x96A779E4U, 0xA7F18118U, 0x13CB69D7U, 0x18A48C1EU, 0xFA1799EFU, 0x304FE870U, 0x50353ED4U,\r
+ 0xD9D65ADCU, 0x8FBC48A5U, 0xA633EB2FU, 0xAB770EB2U, 0x25C4A5AEU, 0x314B4A4AU, 0x9638E3C4U, 0x9C9F3E4AU,\r
+ 0x40DF0B66U, 0xA4911B66U, 0xA4755576U, 0xB9C2A15CU, 0x6264DF7EU, 0xB7DF38E4U, 0xA7D0F959U, 0x121039A9U,\r
+ 0x37D83BF0U, 0xBD8A2A27U, 0xA5B73F41U, 0x017EC639U, 0x5F04F6CEU, 0x7C83EB41U, 0x01A7F2EDU, 0xDEBA3937U,\r
+ 0xA9BCAE53U, 0xF2CBBCE0U, 0xA0F829C4U, 0x9CA9FE80U, 0xED242ADEU, 0x6186DBF9U, 0xC400CC63U, 0xD47F302EU,\r
+ 0xDEBB9EC5U, 0xEBD08DA1U, 0xA13A43F3U, 0x241599E5U, 0xD044036EU, 0xAADA085CU, 0x6277C7D7U, 0x18D530B0U,\r
+ 0x47B2CF7FU, 0xC0FDDE62U, 0xA37CFDAAU, 0x36A0360BU, 0x97E479BEU, 0x2C4E7AF2U, 0x539FDD4AU, 0x965A3753U,\r
+ 0x30B5FFE9U, 0xD9E6EF23U, 0xA2BE979DU, 0x8E1C516EU, 0xAA84500EU, 0xE712A957U, 0xF5E8D6FEU, 0x5AF037CDU,\r
+ 0xBDBDF21CU, 0x14BCE1BDU, 0xB5C473D0U, 0x866616A7U, 0x4834505DU, 0x15921919U, 0x647E3AD9U, 0xFF6B144AU,\r
+ 0xCABAC28AU, 0x0DA7D0FCU, 0xB40619E7U, 0x3EDA71C2U, 0x755479EDU, 0xDECECABCU, 0xC209316DU, 0x33C114D4U,\r
+ 0x53B39330U, 0x268A833FU, 0xB640A7BEU, 0x2C6FDE2CU, 0x32F4033DU, 0x585AB812U, 0xF3E12BF0U, 0xBD4E1337U,\r
+ 0x24B4A3A6U, 0x3F91B27EU, 0xB782CD89U, 0x94D3B949U, 0x0F942A8DU, 0x93066BB7U, 0x55962044U, 0x71E413A9U,\r
+ 0xBAD03605U, 0x70D024B9U, 0xB2CDDB0CU, 0x090481F0U, 0xBDB4F69DU, 0x8E035B0FU, 0x90311ECAU, 0x7B211AB0U,\r
+ 0xCDD70693U, 0x69CB15F8U, 0xB30FB13BU, 0xB1B8E695U, 0x80D4DF2DU, 0x455F88AAU, 0x3646157EU, 0xB78B1A2EU,\r
+ 0x54DE5729U, 0x42E6463BU, 0xB1490F62U, 0xA30D497BU, 0xC774A5FDU, 0xC3CBFA04U, 0x07AE0FE3U, 0x39041DCDU,\r
+ 0x23D967BFU, 0x5BFD777AU, 0xB08B6555U, 0x1BB12E1EU, 0xFA148C4DU, 0x089729A1U, 0xA1D90457U, 0xF5AE1D53U,\r
+ 0xB3667A2EU, 0xDC656BB5U, 0xBBD72268U, 0x43D23E48U, 0x78441B9CU, 0xF9C19B74U, 0x579174BEU, 0x2C8E0FFFU,\r
+ 0xC4614AB8U, 0xC57E5AF4U, 0xBA15485FU, 0xFB6E592DU, 0x4524322CU, 0x329D48D1U, 0xF1E67F0AU, 0xE0240F61U,\r
+ 0x5D681B02U, 0xEE530937U, 0xB853F606U, 0xE9DBF6C3U, 0x028448FCU, 0xB4093A7FU, 0xC00E6597U, 0x6EAB0882U,\r
+ 0x2A6F2B94U, 0xF7483876U, 0xB9919C31U, 0x516791A6U, 0x3FE4614CU, 0x7F55E9DAU, 0x66796E23U, 0xA201081CU,\r
+ 0xB40BBE37U, 0xB809AEB1U, 0xBCDE8AB4U, 0xCCB0A91FU, 0x8DC4BD5CU, 0x6250D962U, 0xA3DE50ADU, 0xA8C40105U,\r
+ 0xC30C8EA1U, 0xA1129FF0U, 0xBD1CE083U, 0x740CCE7AU, 0xB0A494ECU, 0xA90C0AC7U, 0x05A95B19U, 0x646E019BU,\r
+ 0x5A05DF1BU, 0x8A3FCC33U, 0xBF5A5EDAU, 0x66B96194U, 0xF704EE3CU, 0x2F987869U, 0x34414184U, 0xEAE10678U,\r
+ 0x2D02EF8DU, 0x9324FD72U, 0xBE9834EDU, 0xDE0506F1U, 0xCA64C78CU, 0xE4C4ABCCU, 0x92364A30U, 0x264B06E6U,\r
+ };\r
+\r
+ uint32_t ulCrc32;\r
+\r
+ if(pBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulCrc32 = SUSPICIOUS_CRC_VALUE;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+ uint32_t ulIdx = 0U;\r
+ const uint32_t *pulXorCrc0 = &aulCrc32Table[7U];\r
+ const uint32_t *pulXorCrc1 = &aulCrc32Table[6U];\r
+ const uint32_t *pulXorCrc2 = &aulCrc32Table[5U];\r
+ const uint32_t *pulXorCrc3 = &aulCrc32Table[4U];\r
+ const uint32_t *pulXorData4 = &aulCrc32Table[3U];\r
+ const uint32_t *pulXorData5 = &aulCrc32Table[2U];\r
+ const uint32_t *pulXorData6 = &aulCrc32Table[1U];\r
+ const uint32_t *pulXorData7 = &aulCrc32Table[0U];\r
+ uint32_t ulSliceLen;\r
+\r
+ ulCrc32 = ~ulInitCrc32;\r
+\r
+ /* Aligned memory access is used below. To avoid suboptimal\r
+ performance and faults (depending on platform), handle the\r
+ unaligned initial bytes (if any) using the Sarwate algorithm.\r
+ */\r
+ while((ulIdx < ulLength) && !IS_ALIGNED_PTR(&pbBuffer[ulIdx]))\r
+ {\r
+ ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U];\r
+\r
+ ulIdx++;\r
+ }\r
+\r
+ /* Round down the length to the nearest multiple of eight.\r
+ */\r
+ ulSliceLen = (((ulLength - ulIdx) >> 3U) << 3U) + ulIdx;\r
+\r
+ /* Compute the CRC in eight byte "slices". Takes advantage of\r
+ modern processors which can load in parallel from multiple\r
+ memory locations.\r
+ */\r
+ while(ulIdx < ulSliceLen)\r
+ {\r
+ #if REDCONF_ENDIAN_BIG == 1\r
+ ulCrc32 ^= pbBuffer[ulIdx] | ((uint32_t)pbBuffer[ulIdx+1U] << 8U) |\r
+ ((uint32_t)pbBuffer[ulIdx+2U] << 16U) | ((uint32_t)pbBuffer[ulIdx+3U] << 24U);\r
+ #else\r
+ ulCrc32 ^= *CAST_CONST_UINT32_PTR(&pbBuffer[ulIdx]);\r
+ #endif\r
+\r
+ ulCrc32 =\r
+ pulXorCrc3[((ulCrc32 >> 24U) & 0xFFU) << 3U] ^\r
+ pulXorCrc2[((ulCrc32 >> 16U) & 0xFFU) << 3U] ^\r
+ pulXorCrc1[((ulCrc32 >> 8U) & 0xFFU) << 3U] ^\r
+ pulXorCrc0[ (ulCrc32 & 0xFFU) << 3U] ^\r
+ pulXorData7[pbBuffer[ulIdx+7U] << 3U] ^\r
+ pulXorData6[pbBuffer[ulIdx+6U] << 3U] ^\r
+ pulXorData5[pbBuffer[ulIdx+5U] << 3U] ^\r
+ pulXorData4[pbBuffer[ulIdx+4U] << 3U];\r
+\r
+ ulIdx += 8U;\r
+ }\r
+\r
+ /* Compute the remaining bytes with the Sarwate algorithm.\r
+ */\r
+ while(ulIdx < ulLength)\r
+ {\r
+ ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U];\r
+\r
+ ulIdx++;\r
+ }\r
+\r
+ ulCrc32 = ~ulCrc32;\r
+ }\r
+\r
+ return ulCrc32;\r
+}\r
+\r
+#else\r
+\r
+#error "REDCONF_CRC_ALGORITHM must be set to CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8"\r
+\r
+#endif\r
+\r
+\r
+/** @brief Compute a CRC32 for a metadata node buffer.\r
+\r
+ @param pBuffer The metadata node buffer for which to compute a CRC. Must\r
+ be a block sized buffer.\r
+\r
+ @return The CRC of the buffer.\r
+*/\r
+uint32_t RedCrcNode(\r
+ const void *pBuffer)\r
+{\r
+ uint32_t ulCrc;\r
+\r
+ if(pBuffer == NULL)\r
+ {\r
+ REDERROR();\r
+ ulCrc = SUSPICIOUS_CRC_VALUE;\r
+ }\r
+ else\r
+ {\r
+ const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);\r
+\r
+ /* The first eight bytes of a metadata node contain the signature and\r
+ the CRC. There is little value in CRCing the signature, and the\r
+ CRC cannot be CRC'd, so skip over that part of the buffer.\r
+ */\r
+ ulCrc = RedCrc32Update(0U, &pbBuffer[8U], REDCONF_BLOCK_SIZE - 8U);\r
+ }\r
+\r
+ return ulCrc;\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements utilities for performing endian swaps.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+#ifdef REDCONF_ENDIAN_SWAP\r
+\r
+/** @brief Reverse the byte order of a 64-bit number.\r
+\r
+ @param ullToRev Number whose bytes will be reversed\r
+\r
+ @retval @p ullToRev with its bytes reversed.\r
+*/\r
+uint64_t RedRev64(\r
+ uint64_t ullToRev)\r
+{\r
+ uint64_t ullRet = ullToRev;\r
+\r
+ ullRet = ((ullRet & UINT64_SUFFIX(0x00000000FFFFFFFF)) << 32U) | ((ullRet & UINT64_SUFFIX(0xFFFFFFFF00000000)) >> 32U);\r
+ ullRet = ((ullRet & UINT64_SUFFIX(0x0000FFFF0000FFFF)) << 16U) | ((ullRet & UINT64_SUFFIX(0xFFFF0000FFFF0000)) >> 16U);\r
+ ullRet = ((ullRet & UINT64_SUFFIX(0x00FF00FF00FF00FF)) << 8U) | ((ullRet & UINT64_SUFFIX(0xFF00FF00FF00FF00)) >> 8U);\r
+\r
+ return ullRet;\r
+}\r
+\r
+\r
+/** @brief Reverse the byte order of a 32-bit number.\r
+\r
+ @param ulToRev Number whose bytes will be reversed\r
+\r
+ @retval @p ulToRev with its bytes reversed.\r
+*/\r
+uint32_t RedRev32(\r
+ uint32_t ulToRev)\r
+{\r
+ return ((ulToRev & 0x000000FFU) << 24U)\r
+ | ((ulToRev & 0x0000FF00U) << 8U)\r
+ | ((ulToRev & 0x00FF0000U) >> 8U)\r
+ | ((ulToRev & 0xFF000000U) >> 24U);\r
+}\r
+\r
+\r
+/** @brief Reverse the byte order of a 16-bit number.\r
+\r
+ @param uToRev Number whose bytes will be reversed\r
+\r
+ @retval @p uToRev with its bytes reversed.\r
+*/\r
+uint16_t RedRev16(\r
+ uint16_t uToRev)\r
+{\r
+ return ((uToRev & 0xFF00U) >> 8U)\r
+ | ((uToRev & 0x00FFU) << 8U);\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Default implementations of memory manipulation functions.\r
+\r
+ These implementations are intended to be small and simple, and thus forego\r
+ all optimizations. If the C library is available, or if there are better\r
+ third-party implementations available in the system, those can be used\r
+ instead by defining the appropriate macros in redconf.h.\r
+\r
+ These functions are not intended to be completely 100% ANSI C compatible\r
+ implementations, but rather are designed to meet the needs of Reliance Edge.\r
+ The compatibility is close enough that ANSI C compatible implementations\r
+ can be "dropped in" as replacements without difficulty.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+#ifndef RedMemCpyUnchecked\r
+static void RedMemCpyUnchecked(void *pDest, const void *pSrc, uint32_t ulLen);\r
+#endif\r
+#ifndef RedMemMoveUnchecked\r
+static void RedMemMoveUnchecked(void *pDest, const void *pSrc, uint32_t ulLen);\r
+#endif\r
+#ifndef RedMemSetUnchecked\r
+static void RedMemSetUnchecked(void *pDest, uint8_t bVal, uint32_t ulLen);\r
+#endif\r
+#ifndef RedMemCmpUnchecked\r
+static int32_t RedMemCmpUnchecked(const void *pMem1, const void *pMem2, uint32_t ulLen);\r
+#endif\r
+\r
+\r
+/** @brief Copy memory from one address to another.\r
+\r
+ The source and destination memory buffers should not overlap. If the\r
+ buffers overlap, use RedMemMove() instead.\r
+\r
+ @param pDest The destination buffer.\r
+ @param pSrc The source buffer.\r
+ @param ulLen The number of bytes to copy.\r
+*/\r
+void RedMemCpy(\r
+ void *pDest,\r
+ const void *pSrc,\r
+ uint32_t ulLen)\r
+{\r
+ if((pDest == NULL) || (pSrc == NULL))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedMemCpyUnchecked(pDest, pSrc, ulLen);\r
+ }\r
+}\r
+\r
+\r
+#ifndef RedMemCpyUnchecked\r
+/** @brief Copy memory from one address to another.\r
+\r
+ This function should only be called from RedMemCpy().\r
+\r
+ @param pDest The destination buffer.\r
+ @param pSrc The source buffer.\r
+ @param ulLen The number of bytes to copy.\r
+*/\r
+static void RedMemCpyUnchecked(\r
+ void *pDest,\r
+ const void *pSrc,\r
+ uint32_t ulLen)\r
+{\r
+ uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);\r
+ const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);\r
+ uint32_t ulIdx;\r
+\r
+ for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)\r
+ {\r
+ pbDest[ulIdx] = pbSrc[ulIdx];\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Move memory from one address to another.\r
+\r
+ Supports overlapping memory regions. If memory regions do not overlap, it\r
+ is generally better to use RedMemCpy() instead.\r
+\r
+ @param pDest The destination buffer.\r
+ @param pSrc The source buffer.\r
+ @param ulLen The number of bytes to copy.\r
+*/\r
+void RedMemMove(\r
+ void *pDest,\r
+ const void *pSrc,\r
+ uint32_t ulLen)\r
+{\r
+ if((pDest == NULL) || (pSrc == NULL))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedMemMoveUnchecked(pDest, pSrc, ulLen);\r
+ }\r
+}\r
+\r
+\r
+#ifndef RedMemMoveUnchecked\r
+/** @brief Move memory from one address to another.\r
+\r
+ This function should only be called from RedMemMove().\r
+\r
+ @param pDest The destination buffer.\r
+ @param pSrc The source buffer.\r
+ @param ulLen The number of bytes to copy.\r
+*/\r
+static void RedMemMoveUnchecked(\r
+ void *pDest,\r
+ const void *pSrc,\r
+ uint32_t ulLen)\r
+{\r
+ uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);\r
+ const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);\r
+ uint32_t ulIdx;\r
+\r
+ if(MEMMOVE_MUST_COPY_FORWARD(pbDest, pbSrc))\r
+ {\r
+ /* If the destination is lower than the source with overlapping memory\r
+ regions, we must copy from start to end in order to copy the memory\r
+ correctly.\r
+\r
+ Don't use RedMemCpy() to do this. It is possible that RedMemCpy()\r
+ has been replaced (even though this function has not been replaced)\r
+ with an implementation that cannot handle any kind of buffer\r
+ overlap.\r
+ */\r
+ for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)\r
+ {\r
+ pbDest[ulIdx] = pbSrc[ulIdx];\r
+ }\r
+ }\r
+ else\r
+ {\r
+ ulIdx = ulLen;\r
+\r
+ while(ulIdx > 0U)\r
+ {\r
+ ulIdx--;\r
+ pbDest[ulIdx] = pbSrc[ulIdx];\r
+ }\r
+ }\r
+}\r
+#endif /* RedMemMoveUnchecked */\r
+\r
+\r
+/** @brief Initialize a buffer with the specified byte value.\r
+\r
+ @param pDest The buffer to initialize.\r
+ @param bVal The byte value with which to initialize @p pDest.\r
+ @param ulLen The number of bytes to initialize.\r
+*/\r
+void RedMemSet(\r
+ void *pDest,\r
+ uint8_t bVal,\r
+ uint32_t ulLen)\r
+{\r
+ if(pDest == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedMemSetUnchecked(pDest, bVal, ulLen);\r
+ }\r
+}\r
+\r
+\r
+#ifndef RedMemSetUnchecked\r
+/** @brief Initialize a buffer with the specified byte value.\r
+\r
+ This function should only be called from RedMemSet().\r
+\r
+ @param pDest The buffer to initialize.\r
+ @param bVal The byte value with which to initialize @p pDest.\r
+ @param ulLen The number of bytes to initialize.\r
+*/\r
+static void RedMemSetUnchecked(\r
+ void *pDest,\r
+ uint8_t bVal,\r
+ uint32_t ulLen)\r
+{\r
+ uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);\r
+ uint32_t ulIdx;\r
+\r
+ for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)\r
+ {\r
+ pbDest[ulIdx] = bVal;\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Compare the contents of two buffers.\r
+\r
+ @param pMem1 The first buffer to compare.\r
+ @param pMem2 The second buffer to compare.\r
+ @param ulLen The length to compare.\r
+\r
+ @return Zero if the two buffers are the same, otherwise nonzero.\r
+\r
+ @retval 0 @p pMem1 and @p pMem2 are the same.\r
+ @retval 1 @p pMem1 is greater than @p pMem2, as determined by the\r
+ values of the first differing bytes.\r
+ @retval -1 @p pMem2 is greater than @p pMem1, as determined by the\r
+ values of the first differing bytes.\r
+*/\r
+int32_t RedMemCmp(\r
+ const void *pMem1,\r
+ const void *pMem2,\r
+ uint32_t ulLen)\r
+{\r
+ int32_t lResult;\r
+\r
+ if((pMem1 == NULL) || (pMem2 == NULL))\r
+ {\r
+ REDERROR();\r
+ lResult = 0;\r
+ }\r
+ else\r
+ {\r
+ lResult = RedMemCmpUnchecked(pMem1, pMem2, ulLen);\r
+ }\r
+\r
+ return lResult;\r
+}\r
+\r
+\r
+#ifndef RedMemCmpUnchecked\r
+/** @brief Compare the contents of two buffers.\r
+\r
+ @param pMem1 The first buffer to compare.\r
+ @param pMem2 The second buffer to compare.\r
+ @param ulLen The length to compare.\r
+\r
+ @return Zero if the two buffers are the same, otherwise nonzero.\r
+*/\r
+static int32_t RedMemCmpUnchecked(\r
+ const void *pMem1,\r
+ const void *pMem2,\r
+ uint32_t ulLen)\r
+{\r
+ const uint8_t *pbMem1 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem1);\r
+ const uint8_t *pbMem2 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem2);\r
+ uint32_t ulIdx = 0U;\r
+ int32_t lResult;\r
+\r
+ while((ulIdx < ulLen) && (pbMem1[ulIdx] == pbMem2[ulIdx]))\r
+ {\r
+ ulIdx++;\r
+ }\r
+\r
+ if(ulIdx == ulLen)\r
+ {\r
+ lResult = 0;\r
+ }\r
+ else if(pbMem1[ulIdx] > pbMem2[ulIdx])\r
+ {\r
+ lResult = 1;\r
+ }\r
+ else\r
+ {\r
+ lResult = -1;\r
+ }\r
+\r
+ return lResult;\r
+}\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements a utility to find the length of a name.\r
+*/\r
+#include <redfs.h>\r
+\r
+#if REDCONF_API_POSIX == 1\r
+\r
+\r
+/** @brief Determine the length of a name, terminated either by a null or a path\r
+ separator character.\r
+\r
+ @param pszName The name whose length is to be determined.\r
+\r
+ @return The length of the name.\r
+*/\r
+uint32_t RedNameLen(\r
+ const char *pszName)\r
+{\r
+ uint32_t ulIdx = 0U;\r
+\r
+ if(pszName == NULL)\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ while((pszName[ulIdx] != '\0') && (pszName[ulIdx] != REDCONF_PATH_SEPARATOR))\r
+ {\r
+ ulIdx++;\r
+ }\r
+ }\r
+\r
+ return ulIdx;\r
+}\r
+\r
+#endif\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Implements a sign on message.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+/** @brief Display the Reliance Edge signon message.\r
+*/\r
+void RedSignOn(void)\r
+{\r
+ #if REDCONF_OUTPUT == 1\r
+\r
+ /* Use RedOsOutputString() instead of RedPrintf() to avoid using variadic\r
+ arguments, since this function is called from the driver and cannot use\r
+ functions that violate MISRA-C:2012.\r
+ */\r
+ RedOsOutputString(RED_PRODUCT_NAME "\n");\r
+ RedOsOutputString(RED_PRODUCT_EDITION "\n");\r
+ RedOsOutputString(RED_PRODUCT_LEGAL "\n");\r
+ RedOsOutputString(RED_PRODUCT_PATENT "\n");\r
+\r
+ #else\r
+\r
+ /* Always embed the copyright into the program data. Use "volatile" to try\r
+ to avoid the compiler removing the variables.\r
+ */\r
+ static volatile const char szVersion[] = RED_PRODUCT_NAME;\r
+ static volatile const char szEdition[] = RED_PRODUCT_EDITION;\r
+ static volatile const char szCopyright[] = RED_PRODUCT_LEGAL;\r
+ static volatile const char szPatent[] = RED_PRODUCT_PATENT;\r
+\r
+ (void)szVersion;\r
+ (void)szEdition;\r
+ (void)szCopyright;\r
+ (void)szPatent;\r
+\r
+ #endif\r
+}\r
+\r
--- /dev/null
+/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----\r
+\r
+ Copyright (c) 2014-2015 Datalight, Inc.\r
+ All Rights Reserved Worldwide.\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; use version 2 of the License.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty\r
+ of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+*/\r
+/* Businesses and individuals that for commercial or other reasons cannot\r
+ comply with the terms of the GPLv2 license may obtain a commercial license\r
+ before incorporating Reliance Edge into proprietary software for\r
+ distribution in any form. Visit http://www.datalight.com/reliance-edge for\r
+ more information.\r
+*/\r
+/** @file\r
+ @brief Default implementations of string manipulation functions.\r
+\r
+ These implementations are intended to be small and simple, and thus forego\r
+ all optimizations. If the C library is available, or if there are better\r
+ third-party implementations available in the system, those can be used\r
+ instead by defining the appropriate macros in redconf.h.\r
+\r
+ These functions are not intended to be completely 100% ANSI C compatible\r
+ implementations, but rather are designed to meet the needs of Reliance Edge.\r
+ The compatibility is close enough that ANSI C compatible implementations\r
+ can be "dropped in" as replacements without difficulty.\r
+*/\r
+#include <redfs.h>\r
+\r
+\r
+#ifndef RedStrLenUnchecked\r
+static uint32_t RedStrLenUnchecked(const char *pszStr);\r
+#endif\r
+#ifndef RedStrCmpUnchecked\r
+static int32_t RedStrCmpUnchecked(const char *pszStr1, const char *pszStr2);\r
+#endif\r
+#ifndef RedStrNCmpUnchecked\r
+static int32_t RedStrNCmpUnchecked(const char *pszStr1, const char *pszStr2, uint32_t ulLen);\r
+#endif\r
+#ifndef RedStrNCpyUnchecked\r
+static void RedStrNCpyUnchecked(char *pszDst, const char *pszSrc, uint32_t ulLen);\r
+#endif\r
+\r
+\r
+/** @brief Determine the length (in bytes) of a null terminated string.\r
+\r
+ The length does not include the null terminator byte.\r
+\r
+ @param pszStr The null terminated string whose length is to be determined.\r
+\r
+ @return The length of the @p pszStr string.\r
+*/\r
+uint32_t RedStrLen(\r
+ const char *pszStr)\r
+{\r
+ uint32_t ulLen;\r
+\r
+ if(pszStr == NULL)\r
+ {\r
+ REDERROR();\r
+ ulLen = 0U;\r
+ }\r
+ else\r
+ {\r
+ /* Cast the result to uint32_t, since RedStrLenUnchecked() might be\r
+ strlen(), which returns size_t, which is possibly a 64-bit value.\r
+ */\r
+ ulLen = (uint32_t)RedStrLenUnchecked(pszStr);\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+\r
+\r
+#ifndef RedStrLenUnchecked\r
+/** @brief Determine the length (in bytes) of a null terminated string.\r
+\r
+ @param pszStr The null terminated string whose length is to be determined.\r
+\r
+ @return The length of the @p pszStr string.\r
+*/\r
+static uint32_t RedStrLenUnchecked(\r
+ const char *pszStr)\r
+{\r
+ uint32_t ulLen = 0U;\r
+\r
+ while(pszStr[ulLen] != '\0')\r
+ {\r
+ ulLen++;\r
+ }\r
+\r
+ return ulLen;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Compare two null terminated strings.\r
+\r
+ @param pszStr1 The first string to compare.\r
+ @param pszStr2 The second string to compare.\r
+\r
+ @return Zero if the two strings are the same, otherwise nonzero.\r
+\r
+ @retval 0 @p pszStr1 and @p pszStr2 are the same.\r
+ @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the\r
+ values of the first differing bytes.\r
+ @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the\r
+ values of the first differing bytes.\r
+*/\r
+int32_t RedStrCmp(\r
+ const char *pszStr1,\r
+ const char *pszStr2)\r
+{\r
+ int32_t lResult;\r
+\r
+ if((pszStr1 == NULL) || (pszStr2 == NULL))\r
+ {\r
+ REDERROR();\r
+ lResult = 0;\r
+ }\r
+ else\r
+ {\r
+ lResult = RedStrCmpUnchecked(pszStr1, pszStr2);\r
+ }\r
+\r
+ return lResult;\r
+}\r
+\r
+\r
+#ifndef RedStrCmpUnchecked\r
+/** @brief Compare two null terminated strings.\r
+\r
+ @param pszStr1 The first string to compare.\r
+ @param pszStr2 The second string to compare.\r
+\r
+ @return Zero if the two strings are the same, otherwise nonzero.\r
+*/\r
+static int32_t RedStrCmpUnchecked(\r
+ const char *pszStr1,\r
+ const char *pszStr2)\r
+{\r
+ int32_t lResult;\r
+ uint32_t ulIdx = 0U;\r
+\r
+ while((pszStr1[ulIdx] == pszStr2[ulIdx]) && (pszStr1[ulIdx] != '\0'))\r
+ {\r
+ ulIdx++;\r
+ }\r
+\r
+ /* "The sign of a non-zero return value is determined by the sign of the\r
+ difference between the values of the first pair of bytes (both\r
+ interpreted as type unsigned char) that differ in the strings being\r
+ compared." Use uint8_t instead of unsigned char to avoid MISRA C\r
+ deviations.\r
+ */\r
+ if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx])\r
+ {\r
+ lResult = 1;\r
+ }\r
+ else if((uint8_t)pszStr1[ulIdx] < (uint8_t)pszStr2[ulIdx])\r
+ {\r
+ lResult = -1;\r
+ }\r
+ else\r
+ {\r
+ lResult = 0;\r
+ }\r
+\r
+ return lResult;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Compare the first @p ulLen characters of two null terminated strings.\r
+\r
+ @param pszStr1 The first string to compare.\r
+ @param pszStr2 The second string to compare.\r
+ @param ulLen The maximum length to compare. The comparison stops when\r
+ either of the strings end or when @p ulLen bytes have been\r
+ compared.\r
+\r
+ @return Zero if the two strings are the same, otherwise nonzero.\r
+\r
+ @retval 0 @p pszStr1 and @p pszStr2 are the same.\r
+ @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the\r
+ values of the first differing bytes.\r
+ @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the\r
+ values of the first differing bytes.\r
+*/\r
+int32_t RedStrNCmp(\r
+ const char *pszStr1,\r
+ const char *pszStr2,\r
+ uint32_t ulLen)\r
+{\r
+ int32_t lResult;\r
+\r
+ if((pszStr1 == NULL) || (pszStr2 == NULL))\r
+ {\r
+ REDERROR();\r
+ lResult = 0;\r
+ }\r
+ else\r
+ {\r
+ lResult = RedStrNCmpUnchecked(pszStr1, pszStr2, ulLen);\r
+ }\r
+\r
+ return lResult;\r
+}\r
+\r
+\r
+#ifndef RedStrNCmpUnchecked\r
+/** @brief Compare the first @p ulLen characters of two null terminated strings.\r
+\r
+ @param pszStr1 The first string to compare.\r
+ @param pszStr2 The second string to compare.\r
+ @param ulLen The maximum length to compare. The comparison stops when\r
+ either of the strings end or when @p ulLen bytes have been\r
+ compared.\r
+\r
+ @return Zero if the two strings are the same, otherwise nonzero.\r
+*/\r
+static int32_t RedStrNCmpUnchecked(\r
+ const char *pszStr1,\r
+ const char *pszStr2,\r
+ uint32_t ulLen)\r
+{\r
+ int32_t lResult = 0;\r
+ uint32_t ulIdx;\r
+\r
+ for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)\r
+ {\r
+ if(pszStr1[ulIdx] != pszStr2[ulIdx])\r
+ {\r
+ /* "The sign of a non-zero return value is determined by the sign\r
+ of the difference between the values of the first pair of bytes\r
+ (both interpreted as type unsigned char) that differ in the\r
+ strings being compared." Use uint8_t instead of unsigned char\r
+ to avoid MISRA C deviations.\r
+ */\r
+ if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx])\r
+ {\r
+ lResult = 1;\r
+ }\r
+ else\r
+ {\r
+ lResult = -1;\r
+ }\r
+ }\r
+\r
+ if((lResult != 0) || (pszStr1[ulIdx] == '\0'))\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ return lResult;\r
+}\r
+#endif\r
+\r
+\r
+/** @brief Copy a string.\r
+\r
+ Copy up to @p ulLen bytes of a null-terminated string (@p pszSrc) to a\r
+ destination buffer (@p pszDst). The result will not be null-terminated if\r
+ @p pszSrc is longer than @p ulLen - 1 bytes.\r
+\r
+ If @p pszSrc is shorter than @p ulLen - 1 bytes, the remainder of @p pszDst\r
+ will be filled with null bytes.\r
+\r
+ @param pszDst The destination buffer, which is at least @p ulLen bytes\r
+ in size.\r
+ @param pszSrc The null-terminated string to copy.\r
+ @param ulLen The maximum number of characters to copy.\r
+*/\r
+void RedStrNCpy(\r
+ char *pszDst,\r
+ const char *pszSrc,\r
+ uint32_t ulLen)\r
+{\r
+ if((pszDst == NULL) || (pszSrc == NULL))\r
+ {\r
+ REDERROR();\r
+ }\r
+ else\r
+ {\r
+ RedStrNCpyUnchecked(pszDst, pszSrc, ulLen);\r
+ }\r
+}\r
+\r
+\r
+#ifndef RedStrNCpyUnchecked\r
+/** @brief Copy a string.\r
+\r
+ @param pszDst The destination buffer, which is at least @p ulLen bytes\r
+ in size.\r
+ @param pszSrc The null-terminated string to copy.\r
+ @param ulLen The maximum number of characters to copy.\r
+*/\r
+static void RedStrNCpyUnchecked(\r
+ char *pszDst,\r
+ const char *pszSrc,\r
+ uint32_t ulLen)\r
+{\r
+ uint32_t ulIdx = 0U;\r
+\r
+ while((ulIdx < ulLen) && (pszSrc[ulIdx] != '\0'))\r
+ {\r
+ pszDst[ulIdx] = pszSrc[ulIdx];\r
+ ulIdx++;\r
+ }\r
+\r
+ while(ulIdx < ulLen)\r
+ {\r
+ pszDst[ulIdx] = '\0';\r
+ ulIdx++;\r
+ }\r
+}\r
+#endif\r
+\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*****************************************************************************/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
; FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
; http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
; FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
; http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
\r
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
; FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
; http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
\r
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
- 1 tab == 4 spaces!\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
*/\r
\r
/* Standard includes. */\r
/*\r
- FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
- 1 tab == 4 spaces!\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
*/\r
\r
/* Standard includes. */\r
/*\r
- FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
\r
1 tab == 4 spaces!\r
+*/\r
+#ifndef LWIP_APPS_H\r
+#define LWIP_APPS_H\r
+\r
+/* Functions used to obtain and release exclusive access to the Tx buffer. The\r
+Get function will block if the Tx buffer is not available - use with care! */\r
+signed char *pcLwipAppsBlockingGetTxBuffer( void );\r
+void vLwipAppsReleaseTxBuffer( void );\r
+\r
+#endif /* LWIP_APPS_H */\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/
-#ifndef LWIP_APPS_H
-#define LWIP_APPS_H
-
-/* Functions used to obtain and release exclusive access to the Tx buffer. The
-Get function will block if the Tx buffer is not available - use with care! */
-signed char *pcLwipAppsBlockingGetTxBuffer( void );
-void vLwipAppsReleaseTxBuffer( void );
-
-#endif /* LWIP_APPS_H */
-
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
-#define TCP_SND_QUEUELEN ( ( 16 * TCP_SND_BUF )/ TCP_MSS )
+#define TCP_SND_QUEUELEN ( ( 16 * TCP_SND_BUF ) / TCP_MSS )
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
; VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
; VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
- 1 tab == 4 spaces!\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
*/\r
\r
/* Standard includes. */\r
/*\r
- FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
\r
- 1 tab == 4 spaces!\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
*/\r
\r
/* Standard includes. */\r
/*\r
- FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
+ FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
\r
***************************************************************************\r
* *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
* *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
* *\r
***************************************************************************\r
\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
\r
- This file is part of the FreeRTOS distribution.\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
- >>>NOTE<<< The modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
- more details. You should have received a copy of the GNU General Public\r
- License and the FreeRTOS license exception along with FreeRTOS; if not it\r
- can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
- by writing to Richard Barry, contact details for whom are available on the\r
- FreeRTOS WEB site.\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
\r
1 tab == 4 spaces!\r
+*/\r
+#ifndef LWIP_APPS_H\r
+#define LWIP_APPS_H\r
+\r
+/* Functions used to obtain and release exclusive access to the Tx buffer. The\r
+Get function will block if the Tx buffer is not available - use with care! */\r
+signed char *pcLwipAppsBlockingGetTxBuffer( void );\r
+void vLwipAppsReleaseTxBuffer( void );\r
+\r
+#endif /* LWIP_APPS_H */\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and\r
- contact details.\r
-\r
- http://www.SafeRTOS.com - A version that is certified for use in safety\r
- critical systems.\r
-\r
- http://www.OpenRTOS.com - Commercial support, development, porting,\r
- licensing and training services.\r
-*/
-#ifndef LWIP_APPS_H
-#define LWIP_APPS_H
-
-/* Functions used to obtain and release exclusive access to the Tx buffer. The
-Get function will block if the Tx buffer is not available - use with care! */
-signed char *pcLwipAppsBlockingGetTxBuffer( void );
-void vLwipAppsReleaseTxBuffer( void );
-
-#endif /* LWIP_APPS_H */
-
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
The project from this directory has been superseded by the project documented\r
on the following page: http://www.freertos.org/RTOS-Xilinx-Microblaze-KC705.html\r
\r
-If you need the demo that used to be in this directory then download FreeRTOS V8.2.1\r
+If you need the demo that used to be in this directory then download FreeRTOS V8.2.2\r
from http://sourceforge.net/projects/freertos/files/FreeRTOS/\r
\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
; FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT\r
; http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
;\r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
; VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
; VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; \r
;\r
; ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef INC_FREERTOS_H\r
-#define INC_FREERTOS_H\r
-\r
-/*\r
- * Include the generic headers required for the FreeRTOS port being used.\r
- */\r
-#include <stddef.h>\r
-\r
-/*\r
- * If stdint.h cannot be located then:\r
- * + If using GCC ensure the -nostdint options is *not* being used.\r
- * + Ensure the project's include path includes the directory in which your\r
- * compiler stores stdint.h.\r
- * + Set any compiler options necessary for it to support C99, as technically\r
- * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any\r
- * other way).\r
- * + The FreeRTOS download includes a simple stdint.h definition that can be\r
- * used in cases where none is provided by the compiler. The files only\r
- * contains the typedefs required to build FreeRTOS. Read the instructions\r
- * in FreeRTOS/source/stdint.readme for more information.\r
- */\r
-#include <stdint.h> /* READ COMMENT ABOVE. */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* Application specific configuration options. */\r
-#include "FreeRTOSConfig.h"\r
-\r
-/* Basic FreeRTOS definitions. */\r
-#include "projdefs.h"\r
-\r
-/* Definitions specific to the port being used. */\r
-#include "portable.h"\r
-\r
-/*\r
- * Check all the required application specific macros have been defined.\r
- * These macros are application specific and (as downloaded) are defined\r
- * within FreeRTOSConfig.h.\r
- */\r
-\r
-#ifndef configMINIMAL_STACK_SIZE\r
- #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value.\r
-#endif\r
-\r
-#ifndef configMAX_PRIORITIES\r
- #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_PREEMPTION\r
- #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_IDLE_HOOK\r
- #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_TICK_HOOK\r
- #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskPrioritySet\r
- #error Missing definition: INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_uxTaskPriorityGet\r
- #error Missing definition: INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelete\r
- #error Missing definition: INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskSuspend\r
- #error Missing definition: INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelayUntil\r
- #error Missing definition: INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef INCLUDE_vTaskDelay\r
- #error Missing definition: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configUSE_16_BIT_TICKS\r
- #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.\r
-#endif\r
-\r
-#ifndef configMAX_PRIORITIES\r
- #error configMAX_PRIORITIES must be defined to be greater than or equal to 1.\r
-#endif\r
-\r
-#ifndef configUSE_CO_ROUTINES\r
- #define configUSE_CO_ROUTINES 0\r
-#endif\r
-\r
-#if configUSE_CO_ROUTINES != 0\r
- #ifndef configMAX_CO_ROUTINE_PRIORITIES\r
- #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.\r
- #endif\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskGetIdleTaskHandle\r
- #define INCLUDE_xTaskGetIdleTaskHandle 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle\r
- #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xQueueGetMutexHolder\r
- #define INCLUDE_xQueueGetMutexHolder 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xSemaphoreGetMutexHolder\r
- #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder\r
-#endif\r
-\r
-#ifndef INCLUDE_pcTaskGetTaskName\r
- #define INCLUDE_pcTaskGetTaskName 0\r
-#endif\r
-\r
-#ifndef configUSE_APPLICATION_TASK_TAG\r
- #define configUSE_APPLICATION_TASK_TAG 0\r
-#endif\r
-\r
-#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS\r
- #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0\r
-#endif\r
-\r
-#ifndef INCLUDE_uxTaskGetStackHighWaterMark\r
- #define INCLUDE_uxTaskGetStackHighWaterMark 0\r
-#endif\r
-\r
-#ifndef INCLUDE_eTaskGetState\r
- #define INCLUDE_eTaskGetState 0\r
-#endif\r
-\r
-#ifndef configUSE_RECURSIVE_MUTEXES\r
- #define configUSE_RECURSIVE_MUTEXES 0\r
-#endif\r
-\r
-#ifndef configUSE_MUTEXES\r
- #define configUSE_MUTEXES 0\r
-#endif\r
-\r
-#ifndef configUSE_TIMERS\r
- #define configUSE_TIMERS 0\r
-#endif\r
-\r
-#ifndef configUSE_COUNTING_SEMAPHORES\r
- #define configUSE_COUNTING_SEMAPHORES 0\r
-#endif\r
-\r
-#ifndef configUSE_ALTERNATIVE_API\r
- #define configUSE_ALTERNATIVE_API 0\r
-#endif\r
-\r
-#ifndef portCRITICAL_NESTING_IN_TCB\r
- #define portCRITICAL_NESTING_IN_TCB 0\r
-#endif\r
-\r
-#ifndef configMAX_TASK_NAME_LEN\r
- #define configMAX_TASK_NAME_LEN 16\r
-#endif\r
-\r
-#ifndef configIDLE_SHOULD_YIELD\r
- #define configIDLE_SHOULD_YIELD 1\r
-#endif\r
-\r
-#if configMAX_TASK_NAME_LEN < 1\r
- #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskResumeFromISR\r
- #define INCLUDE_xTaskResumeFromISR 1\r
-#endif\r
-\r
-#ifndef INCLUDE_xEventGroupSetBitFromISR\r
- #define INCLUDE_xEventGroupSetBitFromISR 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xTimerPendFunctionCall\r
- #define INCLUDE_xTimerPendFunctionCall 0\r
-#endif\r
-\r
-#ifndef configASSERT\r
- #define configASSERT( x )\r
- #define configASSERT_DEFINED 0\r
-#else\r
- #define configASSERT_DEFINED 1\r
-#endif\r
-\r
-/* The timers module relies on xTaskGetSchedulerState(). */\r
-#if configUSE_TIMERS == 1\r
-\r
- #ifndef configTIMER_TASK_PRIORITY\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.\r
- #endif /* configTIMER_TASK_PRIORITY */\r
-\r
- #ifndef configTIMER_QUEUE_LENGTH\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.\r
- #endif /* configTIMER_QUEUE_LENGTH */\r
-\r
- #ifndef configTIMER_TASK_STACK_DEPTH\r
- #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.\r
- #endif /* configTIMER_TASK_STACK_DEPTH */\r
-\r
-#endif /* configUSE_TIMERS */\r
-\r
-#ifndef INCLUDE_xTaskGetSchedulerState\r
- #define INCLUDE_xTaskGetSchedulerState 0\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
- #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
-#endif\r
-\r
-\r
-#ifndef portSET_INTERRUPT_MASK_FROM_ISR\r
- #define portSET_INTERRUPT_MASK_FROM_ISR() 0\r
-#endif\r
-\r
-#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR\r
- #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue\r
-#endif\r
-\r
-#ifndef portCLEAN_UP_TCB\r
- #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB\r
-#endif\r
-\r
-#ifndef portPRE_TASK_DELETE_HOOK\r
- #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending )\r
-#endif\r
-\r
-#ifndef portSETUP_TCB\r
- #define portSETUP_TCB( pxTCB ) ( void ) pxTCB\r
-#endif\r
-\r
-#ifndef configQUEUE_REGISTRY_SIZE\r
- #define configQUEUE_REGISTRY_SIZE 0U\r
-#endif\r
-\r
-#if ( configQUEUE_REGISTRY_SIZE < 1 )\r
- #define vQueueAddToRegistry( xQueue, pcName )\r
- #define vQueueUnregisterQueue( xQueue )\r
-#endif\r
-\r
-#ifndef portPOINTER_SIZE_TYPE\r
- #define portPOINTER_SIZE_TYPE uint32_t\r
-#endif\r
-\r
-/* Remove any unused trace macros. */\r
-#ifndef traceSTART\r
- /* Used to perform any necessary initialisation - for example, open a file\r
- into which trace is to be written. */\r
- #define traceSTART()\r
-#endif\r
-\r
-#ifndef traceEND\r
- /* Use to close a trace, for example close a file into which trace has been\r
- written. */\r
- #define traceEND()\r
-#endif\r
-\r
-#ifndef traceTASK_SWITCHED_IN\r
- /* Called after a task has been selected to run. pxCurrentTCB holds a pointer\r
- to the task control block of the selected task. */\r
- #define traceTASK_SWITCHED_IN()\r
-#endif\r
-\r
-#ifndef traceINCREASE_TICK_COUNT\r
- /* Called before stepping the tick count after waking from tickless idle\r
- sleep. */\r
- #define traceINCREASE_TICK_COUNT( x )\r
-#endif\r
-\r
-#ifndef traceLOW_POWER_IDLE_BEGIN\r
- /* Called immediately before entering tickless idle. */\r
- #define traceLOW_POWER_IDLE_BEGIN()\r
-#endif\r
-\r
-#ifndef traceLOW_POWER_IDLE_END\r
- /* Called when returning to the Idle task after a tickless idle. */\r
- #define traceLOW_POWER_IDLE_END()\r
-#endif\r
-\r
-#ifndef traceTASK_SWITCHED_OUT\r
- /* Called before a task has been selected to run. pxCurrentTCB holds a pointer\r
- to the task control block of the task being switched out. */\r
- #define traceTASK_SWITCHED_OUT()\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_INHERIT\r
- /* Called when a task attempts to take a mutex that is already held by a\r
- lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task\r
- that holds the mutex. uxInheritedPriority is the priority the mutex holder\r
- will inherit (the priority of the task that is attempting to obtain the\r
- muted. */\r
- #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_DISINHERIT\r
- /* Called when a task releases a mutex, the holding of which had resulted in\r
- the task inheriting the priority of a higher priority task.\r
- pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the\r
- mutex. uxOriginalPriority is the task's configured (base) priority. */\r
- #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )\r
-#endif\r
-\r
-#ifndef traceBLOCKING_ON_QUEUE_RECEIVE\r
- /* Task is about to block because it cannot read from a\r
- queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
- upon which the read was attempted. pxCurrentTCB points to the TCB of the\r
- task that attempted the read. */\r
- #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceBLOCKING_ON_QUEUE_SEND\r
- /* Task is about to block because it cannot write to a\r
- queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore\r
- upon which the write was attempted. pxCurrentTCB points to the TCB of the\r
- task that attempted the write. */\r
- #define traceBLOCKING_ON_QUEUE_SEND( pxQueue )\r
-#endif\r
-\r
-#ifndef configCHECK_FOR_STACK_OVERFLOW\r
- #define configCHECK_FOR_STACK_OVERFLOW 0\r
-#endif\r
-\r
-/* The following event macros are embedded in the kernel API calls. */\r
-\r
-#ifndef traceMOVED_TASK_TO_READY_STATE\r
- #define traceMOVED_TASK_TO_READY_STATE( pxTCB )\r
-#endif\r
-\r
-#ifndef traceQUEUE_CREATE\r
- #define traceQUEUE_CREATE( pxNewQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_CREATE_FAILED\r
- #define traceQUEUE_CREATE_FAILED( ucQueueType )\r
-#endif\r
-\r
-#ifndef traceCREATE_MUTEX\r
- #define traceCREATE_MUTEX( pxNewQueue )\r
-#endif\r
-\r
-#ifndef traceCREATE_MUTEX_FAILED\r
- #define traceCREATE_MUTEX_FAILED()\r
-#endif\r
-\r
-#ifndef traceGIVE_MUTEX_RECURSIVE\r
- #define traceGIVE_MUTEX_RECURSIVE( pxMutex )\r
-#endif\r
-\r
-#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED\r
- #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
-#endif\r
-\r
-#ifndef traceTAKE_MUTEX_RECURSIVE\r
- #define traceTAKE_MUTEX_RECURSIVE( pxMutex )\r
-#endif\r
-\r
-#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED\r
- #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )\r
-#endif\r
-\r
-#ifndef traceCREATE_COUNTING_SEMAPHORE\r
- #define traceCREATE_COUNTING_SEMAPHORE()\r
-#endif\r
-\r
-#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED\r
- #define traceCREATE_COUNTING_SEMAPHORE_FAILED()\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND\r
- #define traceQUEUE_SEND( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FAILED\r
- #define traceQUEUE_SEND_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE\r
- #define traceQUEUE_RECEIVE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_PEEK\r
- #define traceQUEUE_PEEK( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_PEEK_FROM_ISR\r
- #define traceQUEUE_PEEK_FROM_ISR( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FAILED\r
- #define traceQUEUE_RECEIVE_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FROM_ISR\r
- #define traceQUEUE_SEND_FROM_ISR( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_SEND_FROM_ISR_FAILED\r
- #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FROM_ISR\r
- #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED\r
- #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED\r
- #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )\r
-#endif\r
-\r
-#ifndef traceQUEUE_DELETE\r
- #define traceQUEUE_DELETE( pxQueue )\r
-#endif\r
-\r
-#ifndef traceTASK_CREATE\r
- #define traceTASK_CREATE( pxNewTCB )\r
-#endif\r
-\r
-#ifndef traceTASK_CREATE_FAILED\r
- #define traceTASK_CREATE_FAILED()\r
-#endif\r
-\r
-#ifndef traceTASK_DELETE\r
- #define traceTASK_DELETE( pxTaskToDelete )\r
-#endif\r
-\r
-#ifndef traceTASK_DELAY_UNTIL\r
- #define traceTASK_DELAY_UNTIL()\r
-#endif\r
-\r
-#ifndef traceTASK_DELAY\r
- #define traceTASK_DELAY()\r
-#endif\r
-\r
-#ifndef traceTASK_PRIORITY_SET\r
- #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )\r
-#endif\r
-\r
-#ifndef traceTASK_SUSPEND\r
- #define traceTASK_SUSPEND( pxTaskToSuspend )\r
-#endif\r
-\r
-#ifndef traceTASK_RESUME\r
- #define traceTASK_RESUME( pxTaskToResume )\r
-#endif\r
-\r
-#ifndef traceTASK_RESUME_FROM_ISR\r
- #define traceTASK_RESUME_FROM_ISR( pxTaskToResume )\r
-#endif\r
-\r
-#ifndef traceTASK_INCREMENT_TICK\r
- #define traceTASK_INCREMENT_TICK( xTickCount )\r
-#endif\r
-\r
-#ifndef traceTIMER_CREATE\r
- #define traceTIMER_CREATE( pxNewTimer )\r
-#endif\r
-\r
-#ifndef traceTIMER_CREATE_FAILED\r
- #define traceTIMER_CREATE_FAILED()\r
-#endif\r
-\r
-#ifndef traceTIMER_COMMAND_SEND\r
- #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )\r
-#endif\r
-\r
-#ifndef traceTIMER_EXPIRED\r
- #define traceTIMER_EXPIRED( pxTimer )\r
-#endif\r
-\r
-#ifndef traceTIMER_COMMAND_RECEIVED\r
- #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )\r
-#endif\r
-\r
-#ifndef traceMALLOC\r
- #define traceMALLOC( pvAddress, uiSize )\r
-#endif\r
-\r
-#ifndef traceFREE\r
- #define traceFREE( pvAddress, uiSize )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_CREATE\r
- #define traceEVENT_GROUP_CREATE( xEventGroup )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_CREATE_FAILED\r
- #define traceEVENT_GROUP_CREATE_FAILED()\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_SYNC_BLOCK\r
- #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_SYNC_END\r
- #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK\r
- #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_WAIT_BITS_END\r
- #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_CLEAR_BITS\r
- #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR\r
- #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_SET_BITS\r
- #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR\r
- #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet )\r
-#endif\r
-\r
-#ifndef traceEVENT_GROUP_DELETE\r
- #define traceEVENT_GROUP_DELETE( xEventGroup )\r
-#endif\r
-\r
-#ifndef tracePEND_FUNC_CALL\r
- #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret)\r
-#endif\r
-\r
-#ifndef tracePEND_FUNC_CALL_FROM_ISR\r
- #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret)\r
-#endif\r
-\r
-#ifndef traceQUEUE_REGISTRY_ADD\r
- #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName)\r
-#endif\r
-\r
-#ifndef configGENERATE_RUN_TIME_STATS\r
- #define configGENERATE_RUN_TIME_STATS 0\r
-#endif\r
-\r
-#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
-\r
- #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
- #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.\r
- #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */\r
-\r
- #ifndef portGET_RUN_TIME_COUNTER_VALUE\r
- #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE\r
- #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information.\r
- #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */\r
- #endif /* portGET_RUN_TIME_COUNTER_VALUE */\r
-\r
-#endif /* configGENERATE_RUN_TIME_STATS */\r
-\r
-#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS\r
- #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\r
-#endif\r
-\r
-#ifndef configUSE_MALLOC_FAILED_HOOK\r
- #define configUSE_MALLOC_FAILED_HOOK 0\r
-#endif\r
-\r
-#ifndef portPRIVILEGE_BIT\r
- #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )\r
-#endif\r
-\r
-#ifndef portYIELD_WITHIN_API\r
- #define portYIELD_WITHIN_API portYIELD\r
-#endif\r
-\r
-#ifndef pvPortMallocAligned\r
- #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )\r
-#endif\r
-\r
-#ifndef vPortFreeAligned\r
- #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )\r
-#endif\r
-\r
-#ifndef portSUPPRESS_TICKS_AND_SLEEP\r
- #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )\r
-#endif\r
-\r
-#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP\r
- #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2\r
-#endif\r
-\r
-#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2\r
- #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2\r
-#endif\r
-\r
-#ifndef configUSE_TICKLESS_IDLE\r
- #define configUSE_TICKLESS_IDLE 0\r
-#endif\r
-\r
-#ifndef configPRE_SLEEP_PROCESSING\r
- #define configPRE_SLEEP_PROCESSING( x )\r
-#endif\r
-\r
-#ifndef configPOST_SLEEP_PROCESSING\r
- #define configPOST_SLEEP_PROCESSING( x )\r
-#endif\r
-\r
-#ifndef configUSE_QUEUE_SETS\r
- #define configUSE_QUEUE_SETS 0\r
-#endif\r
-\r
-#ifndef portTASK_USES_FLOATING_POINT\r
- #define portTASK_USES_FLOATING_POINT()\r
-#endif\r
-\r
-#ifndef configUSE_TIME_SLICING\r
- #define configUSE_TIME_SLICING 1\r
-#endif\r
-\r
-#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS\r
- #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0\r
-#endif\r
-\r
-#ifndef configUSE_NEWLIB_REENTRANT\r
- #define configUSE_NEWLIB_REENTRANT 0\r
-#endif\r
-\r
-#ifndef configUSE_STATS_FORMATTING_FUNCTIONS\r
- #define configUSE_STATS_FORMATTING_FUNCTIONS 0\r
-#endif\r
-\r
-#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID\r
- #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()\r
-#endif\r
-\r
-#ifndef configUSE_TRACE_FACILITY\r
- #define configUSE_TRACE_FACILITY 0\r
-#endif\r
-\r
-#ifndef mtCOVERAGE_TEST_MARKER\r
- #define mtCOVERAGE_TEST_MARKER()\r
-#endif\r
-\r
-#ifndef mtCOVERAGE_TEST_DELAY\r
- #define mtCOVERAGE_TEST_DELAY()\r
-#endif\r
-\r
-#ifndef portASSERT_IF_IN_ISR\r
- #define portASSERT_IF_IN_ISR()\r
-#endif\r
-\r
-#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION\r
- #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0\r
-#endif\r
-\r
-#ifndef configAPPLICATION_ALLOCATED_HEAP\r
- #define configAPPLICATION_ALLOCATED_HEAP 0\r
-#endif\r
-\r
-#ifndef configUSE_TASK_NOTIFICATIONS\r
- #define configUSE_TASK_NOTIFICATIONS 1\r
-#endif\r
-\r
-#ifndef portTICK_TYPE_IS_ATOMIC\r
- #define portTICK_TYPE_IS_ATOMIC 0\r
-#endif\r
-\r
-#if( portTICK_TYPE_IS_ATOMIC == 0 )\r
- /* Either variables of tick type cannot be read atomically, or\r
- portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when\r
- the tick count is returned to the standard critical section macros. */\r
- #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL()\r
- #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL()\r
- #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()\r
- #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) )\r
-#else\r
- /* The tick type can be read atomically, so critical sections used when the\r
- tick count is returned can be defined away. */\r
- #define portTICK_TYPE_ENTER_CRITICAL()\r
- #define portTICK_TYPE_EXIT_CRITICAL()\r
- #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0\r
- #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x\r
-#endif\r
-\r
-/* Definitions to allow backward compatibility with FreeRTOS versions prior to\r
-V8 if desired. */\r
-#ifndef configENABLE_BACKWARD_COMPATIBILITY\r
- #define configENABLE_BACKWARD_COMPATIBILITY 1\r
-#endif\r
-\r
-#if configENABLE_BACKWARD_COMPATIBILITY == 1\r
- #define eTaskStateGet eTaskGetState\r
- #define portTickType TickType_t\r
- #define xTaskHandle TaskHandle_t\r
- #define xQueueHandle QueueHandle_t\r
- #define xSemaphoreHandle SemaphoreHandle_t\r
- #define xQueueSetHandle QueueSetHandle_t\r
- #define xQueueSetMemberHandle QueueSetMemberHandle_t\r
- #define xTimeOutType TimeOut_t\r
- #define xMemoryRegion MemoryRegion_t\r
- #define xTaskParameters TaskParameters_t\r
- #define xTaskStatusType TaskStatus_t\r
- #define xTimerHandle TimerHandle_t\r
- #define xCoRoutineHandle CoRoutineHandle_t\r
- #define pdTASK_HOOK_CODE TaskHookFunction_t\r
- #define portTICK_RATE_MS portTICK_PERIOD_MS\r
-\r
- /* Backward compatibility within the scheduler code only - these definitions\r
- are not really required but are included for completeness. */\r
- #define tmrTIMER_CALLBACK TimerCallbackFunction_t\r
- #define pdTASK_CODE TaskFunction_t\r
- #define xListItem ListItem_t\r
- #define xList List_t\r
-#endif /* configENABLE_BACKWARD_COMPATIBILITY */\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* INC_FREERTOS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef STACK_MACROS_H\r
-#define STACK_MACROS_H\r
-\r
-/*\r
- * Call the stack overflow hook function if the stack of the task being swapped\r
- * out is currently overflowed, or looks like it might have overflowed in the\r
- * past.\r
- *\r
- * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check\r
- * the current stack state only - comparing the current top of stack value to\r
- * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1\r
- * will also cause the last few stack bytes to be checked to ensure the value\r
- * to which the bytes were set when the task was created have not been\r
- * overwritten. Note this second test does not guarantee that an overflowed\r
- * stack will always be recognised.\r
- */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( configCHECK_FOR_STACK_OVERFLOW == 0 )\r
-\r
- /* FreeRTOSConfig.h is not set to check for stack overflows. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW()\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( configCHECK_FOR_STACK_OVERFLOW == 1 )\r
-\r
- /* FreeRTOSConfig.h is only set to use the first method of\r
- overflow checking. */\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW()\r
-\r
-#endif\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )\r
-\r
- /* Only the current stack state is to be checked. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- /* Is the currently saved stack pointer within the stack limit? */ \\r
- if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \\r
- { \\r
- vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )\r
-\r
- /* Only the current stack state is to be checked. */\r
- #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- \\r
- /* Is the currently saved stack pointer within the stack limit? */ \\r
- if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \\r
- { \\r
- vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )\r
-\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
- \\r
- \\r
- /* Has the extremity of the task stack ever been written over? */ \\r
- if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
- { \\r
- vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
-/*-----------------------------------------------------------*/\r
-\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )\r
-\r
- #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \\r
- { \\r
- int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \\r
- static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \\r
- tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \\r
- \\r
- \\r
- pcEndOfStack -= sizeof( ucExpectedStackBytes ); \\r
- \\r
- /* Has the extremity of the task stack ever been written over? */ \\r
- if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \\r
- { \\r
- vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \\r
- } \\r
- }\r
-\r
-#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
-/*-----------------------------------------------------------*/\r
-\r
-#endif /* STACK_MACROS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef CO_ROUTINE_H\r
-#define CO_ROUTINE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include croutine.h"\r
-#endif\r
-\r
-#include "list.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* Used to hide the implementation of the co-routine control block. The\r
-control block structure however has to be included in the header due to\r
-the macro implementation of the co-routine functionality. */\r
-typedef void * CoRoutineHandle_t;\r
-\r
-/* Defines the prototype to which co-routine functions must conform. */\r
-typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );\r
-\r
-typedef struct corCoRoutineControlBlock\r
-{\r
- crCOROUTINE_CODE pxCoRoutineFunction;\r
- ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */\r
- ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */\r
- UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */\r
- UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */\r
- uint16_t uxState; /*< Used internally by the co-routine implementation. */\r
-} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- BaseType_t xCoRoutineCreate(\r
- crCOROUTINE_CODE pxCoRoutineCode,\r
- UBaseType_t uxPriority,\r
- UBaseType_t uxIndex\r
- );</pre>\r
- *\r
- * Create a new co-routine and add it to the list of co-routines that are\r
- * ready to run.\r
- *\r
- * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine\r
- * functions require special syntax - see the co-routine section of the WEB\r
- * documentation for more information.\r
- *\r
- * @param uxPriority The priority with respect to other co-routines at which\r
- * the co-routine will run.\r
- *\r
- * @param uxIndex Used to distinguish between different co-routines that\r
- * execute the same function. See the example below and the co-routine section\r
- * of the WEB documentation for further information.\r
- *\r
- * @return pdPASS if the co-routine was successfully created and added to a ready\r
- * list, otherwise an error code defined with ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- static const char cLedToFlash[ 2 ] = { 5, 6 };\r
- static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This co-routine just delays for a fixed period, then toggles\r
- // an LED. Two co-routines are created using this function, so\r
- // the uxIndex parameter is used to tell the co-routine which\r
- // LED to flash and how int32_t to delay. This assumes xQueue has\r
- // already been created.\r
- vParTestToggleLED( cLedToFlash[ uxIndex ] );\r
- crDELAY( xHandle, uxFlashRates[ uxIndex ] );\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }\r
-\r
- // Function that creates two co-routines.\r
- void vOtherFunction( void )\r
- {\r
- uint8_t ucParameterToPass;\r
- TaskHandle_t xHandle;\r
-\r
- // Create two co-routines at priority 0. The first is given index 0\r
- // so (from the code above) toggles LED 5 every 200 ticks. The second\r
- // is given index 1 so toggles LED 6 every 400 ticks.\r
- for( uxIndex = 0; uxIndex < 2; uxIndex++ )\r
- {\r
- xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );\r
- }\r
- }\r
- </pre>\r
- * \defgroup xCoRoutineCreate xCoRoutineCreate\r
- * \ingroup Tasks\r
- */\r
-BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );\r
-\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- void vCoRoutineSchedule( void );</pre>\r
- *\r
- * Run a co-routine.\r
- *\r
- * vCoRoutineSchedule() executes the highest priority co-routine that is able\r
- * to run. The co-routine will execute until it either blocks, yields or is\r
- * preempted by a task. Co-routines execute cooperatively so one\r
- * co-routine cannot be preempted by another, but can be preempted by a task.\r
- *\r
- * If an application comprises of both tasks and co-routines then\r
- * vCoRoutineSchedule should be called from the idle task (in an idle task\r
- * hook).\r
- *\r
- * Example usage:\r
- <pre>\r
- // This idle task hook will schedule a co-routine each time it is called.\r
- // The rest of the idle task will execute between co-routine calls.\r
- void vApplicationIdleHook( void )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
-\r
- // Alternatively, if you do not require any other part of the idle task to\r
- // execute, the idle task hook can call vCoRoutineScheduler() within an\r
- // infinite loop.\r
- void vApplicationIdleHook( void )\r
- {\r
- for( ;; )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
- }\r
- </pre>\r
- * \defgroup vCoRoutineSchedule vCoRoutineSchedule\r
- * \ingroup Tasks\r
- */\r
-void vCoRoutineSchedule( void );\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crSTART( CoRoutineHandle_t xHandle );</pre>\r
- *\r
- * This macro MUST always be called at the start of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static int32_t ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crEND();</pre>\r
- *\r
- * This macro MUST always be called at the end of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static int32_t ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crEND() }\r
-\r
-/*\r
- * These macros are intended for internal use by the co-routine implementation\r
- * only. The macros should not be used directly by application writers.\r
- */\r
-#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):\r
-#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>\r
- *\r
- * Delay a co-routine for a fixed period of time.\r
- *\r
- * crDELAY can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * @param xHandle The handle of the co-routine to delay. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should delay\r
- * for. The actual amount of time this equates to is defined by\r
- * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS\r
- * can be used to convert ticks to milliseconds.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- // We are to delay for 200ms.\r
- static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Delay for 200ms.\r
- crDELAY( xHandle, xDelayTime );\r
-\r
- // Do something here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crDELAY crDELAY\r
- * \ingroup Tasks\r
- */\r
-#define crDELAY( xHandle, xTicksToDelay ) \\r
- if( ( xTicksToDelay ) > 0 ) \\r
- { \\r
- vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \\r
- } \\r
- crSET_STATE0( ( xHandle ) );\r
-\r
-/**\r
- * <pre>\r
- crQUEUE_SEND(\r
- CoRoutineHandle_t xHandle,\r
- QueueHandle_t pxQueue,\r
- void *pvItemToQueue,\r
- TickType_t xTicksToWait,\r
- BaseType_t *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_SEND can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue on which the data will be posted.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvItemToQueue A pointer to the data being posted onto the queue.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied from pvItemToQueue into the queue\r
- * itself.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for space to become available on the queue, should space not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example\r
- * below).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully posted onto the queue, otherwise it will be set to an\r
- * error defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine function that blocks for a fixed period then posts a number onto\r
- // a queue.\r
- static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static BaseType_t xNumberToPost = 0;\r
- static BaseType_t xResult;\r
-\r
- // Co-routines must begin with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This assumes the queue has already been created.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );\r
-\r
- if( xResult != pdPASS )\r
- {\r
- // The message was not posted!\r
- }\r
-\r
- // Increment the number to be posted onto the queue.\r
- xNumberToPost++;\r
-\r
- // Delay for 100 ticks.\r
- crDELAY( xHandle, 100 );\r
- }\r
-\r
- // Co-routines must end with a call to crEND().\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_SEND crQUEUE_SEND\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \\r
- } \\r
- if( *pxResult == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *pxResult = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_RECEIVE(\r
- CoRoutineHandle_t xHandle,\r
- QueueHandle_t pxQueue,\r
- void *pvBuffer,\r
- TickType_t xTicksToWait,\r
- BaseType_t *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_RECEIVE can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue from which the data will be received.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvBuffer The buffer into which the received item is to be copied.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied into pvBuffer.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for data to become available from the queue, should data not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the\r
- * crQUEUE_SEND example).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully retrieved from the queue, otherwise it will be set to\r
- * an error code as defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine receives the number of an LED to flash from a queue. It\r
- // blocks on the queue until the number is received.\r
- static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static BaseType_t xResult;\r
- static UBaseType_t uxLEDToFlash;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue.\r
- crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // We received the LED to flash - flash it!\r
- vParTestToggleLED( uxLEDToFlash );\r
- }\r
- }\r
-\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \\r
- } \\r
- if( *( pxResult ) == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *( pxResult ) = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- QueueHandle_t pxQueue,\r
- void *pvItemToQueue,\r
- BaseType_t xCoRoutinePreviouslyWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue\r
- * that is being used from within a co-routine.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto\r
- * the same queue multiple times from a single interrupt. The first call\r
- * should always pass in pdFALSE. Subsequent calls should pass in\r
- * the value returned from the previous call.\r
- *\r
- * @return pdTRUE if a co-routine was woken by posting onto the queue. This is\r
- * used by the ISR to determine if a context switch may be required following\r
- * the ISR.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that blocks on a queue waiting for characters to be received.\r
- static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- char cRxedChar;\r
- BaseType_t xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue. This assumes the\r
- // queue xCommsRxQueue has already been created!\r
- crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- // Was a character received?\r
- if( xResult == pdPASS )\r
- {\r
- // Process the character here.\r
- }\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to send characters received on a serial port to\r
- // a co-routine.\r
- void vUART_ISR( void )\r
- {\r
- char cRxedChar;\r
- BaseType_t xCRWokenByPost = pdFALSE;\r
-\r
- // We loop around reading characters until there are none left in the UART.\r
- while( UART_RX_REG_NOT_EMPTY() )\r
- {\r
- // Obtain the character from the UART.\r
- cRxedChar = UART_RX_REG;\r
-\r
- // Post the character onto a queue. xCRWokenByPost will be pdFALSE\r
- // the first time around the loop. If the post causes a co-routine\r
- // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.\r
- // In this manner we can ensure that if more than one co-routine is\r
- // blocked on the queue only one is woken by this ISR no matter how\r
- // many characters are posted to the queue.\r
- xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )\r
-\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- QueueHandle_t pxQueue,\r
- void *pvBuffer,\r
- BaseType_t * pxCoRoutineWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data\r
- * from a queue that is being used from within a co-routine (a co-routine\r
- * posted to the queue).\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvBuffer A pointer to a buffer into which the received item will be\r
- * placed. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from the queue into\r
- * pvBuffer.\r
- *\r
- * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become\r
- * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a\r
- * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise\r
- * *pxCoRoutineWoken will remain unchanged.\r
- *\r
- * @return pdTRUE an item was successfully received from the queue, otherwise\r
- * pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that posts a character to a queue then blocks for a fixed\r
- // period. The character is incremented each time.\r
- static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )\r
- {\r
- // cChar holds its value while this co-routine is blocked and must therefore\r
- // be declared static.\r
- static char cCharToTx = 'a';\r
- BaseType_t xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Send the next character to the queue.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // The character was successfully posted to the queue.\r
- }\r
- else\r
- {\r
- // Could not post the character to the queue.\r
- }\r
-\r
- // Enable the UART Tx interrupt to cause an interrupt in this\r
- // hypothetical UART. The interrupt will obtain the character\r
- // from the queue and send it.\r
- ENABLE_RX_INTERRUPT();\r
-\r
- // Increment to the next character then block for a fixed period.\r
- // cCharToTx will maintain its value across the delay as it is\r
- // declared static.\r
- cCharToTx++;\r
- if( cCharToTx > 'x' )\r
- {\r
- cCharToTx = 'a';\r
- }\r
- crDELAY( 100 );\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to receive characters to send on a UART.\r
- void vUART_ISR( void )\r
- {\r
- char cCharToTx;\r
- BaseType_t xCRWokenByPost = pdFALSE;\r
-\r
- while( UART_TX_REG_EMPTY() )\r
- {\r
- // Are there any characters in the queue waiting to be sent?\r
- // xCRWokenByPost will automatically be set to pdTRUE if a co-routine\r
- // is woken by the post - ensuring that only a single co-routine is\r
- // woken no matter how many times we go around this loop.\r
- if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )\r
- {\r
- SEND_CHARACTER( cCharToTx );\r
- }\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )\r
-\r
-/*\r
- * This function is intended for internal use by the co-routine macros only.\r
- * The macro nature of the co-routine implementation requires that the\r
- * prototype appears here. The function should not be used by application\r
- * writers.\r
- *\r
- * Removes the current co-routine from its ready list and places it in the\r
- * appropriate delayed list.\r
- */\r
-void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );\r
-\r
-/*\r
- * This function is intended for internal use by the queue implementation only.\r
- * The function should not be used by application writers.\r
- *\r
- * Removes the highest priority co-routine from the event list and places it in\r
- * the pending ready list.\r
- */\r
-BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* CO_ROUTINE_H */\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef DEPRECATED_DEFINITIONS_H\r
-#define DEPRECATED_DEFINITIONS_H\r
-\r
-\r
-/* Each FreeRTOS port has a unique portmacro.h header file. Originally a\r
-pre-processor definition was used to ensure the pre-processor found the correct\r
-portmacro.h file for the port being used. That scheme was deprecated in favour\r
-of setting the compiler's include path such that it found the correct\r
-portmacro.h file - removing the need for the constant and allowing the\r
-portmacro.h file to be located anywhere in relation to the port being used. The\r
-definitions below remain in the code for backward compatibility only. New\r
-projects should not use them. */\r
-\r
-#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT\r
- #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT\r
- #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef GCC_MEGA_AVR\r
- #include "../portable/GCC/ATMega323/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_MEGA_AVR\r
- #include "../portable/IAR/ATMega323/portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC24_PORT\r
- #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_DSPIC_PORT\r
- #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC18F_PORT\r
- #include "../../Source/portable/MPLAB/PIC18F/portmacro.h"\r
-#endif\r
-\r
-#ifdef MPLAB_PIC32MX_PORT\r
- #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"\r
-#endif\r
-\r
-#ifdef _FEDPICC\r
- #include "libFreeRTOS/Include/portmacro.h"\r
-#endif\r
-\r
-#ifdef SDCC_CYGNAL\r
- #include "../../Source/portable/SDCC/Cygnal/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARM7\r
- #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARM7_ECLIPSE\r
- #include "portmacro.h"\r
-#endif\r
-\r
-#ifdef ROWLEY_LPC23xx\r
- #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_MSP430\r
- #include "..\..\Source\portable\IAR\MSP430\portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_MSP430\r
- #include "../../Source/portable/GCC/MSP430F449/portmacro.h"\r
-#endif\r
-\r
-#ifdef ROWLEY_MSP430\r
- #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"\r
-#endif\r
-\r
-#ifdef ARM7_LPC21xx_KEIL_RVDS\r
- #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM7_GCC\r
- #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM7_IAR\r
- #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"\r
-#endif\r
-\r
-#ifdef SAM9XE_IAR\r
- #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"\r
-#endif\r
-\r
-#ifdef LPC2000_IAR\r
- #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR71X_IAR\r
- #include "..\..\Source\portable\IAR\STR71x\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR75X_IAR\r
- #include "..\..\Source\portable\IAR\STR75x\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR75X_GCC\r
- #include "..\..\Source\portable\GCC\STR75x\portmacro.h"\r
-#endif\r
-\r
-#ifdef STR91X_IAR\r
- #include "..\..\Source\portable\IAR\STR91x\portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_H8S\r
- #include "../../Source/portable/GCC/H8S2329/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_AT91FR40008\r
- #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"\r
-#endif\r
-\r
-#ifdef RVDS_ARMCM3_LM3S102\r
- #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARMCM3_LM3S102\r
- #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_ARMCM3\r
- #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_ARM_CM3\r
- #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef IAR_ARMCM3_LM\r
- #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"\r
-#endif\r
-\r
-#ifdef HCS12_CODE_WARRIOR\r
- #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"\r
-#endif\r
-\r
-#ifdef MICROBLAZE_GCC\r
- #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"\r
-#endif\r
-\r
-#ifdef TERN_EE\r
- #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_HCS12\r
- #include "../../Source/portable/GCC/HCS12/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_MCF5235\r
- #include "../../Source/portable/GCC/MCF5235/portmacro.h"\r
-#endif\r
-\r
-#ifdef COLDFIRE_V2_GCC\r
- #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"\r
-#endif\r
-\r
-#ifdef COLDFIRE_V2_CODEWARRIOR\r
- #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_PPC405\r
- #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"\r
-#endif\r
-\r
-#ifdef GCC_PPC440\r
- #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"\r
-#endif\r
-\r
-#ifdef _16FX_SOFTUNE\r
- #include "..\..\Source\portable\Softune\MB96340\portmacro.h"\r
-#endif\r
-\r
-#ifdef BCC_INDUSTRIAL_PC_PORT\r
- /* A short file name has to be used in place of the normal\r
- FreeRTOSConfig.h when using the Borland compiler. */\r
- #include "frconfig.h"\r
- #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef BCC_FLASH_LITE_186_PORT\r
- /* A short file name has to be used in place of the normal\r
- FreeRTOSConfig.h when using the Borland compiler. */\r
- #include "frconfig.h"\r
- #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"\r
- typedef void ( __interrupt __far *pxISR )();\r
-#endif\r
-\r
-#ifdef __GNUC__\r
- #ifdef __AVR32_AVR32A__\r
- #include "portmacro.h"\r
- #endif\r
-#endif\r
-\r
-#ifdef __ICCAVR32__\r
- #ifdef __CORE__\r
- #if __CORE__ == __AVR32A__\r
- #include "portmacro.h"\r
- #endif\r
- #endif\r
-#endif\r
-\r
-#ifdef __91467D\r
- #include "portmacro.h"\r
-#endif\r
-\r
-#ifdef __96340\r
- #include "portmacro.h"\r
-#endif\r
-\r
-\r
-#ifdef __IAR_V850ES_Fx3__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx3__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx3_L__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Jx2__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_V850ES_Hx2__\r
- #include "../../Source/portable/IAR/V850ES/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_78K0R_Kx3__\r
- #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
-#endif\r
-\r
-#ifdef __IAR_78K0R_Kx3L__\r
- #include "../../Source/portable/IAR/78K0R/portmacro.h"\r
-#endif\r
-\r
-#endif /* DEPRECATED_DEFINITIONS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef EVENT_GROUPS_H\r
-#define EVENT_GROUPS_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"\r
-#endif\r
-\r
-#include "timers.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/**\r
- * An event group is a collection of bits to which an application can assign a\r
- * meaning. For example, an application may create an event group to convey\r
- * the status of various CAN bus related events in which bit 0 might mean "A CAN\r
- * message has been received and is ready for processing", bit 1 might mean "The\r
- * application has queued a message that is ready for sending onto the CAN\r
- * network", and bit 2 might mean "It is time to send a SYNC message onto the\r
- * CAN network" etc. A task can then test the bit values to see which events\r
- * are active, and optionally enter the Blocked state to wait for a specified\r
- * bit or a group of specified bits to be active. To continue the CAN bus\r
- * example, a CAN controlling task can enter the Blocked state (and therefore\r
- * not consume any processing time) until either bit 0, bit 1 or bit 2 are\r
- * active, at which time the bit that was actually active would inform the task\r
- * which action it had to take (process a received message, send a message, or\r
- * send a SYNC).\r
- *\r
- * The event groups implementation contains intelligence to avoid race\r
- * conditions that would otherwise occur were an application to use a simple\r
- * variable for the same purpose. This is particularly important with respect\r
- * to when a bit within an event group is to be cleared, and when bits have to\r
- * be set and then tested atomically - as is the case where event groups are\r
- * used to create a synchronisation point between multiple tasks (a\r
- * 'rendezvous').\r
- *\r
- * \defgroup EventGroup\r
- */\r
-\r
-\r
-\r
-/**\r
- * event_groups.h\r
- *\r
- * Type by which event groups are referenced. For example, a call to\r
- * xEventGroupCreate() returns an EventGroupHandle_t variable that can then\r
- * be used as a parameter to other event group functions.\r
- *\r
- * \defgroup EventGroupHandle_t EventGroupHandle_t\r
- * \ingroup EventGroup\r
- */\r
-typedef void * EventGroupHandle_t;\r
-\r
-/* \r
- * The type that holds event bits always matches TickType_t - therefore the\r
- * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,\r
- * 32 bits if set to 0. \r
- *\r
- * \defgroup EventBits_t EventBits_t\r
- * \ingroup EventGroup\r
- */\r
-typedef TickType_t EventBits_t;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventGroupHandle_t xEventGroupCreate( void );\r
- </pre>\r
- *\r
- * Create a new event group. This function cannot be called from an interrupt.\r
- *\r
- * Although event groups are not related to ticks, for internal implementation\r
- * reasons the number of bits available for use in an event group is dependent\r
- * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If\r
- * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit\r
- * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has\r
- * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store\r
- * event bits within an event group.\r
- *\r
- * @return If the event group was created then a handle to the event group is\r
- * returned. If there was insufficient FreeRTOS heap available to create the\r
- * event group then NULL is returned. See http://www.freertos.org/a00111.html\r
- *\r
- * Example usage:\r
- <pre>\r
- // Declare a variable to hold the created event group.\r
- EventGroupHandle_t xCreatedEventGroup;\r
-\r
- // Attempt to create the event group.\r
- xCreatedEventGroup = xEventGroupCreate();\r
-\r
- // Was the event group created successfully?\r
- if( xCreatedEventGroup == NULL )\r
- {\r
- // The event group was not created because there was insufficient\r
- // FreeRTOS heap available.\r
- }\r
- else\r
- {\r
- // The event group was created.\r
- }\r
- </pre>\r
- * \defgroup xEventGroupCreate xEventGroupCreate\r
- * \ingroup EventGroup\r
- */\r
-EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,\r
- const EventBits_t uxBitsToWaitFor,\r
- const BaseType_t xClearOnExit,\r
- const BaseType_t xWaitForAllBits,\r
- const TickType_t xTicksToWait );\r
- </pre>\r
- *\r
- * [Potentially] block to wait for one or more bits to be set within a\r
- * previously created event group.\r
- *\r
- * This function cannot be called from an interrupt.\r
- *\r
- * @param xEventGroup The event group in which the bits are being tested. The\r
- * event group must have previously been created using a call to\r
- * xEventGroupCreate().\r
- *\r
- * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test\r
- * inside the event group. For example, to wait for bit 0 and/or bit 2 set\r
- * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set\r
- * uxBitsToWaitFor to 0x07. Etc.\r
- *\r
- * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within\r
- * uxBitsToWaitFor that are set within the event group will be cleared before\r
- * xEventGroupWaitBits() returns if the wait condition was met (if the function\r
- * returns for a reason other than a timeout). If xClearOnExit is set to\r
- * pdFALSE then the bits set in the event group are not altered when the call to\r
- * xEventGroupWaitBits() returns.\r
- *\r
- * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then\r
- * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor\r
- * are set or the specified block time expires. If xWaitForAllBits is set to\r
- * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set\r
- * in uxBitsToWaitFor is set or the specified block time expires. The block\r
- * time is specified by the xTicksToWait parameter.\r
- *\r
- * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait\r
- * for one/all (depending on the xWaitForAllBits value) of the bits specified by\r
- * uxBitsToWaitFor to become set.\r
- *\r
- * @return The value of the event group at the time either the bits being waited\r
- * for became set, or the block time expired. Test the return value to know\r
- * which bits were set. If xEventGroupWaitBits() returned because its timeout\r
- * expired then not all the bits being waited for will be set. If\r
- * xEventGroupWaitBits() returned because the bits it was waiting for were set\r
- * then the returned value is the event group value before any bits were\r
- * automatically cleared in the case that xClearOnExit parameter was set to\r
- * pdTRUE.\r
- *\r
- * Example usage:\r
- <pre>\r
- #define BIT_0 ( 1 << 0 )\r
- #define BIT_4 ( 1 << 4 )\r
-\r
- void aFunction( EventGroupHandle_t xEventGroup )\r
- {\r
- EventBits_t uxBits;\r
- const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;\r
-\r
- // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within\r
- // the event group. Clear the bits before exiting.\r
- uxBits = xEventGroupWaitBits(\r
- xEventGroup, // The event group being tested.\r
- BIT_0 | BIT_4, // The bits within the event group to wait for.\r
- pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.\r
- pdFALSE, // Don't wait for both bits, either bit will do.\r
- xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.\r
-\r
- if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
- {\r
- // xEventGroupWaitBits() returned because both bits were set.\r
- }\r
- else if( ( uxBits & BIT_0 ) != 0 )\r
- {\r
- // xEventGroupWaitBits() returned because just BIT_0 was set.\r
- }\r
- else if( ( uxBits & BIT_4 ) != 0 )\r
- {\r
- // xEventGroupWaitBits() returned because just BIT_4 was set.\r
- }\r
- else\r
- {\r
- // xEventGroupWaitBits() returned because xTicksToWait ticks passed\r
- // without either BIT_0 or BIT_4 becoming set.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xEventGroupWaitBits xEventGroupWaitBits\r
- * \ingroup EventGroup\r
- */\r
-EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );\r
- </pre>\r
- *\r
- * Clear bits within an event group. This function cannot be called from an\r
- * interrupt.\r
- *\r
- * @param xEventGroup The event group in which the bits are to be cleared.\r
- *\r
- * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear\r
- * in the event group. For example, to clear bit 3 only, set uxBitsToClear to\r
- * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.\r
- *\r
- * @return The value of the event group before the specified bits were cleared.\r
- *\r
- * Example usage:\r
- <pre>\r
- #define BIT_0 ( 1 << 0 )\r
- #define BIT_4 ( 1 << 4 )\r
-\r
- void aFunction( EventGroupHandle_t xEventGroup )\r
- {\r
- EventBits_t uxBits;\r
-\r
- // Clear bit 0 and bit 4 in xEventGroup.\r
- uxBits = xEventGroupClearBits(\r
- xEventGroup, // The event group being updated.\r
- BIT_0 | BIT_4 );// The bits being cleared.\r
-\r
- if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
- {\r
- // Both bit 0 and bit 4 were set before xEventGroupClearBits() was\r
- // called. Both will now be clear (not set).\r
- }\r
- else if( ( uxBits & BIT_0 ) != 0 )\r
- {\r
- // Bit 0 was set before xEventGroupClearBits() was called. It will\r
- // now be clear.\r
- }\r
- else if( ( uxBits & BIT_4 ) != 0 )\r
- {\r
- // Bit 4 was set before xEventGroupClearBits() was called. It will\r
- // now be clear.\r
- }\r
- else\r
- {\r
- // Neither bit 0 nor bit 4 were set in the first place.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xEventGroupClearBits xEventGroupClearBits\r
- * \ingroup EventGroup\r
- */\r
-EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );\r
- </pre>\r
- *\r
- * A version of xEventGroupClearBits() that can be called from an interrupt.\r
- *\r
- * Setting bits in an event group is not a deterministic operation because there\r
- * are an unknown number of tasks that may be waiting for the bit or bits being\r
- * set. FreeRTOS does not allow nondeterministic operations to be performed\r
- * while interrupts are disabled, so protects event groups that are accessed\r
- * from tasks by suspending the scheduler rather than disabling interrupts. As\r
- * a result event groups cannot be accessed directly from an interrupt service\r
- * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the \r
- * timer task to have the clear operation performed in the context of the timer \r
- * task.\r
- *\r
- * @param xEventGroup The event group in which the bits are to be cleared.\r
- *\r
- * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.\r
- * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3\r
- * and bit 0 set uxBitsToClear to 0x09.\r
- *\r
- * @return If the request to execute the function was posted successfully then \r
- * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned \r
- * if the timer service queue was full.\r
- *\r
- * Example usage:\r
- <pre>\r
- #define BIT_0 ( 1 << 0 )\r
- #define BIT_4 ( 1 << 4 )\r
-\r
- // An event group which it is assumed has already been created by a call to\r
- // xEventGroupCreate().\r
- EventGroupHandle_t xEventGroup;\r
-\r
- void anInterruptHandler( void )\r
- {\r
- // Clear bit 0 and bit 4 in xEventGroup.\r
- xResult = xEventGroupClearBitsFromISR(\r
- xEventGroup, // The event group being updated.\r
- BIT_0 | BIT_4 ); // The bits being set.\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // The message was posted successfully.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR\r
- * \ingroup EventGroup\r
- */\r
-#if( configUSE_TRACE_FACILITY == 1 )\r
- BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;\r
-#else\r
- #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )\r
-#endif\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );\r
- </pre>\r
- *\r
- * Set bits within an event group.\r
- * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()\r
- * is a version that can be called from an interrupt.\r
- *\r
- * Setting bits in an event group will automatically unblock tasks that are\r
- * blocked waiting for the bits.\r
- *\r
- * @param xEventGroup The event group in which the bits are to be set.\r
- *\r
- * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
- * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3\r
- * and bit 0 set uxBitsToSet to 0x09.\r
- *\r
- * @return The value of the event group at the time the call to\r
- * xEventGroupSetBits() returns. There are two reasons why the returned value\r
- * might have the bits specified by the uxBitsToSet parameter cleared. First,\r
- * if setting a bit results in a task that was waiting for the bit leaving the\r
- * blocked state then it is possible the bit will be cleared automatically\r
- * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any\r
- * unblocked (or otherwise Ready state) task that has a priority above that of\r
- * the task that called xEventGroupSetBits() will execute and may change the\r
- * event group value before the call to xEventGroupSetBits() returns.\r
- *\r
- * Example usage:\r
- <pre>\r
- #define BIT_0 ( 1 << 0 )\r
- #define BIT_4 ( 1 << 4 )\r
-\r
- void aFunction( EventGroupHandle_t xEventGroup )\r
- {\r
- EventBits_t uxBits;\r
-\r
- // Set bit 0 and bit 4 in xEventGroup.\r
- uxBits = xEventGroupSetBits(\r
- xEventGroup, // The event group being updated.\r
- BIT_0 | BIT_4 );// The bits being set.\r
-\r
- if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
- {\r
- // Both bit 0 and bit 4 remained set when the function returned.\r
- }\r
- else if( ( uxBits & BIT_0 ) != 0 )\r
- {\r
- // Bit 0 remained set when the function returned, but bit 4 was\r
- // cleared. It might be that bit 4 was cleared automatically as a\r
- // task that was waiting for bit 4 was removed from the Blocked\r
- // state.\r
- }\r
- else if( ( uxBits & BIT_4 ) != 0 )\r
- {\r
- // Bit 4 remained set when the function returned, but bit 0 was\r
- // cleared. It might be that bit 0 was cleared automatically as a\r
- // task that was waiting for bit 0 was removed from the Blocked\r
- // state.\r
- }\r
- else\r
- {\r
- // Neither bit 0 nor bit 4 remained set. It might be that a task\r
- // was waiting for both of the bits to be set, and the bits were\r
- // cleared as the task left the Blocked state.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xEventGroupSetBits xEventGroupSetBits\r
- * \ingroup EventGroup\r
- */\r
-EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );\r
- </pre>\r
- *\r
- * A version of xEventGroupSetBits() that can be called from an interrupt.\r
- *\r
- * Setting bits in an event group is not a deterministic operation because there\r
- * are an unknown number of tasks that may be waiting for the bit or bits being\r
- * set. FreeRTOS does not allow nondeterministic operations to be performed in\r
- * interrupts or from critical sections. Therefore xEventGroupSetBitFromISR()\r
- * sends a message to the timer task to have the set operation performed in the\r
- * context of the timer task - where a scheduler lock is used in place of a\r
- * critical section.\r
- *\r
- * @param xEventGroup The event group in which the bits are to be set.\r
- *\r
- * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
- * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3\r
- * and bit 0 set uxBitsToSet to 0x09.\r
- *\r
- * @param pxHigherPriorityTaskWoken As mentioned above, calling this function\r
- * will result in a message being sent to the timer daemon task. If the\r
- * priority of the timer daemon task is higher than the priority of the\r
- * currently running task (the task the interrupt interrupted) then\r
- * *pxHigherPriorityTaskWoken will be set to pdTRUE by\r
- * xEventGroupSetBitsFromISR(), indicating that a context switch should be\r
- * requested before the interrupt exits. For that reason\r
- * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the\r
- * example code below.\r
- *\r
- * @return If the request to execute the function was posted successfully then \r
- * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned \r
- * if the timer service queue was full.\r
- *\r
- * Example usage:\r
- <pre>\r
- #define BIT_0 ( 1 << 0 )\r
- #define BIT_4 ( 1 << 4 )\r
-\r
- // An event group which it is assumed has already been created by a call to\r
- // xEventGroupCreate().\r
- EventGroupHandle_t xEventGroup;\r
-\r
- void anInterruptHandler( void )\r
- {\r
- BaseType_t xHigherPriorityTaskWoken, xResult;\r
-\r
- // xHigherPriorityTaskWoken must be initialised to pdFALSE.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Set bit 0 and bit 4 in xEventGroup.\r
- xResult = xEventGroupSetBitsFromISR(\r
- xEventGroup, // The event group being updated.\r
- BIT_0 | BIT_4 // The bits being set.\r
- &xHigherPriorityTaskWoken );\r
-\r
- // Was the message posted successfully?\r
- if( xResult == pdPASS )\r
- {\r
- // If xHigherPriorityTaskWoken is now set to pdTRUE then a context\r
- // switch should be requested. The macro used is port specific and \r
- // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - \r
- // refer to the documentation page for the port being used.\r
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
- }\r
- }\r
- </pre>\r
- * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR\r
- * \ingroup EventGroup\r
- */\r
-#if( configUSE_TRACE_FACILITY == 1 )\r
- BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-#else\r
- #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )\r
-#endif\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,\r
- const EventBits_t uxBitsToSet,\r
- const EventBits_t uxBitsToWaitFor,\r
- TickType_t xTicksToWait );\r
- </pre>\r
- *\r
- * Atomically set bits within an event group, then wait for a combination of\r
- * bits to be set within the same event group. This functionality is typically\r
- * used to synchronise multiple tasks, where each task has to wait for the other\r
- * tasks to reach a synchronisation point before proceeding.\r
- *\r
- * This function cannot be used from an interrupt.\r
- *\r
- * The function will return before its block time expires if the bits specified\r
- * by the uxBitsToWait parameter are set, or become set within that time. In\r
- * this case all the bits specified by uxBitsToWait will be automatically\r
- * cleared before the function returns.\r
- *\r
- * @param xEventGroup The event group in which the bits are being tested. The\r
- * event group must have previously been created using a call to\r
- * xEventGroupCreate().\r
- *\r
- * @param uxBitsToSet The bits to set in the event group before determining\r
- * if, and possibly waiting for, all the bits specified by the uxBitsToWait\r
- * parameter are set.\r
- *\r
- * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test\r
- * inside the event group. For example, to wait for bit 0 and bit 2 set\r
- * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set\r
- * uxBitsToWaitFor to 0x07. Etc.\r
- *\r
- * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait\r
- * for all of the bits specified by uxBitsToWaitFor to become set.\r
- *\r
- * @return The value of the event group at the time either the bits being waited\r
- * for became set, or the block time expired. Test the return value to know\r
- * which bits were set. If xEventGroupSync() returned because its timeout\r
- * expired then not all the bits being waited for will be set. If\r
- * xEventGroupSync() returned because all the bits it was waiting for were\r
- * set then the returned value is the event group value before any bits were\r
- * automatically cleared.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Bits used by the three tasks.\r
- #define TASK_0_BIT ( 1 << 0 )\r
- #define TASK_1_BIT ( 1 << 1 )\r
- #define TASK_2_BIT ( 1 << 2 )\r
-\r
- #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )\r
-\r
- // Use an event group to synchronise three tasks. It is assumed this event\r
- // group has already been created elsewhere.\r
- EventGroupHandle_t xEventBits;\r
-\r
- void vTask0( void *pvParameters )\r
- {\r
- EventBits_t uxReturn;\r
- TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;\r
-\r
- for( ;; )\r
- {\r
- // Perform task functionality here.\r
-\r
- // Set bit 0 in the event flag to note this task has reached the\r
- // sync point. The other two tasks will set the other two bits defined\r
- // by ALL_SYNC_BITS. All three tasks have reached the synchronisation\r
- // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms\r
- // for this to happen.\r
- uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );\r
-\r
- if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )\r
- {\r
- // All three tasks reached the synchronisation point before the call\r
- // to xEventGroupSync() timed out.\r
- }\r
- }\r
- }\r
-\r
- void vTask1( void *pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Perform task functionality here.\r
-\r
- // Set bit 1 in the event flag to note this task has reached the\r
- // synchronisation point. The other two tasks will set the other two\r
- // bits defined by ALL_SYNC_BITS. All three tasks have reached the\r
- // synchronisation point when all the ALL_SYNC_BITS are set. Wait\r
- // indefinitely for this to happen.\r
- xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
-\r
- // xEventGroupSync() was called with an indefinite block time, so\r
- // this task will only reach here if the syncrhonisation was made by all\r
- // three tasks, so there is no need to test the return value.\r
- }\r
- }\r
-\r
- void vTask2( void *pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Perform task functionality here.\r
-\r
- // Set bit 2 in the event flag to note this task has reached the\r
- // synchronisation point. The other two tasks will set the other two\r
- // bits defined by ALL_SYNC_BITS. All three tasks have reached the\r
- // synchronisation point when all the ALL_SYNC_BITS are set. Wait\r
- // indefinitely for this to happen.\r
- xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
-\r
- // xEventGroupSync() was called with an indefinite block time, so\r
- // this task will only reach here if the syncrhonisation was made by all\r
- // three tasks, so there is no need to test the return value.\r
- }\r
- }\r
-\r
- </pre>\r
- * \defgroup xEventGroupSync xEventGroupSync\r
- * \ingroup EventGroup\r
- */\r
-EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );\r
- </pre>\r
- *\r
- * Returns the current value of the bits in an event group. This function\r
- * cannot be used from an interrupt.\r
- *\r
- * @param xEventGroup The event group being queried.\r
- *\r
- * @return The event group bits at the time xEventGroupGetBits() was called.\r
- *\r
- * \defgroup xEventGroupGetBits xEventGroupGetBits\r
- * \ingroup EventGroup\r
- */\r
-#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );\r
- </pre>\r
- *\r
- * A version of xEventGroupGetBits() that can be called from an ISR.\r
- *\r
- * @param xEventGroup The event group being queried.\r
- *\r
- * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.\r
- *\r
- * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR\r
- * \ingroup EventGroup\r
- */\r
-EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * event_groups.h\r
- *<pre>\r
- void xEventGroupDelete( EventGroupHandle_t xEventGroup );\r
- </pre>\r
- *\r
- * Delete an event group that was previously created by a call to\r
- * xEventGroupCreate(). Tasks that are blocked on the event group will be\r
- * unblocked and obtain 0 as the event group's value.\r
- *\r
- * @param xEventGroup The event group being deleted.\r
- */\r
-void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;\r
-\r
-/* For internal use only. */\r
-void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;\r
-void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;\r
-\r
-#if (configUSE_TRACE_FACILITY == 1)\r
- UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* EVENT_GROUPS_H */\r
-\r
-\r
+++ /dev/null
-/*\r
- OpenRTOS V8.2.1 Copyright (C) 2015 Real Time Engineers Ltd.\r
-\r
- This file is part of the OpenRTOS product.\r
-\r
- OpenRTOS is distributed exclusively by WITTENSTEIN high integrity systems,\r
- and is subject to the terms of the License granted to your organization,\r
- including its warranties and limitations on use and distribution. It cannot be\r
- copied or reproduced in any way except as permitted by the License.\r
-\r
- Licenses authorize use by processor, compiler, business unit, and product.\r
- \r
- WITTENSTEIN high integrity systems is a trading name of WITTENSTEIN\r
- aerospace & simulation ltd, Registered Office: Brown's Court, Long Ashton\r
- Business Park, Yanley Lane, Long Ashton, Bristol, BS41 9LB, UK.\r
- Tel: +44 (0) 1275 395 600, fax: +44 (0) 1275 393 630.\r
- E-mail: info@HighIntegritySystems.com\r
-\r
- http://www.HighIntegritySystems.com\r
-*/\r
-\r
-/*\r
- * This is the list implementation used by the scheduler. While it is tailored\r
- * heavily for the schedulers needs, it is also available for use by\r
- * application code.\r
- *\r
- * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a\r
- * numeric value (xItemValue). Most of the time the lists are sorted in\r
- * descending item value order.\r
- *\r
- * Lists are created already containing one list item. The value of this\r
- * item is the maximum possible that can be stored, it is therefore always at\r
- * the end of the list and acts as a marker. The list member pxHead always\r
- * points to this marker - even though it is at the tail of the list. This\r
- * is because the tail contains a wrap back pointer to the true head of\r
- * the list.\r
- *\r
- * In addition to it's value, each list item contains a pointer to the next\r
- * item in the list (pxNext), a pointer to the list it is in (pxContainer)\r
- * and a pointer to back to the object that contains it. These later two\r
- * pointers are included for efficiency of list manipulation. There is\r
- * effectively a two way link between the object containing the list item and\r
- * the list item itself.\r
- *\r
- *\r
- * \page ListIntroduction List Implementation\r
- * \ingroup FreeRTOSIntro\r
- */\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error FreeRTOS.h must be included before list.h\r
-#endif\r
-\r
-#ifndef LIST_H\r
-#define LIST_H\r
-\r
-/*\r
- * The list structure members are modified from within interrupts, and therefore\r
- * by rights should be declared volatile. However, they are only modified in a\r
- * functionally atomic way (within critical sections of with the scheduler\r
- * suspended) and are either passed by reference into a function or indexed via\r
- * a volatile variable. Therefore, in all use cases tested so far, the volatile\r
- * qualifier can be omitted in order to provide a moderate performance\r
- * improvement without adversely affecting functional behaviour. The assembly\r
- * instructions generated by the IAR, ARM and GCC compilers when the respective\r
- * compiler's options were set for maximum optimisation has been inspected and\r
- * deemed to be as intended. That said, as compiler technology advances, and\r
- * especially if aggressive cross module optimisation is used (a use case that\r
- * has not been exercised to any great extend) then it is feasible that the\r
- * volatile qualifier will be needed for correct optimisation. It is expected\r
- * that a compiler removing essential code because, without the volatile\r
- * qualifier on the list structure members and with aggressive cross module\r
- * optimisation, the compiler deemed the code unnecessary will result in\r
- * complete and obvious failure of the scheduler. If this is ever experienced\r
- * then the volatile qualifier can be inserted in the relevant places within the\r
- * list structures by simply defining configLIST_VOLATILE to volatile in\r
- * FreeRTOSConfig.h (as per the example at the bottom of this comment block).\r
- * If configLIST_VOLATILE is not defined then the preprocessor directives below\r
- * will simply #define configLIST_VOLATILE away completely.\r
- *\r
- * To use volatile list structure members then add the following line to\r
- * FreeRTOSConfig.h (without the quotes):\r
- * "#define configLIST_VOLATILE volatile"\r
- */\r
-#ifndef configLIST_VOLATILE\r
- #define configLIST_VOLATILE\r
-#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* Macros that can be used to place known values within the list structures,\r
-then check that the known values do not get corrupted during the execution of\r
-the application. These may catch the list data structures being overwritten in\r
-memory. They will not catch data errors caused by incorrect configuration or\r
-use of FreeRTOS.*/\r
-#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )\r
- /* Define the macros to do nothing. */\r
- #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE\r
- #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE\r
- #define listFIRST_LIST_INTEGRITY_CHECK_VALUE\r
- #define listSECOND_LIST_INTEGRITY_CHECK_VALUE\r
- #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )\r
- #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )\r
- #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )\r
- #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )\r
- #define listTEST_LIST_ITEM_INTEGRITY( pxItem )\r
- #define listTEST_LIST_INTEGRITY( pxList )\r
-#else\r
- /* Define macros that add new members into the list structures. */\r
- #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1;\r
- #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2;\r
- #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1;\r
- #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2;\r
-\r
- /* Define macros that set the new structure members to known values. */\r
- #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE\r
- #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE\r
- #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE\r
- #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE\r
-\r
- /* Define macros that will assert if one of the structure members does not\r
- contain its expected value. */\r
- #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )\r
- #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )\r
-#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */\r
-\r
-\r
-/*\r
- * Definition of the only type of object that a list can contain.\r
- */\r
-struct xLIST_ITEM\r
-{\r
- listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
- configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */\r
- struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */\r
- struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */\r
- void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */\r
- void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */\r
- listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
-};\r
-typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */\r
-\r
-struct xMINI_LIST_ITEM\r
-{\r
- listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
- configLIST_VOLATILE TickType_t xItemValue;\r
- struct xLIST_ITEM * configLIST_VOLATILE pxNext;\r
- struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;\r
-};\r
-typedef struct xMINI_LIST_ITEM MiniListItem_t;\r
-\r
-/*\r
- * Definition of the type of queue used by the scheduler.\r
- */\r
-typedef struct xLIST\r
-{\r
- listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
- configLIST_VOLATILE UBaseType_t uxNumberOfItems;\r
- ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */\r
- MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */\r
- listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */\r
-} List_t;\r
-\r
-/*\r
- * Access macro to set the owner of a list item. The owner of a list item\r
- * is the object (usually a TCB) that contains the list item.\r
- *\r
- * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
- * \ingroup LinkedList\r
- */\r
-#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )\r
-\r
-/*\r
- * Access macro to get the owner of a list item. The owner of a list item\r
- * is the object (usually a TCB) that contains the list item.\r
- *\r
- * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )\r
-\r
-/*\r
- * Access macro to set the value of the list item. In most cases the value is\r
- * used to sort the list in descending order.\r
- *\r
- * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )\r
-\r
-/*\r
- * Access macro to retrieve the value of the list item. The value can\r
- * represent anything - for example the priority of a task, or the time at\r
- * which a task should be unblocked.\r
- *\r
- * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )\r
-\r
-/*\r
- * Access macro to retrieve the value of the list item at the head of a given\r
- * list.\r
- *\r
- * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )\r
-\r
-/*\r
- * Return the list item at the head of the list.\r
- *\r
- * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )\r
-\r
-/*\r
- * Return the list item at the head of the list.\r
- *\r
- * \page listGET_NEXT listGET_NEXT\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )\r
-\r
-/*\r
- * Return the list item that marks the end of the list\r
- *\r
- * \page listGET_END_MARKER listGET_END_MARKER\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )\r
-\r
-/*\r
- * Access macro to determine if a list contains any items. The macro will\r
- * only have the value true if the list is empty.\r
- *\r
- * \page listLIST_IS_EMPTY listLIST_IS_EMPTY\r
- * \ingroup LinkedList\r
- */\r
-#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )\r
-\r
-/*\r
- * Access macro to return the number of items in the list.\r
- */\r
-#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )\r
-\r
-/*\r
- * Access function to obtain the owner of the next entry in a list.\r
- *\r
- * The list member pxIndex is used to walk through a list. Calling\r
- * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list\r
- * and returns that entry's pxOwner parameter. Using multiple calls to this\r
- * function it is therefore possible to move through every item contained in\r
- * a list.\r
- *\r
- * The pxOwner parameter of a list item is a pointer to the object that owns\r
- * the list item. In the scheduler this is normally a task control block.\r
- * The pxOwner parameter effectively creates a two way link between the list\r
- * item and its owner.\r
- *\r
- * @param pxTCB pxTCB is set to the address of the owner of the next list item.\r
- * @param pxList The list from which the next item owner is to be returned.\r
- *\r
- * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \\r
-{ \\r
-List_t * const pxConstList = ( pxList ); \\r
- /* Increment the index to the next item and return the item, ensuring */ \\r
- /* we don't return the marker used at the end of the list. */ \\r
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
- if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \\r
- { \\r
- ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \\r
- } \\r
- ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \\r
-}\r
-\r
-\r
-/*\r
- * Access function to obtain the owner of the first entry in a list. Lists\r
- * are normally sorted in ascending item value order.\r
- *\r
- * This function returns the pxOwner member of the first item in the list.\r
- * The pxOwner parameter of a list item is a pointer to the object that owns\r
- * the list item. In the scheduler this is normally a task control block.\r
- * The pxOwner parameter effectively creates a two way link between the list\r
- * item and its owner.\r
- *\r
- * @param pxList The list from which the owner of the head item is to be\r
- * returned.\r
- *\r
- * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY\r
- * \ingroup LinkedList\r
- */\r
-#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )\r
-\r
-/*\r
- * Check to see if a list item is within a list. The list item maintains a\r
- * "container" pointer that points to the list it is in. All this macro does\r
- * is check to see if the container and the list match.\r
- *\r
- * @param pxList The list we want to know if the list item is within.\r
- * @param pxListItem The list item we want to know if is in the list.\r
- * @return pdTRUE if the list item is in the list, otherwise pdFALSE.\r
- */\r
-#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )\r
-\r
-/*\r
- * Return the list a list item is contained within (referenced from).\r
- *\r
- * @param pxListItem The list item being queried.\r
- * @return A pointer to the List_t object that references the pxListItem\r
- */\r
-#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )\r
-\r
-/*\r
- * This provides a crude means of knowing if a list has been initialised, as\r
- * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()\r
- * function.\r
- */\r
-#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )\r
-\r
-/*\r
- * Must be called before a list is used! This initialises all the members\r
- * of the list structure and inserts the xListEnd item into the list as a\r
- * marker to the back of the list.\r
- *\r
- * @param pxList Pointer to the list being initialised.\r
- *\r
- * \page vListInitialise vListInitialise\r
- * \ingroup LinkedList\r
- */\r
-void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Must be called before a list item is used. This sets the list container to\r
- * null so the item does not think that it is already contained in a list.\r
- *\r
- * @param pxItem Pointer to the list item being initialised.\r
- *\r
- * \page vListInitialiseItem vListInitialiseItem\r
- * \ingroup LinkedList\r
- */\r
-void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Insert a list item into a list. The item will be inserted into the list in\r
- * a position determined by its item value (descending item value order).\r
- *\r
- * @param pxList The list into which the item is to be inserted.\r
- *\r
- * @param pxNewListItem The item that is to be placed in the list.\r
- *\r
- * \page vListInsert vListInsert\r
- * \ingroup LinkedList\r
- */\r
-void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Insert a list item into a list. The item will be inserted in a position\r
- * such that it will be the last item within the list returned by multiple\r
- * calls to listGET_OWNER_OF_NEXT_ENTRY.\r
- *\r
- * The list member pvIndex is used to walk through a list. Calling\r
- * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.\r
- * Placing an item in a list using vListInsertEnd effectively places the item\r
- * in the list position pointed to by pvIndex. This means that every other\r
- * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before\r
- * the pvIndex parameter again points to the item being inserted.\r
- *\r
- * @param pxList The list into which the item is to be inserted.\r
- *\r
- * @param pxNewListItem The list item to be inserted into the list.\r
- *\r
- * \page vListInsertEnd vListInsertEnd\r
- * \ingroup LinkedList\r
- */\r
-void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Remove an item from a list. The list item has a pointer to the list that\r
- * it is in, so only the list item need be passed into the function.\r
- *\r
- * @param uxListRemove The item to be removed. The item will remove itself from\r
- * the list pointed to by it's pxContainer parameter.\r
- *\r
- * @return The number of items that remain in the list after the list item has\r
- * been removed.\r
- *\r
- * \page uxListRemove uxListRemove\r
- * \ingroup LinkedList\r
- */\r
-UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef MPU_WRAPPERS_H\r
-#define MPU_WRAPPERS_H\r
-\r
-/* This file redefines API functions to be called through a wrapper macro, but\r
-only for ports that are using the MPU. */\r
-#ifdef portUSING_MPU_WRAPPERS\r
-\r
- /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is\r
- included from queue.c or task.c to prevent it from having an effect within\r
- those files. */\r
- #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
-\r
- #define xTaskGenericCreate MPU_xTaskGenericCreate\r
- #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions\r
- #define vTaskDelete MPU_vTaskDelete\r
- #define vTaskDelayUntil MPU_vTaskDelayUntil\r
- #define vTaskDelay MPU_vTaskDelay\r
- #define uxTaskPriorityGet MPU_uxTaskPriorityGet\r
- #define vTaskPrioritySet MPU_vTaskPrioritySet\r
- #define eTaskGetState MPU_eTaskGetState\r
- #define vTaskSuspend MPU_vTaskSuspend\r
- #define vTaskResume MPU_vTaskResume\r
- #define vTaskSuspendAll MPU_vTaskSuspendAll\r
- #define xTaskResumeAll MPU_xTaskResumeAll\r
- #define xTaskGetTickCount MPU_xTaskGetTickCount\r
- #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks\r
- #define vTaskList MPU_vTaskList\r
- #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats\r
- #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag\r
- #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag\r
- #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook\r
- #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark\r
- #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle\r
- #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState\r
- #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle\r
- #define uxTaskGetSystemState MPU_uxTaskGetSystemState\r
-\r
- #define xQueueGenericCreate MPU_xQueueGenericCreate\r
- #define xQueueCreateMutex MPU_xQueueCreateMutex\r
- #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive\r
- #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive\r
- #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore\r
- #define xQueueGenericSend MPU_xQueueGenericSend\r
- #define xQueueAltGenericSend MPU_xQueueAltGenericSend\r
- #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive\r
- #define xQueueGenericReceive MPU_xQueueGenericReceive\r
- #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting\r
- #define vQueueDelete MPU_vQueueDelete\r
- #define xQueueGenericReset MPU_xQueueGenericReset\r
- #define xQueueCreateSet MPU_xQueueCreateSet\r
- #define xQueueSelectFromSet MPU_xQueueSelectFromSet\r
- #define xQueueAddToSet MPU_xQueueAddToSet\r
- #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet\r
- #define xQueuePeekFromISR MPU_xQueuePeekFromISR\r
- #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder\r
-\r
- #define pvPortMalloc MPU_pvPortMalloc\r
- #define vPortFree MPU_vPortFree\r
- #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize\r
- #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks\r
-\r
- #if configQUEUE_REGISTRY_SIZE > 0\r
- #define vQueueAddToRegistry MPU_vQueueAddToRegistry\r
- #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue\r
- #endif\r
-\r
- /* Remove the privileged function macro. */\r
- #define PRIVILEGED_FUNCTION\r
-\r
- #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
-\r
- /* Ensure API functions go in the privileged execution section. */\r
- #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))\r
- #define PRIVILEGED_DATA __attribute__((section("privileged_data")))\r
-\r
- #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */\r
-\r
-#else /* portUSING_MPU_WRAPPERS */\r
-\r
- #define PRIVILEGED_FUNCTION\r
- #define PRIVILEGED_DATA\r
- #define portUSING_MPU_WRAPPERS 0\r
-\r
-#endif /* portUSING_MPU_WRAPPERS */\r
-\r
-\r
-#endif /* MPU_WRAPPERS_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-/*-----------------------------------------------------------\r
- * Portable layer API. Each function must be defined for each port.\r
- *----------------------------------------------------------*/\r
-\r
-#ifndef PORTABLE_H\r
-#define PORTABLE_H\r
-\r
-/* Each FreeRTOS port has a unique portmacro.h header file. Originally a\r
-pre-processor definition was used to ensure the pre-processor found the correct\r
-portmacro.h file for the port being used. That scheme was deprecated in favour\r
-of setting the compiler's include path such that it found the correct\r
-portmacro.h file - removing the need for the constant and allowing the\r
-portmacro.h file to be located anywhere in relation to the port being used.\r
-Purely for reasons of backward compatibility the old method is still valid, but\r
-to make it clear that new projects should not use it, support for the port\r
-specific constants has been moved into the deprecated_definitions.h header\r
-file. */\r
-#include "deprecated_definitions.h"\r
-\r
-/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h\r
-did not result in a portmacro.h header file being included - and it should be\r
-included here. In this case the path to the correct portmacro.h header file\r
-must be set in the compiler's include path. */\r
-#ifndef portENTER_CRITICAL\r
- #include "portmacro.h"\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 32\r
- #define portBYTE_ALIGNMENT_MASK ( 0x001f )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 16\r
- #define portBYTE_ALIGNMENT_MASK ( 0x000f )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 8\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0007 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 4\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0003 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 2\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0001 )\r
-#endif\r
-\r
-#if portBYTE_ALIGNMENT == 1\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0000 )\r
-#endif\r
-\r
-#ifndef portBYTE_ALIGNMENT_MASK\r
- #error "Invalid portBYTE_ALIGNMENT definition"\r
-#endif\r
-\r
-#ifndef portNUM_CONFIGURABLE_REGIONS\r
- #define portNUM_CONFIGURABLE_REGIONS 1\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#include "mpu_wrappers.h"\r
-\r
-/*\r
- * Setup the stack of a new task so it is ready to be placed under the\r
- * scheduler control. The registers have to be placed on the stack in\r
- * the order that the port expects to find them.\r
- *\r
- */\r
-#if( portUSING_MPU_WRAPPERS == 1 )\r
- StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;\r
-#else\r
- StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-/* Used by heap_5.c. */\r
-typedef struct HeapRegion\r
-{\r
- uint8_t *pucStartAddress;\r
- size_t xSizeInBytes;\r
-} HeapRegion_t;\r
-\r
-/*\r
- * Used to define multiple heap regions for use by heap_5.c. This function\r
- * must be called before any calls to pvPortMalloc() - not creating a task,\r
- * queue, semaphore, mutex, software timer, event group, etc. will result in\r
- * pvPortMalloc being called.\r
- *\r
- * pxHeapRegions passes in an array of HeapRegion_t structures - each of which\r
- * defines a region of memory that can be used as the heap. The array is\r
- * terminated by a HeapRegions_t structure that has a size of 0. The region\r
- * with the lowest start address must appear first in the array.\r
- */\r
-void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;\r
-\r
-\r
-/*\r
- * Map to the memory management routines required for the port.\r
- */\r
-void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;\r
-void vPortFree( void *pv ) PRIVILEGED_FUNCTION;\r
-void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;\r
-size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;\r
-size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Setup the hardware ready for the scheduler to take control. This generally\r
- * sets up a tick interrupt and sets timers for the correct tick frequency.\r
- */\r
-BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so\r
- * the hardware is left in its original condition after the scheduler stops\r
- * executing.\r
- */\r
-void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * The structures and methods of manipulating the MPU are contained within the\r
- * port layer.\r
- *\r
- * Fills the xMPUSettings structure with the memory region information\r
- * contained in xRegions.\r
- */\r
-#if( portUSING_MPU_WRAPPERS == 1 )\r
- struct xMEMORY_REGION;\r
- void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* PORTABLE_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef PROJDEFS_H\r
-#define PROJDEFS_H\r
-\r
-/*\r
- * Defines the prototype to which task functions must conform. Defined in this\r
- * file to ensure the type is known before portable.h is included.\r
- */\r
-typedef void (*TaskFunction_t)( void * );\r
-\r
-/* Converts a time in milliseconds to a time in ticks. */\r
-#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )\r
-\r
-#define pdFALSE ( ( BaseType_t ) 0 )\r
-#define pdTRUE ( ( BaseType_t ) 1 )\r
-\r
-#define pdPASS ( pdTRUE )\r
-#define pdFAIL ( pdFALSE )\r
-#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )\r
-#define errQUEUE_FULL ( ( BaseType_t ) 0 )\r
-\r
-/* FreeRTOS error definitions. */\r
-#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )\r
-#define errQUEUE_BLOCKED ( -4 )\r
-#define errQUEUE_YIELD ( -5 )\r
-\r
-/* Macros used for basic data corruption checks. */\r
-#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES\r
- #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0\r
-#endif\r
-\r
-#if( configUSE_16_BIT_TICKS == 1 )\r
- #define pdINTEGRITY_CHECK_VALUE 0x5a5a\r
-#else\r
- #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL\r
-#endif\r
-\r
-/* The following errno values are used by FreeRTOS+ components, not FreeRTOS\r
-itself. */\r
-#define pdFREERTOS_ERRNO_NONE 0 /* No errors */\r
-#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */\r
-#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */\r
-#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */\r
-#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */\r
-#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */\r
-#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */\r
-#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */\r
-#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */\r
-#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */\r
-#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */\r
-#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */\r
-#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */\r
-#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */\r
-#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */\r
-#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */\r
-#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */\r
-#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */\r
-#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */\r
-#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */\r
-#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */\r
-#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */\r
-#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */\r
-#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */\r
-#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */\r
-#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */\r
-#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */\r
-#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */\r
-#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */\r
-#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */\r
-#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */\r
-#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */\r
-#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */\r
-#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */\r
-#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */\r
-#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */\r
-#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */\r
-#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */\r
-#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */\r
-\r
-/* The following endian values are used by FreeRTOS+ components, not FreeRTOS\r
-itself. */\r
-#define pdFREERTOS_LITTLE_ENDIAN 0\r
-#define pdFREERTOS_BIG_ENDIAN 1\r
-\r
-#endif /* PROJDEFS_H */\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-\r
-#ifndef QUEUE_H\r
-#define QUEUE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h" must appear in source files before "include queue.h"\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-/**\r
- * Type by which queues are referenced. For example, a call to xQueueCreate()\r
- * returns an QueueHandle_t variable that can then be used as a parameter to\r
- * xQueueSend(), xQueueReceive(), etc.\r
- */\r
-typedef void * QueueHandle_t;\r
-\r
-/**\r
- * Type by which queue sets are referenced. For example, a call to\r
- * xQueueCreateSet() returns an xQueueSet variable that can then be used as a\r
- * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.\r
- */\r
-typedef void * QueueSetHandle_t;\r
-\r
-/**\r
- * Queue sets can contain both queues and semaphores, so the\r
- * QueueSetMemberHandle_t is defined as a type to be used where a parameter or\r
- * return value can be either an QueueHandle_t or an SemaphoreHandle_t.\r
- */\r
-typedef void * QueueSetMemberHandle_t;\r
-\r
-/* For internal use only. */\r
-#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )\r
-#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )\r
-#define queueOVERWRITE ( ( BaseType_t ) 2 )\r
-\r
-/* For internal use only. These definitions *must* match those in queue.c. */\r
-#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U )\r
-#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U )\r
-#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U )\r
-#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U )\r
-#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )\r
-#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- QueueHandle_t xQueueCreate(\r
- UBaseType_t uxQueueLength,\r
- UBaseType_t uxItemSize\r
- );\r
- * </pre>\r
- *\r
- * Creates a new queue instance. This allocates the storage required by the\r
- * new queue and returns a handle for the queue.\r
- *\r
- * @param uxQueueLength The maximum number of items that the queue can contain.\r
- *\r
- * @param uxItemSize The number of bytes each item in the queue will require.\r
- * Items are queued by copy, not by reference, so this is the number of bytes\r
- * that will be copied for each posted item. Each item on the queue must be\r
- * the same size.\r
- *\r
- * @return If the queue is successfully create then a handle to the newly\r
- * created queue is returned. If the queue cannot be created then 0 is\r
- * returned.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- };\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue1, xQueue2;\r
-\r
- // Create a queue capable of containing 10 uint32_t values.\r
- xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );\r
- if( xQueue1 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue2 == 0 )\r
- {\r
- // Queue was not created and must not be used.\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueCreate xQueueCreate\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSendToToFront(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- TickType_t xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend().\r
- *\r
- * Post an item to the front of a queue. The item is queued by copy, not by\r
- * reference. This function must not be called from an interrupt service\r
- * routine. See xQueueSendFromISR () for an alternative which may be used\r
- * in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- uint32_t ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 uint32_t values.\r
- xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an uint32_t. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSendToBack(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- TickType_t xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend().\r
- *\r
- * Post an item to the back of a queue. The item is queued by copy, not by\r
- * reference. This function must not be called from an interrupt service\r
- * routine. See xQueueSendFromISR () for an alternative which may be used\r
- * in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the queue\r
- * is full. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- uint32_t ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 uint32_t values.\r
- xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an uint32_t. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSend(\r
- QueueHandle_t xQueue,\r
- const void * pvItemToQueue,\r
- TickType_t xTicksToWait\r
- );\r
- * </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSend(). It is included for\r
- * backward compatibility with versions of FreeRTOS.org that did not\r
- * include the xQueueSendToFront() and xQueueSendToBack() macros. It is\r
- * equivalent to xQueueSendToBack().\r
- *\r
- * Post an item on a queue. The item is queued by copy, not by reference.\r
- * This function must not be called from an interrupt service routine.\r
- * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- uint32_t ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 uint32_t values.\r
- xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an uint32_t. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueOverwrite(\r
- QueueHandle_t xQueue,\r
- const void * pvItemToQueue\r
- );\r
- * </pre>\r
- *\r
- * Only for use with queues that have a length of one - so the queue is either\r
- * empty or full.\r
- *\r
- * Post an item on a queue. If the queue is already full then overwrite the\r
- * value held in the queue. The item is queued by copy, not by reference.\r
- *\r
- * This function must not be called from an interrupt service routine.\r
- * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR.\r
- *\r
- * @param xQueue The handle of the queue to which the data is being sent.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and\r
- * therefore has the same return values as xQueueSendToFront(). However, pdPASS\r
- * is the only value that can be returned because xQueueOverwrite() will write\r
- * to the queue even when the queue is already full.\r
- *\r
- * Example usage:\r
- <pre>\r
-\r
- void vFunction( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue;\r
- uint32_t ulVarToSend, ulValReceived;\r
-\r
- // Create a queue to hold one uint32_t value. It is strongly\r
- // recommended *not* to use xQueueOverwrite() on queues that can\r
- // contain more than one value, and doing so will trigger an assertion\r
- // if configASSERT() is defined.\r
- xQueue = xQueueCreate( 1, sizeof( uint32_t ) );\r
-\r
- // Write the value 10 to the queue using xQueueOverwrite().\r
- ulVarToSend = 10;\r
- xQueueOverwrite( xQueue, &ulVarToSend );\r
-\r
- // Peeking the queue should now return 10, but leave the value 10 in\r
- // the queue. A block time of zero is used as it is known that the\r
- // queue holds a value.\r
- ulValReceived = 0;\r
- xQueuePeek( xQueue, &ulValReceived, 0 );\r
-\r
- if( ulValReceived != 10 )\r
- {\r
- // Error unless the item was removed by a different task.\r
- }\r
-\r
- // The queue is still full. Use xQueueOverwrite() to overwrite the\r
- // value held in the queue with 100.\r
- ulVarToSend = 100;\r
- xQueueOverwrite( xQueue, &ulVarToSend );\r
-\r
- // This time read from the queue, leaving the queue empty once more.\r
- // A block time of 0 is used again.\r
- xQueueReceive( xQueue, &ulValReceived, 0 );\r
-\r
- // The value read should be the last value written, even though the\r
- // queue was already full when the value was written.\r
- if( ulValReceived != 100 )\r
- {\r
- // Error!\r
- }\r
-\r
- // ...\r
-}\r
- </pre>\r
- * \defgroup xQueueOverwrite xQueueOverwrite\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueGenericSend(\r
- QueueHandle_t xQueue,\r
- const void * pvItemToQueue,\r
- TickType_t xTicksToWait\r
- BaseType_t xCopyPosition\r
- );\r
- * </pre>\r
- *\r
- * It is preferred that the macros xQueueSend(), xQueueSendToFront() and\r
- * xQueueSendToBack() are used in place of calling this function directly.\r
- *\r
- * Post an item on a queue. The item is queued by copy, not by reference.\r
- * This function must not be called from an interrupt service routine.\r
- * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for space to become available on the queue, should it already\r
- * be full. The call will return immediately if this is set to 0 and the\r
- * queue is full. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- *\r
- * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
- * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
- * at the front of the queue (for high priority messages).\r
- *\r
- * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- uint32_t ulVar = 10UL;\r
-\r
- void vATask( void *pvParameters )\r
- {\r
- QueueHandle_t xQueue1, xQueue2;\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 uint32_t values.\r
- xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
-\r
- // ...\r
-\r
- if( xQueue1 != 0 )\r
- {\r
- // Send an uint32_t. Wait for 10 ticks for space to become\r
- // available if necessary.\r
- if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )\r
- {\r
- // Failed to post the message, even after 10 ticks.\r
- }\r
- }\r
-\r
- if( xQueue2 != 0 )\r
- {\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueSend xQueueSend\r
- * \ingroup QueueManagement\r
- */\r
-BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueuePeek(\r
- QueueHandle_t xQueue,\r
- void *pvBuffer,\r
- TickType_t xTicksToWait\r
- );</pre>\r
- *\r
- * This is a macro that calls the xQueueGenericReceive() function.\r
- *\r
- * Receive an item from a queue without removing the item from the queue.\r
- * The item is received by copy so a buffer of adequate size must be\r
- * provided. The number of bytes copied into the buffer was defined when\r
- * the queue was created.\r
- *\r
- * Successfully received items remain on the queue so will be returned again\r
- * by the next call, or a call to xQueueReceive().\r
- *\r
- * This macro must not be used in an interrupt service routine. See\r
- * xQueuePeekFromISR() for an alternative that can be called from an interrupt\r
- * service routine.\r
- *\r
- * @param xQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue\r
- * is empty.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- QueueHandle_t xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to peek the data from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Peek a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask, but the item still remains on the queue.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueuePeekFromISR(\r
- QueueHandle_t xQueue,\r
- void *pvBuffer,\r
- );</pre>\r
- *\r
- * A version of xQueuePeek() that can be called from an interrupt service\r
- * routine (ISR).\r
- *\r
- * Receive an item from a queue without removing the item from the queue.\r
- * The item is received by copy so a buffer of adequate size must be\r
- * provided. The number of bytes copied into the buffer was defined when\r
- * the queue was created.\r
- *\r
- * Successfully received items remain on the queue so will be returned again\r
- * by the next call, or a call to xQueueReceive().\r
- *\r
- * @param xQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * \defgroup xQueuePeekFromISR xQueuePeekFromISR\r
- * \ingroup QueueManagement\r
- */\r
-BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueReceive(\r
- QueueHandle_t xQueue,\r
- void *pvBuffer,\r
- TickType_t xTicksToWait\r
- );</pre>\r
- *\r
- * This is a macro that calls the xQueueGenericReceive() function.\r
- *\r
- * Receive an item from a queue. The item is received by copy so a buffer of\r
- * adequate size must be provided. The number of bytes copied into the buffer\r
- * was defined when the queue was created.\r
- *\r
- * Successfully received items are removed from the queue.\r
- *\r
- * This function must not be used in an interrupt service routine. See\r
- * xQueueReceiveFromISR for an alternative that can.\r
- *\r
- * @param xQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. xQueueReceive() will return immediately if xTicksToWait\r
- * is zero and the queue is empty. The time is defined in tick periods so the\r
- * constant portTICK_PERIOD_MS should be used to convert to real time if this is\r
- * required.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- QueueHandle_t xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to receive from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueGenericReceive(\r
- QueueHandle_t xQueue,\r
- void *pvBuffer,\r
- TickType_t xTicksToWait\r
- BaseType_t xJustPeek\r
- );</pre>\r
- *\r
- * It is preferred that the macro xQueueReceive() be used rather than calling\r
- * this function directly.\r
- *\r
- * Receive an item from a queue. The item is received by copy so a buffer of\r
- * adequate size must be provided. The number of bytes copied into the buffer\r
- * was defined when the queue was created.\r
- *\r
- * This function must not be used in an interrupt service routine. See\r
- * xQueueReceiveFromISR for an alternative that can.\r
- *\r
- * @param xQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param xTicksToWait The maximum amount of time the task should block\r
- * waiting for an item to receive should the queue be empty at the time\r
- * of the call. The time is defined in tick periods so the constant\r
- * portTICK_PERIOD_MS should be used to convert to real time if this is required.\r
- * xQueueGenericReceive() will return immediately if the queue is empty and\r
- * xTicksToWait is 0.\r
- *\r
- * @param xJustPeek When set to true, the item received from the queue is not\r
- * actually removed from the queue - meaning a subsequent call to\r
- * xQueueReceive() will return the same item. When set to false, the item\r
- * being received from the queue is also removed from the queue.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- struct AMessage\r
- {\r
- char ucMessageID;\r
- char ucData[ 20 ];\r
- } xMessage;\r
-\r
- QueueHandle_t xQueue;\r
-\r
- // Task to create a queue and post a value.\r
- void vATask( void *pvParameters )\r
- {\r
- struct AMessage *pxMessage;\r
-\r
- // Create a queue capable of containing 10 pointers to AMessage structures.\r
- // These should be passed by pointer as they contain a lot of data.\r
- xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Send a pointer to a struct AMessage object. Don't block if the\r
- // queue is already full.\r
- pxMessage = & xMessage;\r
- xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );\r
-\r
- // ... Rest of task code.\r
- }\r
-\r
- // Task to receive from the queue.\r
- void vADifferentTask( void *pvParameters )\r
- {\r
- struct AMessage *pxRxedMessage;\r
-\r
- if( xQueue != 0 )\r
- {\r
- // Receive a message on the created queue. Block for 10 ticks if a\r
- // message is not immediately available.\r
- if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )\r
- {\r
- // pcRxedMessage now points to the struct AMessage variable posted\r
- // by vATask.\r
- }\r
- }\r
-\r
- // ... Rest of task code.\r
- }\r
- </pre>\r
- * \defgroup xQueueReceive xQueueReceive\r
- * \ingroup QueueManagement\r
- */\r
-BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );</pre>\r
- *\r
- * Return the number of messages stored in a queue.\r
- *\r
- * @param xQueue A handle to the queue being queried.\r
- *\r
- * @return The number of messages available in the queue.\r
- *\r
- * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting\r
- * \ingroup QueueManagement\r
- */\r
-UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );</pre>\r
- *\r
- * Return the number of free spaces available in a queue. This is equal to the\r
- * number of items that can be sent to the queue before the queue becomes full\r
- * if no items are removed.\r
- *\r
- * @param xQueue A handle to the queue being queried.\r
- *\r
- * @return The number of spaces available in the queue.\r
- *\r
- * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting\r
- * \ingroup QueueManagement\r
- */\r
-UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>void vQueueDelete( QueueHandle_t xQueue );</pre>\r
- *\r
- * Delete a queue - freeing all the memory allocated for storing of items\r
- * placed on the queue.\r
- *\r
- * @param xQueue A handle to the queue to be deleted.\r
- *\r
- * \defgroup vQueueDelete vQueueDelete\r
- * \ingroup QueueManagement\r
- */\r
-void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSendToFrontFromISR(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR().\r
- *\r
- * Post an item to the front of a queue. It is safe to use this macro from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- BaseType_t xHigherPrioritTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT )\r
-\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSendToBackFromISR(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR().\r
- *\r
- * Post an item to the back of a queue. It is safe to use this macro from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- BaseType_t xHigherPriorityTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueOverwriteFromISR(\r
- QueueHandle_t xQueue,\r
- const void * pvItemToQueue,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- );\r
- * </pre>\r
- *\r
- * A version of xQueueOverwrite() that can be used in an interrupt service\r
- * routine (ISR).\r
- *\r
- * Only for use with queues that can hold a single item - so the queue is either\r
- * empty or full.\r
- *\r
- * Post an item on a queue. If the queue is already full then overwrite the\r
- * value held in the queue. The item is queued by copy, not by reference.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return xQueueOverwriteFromISR() is a macro that calls\r
- * xQueueGenericSendFromISR(), and therefore has the same return values as\r
- * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be\r
- * returned because xQueueOverwriteFromISR() will write to the queue even when\r
- * the queue is already full.\r
- *\r
- * Example usage:\r
- <pre>\r
-\r
- QueueHandle_t xQueue;\r
-\r
- void vFunction( void *pvParameters )\r
- {\r
- // Create a queue to hold one uint32_t value. It is strongly\r
- // recommended *not* to use xQueueOverwriteFromISR() on queues that can\r
- // contain more than one value, and doing so will trigger an assertion\r
- // if configASSERT() is defined.\r
- xQueue = xQueueCreate( 1, sizeof( uint32_t ) );\r
-}\r
-\r
-void vAnInterruptHandler( void )\r
-{\r
-// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.\r
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
-uint32_t ulVarToSend, ulValReceived;\r
-\r
- // Write the value 10 to the queue using xQueueOverwriteFromISR().\r
- ulVarToSend = 10;\r
- xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );\r
-\r
- // The queue is full, but calling xQueueOverwriteFromISR() again will still\r
- // pass because the value held in the queue will be overwritten with the\r
- // new value.\r
- ulVarToSend = 100;\r
- xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );\r
-\r
- // Reading from the queue will now return 100.\r
-\r
- // ...\r
-\r
- if( xHigherPrioritytaskWoken == pdTRUE )\r
- {\r
- // Writing to the queue caused a task to unblock and the unblocked task\r
- // has a priority higher than or equal to the priority of the currently\r
- // executing task (the task this interrupt interrupted). Perform a context\r
- // switch so this interrupt returns directly to the unblocked task.\r
- portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.\r
- }\r
-}\r
- </pre>\r
- * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueSendFromISR(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- );\r
- </pre>\r
- *\r
- * This is a macro that calls xQueueGenericSendFromISR(). It is included\r
- * for backward compatibility with versions of FreeRTOS.org that did not\r
- * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()\r
- * macros.\r
- *\r
- * Post an item to the back of a queue. It is safe to use this function from\r
- * within an interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueSendFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- BaseType_t xHigherPriorityTaskWoken;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWoken = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post the byte.\r
- xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary.\r
- if( xHigherPriorityTaskWoken )\r
- {\r
- // Actual macro used here is port specific.\r
- portYIELD_FROM_ISR ();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueGenericSendFromISR(\r
- QueueHandle_t xQueue,\r
- const void *pvItemToQueue,\r
- BaseType_t *pxHigherPriorityTaskWoken,\r
- BaseType_t xCopyPosition\r
- );\r
- </pre>\r
- *\r
- * It is preferred that the macros xQueueSendFromISR(),\r
- * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place\r
- * of calling this function directly. xQueueGiveFromISR() is an\r
- * equivalent for use by semaphores that don't actually copy any data.\r
- *\r
- * Post an item on a queue. It is safe to use this function from within an\r
- * interrupt service routine.\r
- *\r
- * Items are queued by copy not reference so it is preferable to only\r
- * queue small items, especially when called from an ISR. In most cases\r
- * it would be preferable to store a pointer to the item being queued.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
- * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
- * at the front of the queue (for high priority messages).\r
- *\r
- * @return pdTRUE if the data was successfully sent to the queue, otherwise\r
- * errQUEUE_FULL.\r
- *\r
- * Example usage for buffered IO (where the ISR can obtain more than one value\r
- * per call):\r
- <pre>\r
- void vBufferISR( void )\r
- {\r
- char cIn;\r
- BaseType_t xHigherPriorityTaskWokenByPost;\r
-\r
- // We have not woken a task at the start of the ISR.\r
- xHigherPriorityTaskWokenByPost = pdFALSE;\r
-\r
- // Loop until the buffer is empty.\r
- do\r
- {\r
- // Obtain a byte from the buffer.\r
- cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );\r
-\r
- // Post each byte.\r
- xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );\r
-\r
- } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
-\r
- // Now the buffer is empty we can switch context if necessary. Note that the\r
- // name of the yield function required is port specific.\r
- if( xHigherPriorityTaskWokenByPost )\r
- {\r
- taskYIELD_YIELD_FROM_ISR();\r
- }\r
- }\r
- </pre>\r
- *\r
- * \defgroup xQueueSendFromISR xQueueSendFromISR\r
- * \ingroup QueueManagement\r
- */\r
-BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;\r
-BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * queue. h\r
- * <pre>\r
- BaseType_t xQueueReceiveFromISR(\r
- QueueHandle_t xQueue,\r
- void *pvBuffer,\r
- BaseType_t *pxTaskWoken\r
- );\r
- * </pre>\r
- *\r
- * Receive an item from a queue. It is safe to use this function from within an\r
- * interrupt service routine.\r
- *\r
- * @param xQueue The handle to the queue from which the item is to be\r
- * received.\r
- *\r
- * @param pvBuffer Pointer to the buffer into which the received item will\r
- * be copied.\r
- *\r
- * @param pxTaskWoken A task may be blocked waiting for space to become\r
- * available on the queue. If xQueueReceiveFromISR causes such a task to\r
- * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will\r
- * remain unchanged.\r
- *\r
- * @return pdTRUE if an item was successfully received from the queue,\r
- * otherwise pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
-\r
- QueueHandle_t xQueue;\r
-\r
- // Function to create a queue and post some values.\r
- void vAFunction( void *pvParameters )\r
- {\r
- char cValueToPost;\r
- const TickType_t xTicksToWait = ( TickType_t )0xff;\r
-\r
- // Create a queue capable of containing 10 characters.\r
- xQueue = xQueueCreate( 10, sizeof( char ) );\r
- if( xQueue == 0 )\r
- {\r
- // Failed to create the queue.\r
- }\r
-\r
- // ...\r
-\r
- // Post some characters that will be used within an ISR. If the queue\r
- // is full then this task will block for xTicksToWait ticks.\r
- cValueToPost = 'a';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
- cValueToPost = 'b';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
-\r
- // ... keep posting characters ... this task may block when the queue\r
- // becomes full.\r
-\r
- cValueToPost = 'c';\r
- xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );\r
- }\r
-\r
- // ISR that outputs all the characters received on the queue.\r
- void vISR_Routine( void )\r
- {\r
- BaseType_t xTaskWokenByReceive = pdFALSE;\r
- char cRxedChar;\r
-\r
- while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
- {\r
- // A character was received. Output the character now.\r
- vOutputCharacter( cRxedChar );\r
-\r
- // If removing the character from the queue woke the task that was\r
- // posting onto the queue cTaskWokenByReceive will have been set to\r
- // pdTRUE. No matter how many times this loop iterates only one\r
- // task will be woken.\r
- }\r
-\r
- if( cTaskWokenByPost != ( char ) pdFALSE;\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- </pre>\r
- * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
- * \ingroup QueueManagement\r
- */\r
-BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Utilities to query queues that are safe to use from an ISR. These utilities\r
- * should be used only from witin an ISR, or within a critical section.\r
- */\r
-BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-\r
-\r
-/*\r
- * xQueueAltGenericSend() is an alternative version of xQueueGenericSend().\r
- * Likewise xQueueAltGenericReceive() is an alternative version of\r
- * xQueueGenericReceive().\r
- *\r
- * The source code that implements the alternative (Alt) API is much\r
- * simpler because it executes everything from within a critical section.\r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
- * preferred fully featured API too. The fully featured API has more\r
- * complex code that takes longer to execute, but makes much less use of\r
- * critical sections. Therefore the alternative API sacrifices interrupt\r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-BaseType_t xQueueAltGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;\r
-BaseType_t xQueueAltGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ) PRIVILEGED_FUNCTION;\r
-#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )\r
-#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )\r
-#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE )\r
-#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE )\r
-\r
-/*\r
- * The functions defined above are for passing data to and from tasks. The\r
- * functions below are the equivalents for passing data to and from\r
- * co-routines.\r
- *\r
- * These functions are called from the co-routine macro implementation and\r
- * should not be called directly from application code. Instead use the macro\r
- * wrappers defined within croutine.h.\r
- */\r
-BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken );\r
-BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken );\r
-BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait );\r
-BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait );\r
-\r
-/*\r
- * For internal use only. Use xSemaphoreCreateMutex(),\r
- * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling\r
- * these functions directly.\r
- */\r
-QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;\r
-QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;\r
-void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * For internal use only. Use xSemaphoreTakeMutexRecursive() or\r
- * xSemaphoreGiveMutexRecursive() instead of calling these functions directly.\r
- */\r
-BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Reset a queue back to its original empty state. The return value is now\r
- * obsolete and is always set to pdPASS.\r
- */\r
-#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )\r
-\r
-/*\r
- * The registry is provided as a means for kernel aware debuggers to\r
- * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add\r
- * a queue, semaphore or mutex handle to the registry if you want the handle\r
- * to be available to a kernel aware debugger. If you are not using a kernel\r
- * aware debugger then this function can be ignored.\r
- *\r
- * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the\r
- * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0\r
- * within FreeRTOSConfig.h for the registry to be available. Its value\r
- * does not effect the number of queues, semaphores and mutexes that can be\r
- * created - just the number that the registry can hold.\r
- *\r
- * @param xQueue The handle of the queue being added to the registry. This\r
- * is the handle returned by a call to xQueueCreate(). Semaphore and mutex\r
- * handles can also be passed in here.\r
- *\r
- * @param pcName The name to be associated with the handle. This is the\r
- * name that the kernel aware debugger will display. The queue registry only\r
- * stores a pointer to the string - so the string must be persistent (global or\r
- * preferably in ROM/Flash), not on the stack.\r
- */\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
- void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-#endif\r
-\r
-/*\r
- * The registry is provided as a means for kernel aware debuggers to\r
- * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add\r
- * a queue, semaphore or mutex handle to the registry if you want the handle\r
- * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to\r
- * remove the queue, semaphore or mutex from the register. If you are not using\r
- * a kernel aware debugger then this function can be ignored.\r
- *\r
- * @param xQueue The handle of the queue being removed from the registry.\r
- */\r
-#if configQUEUE_REGISTRY_SIZE > 0\r
- void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-#endif\r
-\r
-/*\r
- * Generic version of the queue creation function, which is in turn called by\r
- * any queue, semaphore or mutex creation function or macro.\r
- */\r
-QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Queue sets provide a mechanism to allow a task to block (pend) on a read\r
- * operation from multiple queues or semaphores simultaneously.\r
- *\r
- * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
- * function.\r
- *\r
- * A queue set must be explicitly created using a call to xQueueCreateSet()\r
- * before it can be used. Once created, standard FreeRTOS queues and semaphores\r
- * can be added to the set using calls to xQueueAddToSet().\r
- * xQueueSelectFromSet() is then used to determine which, if any, of the queues\r
- * or semaphores contained in the set is in a state where a queue read or\r
- * semaphore take operation would be successful.\r
- *\r
- * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html\r
- * for reasons why queue sets are very rarely needed in practice as there are\r
- * simpler methods of blocking on multiple objects.\r
- *\r
- * Note 2: Blocking on a queue set that contains a mutex will not cause the\r
- * mutex holder to inherit the priority of the blocked task.\r
- *\r
- * Note 3: An additional 4 bytes of RAM is required for each space in a every\r
- * queue added to a queue set. Therefore counting semaphores that have a high\r
- * maximum count value should not be added to a queue set.\r
- *\r
- * Note 4: A receive (in the case of a queue) or take (in the case of a\r
- * semaphore) operation must not be performed on a member of a queue set unless\r
- * a call to xQueueSelectFromSet() has first returned a handle to that set member.\r
- *\r
- * @param uxEventQueueLength Queue sets store events that occur on\r
- * the queues and semaphores contained in the set. uxEventQueueLength specifies\r
- * the maximum number of events that can be queued at once. To be absolutely\r
- * certain that events are not lost uxEventQueueLength should be set to the\r
- * total sum of the length of the queues added to the set, where binary\r
- * semaphores and mutexes have a length of 1, and counting semaphores have a\r
- * length set by their maximum count value. Examples:\r
- * + If a queue set is to hold a queue of length 5, another queue of length 12,\r
- * and a binary semaphore, then uxEventQueueLength should be set to\r
- * (5 + 12 + 1), or 18.\r
- * + If a queue set is to hold three binary semaphores then uxEventQueueLength\r
- * should be set to (1 + 1 + 1 ), or 3.\r
- * + If a queue set is to hold a counting semaphore that has a maximum count of\r
- * 5, and a counting semaphore that has a maximum count of 3, then\r
- * uxEventQueueLength should be set to (5 + 3), or 8.\r
- *\r
- * @return If the queue set is created successfully then a handle to the created\r
- * queue set is returned. Otherwise NULL is returned.\r
- */\r
-QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Adds a queue or semaphore to a queue set that was previously created by a\r
- * call to xQueueCreateSet().\r
- *\r
- * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
- * function.\r
- *\r
- * Note 1: A receive (in the case of a queue) or take (in the case of a\r
- * semaphore) operation must not be performed on a member of a queue set unless\r
- * a call to xQueueSelectFromSet() has first returned a handle to that set member.\r
- *\r
- * @param xQueueOrSemaphore The handle of the queue or semaphore being added to\r
- * the queue set (cast to an QueueSetMemberHandle_t type).\r
- *\r
- * @param xQueueSet The handle of the queue set to which the queue or semaphore\r
- * is being added.\r
- *\r
- * @return If the queue or semaphore was successfully added to the queue set\r
- * then pdPASS is returned. If the queue could not be successfully added to the\r
- * queue set because it is already a member of a different queue set then pdFAIL\r
- * is returned.\r
- */\r
-BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Removes a queue or semaphore from a queue set. A queue or semaphore can only\r
- * be removed from a set if the queue or semaphore is empty.\r
- *\r
- * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
- * function.\r
- *\r
- * @param xQueueOrSemaphore The handle of the queue or semaphore being removed\r
- * from the queue set (cast to an QueueSetMemberHandle_t type).\r
- *\r
- * @param xQueueSet The handle of the queue set in which the queue or semaphore\r
- * is included.\r
- *\r
- * @return If the queue or semaphore was successfully removed from the queue set\r
- * then pdPASS is returned. If the queue was not in the queue set, or the\r
- * queue (or semaphore) was not empty, then pdFAIL is returned.\r
- */\r
-BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * xQueueSelectFromSet() selects from the members of a queue set a queue or\r
- * semaphore that either contains data (in the case of a queue) or is available\r
- * to take (in the case of a semaphore). xQueueSelectFromSet() effectively\r
- * allows a task to block (pend) on a read operation on all the queues and\r
- * semaphores in a queue set simultaneously.\r
- *\r
- * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this\r
- * function.\r
- *\r
- * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html\r
- * for reasons why queue sets are very rarely needed in practice as there are\r
- * simpler methods of blocking on multiple objects.\r
- *\r
- * Note 2: Blocking on a queue set that contains a mutex will not cause the\r
- * mutex holder to inherit the priority of the blocked task.\r
- *\r
- * Note 3: A receive (in the case of a queue) or take (in the case of a\r
- * semaphore) operation must not be performed on a member of a queue set unless\r
- * a call to xQueueSelectFromSet() has first returned a handle to that set member.\r
- *\r
- * @param xQueueSet The queue set on which the task will (potentially) block.\r
- *\r
- * @param xTicksToWait The maximum time, in ticks, that the calling task will\r
- * remain in the Blocked state (with other tasks executing) to wait for a member\r
- * of the queue set to be ready for a successful queue read or semaphore take\r
- * operation.\r
- *\r
- * @return xQueueSelectFromSet() will return the handle of a queue (cast to\r
- * a QueueSetMemberHandle_t type) contained in the queue set that contains data,\r
- * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained\r
- * in the queue set that is available, or NULL if no such queue or semaphore\r
- * exists before before the specified block time expires.\r
- */\r
-QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * A version of xQueueSelectFromSet() that can be used from an ISR.\r
- */\r
-QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;\r
-\r
-/* Not public API functions. */\r
-void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;\r
-BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;\r
-void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION;\r
-UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;\r
-\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* QUEUE_H */\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-#ifndef SEMAPHORE_H\r
-#define SEMAPHORE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h" must appear in source files before "include semphr.h"\r
-#endif\r
-\r
-#include "queue.h"\r
-\r
-typedef QueueHandle_t SemaphoreHandle_t;\r
-\r
-#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U )\r
-#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )\r
-#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )\r
-\r
-\r
-/**\r
- * semphr. h\r
- * <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>\r
- *\r
- * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the\r
- * xSemaphoreCreateBinary() function. Note that binary semaphores created using\r
- * the vSemaphoreCreateBinary() macro are created in a state such that the\r
- * first call to 'take' the semaphore would pass, whereas binary semaphores\r
- * created using xSemaphoreCreateBinary() are created in a state such that the\r
- * the semaphore must first be 'given' before it can be 'taken'.\r
- *\r
- * <i>Macro</i> that implements a semaphore by using the existing queue mechanism.\r
- * The queue length is 1 as this is a binary semaphore. The data size is 0\r
- * as we don't want to actually store any data - we just want to know if the\r
- * queue is empty or full.\r
- *\r
- * This type of semaphore can be used for pure synchronisation between tasks or\r
- * between an interrupt and a task. The semaphore need not be given back once\r
- * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
- * another continuously 'takes' the semaphore. For this reason this type of\r
- * semaphore does not use a priority inheritance mechanism. For an alternative\r
- * that does use priority inheritance see xSemaphoreCreateMutex().\r
- *\r
- * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
- // This is a macro so pass the variable in directly.\r
- vSemaphoreCreateBinary( xSemaphore );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
- * \ingroup Semaphores\r
- */\r
-#define vSemaphoreCreateBinary( xSemaphore ) \\r
- { \\r
- ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \\r
- if( ( xSemaphore ) != NULL ) \\r
- { \\r
- ( void ) xSemaphoreGive( ( xSemaphore ) ); \\r
- } \\r
- }\r
-\r
-/**\r
- * semphr. h\r
- * <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>\r
- *\r
- * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this\r
- * xSemaphoreCreateBinary() function. Note that binary semaphores created using\r
- * the vSemaphoreCreateBinary() macro are created in a state such that the\r
- * first call to 'take' the semaphore would pass, whereas binary semaphores\r
- * created using xSemaphoreCreateBinary() are created in a state such that the\r
- * the semaphore must first be 'given' before it can be 'taken'.\r
- *\r
- * Function that creates a semaphore by using the existing queue mechanism.\r
- * The queue length is 1 as this is a binary semaphore. The data size is 0\r
- * as nothing is actually stored - all that is important is whether the queue is\r
- * empty or full (the binary semaphore is available or not).\r
- *\r
- * This type of semaphore can be used for pure synchronisation between tasks or\r
- * between an interrupt and a task. The semaphore need not be given back once\r
- * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
- * another continuously 'takes' the semaphore. For this reason this type of\r
- * semaphore does not use a priority inheritance mechanism. For an alternative\r
- * that does use priority inheritance see xSemaphoreCreateMutex().\r
- *\r
- * @return Handle to the created semaphore.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
- // This is a macro so pass the variable in directly.\r
- xSemaphore = xSemaphoreCreateBinary();\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreTake(\r
- * SemaphoreHandle_t xSemaphore,\r
- * TickType_t xBlockTime\r
- * )</pre>\r
- *\r
- * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
- * xSemaphoreCreateCounting().\r
- *\r
- * @param xSemaphore A handle to the semaphore being taken - obtained when\r
- * the semaphore was created.\r
- *\r
- * @param xBlockTime The time in ticks to wait for the semaphore to become\r
- * available. The macro portTICK_PERIOD_MS can be used to convert this to a\r
- * real time. A block time of zero can be used to poll the semaphore. A block\r
- * time of portMAX_DELAY can be used to block indefinitely (provided\r
- * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).\r
- *\r
- * @return pdTRUE if the semaphore was obtained. pdFALSE\r
- * if xBlockTime expired without the semaphore becoming available.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- // A task that creates a semaphore.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the semaphore to guard a shared resource.\r
- vSemaphoreCreateBinary( xSemaphore );\r
- }\r
-\r
- // A task that uses the semaphore.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // See if we can obtain the semaphore. If the semaphore is not available\r
- // wait 10 ticks to see if it becomes free.\r
- if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the semaphore and can now access the\r
- // shared resource.\r
-\r
- // ...\r
-\r
- // We have finished accessing the shared resource. Release the\r
- // semaphore.\r
- xSemaphoreGive( xSemaphore );\r
- }\r
- else\r
- {\r
- // We could not obtain the semaphore and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreTake xSemaphoreTake\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
-\r
-/**\r
- * semphr. h\r
- * xSemaphoreTakeRecursive(\r
- * SemaphoreHandle_t xMutex,\r
- * TickType_t xBlockTime\r
- * )\r
- *\r
- * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.\r
- * The mutex must have previously been created using a call to\r
- * xSemaphoreCreateRecursiveMutex();\r
- *\r
- * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
- * macro to be available.\r
- *\r
- * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
- *\r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
- * doesn't become available again until the owner has called\r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example,\r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- *\r
- * @param xMutex A handle to the mutex being obtained. This is the\r
- * handle returned by xSemaphoreCreateRecursiveMutex();\r
- *\r
- * @param xBlockTime The time in ticks to wait for the semaphore to become\r
- * available. The macro portTICK_PERIOD_MS can be used to convert this to a\r
- * real time. A block time of zero can be used to poll the semaphore. If\r
- * the task already owns the semaphore then xSemaphoreTakeRecursive() will\r
- * return immediately no matter what the value of xBlockTime.\r
- *\r
- * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime\r
- * expired without the semaphore becoming available.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xMutex = NULL;\r
-\r
- // A task that creates a mutex.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the mutex to guard a shared resource.\r
- xMutex = xSemaphoreCreateRecursiveMutex();\r
- }\r
-\r
- // A task that uses the mutex.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xMutex != NULL )\r
- {\r
- // See if we can obtain the mutex. If the mutex is not available\r
- // wait 10 ticks to see if it becomes free.\r
- if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the mutex and can now access the\r
- // shared resource.\r
-\r
- // ...\r
- // For some reason due to the nature of the code further calls to\r
- // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
- // code these would not be just sequential calls as this would make\r
- // no sense. Instead the calls are likely to be buried inside\r
- // a more complex call structure.\r
- xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
- xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
-\r
- // The mutex has now been 'taken' three times, so will not be\r
- // available to another task until it has also been given back\r
- // three times. Again it is unlikely that real code would have\r
- // these calls sequentially, but instead buried in a more complex\r
- // call structure. This is just for illustrative purposes.\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
-\r
- // Now the mutex can be taken by other tasks.\r
- }\r
- else\r
- {\r
- // We could not obtain the mutex and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )\r
-\r
-\r
-/*\r
- * xSemaphoreAltTake() is an alternative version of xSemaphoreTake().\r
- *\r
- * The source code that implements the alternative (Alt) API is much\r
- * simpler because it executes everything from within a critical section.\r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
- * preferred fully featured API too. The fully featured API has more\r
- * complex code that takes longer to execute, but makes much less use of\r
- * critical sections. Therefore the alternative API sacrifices interrupt\r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre>\r
- *\r
- * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or\r
- * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().\r
- *\r
- * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for\r
- * an alternative which can be used from an ISR.\r
- *\r
- * This macro must also not be used on semaphores created using\r
- * xSemaphoreCreateRecursiveMutex().\r
- *\r
- * @param xSemaphore A handle to the semaphore being released. This is the\r
- * handle returned when the semaphore was created.\r
- *\r
- * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.\r
- * Semaphores are implemented using queues. An error can occur if there is\r
- * no space on the queue to post a message - indicating that the\r
- * semaphore was not first obtained correctly.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the semaphore to guard a shared resource.\r
- vSemaphoreCreateBinary( xSemaphore );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
- {\r
- // We would expect this call to fail because we cannot give\r
- // a semaphore without first "taking" it!\r
- }\r
-\r
- // Obtain the semaphore - don't block if the semaphore is not\r
- // immediately available.\r
- if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )\r
- {\r
- // We now have the semaphore and can access the shared resource.\r
-\r
- // ...\r
-\r
- // We have finished accessing the shared resource so can free the\r
- // semaphore.\r
- if( xSemaphoreGive( xSemaphore ) != pdTRUE )\r
- {\r
- // We would not expect this call to fail because we must have\r
- // obtained the semaphore to get here.\r
- }\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGive xSemaphoreGive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre>\r
- *\r
- * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.\r
- * The mutex must have previously been created using a call to\r
- * xSemaphoreCreateRecursiveMutex();\r
- *\r
- * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this\r
- * macro to be available.\r
- *\r
- * This macro must not be used on mutexes created using xSemaphoreCreateMutex().\r
- *\r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
- * doesn't become available again until the owner has called\r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example,\r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- *\r
- * @param xMutex A handle to the mutex being released, or 'given'. This is the\r
- * handle returned by xSemaphoreCreateMutex();\r
- *\r
- * @return pdTRUE if the semaphore was given.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xMutex = NULL;\r
-\r
- // A task that creates a mutex.\r
- void vATask( void * pvParameters )\r
- {\r
- // Create the mutex to guard a shared resource.\r
- xMutex = xSemaphoreCreateRecursiveMutex();\r
- }\r
-\r
- // A task that uses the mutex.\r
- void vAnotherTask( void * pvParameters )\r
- {\r
- // ... Do other things.\r
-\r
- if( xMutex != NULL )\r
- {\r
- // See if we can obtain the mutex. If the mutex is not available\r
- // wait 10 ticks to see if it becomes free.\r
- if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )\r
- {\r
- // We were able to obtain the mutex and can now access the\r
- // shared resource.\r
-\r
- // ...\r
- // For some reason due to the nature of the code further calls to\r
- // xSemaphoreTakeRecursive() are made on the same mutex. In real\r
- // code these would not be just sequential calls as this would make\r
- // no sense. Instead the calls are likely to be buried inside\r
- // a more complex call structure.\r
- xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
- xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );\r
-\r
- // The mutex has now been 'taken' three times, so will not be\r
- // available to another task until it has also been given back\r
- // three times. Again it is unlikely that real code would have\r
- // these calls sequentially, it would be more likely that the calls\r
- // to xSemaphoreGiveRecursive() would be called as a call stack\r
- // unwound. This is just for demonstrative purposes.\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
- xSemaphoreGiveRecursive( xMutex );\r
-\r
- // Now the mutex can be taken by other tasks.\r
- }\r
- else\r
- {\r
- // We could not obtain the mutex and can therefore not access\r
- // the shared resource safely.\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )\r
-\r
-/*\r
- * xSemaphoreAltGive() is an alternative version of xSemaphoreGive().\r
- *\r
- * The source code that implements the alternative (Alt) API is much\r
- * simpler because it executes everything from within a critical section.\r
- * This is the approach taken by many other RTOSes, but FreeRTOS.org has the\r
- * preferred fully featured API too. The fully featured API has more\r
- * complex code that takes longer to execute, but makes much less use of\r
- * critical sections. Therefore the alternative API sacrifices interrupt\r
- * responsiveness to gain execution speed, whereas the fully featured API\r
- * sacrifices execution speed to ensure better interrupt responsiveness.\r
- */\r
-#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>\r
- xSemaphoreGiveFromISR(\r
- SemaphoreHandle_t xSemaphore,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- )</pre>\r
- *\r
- * <i>Macro</i> to release a semaphore. The semaphore must have previously been\r
- * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().\r
- *\r
- * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
- * must not be used with this macro.\r
- *\r
- * This macro can be used from an ISR.\r
- *\r
- * @param xSemaphore A handle to the semaphore being released. This is the\r
- * handle returned when the semaphore was created.\r
- *\r
- * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.\r
- *\r
- * Example usage:\r
- <pre>\r
- \#define LONG_TIME 0xffff\r
- \#define TICKS_TO_WAIT 10\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- // Repetitive task.\r
- void vATask( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // We want this task to run every 10 ticks of a timer. The semaphore\r
- // was created before this task was started.\r
-\r
- // Block waiting for the semaphore to become available.\r
- if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )\r
- {\r
- // It is time to execute.\r
-\r
- // ...\r
-\r
- // We have finished our task. Return to the top of the loop where\r
- // we will block on the semaphore until it is time to execute\r
- // again. Note when using the semaphore for synchronisation with an\r
- // ISR in this manner there is no need to 'give' the semaphore back.\r
- }\r
- }\r
- }\r
-\r
- // Timer ISR\r
- void vTimerISR( void * pvParameters )\r
- {\r
- static uint8_t ucLocalTickCount = 0;\r
- static BaseType_t xHigherPriorityTaskWoken;\r
-\r
- // A timer tick has occurred.\r
-\r
- // ... Do other time functions.\r
-\r
- // Is it time for vATask () to run?\r
- xHigherPriorityTaskWoken = pdFALSE;\r
- ucLocalTickCount++;\r
- if( ucLocalTickCount >= TICKS_TO_WAIT )\r
- {\r
- // Unblock the task by releasing the semaphore.\r
- xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );\r
-\r
- // Reset the count so we release the semaphore again in 10 ticks time.\r
- ucLocalTickCount = 0;\r
- }\r
-\r
- if( xHigherPriorityTaskWoken != pdFALSE )\r
- {\r
- // We can force a context switch here. Context switching from an\r
- // ISR uses port specific syntax. Check the demo task for your port\r
- // to find the syntax required.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>\r
- xSemaphoreTakeFromISR(\r
- SemaphoreHandle_t xSemaphore,\r
- BaseType_t *pxHigherPriorityTaskWoken\r
- )</pre>\r
- *\r
- * <i>Macro</i> to take a semaphore from an ISR. The semaphore must have\r
- * previously been created with a call to vSemaphoreCreateBinary() or\r
- * xSemaphoreCreateCounting().\r
- *\r
- * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
- * must not be used with this macro.\r
- *\r
- * This macro can be used from an ISR, however taking a semaphore from an ISR\r
- * is not a common operation. It is likely to only be useful when taking a\r
- * counting semaphore when an interrupt is obtaining an object from a resource\r
- * pool (when the semaphore count indicates the number of resources available).\r
- *\r
- * @param xSemaphore A handle to the semaphore being taken. This is the\r
- * handle returned when the semaphore was created.\r
- *\r
- * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task\r
- * to unblock, and the unblocked task has a priority higher than the currently\r
- * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then\r
- * a context switch should be requested before the interrupt is exited.\r
- *\r
- * @return pdTRUE if the semaphore was successfully taken, otherwise\r
- * pdFALSE\r
- */\r
-#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre>\r
- *\r
- * <i>Macro</i> that implements a mutex semaphore by using the existing queue\r
- * mechanism.\r
- *\r
- * Mutexes created using this macro can be accessed using the xSemaphoreTake()\r
- * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and\r
- * xSemaphoreGiveRecursive() macros should not be used.\r
- *\r
- * This type of semaphore uses a priority inheritance mechanism so a task\r
- * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
- * semaphore it is no longer required.\r
- *\r
- * Mutex type semaphores cannot be used from within interrupt service routines.\r
- *\r
- * See vSemaphoreCreateBinary() for an alternative implementation that can be\r
- * used for pure synchronisation (where one task or interrupt always 'gives' the\r
- * semaphore and another always 'takes' the semaphore) and from within interrupt\r
- * service routines.\r
- *\r
- * @return xSemaphore Handle to the created mutex semaphore. Should be of type\r
- * SemaphoreHandle_t.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
- // This is a macro so pass the variable in directly.\r
- xSemaphore = xSemaphoreCreateMutex();\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )\r
-\r
-\r
-/**\r
- * semphr. h\r
- * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre>\r
- *\r
- * <i>Macro</i> that implements a recursive mutex by using the existing queue\r
- * mechanism.\r
- *\r
- * Mutexes created using this macro can be accessed using the\r
- * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The\r
- * xSemaphoreTake() and xSemaphoreGive() macros should not be used.\r
- *\r
- * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex\r
- * doesn't become available again until the owner has called\r
- * xSemaphoreGiveRecursive() for each successful 'take' request. For example,\r
- * if a task successfully 'takes' the same mutex 5 times then the mutex will\r
- * not be available to any other task until it has also 'given' the mutex back\r
- * exactly five times.\r
- *\r
- * This type of semaphore uses a priority inheritance mechanism so a task\r
- * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the\r
- * semaphore it is no longer required.\r
- *\r
- * Mutex type semaphores cannot be used from within interrupt service routines.\r
- *\r
- * See vSemaphoreCreateBinary() for an alternative implementation that can be\r
- * used for pure synchronisation (where one task or interrupt always 'gives' the\r
- * semaphore and another always 'takes' the semaphore) and from within interrupt\r
- * service routines.\r
- *\r
- * @return xSemaphore Handle to the created mutex semaphore. Should be of type\r
- * SemaphoreHandle_t.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- // Semaphore cannot be used before a call to xSemaphoreCreateMutex().\r
- // This is a macro so pass the variable in directly.\r
- xSemaphore = xSemaphoreCreateRecursiveMutex();\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre>\r
- *\r
- * <i>Macro</i> that creates a counting semaphore by using the existing\r
- * queue mechanism.\r
- *\r
- * Counting semaphores are typically used for two things:\r
- *\r
- * 1) Counting events.\r
- *\r
- * In this usage scenario an event handler will 'give' a semaphore each time\r
- * an event occurs (incrementing the semaphore count value), and a handler\r
- * task will 'take' a semaphore each time it processes an event\r
- * (decrementing the semaphore count value). The count value is therefore\r
- * the difference between the number of events that have occurred and the\r
- * number that have been processed. In this case it is desirable for the\r
- * initial count value to be zero.\r
- *\r
- * 2) Resource management.\r
- *\r
- * In this usage scenario the count value indicates the number of resources\r
- * available. To obtain control of a resource a task must first obtain a\r
- * semaphore - decrementing the semaphore count value. When the count value\r
- * reaches zero there are no free resources. When a task finishes with the\r
- * resource it 'gives' the semaphore back - incrementing the semaphore count\r
- * value. In this case it is desirable for the initial count value to be\r
- * equal to the maximum count value, indicating that all resources are free.\r
- *\r
- * @param uxMaxCount The maximum count value that can be reached. When the\r
- * semaphore reaches this value it can no longer be 'given'.\r
- *\r
- * @param uxInitialCount The count value assigned to the semaphore when it is\r
- * created.\r
- *\r
- * @return Handle to the created semaphore. Null if the semaphore could not be\r
- * created.\r
- *\r
- * Example usage:\r
- <pre>\r
- SemaphoreHandle_t xSemaphore;\r
-\r
- void vATask( void * pvParameters )\r
- {\r
- SemaphoreHandle_t xSemaphore = NULL;\r
-\r
- // Semaphore cannot be used before a call to xSemaphoreCreateCounting().\r
- // The max value to which the semaphore can count should be 10, and the\r
- // initial value assigned to the count should be 0.\r
- xSemaphore = xSemaphoreCreateCounting( 10, 0 );\r
-\r
- if( xSemaphore != NULL )\r
- {\r
- // The semaphore was created successfully.\r
- // The semaphore can now be used.\r
- }\r
- }\r
- </pre>\r
- * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting\r
- * \ingroup Semaphores\r
- */\r
-#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )\r
-\r
-/**\r
- * semphr. h\r
- * <pre>void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );</pre>\r
- *\r
- * Delete a semaphore. This function must be used with care. For example,\r
- * do not delete a mutex type semaphore if the mutex is held by a task.\r
- *\r
- * @param xSemaphore A handle to the semaphore to be deleted.\r
- *\r
- * \defgroup vSemaphoreDelete vSemaphoreDelete\r
- * \ingroup Semaphores\r
- */\r
-#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )\r
-\r
-/**\r
- * semphr.h\r
- * <pre>TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );</pre>\r
- *\r
- * If xMutex is indeed a mutex type semaphore, return the current mutex holder.\r
- * If xMutex is not a mutex type semaphore, or the mutex is available (not held\r
- * by a task), return NULL.\r
- *\r
- * Note: This is a good way of determining if the calling task is the mutex\r
- * holder, but not a good way of determining the identity of the mutex holder as\r
- * the holder may change between the function exiting and the returned value\r
- * being tested.\r
- */\r
-#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )\r
-\r
-#endif /* SEMAPHORE_H */\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-\r
-#ifndef INC_TASK_H\r
-#define INC_TASK_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include task.h"\r
-#endif\r
-\r
-#include "list.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * MACROS AND DEFINITIONS\r
- *----------------------------------------------------------*/\r
-\r
-#define tskKERNEL_VERSION_NUMBER "V8.2.1"\r
-#define tskKERNEL_VERSION_MAJOR 8\r
-#define tskKERNEL_VERSION_MINOR 2\r
-#define tskKERNEL_VERSION_BUILD 1\r
-\r
-/**\r
- * task. h\r
- *\r
- * Type by which tasks are referenced. For example, a call to xTaskCreate\r
- * returns (via a pointer parameter) an TaskHandle_t variable that can then\r
- * be used as a parameter to vTaskDelete to delete the task.\r
- *\r
- * \defgroup TaskHandle_t TaskHandle_t\r
- * \ingroup Tasks\r
- */\r
-typedef void * TaskHandle_t;\r
-\r
-/*\r
- * Defines the prototype to which the application task hook function must\r
- * conform.\r
- */\r
-typedef BaseType_t (*TaskHookFunction_t)( void * );\r
-\r
-/* Task states returned by eTaskGetState. */\r
-typedef enum\r
-{\r
- eRunning = 0, /* A task is querying the state of itself, so must be running. */\r
- eReady, /* The task being queried is in a read or pending ready list. */\r
- eBlocked, /* The task being queried is in the Blocked state. */\r
- eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */\r
- eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */\r
-} eTaskState;\r
-\r
-/* Actions that can be performed when vTaskNotify() is called. */\r
-typedef enum\r
-{\r
- eNoAction = 0, /* Notify the task without updating its notify value. */\r
- eSetBits, /* Set bits in the task's notification value. */\r
- eIncrement, /* Increment the task's notification value. */\r
- eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */\r
- eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */\r
-} eNotifyAction;\r
-\r
-/*\r
- * Used internally only.\r
- */\r
-typedef struct xTIME_OUT\r
-{\r
- BaseType_t xOverflowCount;\r
- TickType_t xTimeOnEntering;\r
-} TimeOut_t;\r
-\r
-/*\r
- * Defines the memory ranges allocated to the task when an MPU is used.\r
- */\r
-typedef struct xMEMORY_REGION\r
-{\r
- void *pvBaseAddress;\r
- uint32_t ulLengthInBytes;\r
- uint32_t ulParameters;\r
-} MemoryRegion_t;\r
-\r
-/*\r
- * Parameters required to create an MPU protected task.\r
- */\r
-typedef struct xTASK_PARAMETERS\r
-{\r
- TaskFunction_t pvTaskCode;\r
- const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
- uint16_t usStackDepth;\r
- void *pvParameters;\r
- UBaseType_t uxPriority;\r
- StackType_t *puxStackBuffer;\r
- MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ];\r
-} TaskParameters_t;\r
-\r
-/* Used with the uxTaskGetSystemState() function to return the state of each task\r
-in the system. */\r
-typedef struct xTASK_STATUS\r
-{\r
- TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */\r
- const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
- UBaseType_t xTaskNumber; /* A number unique to the task. */\r
- eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */\r
- UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */\r
- UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */\r
- uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */\r
- uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */\r
-} TaskStatus_t;\r
-\r
-/* Possible return values for eTaskConfirmSleepModeStatus(). */\r
-typedef enum\r
-{\r
- eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */\r
- eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */\r
- eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */\r
-} eSleepModeStatus;\r
-\r
-\r
-/**\r
- * Defines the priority used by the idle task. This must not be modified.\r
- *\r
- * \ingroup TaskUtils\r
- */\r
-#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U )\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro for forcing a context switch.\r
- *\r
- * \defgroup taskYIELD taskYIELD\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskYIELD() portYIELD()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to mark the start of a critical code region. Preemptive context\r
- * switches cannot occur when in a critical region.\r
- *\r
- * NOTE: This may alter the stack (depending on the portable implementation)\r
- * so must be used with care!\r
- *\r
- * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskENTER_CRITICAL() portENTER_CRITICAL()\r
-#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to mark the end of a critical code region. Preemptive context\r
- * switches cannot occur when in a critical region.\r
- *\r
- * NOTE: This may alter the stack (depending on the portable implementation)\r
- * so must be used with care!\r
- *\r
- * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskEXIT_CRITICAL() portEXIT_CRITICAL()\r
-#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )\r
-/**\r
- * task. h\r
- *\r
- * Macro to disable all maskable interrupts.\r
- *\r
- * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS()\r
-\r
-/**\r
- * task. h\r
- *\r
- * Macro to enable microcontroller interrupts.\r
- *\r
- * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS\r
- * \ingroup SchedulerControl\r
- */\r
-#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()\r
-\r
-/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is\r
-0 to generate more optimal code when configASSERT() is defined as the constant\r
-is used in assert() statements. */\r
-#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 )\r
-#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 )\r
-#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 )\r
-\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CREATION API\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- BaseType_t xTaskCreate(\r
- TaskFunction_t pvTaskCode,\r
- const char * const pcName,\r
- uint16_t usStackDepth,\r
- void *pvParameters,\r
- UBaseType_t uxPriority,\r
- TaskHandle_t *pvCreatedTask\r
- );</pre>\r
- *\r
- * Create a new task and add it to the list of tasks that are ready to run.\r
- *\r
- * xTaskCreate() can only be used to create a task that has unrestricted\r
- * access to the entire microcontroller memory map. Systems that include MPU\r
- * support can alternatively create an MPU constrained task using\r
- * xTaskCreateRestricted().\r
- *\r
- * @param pvTaskCode Pointer to the task entry function. Tasks\r
- * must be implemented to never return (i.e. continuous loop).\r
- *\r
- * @param pcName A descriptive name for the task. This is mainly used to\r
- * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default\r
- * is 16.\r
- *\r
- * @param usStackDepth The size of the task stack specified as the number of\r
- * variables the stack can hold - not the number of bytes. For example, if\r
- * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes\r
- * will be allocated for stack storage.\r
- *\r
- * @param pvParameters Pointer that will be used as the parameter for the task\r
- * being created.\r
- *\r
- * @param uxPriority The priority at which the task should run. Systems that\r
- * include MPU support can optionally create tasks in a privileged (system)\r
- * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For\r
- * example, to create a privileged task at priority 2 the uxPriority parameter\r
- * should be set to ( 2 | portPRIVILEGE_BIT ).\r
- *\r
- * @param pvCreatedTask Used to pass back a handle by which the created task\r
- * can be referenced.\r
- *\r
- * @return pdPASS if the task was successfully created and added to a ready\r
- * list, otherwise an error code defined in the file projdefs.h\r
- *\r
- * Example usage:\r
- <pre>\r
- // Task to be created.\r
- void vTaskCode( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
- }\r
- }\r
-\r
- // Function that creates a task.\r
- void vOtherFunction( void )\r
- {\r
- static uint8_t ucParameterToPass;\r
- TaskHandle_t xHandle = NULL;\r
-\r
- // Create the task, storing the handle. Note that the passed parameter ucParameterToPass\r
- // must exist for the lifetime of the task, so in this case is declared static. If it was just an\r
- // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time\r
- // the new task attempts to access it.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );\r
- configASSERT( xHandle );\r
-\r
- // Use the handle to delete the task.\r
- if( xHandle != NULL )\r
- {\r
- vTaskDelete( xHandle );\r
- }\r
- }\r
- </pre>\r
- * \defgroup xTaskCreate xTaskCreate\r
- * \ingroup Tasks\r
- */\r
-#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );</pre>\r
- *\r
- * xTaskCreateRestricted() should only be used in systems that include an MPU\r
- * implementation.\r
- *\r
- * Create a new task and add it to the list of tasks that are ready to run.\r
- * The function parameters define the memory regions and associated access\r
- * permissions allocated to the task.\r
- *\r
- * @param pxTaskDefinition Pointer to a structure that contains a member\r
- * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API\r
- * documentation) plus an optional stack buffer and the memory region\r
- * definitions.\r
- *\r
- * @param pxCreatedTask Used to pass back a handle by which the created task\r
- * can be referenced.\r
- *\r
- * @return pdPASS if the task was successfully created and added to a ready\r
- * list, otherwise an error code defined in the file projdefs.h\r
- *\r
- * Example usage:\r
- <pre>\r
-// Create an TaskParameters_t structure that defines the task to be created.\r
-static const TaskParameters_t xCheckTaskParameters =\r
-{\r
- vATask, // pvTaskCode - the function that implements the task.\r
- "ATask", // pcName - just a text name for the task to assist debugging.\r
- 100, // usStackDepth - the stack size DEFINED IN WORDS.\r
- NULL, // pvParameters - passed into the task function as the function parameters.\r
- ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.\r
- cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.\r
-\r
- // xRegions - Allocate up to three separate memory regions for access by\r
- // the task, with appropriate access permissions. Different processors have\r
- // different memory alignment requirements - refer to the FreeRTOS documentation\r
- // for full information.\r
- {\r
- // Base address Length Parameters\r
- { cReadWriteArray, 32, portMPU_REGION_READ_WRITE },\r
- { cReadOnlyArray, 32, portMPU_REGION_READ_ONLY },\r
- { cPrivilegedOnlyAccessArray, 128, portMPU_REGION_PRIVILEGED_READ_WRITE }\r
- }\r
-};\r
-\r
-int main( void )\r
-{\r
-TaskHandle_t xHandle;\r
-\r
- // Create a task from the const structure defined above. The task handle\r
- // is requested (the second parameter is not NULL) but in this case just for\r
- // demonstration purposes as its not actually used.\r
- xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );\r
-\r
- // Start the scheduler.\r
- vTaskStartScheduler();\r
-\r
- // Will only get here if there was insufficient memory to create the idle\r
- // and/or timer task.\r
- for( ;; );\r
-}\r
- </pre>\r
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
- * \ingroup Tasks\r
- */\r
-#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) )\r
-\r
-/**\r
- * task. h\r
- *<pre>\r
- void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );</pre>\r
- *\r
- * Memory regions are assigned to a restricted task when the task is created by\r
- * a call to xTaskCreateRestricted(). These regions can be redefined using\r
- * vTaskAllocateMPURegions().\r
- *\r
- * @param xTask The handle of the task being updated.\r
- *\r
- * @param xRegions A pointer to an MemoryRegion_t structure that contains the\r
- * new memory region definitions.\r
- *\r
- * Example usage:\r
- <pre>\r
-// Define an array of MemoryRegion_t structures that configures an MPU region\r
-// allowing read/write access for 1024 bytes starting at the beginning of the\r
-// ucOneKByte array. The other two of the maximum 3 definable regions are\r
-// unused so set to zero.\r
-static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =\r
-{\r
- // Base address Length Parameters\r
- { ucOneKByte, 1024, portMPU_REGION_READ_WRITE },\r
- { 0, 0, 0 },\r
- { 0, 0, 0 }\r
-};\r
-\r
-void vATask( void *pvParameters )\r
-{\r
- // This task was created such that it has access to certain regions of\r
- // memory as defined by the MPU configuration. At some point it is\r
- // desired that these MPU regions are replaced with that defined in the\r
- // xAltRegions const struct above. Use a call to vTaskAllocateMPURegions()\r
- // for this purpose. NULL is used as the task handle to indicate that this\r
- // function should modify the MPU regions of the calling task.\r
- vTaskAllocateMPURegions( NULL, xAltRegions );\r
-\r
- // Now the task can continue its function, but from this point on can only\r
- // access its stack and the ucOneKByte array (unless any other statically\r
- // defined or shared regions have been declared elsewhere).\r
-}\r
- </pre>\r
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted\r
- * \ingroup Tasks\r
- */\r
-void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelete( TaskHandle_t xTask );</pre>\r
- *\r
- * INCLUDE_vTaskDelete must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Remove a task from the RTOS real time kernel's management. The task being\r
- * deleted will be removed from all ready, blocked, suspended and event lists.\r
- *\r
- * NOTE: The idle task is responsible for freeing the kernel allocated\r
- * memory from tasks that have been deleted. It is therefore important that\r
- * the idle task is not starved of microcontroller processing time if your\r
- * application makes any calls to vTaskDelete (). Memory allocated by the\r
- * task code is not automatically freed, and should be freed before the task\r
- * is deleted.\r
- *\r
- * See the demo application file death.c for sample code that utilises\r
- * vTaskDelete ().\r
- *\r
- * @param xTask The handle of the task to be deleted. Passing NULL will\r
- * cause the calling task to be deleted.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vOtherFunction( void )\r
- {\r
- TaskHandle_t xHandle;\r
-\r
- // Create the task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // Use the handle to delete the task.\r
- vTaskDelete( xHandle );\r
- }\r
- </pre>\r
- * \defgroup vTaskDelete vTaskDelete\r
- * \ingroup Tasks\r
- */\r
-void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * TASK CONTROL API\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelay( const TickType_t xTicksToDelay );</pre>\r
- *\r
- * Delay a task for a given number of ticks. The actual time that the\r
- * task remains blocked depends on the tick rate. The constant\r
- * portTICK_PERIOD_MS can be used to calculate real time from the tick\r
- * rate - with the resolution of one tick period.\r
- *\r
- * INCLUDE_vTaskDelay must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- *\r
- * vTaskDelay() specifies a time at which the task wishes to unblock relative to\r
- * the time at which vTaskDelay() is called. For example, specifying a block\r
- * period of 100 ticks will cause the task to unblock 100 ticks after\r
- * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method\r
- * of controlling the frequency of a periodic task as the path taken through the\r
- * code, as well as other task and interrupt activity, will effect the frequency\r
- * at which vTaskDelay() gets called and therefore the time at which the task\r
- * next executes. See vTaskDelayUntil() for an alternative API function designed\r
- * to facilitate fixed frequency execution. It does this by specifying an\r
- * absolute time (rather than a relative time) at which the calling task should\r
- * unblock.\r
- *\r
- * @param xTicksToDelay The amount of time, in tick periods, that\r
- * the calling task should block.\r
- *\r
- * Example usage:\r
-\r
- void vTaskFunction( void * pvParameters )\r
- {\r
- // Block for 500ms.\r
- const TickType_t xDelay = 500 / portTICK_PERIOD_MS;\r
-\r
- for( ;; )\r
- {\r
- // Simply toggle the LED every 500ms, blocking between each toggle.\r
- vToggleLED();\r
- vTaskDelay( xDelay );\r
- }\r
- }\r
-\r
- * \defgroup vTaskDelay vTaskDelay\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );</pre>\r
- *\r
- * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Delay a task until a specified time. This function can be used by periodic\r
- * tasks to ensure a constant execution frequency.\r
- *\r
- * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will\r
- * cause a task to block for the specified number of ticks from the time vTaskDelay () is\r
- * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed\r
- * execution frequency as the time between a task starting to execute and that task\r
- * calling vTaskDelay () may not be fixed [the task may take a different path though the\r
- * code between calls, or may get interrupted or preempted a different number of times\r
- * each time it executes].\r
- *\r
- * Whereas vTaskDelay () specifies a wake time relative to the time at which the function\r
- * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to\r
- * unblock.\r
- *\r
- * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick\r
- * rate - with the resolution of one tick period.\r
- *\r
- * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the\r
- * task was last unblocked. The variable must be initialised with the current time\r
- * prior to its first use (see the example below). Following this the variable is\r
- * automatically updated within vTaskDelayUntil ().\r
- *\r
- * @param xTimeIncrement The cycle time period. The task will be unblocked at\r
- * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the\r
- * same xTimeIncrement parameter value will cause the task to execute with\r
- * a fixed interface period.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Perform an action every 10 ticks.\r
- void vTaskFunction( void * pvParameters )\r
- {\r
- TickType_t xLastWakeTime;\r
- const TickType_t xFrequency = 10;\r
-\r
- // Initialise the xLastWakeTime variable with the current time.\r
- xLastWakeTime = xTaskGetTickCount ();\r
- for( ;; )\r
- {\r
- // Wait for the next cycle.\r
- vTaskDelayUntil( &xLastWakeTime, xFrequency );\r
-\r
- // Perform action here.\r
- }\r
- }\r
- </pre>\r
- * \defgroup vTaskDelayUntil vTaskDelayUntil\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );</pre>\r
- *\r
- * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Obtain the priority of any task.\r
- *\r
- * @param xTask Handle of the task to be queried. Passing a NULL\r
- * handle results in the priority of the calling task being returned.\r
- *\r
- * @return The priority of xTask.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- TaskHandle_t xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to obtain the priority of the created task.\r
- // It was created with tskIDLE_PRIORITY, but may have changed\r
- // it itself.\r
- if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )\r
- {\r
- // The task has changed it's priority.\r
- }\r
-\r
- // ...\r
-\r
- // Is our priority higher than the created task?\r
- if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )\r
- {\r
- // Our priority (obtained using NULL handle) is higher.\r
- }\r
- }\r
- </pre>\r
- * \defgroup uxTaskPriorityGet uxTaskPriorityGet\r
- * \ingroup TaskCtrl\r
- */\r
-UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask );</pre>\r
- *\r
- * A version of uxTaskPriorityGet() that can be used from an ISR.\r
- */\r
-UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>eTaskState eTaskGetState( TaskHandle_t xTask );</pre>\r
- *\r
- * INCLUDE_eTaskGetState must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Obtain the state of any task. States are encoded by the eTaskState\r
- * enumerated type.\r
- *\r
- * @param xTask Handle of the task to be queried.\r
- *\r
- * @return The state of xTask at the time the function was called. Note the\r
- * state of the task might change between the function being called, and the\r
- * functions return value being tested by the calling task.\r
- */\r
-eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );</pre>\r
- *\r
- * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Set the priority of any task.\r
- *\r
- * A context switch will occur before the function returns if the priority\r
- * being set is higher than the currently executing task.\r
- *\r
- * @param xTask Handle to the task for which the priority is being set.\r
- * Passing a NULL handle results in the priority of the calling task being set.\r
- *\r
- * @param uxNewPriority The priority to which the task will be set.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- TaskHandle_t xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to raise the priority of the created task.\r
- vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );\r
-\r
- // ...\r
-\r
- // Use a NULL handle to raise our priority to the same value.\r
- vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );\r
- }\r
- </pre>\r
- * \defgroup vTaskPrioritySet vTaskPrioritySet\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskSuspend( TaskHandle_t xTaskToSuspend );</pre>\r
- *\r
- * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Suspend any task. When suspended a task will never get any microcontroller\r
- * processing time, no matter what its priority.\r
- *\r
- * Calls to vTaskSuspend are not accumulative -\r
- * i.e. calling vTaskSuspend () twice on the same task still only requires one\r
- * call to vTaskResume () to ready the suspended task.\r
- *\r
- * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL\r
- * handle will cause the calling task to be suspended.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- TaskHandle_t xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to suspend the created task.\r
- vTaskSuspend( xHandle );\r
-\r
- // ...\r
-\r
- // The created task will not run during this period, unless\r
- // another task calls vTaskResume( xHandle ).\r
-\r
- //...\r
-\r
-\r
- // Suspend ourselves.\r
- vTaskSuspend( NULL );\r
-\r
- // We cannot get here unless another task calls vTaskResume\r
- // with our handle as the parameter.\r
- }\r
- </pre>\r
- * \defgroup vTaskSuspend vTaskSuspend\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskResume( TaskHandle_t xTaskToResume );</pre>\r
- *\r
- * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available.\r
- * See the configuration section for more information.\r
- *\r
- * Resumes a suspended task.\r
- *\r
- * A task that has been suspended by one or more calls to vTaskSuspend ()\r
- * will be made available for running again by a single call to\r
- * vTaskResume ().\r
- *\r
- * @param xTaskToResume Handle to the task being readied.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- TaskHandle_t xHandle;\r
-\r
- // Create a task, storing the handle.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );\r
-\r
- // ...\r
-\r
- // Use the handle to suspend the created task.\r
- vTaskSuspend( xHandle );\r
-\r
- // ...\r
-\r
- // The created task will not run during this period, unless\r
- // another task calls vTaskResume( xHandle ).\r
-\r
- //...\r
-\r
-\r
- // Resume the suspended task ourselves.\r
- vTaskResume( xHandle );\r
-\r
- // The created task will once again get microcontroller processing\r
- // time in accordance with its priority within the system.\r
- }\r
- </pre>\r
- * \defgroup vTaskResume vTaskResume\r
- * \ingroup TaskCtrl\r
- */\r
-void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void xTaskResumeFromISR( TaskHandle_t xTaskToResume );</pre>\r
- *\r
- * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be\r
- * available. See the configuration section for more information.\r
- *\r
- * An implementation of vTaskResume() that can be called from within an ISR.\r
- *\r
- * A task that has been suspended by one or more calls to vTaskSuspend ()\r
- * will be made available for running again by a single call to\r
- * xTaskResumeFromISR ().\r
- *\r
- * xTaskResumeFromISR() should not be used to synchronise a task with an\r
- * interrupt if there is a chance that the interrupt could arrive prior to the\r
- * task being suspended - as this can lead to interrupts being missed. Use of a\r
- * semaphore as a synchronisation mechanism would avoid this eventuality.\r
- *\r
- * @param xTaskToResume Handle to the task being readied.\r
- *\r
- * @return pdTRUE if resuming the task should result in a context switch,\r
- * otherwise pdFALSE. This is used by the ISR to determine if a context switch\r
- * may be required following the ISR.\r
- *\r
- * \defgroup vTaskResumeFromISR vTaskResumeFromISR\r
- * \ingroup TaskCtrl\r
- */\r
-BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER CONTROL\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskStartScheduler( void );</pre>\r
- *\r
- * Starts the real time kernel tick processing. After calling the kernel\r
- * has control over which tasks are executed and when.\r
- *\r
- * See the demo application file main.c for an example of creating\r
- * tasks and starting the kernel.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vAFunction( void )\r
- {\r
- // Create at least one task before starting the kernel.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
-\r
- // Start the real time kernel with preemption.\r
- vTaskStartScheduler ();\r
-\r
- // Will not get here unless a task calls vTaskEndScheduler ()\r
- }\r
- </pre>\r
- *\r
- * \defgroup vTaskStartScheduler vTaskStartScheduler\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskEndScheduler( void );</pre>\r
- *\r
- * NOTE: At the time of writing only the x86 real mode port, which runs on a PC\r
- * in place of DOS, implements this function.\r
- *\r
- * Stops the real time kernel tick. All created tasks will be automatically\r
- * deleted and multitasking (either preemptive or cooperative) will\r
- * stop. Execution then resumes from the point where vTaskStartScheduler ()\r
- * was called, as if vTaskStartScheduler () had just returned.\r
- *\r
- * See the demo application file main. c in the demo/PC directory for an\r
- * example that uses vTaskEndScheduler ().\r
- *\r
- * vTaskEndScheduler () requires an exit function to be defined within the\r
- * portable layer (see vPortEndScheduler () in port. c for the PC port). This\r
- * performs hardware specific operations such as stopping the kernel tick.\r
- *\r
- * vTaskEndScheduler () will cause all of the resources allocated by the\r
- * kernel to be freed - but will not free resources allocated by application\r
- * tasks.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTaskCode( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // At some point we want to end the real time kernel processing\r
- // so call ...\r
- vTaskEndScheduler ();\r
- }\r
- }\r
-\r
- void vAFunction( void )\r
- {\r
- // Create at least one task before starting the kernel.\r
- xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
-\r
- // Start the real time kernel with preemption.\r
- vTaskStartScheduler ();\r
-\r
- // Will only get here when the vTaskCode () task has called\r
- // vTaskEndScheduler (). When we get here we are back to single task\r
- // execution.\r
- }\r
- </pre>\r
- *\r
- * \defgroup vTaskEndScheduler vTaskEndScheduler\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>void vTaskSuspendAll( void );</pre>\r
- *\r
- * Suspends the scheduler without disabling interrupts. Context switches will\r
- * not occur while the scheduler is suspended.\r
- *\r
- * After calling vTaskSuspendAll () the calling task will continue to execute\r
- * without risk of being swapped out until a call to xTaskResumeAll () has been\r
- * made.\r
- *\r
- * API functions that have the potential to cause a context switch (for example,\r
- * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler\r
- * is suspended.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTask1( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // ...\r
-\r
- // At some point the task wants to perform a long operation during\r
- // which it does not want to get swapped out. It cannot use\r
- // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
- // operation may cause interrupts to be missed - including the\r
- // ticks.\r
-\r
- // Prevent the real time kernel swapping out the task.\r
- vTaskSuspendAll ();\r
-\r
- // Perform the operation here. There is no need to use critical\r
- // sections as we have all the microcontroller processing time.\r
- // During this time interrupts will still operate and the kernel\r
- // tick count will be maintained.\r
-\r
- // ...\r
-\r
- // The operation is complete. Restart the kernel.\r
- xTaskResumeAll ();\r
- }\r
- }\r
- </pre>\r
- * \defgroup vTaskSuspendAll vTaskSuspendAll\r
- * \ingroup SchedulerControl\r
- */\r
-void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <pre>BaseType_t xTaskResumeAll( void );</pre>\r
- *\r
- * Resumes scheduler activity after it was suspended by a call to\r
- * vTaskSuspendAll().\r
- *\r
- * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks\r
- * that were previously suspended by a call to vTaskSuspend().\r
- *\r
- * @return If resuming the scheduler caused a context switch then pdTRUE is\r
- * returned, otherwise pdFALSE is returned.\r
- *\r
- * Example usage:\r
- <pre>\r
- void vTask1( void * pvParameters )\r
- {\r
- for( ;; )\r
- {\r
- // Task code goes here.\r
-\r
- // ...\r
-\r
- // At some point the task wants to perform a long operation during\r
- // which it does not want to get swapped out. It cannot use\r
- // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the\r
- // operation may cause interrupts to be missed - including the\r
- // ticks.\r
-\r
- // Prevent the real time kernel swapping out the task.\r
- vTaskSuspendAll ();\r
-\r
- // Perform the operation here. There is no need to use critical\r
- // sections as we have all the microcontroller processing time.\r
- // During this time interrupts will still operate and the real\r
- // time kernel tick count will be maintained.\r
-\r
- // ...\r
-\r
- // The operation is complete. Restart the kernel. We want to force\r
- // a context switch - but there is no point if resuming the scheduler\r
- // caused a context switch already.\r
- if( !xTaskResumeAll () )\r
- {\r
- taskYIELD ();\r
- }\r
- }\r
- }\r
- </pre>\r
- * \defgroup xTaskResumeAll xTaskResumeAll\r
- * \ingroup SchedulerControl\r
- */\r
-BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * TASK UTILITIES\r
- *----------------------------------------------------------*/\r
-\r
-/**\r
- * task. h\r
- * <PRE>TickType_t xTaskGetTickCount( void );</PRE>\r
- *\r
- * @return The count of ticks since vTaskStartScheduler was called.\r
- *\r
- * \defgroup xTaskGetTickCount xTaskGetTickCount\r
- * \ingroup TaskUtils\r
- */\r
-TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>TickType_t xTaskGetTickCountFromISR( void );</PRE>\r
- *\r
- * @return The count of ticks since vTaskStartScheduler was called.\r
- *\r
- * This is a version of xTaskGetTickCount() that is safe to be called from an\r
- * ISR - provided that TickType_t is the natural word size of the\r
- * microcontroller being used or interrupt nesting is either not supported or\r
- * not being used.\r
- *\r
- * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR\r
- * \ingroup TaskUtils\r
- */\r
-TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>uint16_t uxTaskGetNumberOfTasks( void );</PRE>\r
- *\r
- * @return The number of tasks that the real time kernel is currently managing.\r
- * This includes all ready, blocked and suspended tasks. A task that\r
- * has been deleted but not yet freed by the idle task will also be\r
- * included in the count.\r
- *\r
- * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks\r
- * \ingroup TaskUtils\r
- */\r
-UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery );</PRE>\r
- *\r
- * @return The text (human readable) name of the task referenced by the handle\r
- * xTaskToQuery. A task can query its own name by either passing in its own\r
- * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be\r
- * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available.\r
- *\r
- * \defgroup pcTaskGetTaskName pcTaskGetTaskName\r
- * \ingroup TaskUtils\r
- */\r
-char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/**\r
- * task.h\r
- * <PRE>UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );</PRE>\r
- *\r
- * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for\r
- * this function to be available.\r
- *\r
- * Returns the high water mark of the stack associated with xTask. That is,\r
- * the minimum free stack space there has been (in words, so on a 32 bit machine\r
- * a value of 1 means 4 bytes) since the task started. The smaller the returned\r
- * number the closer the task has come to overflowing its stack.\r
- *\r
- * @param xTask Handle of the task associated with the stack to be checked.\r
- * Set xTask to NULL to check the stack of the calling task.\r
- *\r
- * @return The smallest amount of free stack space there has been (in words, so\r
- * actual spaces on the stack rather than bytes) since the task referenced by\r
- * xTask was created.\r
- */\r
-UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/* When using trace macros it is sometimes necessary to include task.h before\r
-FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined,\r
-so the following two prototypes will cause a compilation error. This can be\r
-fixed by simply guarding against the inclusion of these two prototypes unless\r
-they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration\r
-constant. */\r
-#ifdef configUSE_APPLICATION_TASK_TAG\r
- #if configUSE_APPLICATION_TASK_TAG == 1\r
- /**\r
- * task.h\r
- * <pre>void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );</pre>\r
- *\r
- * Sets pxHookFunction to be the task hook function used by the task xTask.\r
- * Passing xTask as NULL has the effect of setting the calling tasks hook\r
- * function.\r
- */\r
- void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION;\r
-\r
- /**\r
- * task.h\r
- * <pre>void xTaskGetApplicationTaskTag( TaskHandle_t xTask );</pre>\r
- *\r
- * Returns the pxHookFunction value assigned to the task xTask.\r
- */\r
- TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
- #endif /* configUSE_APPLICATION_TASK_TAG ==1 */\r
-#endif /* ifdef configUSE_APPLICATION_TASK_TAG */\r
-\r
-#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )\r
-\r
- /* Each task contains an array of pointers that is dimensioned by the\r
- configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The\r
- kernel does not use the pointers itself, so the application writer can use\r
- the pointers for any purpose they wish. The following two functions are\r
- used to set and query a pointer respectively. */\r
- void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION;\r
- void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION;\r
-\r
-#endif\r
-\r
-/**\r
- * task.h\r
- * <pre>BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );</pre>\r
- *\r
- * Calls the hook function associated with xTask. Passing xTask as NULL has\r
- * the effect of calling the Running tasks (the calling task) hook function.\r
- *\r
- * pvParameter is passed to the hook function for the task to interpret as it\r
- * wants. The return value is the value returned by the task hook function\r
- * registered by the user.\r
- */\r
-BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * xTaskGetIdleTaskHandle() is only available if\r
- * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.\r
- *\r
- * Simply returns the handle of the idle task. It is not valid to call\r
- * xTaskGetIdleTaskHandle() before the scheduler has been started.\r
- */\r
-TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for\r
- * uxTaskGetSystemState() to be available.\r
- *\r
- * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in\r
- * the system. TaskStatus_t structures contain, among other things, members\r
- * for the task handle, task name, task priority, task state, and total amount\r
- * of run time consumed by the task. See the TaskStatus_t structure\r
- * definition in this file for the full member list.\r
- *\r
- * NOTE: This function is intended for debugging use only as its use results in\r
- * the scheduler remaining suspended for an extended period.\r
- *\r
- * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures.\r
- * The array must contain at least one TaskStatus_t structure for each task\r
- * that is under the control of the RTOS. The number of tasks under the control\r
- * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function.\r
- *\r
- * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray\r
- * parameter. The size is specified as the number of indexes in the array, or\r
- * the number of TaskStatus_t structures contained in the array, not by the\r
- * number of bytes in the array.\r
- *\r
- * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in\r
- * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the\r
- * total run time (as defined by the run time stats clock, see\r
- * http://www.freertos.org/rtos-run-time-stats.html) since the target booted.\r
- * pulTotalRunTime can be set to NULL to omit the total run time information.\r
- *\r
- * @return The number of TaskStatus_t structures that were populated by\r
- * uxTaskGetSystemState(). This should equal the number returned by the\r
- * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed\r
- * in the uxArraySize parameter was too small.\r
- *\r
- * Example usage:\r
- <pre>\r
- // This example demonstrates how a human readable table of run time stats\r
- // information is generated from raw data provided by uxTaskGetSystemState().\r
- // The human readable table is written to pcWriteBuffer\r
- void vTaskGetRunTimeStats( char *pcWriteBuffer )\r
- {\r
- TaskStatus_t *pxTaskStatusArray;\r
- volatile UBaseType_t uxArraySize, x;\r
- uint32_t ulTotalRunTime, ulStatsAsPercentage;\r
-\r
- // Make sure the write buffer does not contain a string.\r
- *pcWriteBuffer = 0x00;\r
-\r
- // Take a snapshot of the number of tasks in case it changes while this\r
- // function is executing.\r
- uxArraySize = uxTaskGetNumberOfTasks();\r
-\r
- // Allocate a TaskStatus_t structure for each task. An array could be\r
- // allocated statically at compile time.\r
- pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );\r
-\r
- if( pxTaskStatusArray != NULL )\r
- {\r
- // Generate raw status information about each task.\r
- uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );\r
-\r
- // For percentage calculations.\r
- ulTotalRunTime /= 100UL;\r
-\r
- // Avoid divide by zero errors.\r
- if( ulTotalRunTime > 0 )\r
- {\r
- // For each populated position in the pxTaskStatusArray array,\r
- // format the raw data as human readable ASCII data\r
- for( x = 0; x < uxArraySize; x++ )\r
- {\r
- // What percentage of the total run time has the task used?\r
- // This will always be rounded down to the nearest integer.\r
- // ulTotalRunTimeDiv100 has already been divided by 100.\r
- ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;\r
-\r
- if( ulStatsAsPercentage > 0UL )\r
- {\r
- sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );\r
- }\r
- else\r
- {\r
- // If the percentage is zero here then the task has\r
- // consumed less than 1% of the total run time.\r
- sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );\r
- }\r
-\r
- pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );\r
- }\r
- }\r
-\r
- // The array is no longer needed, free the memory it consumes.\r
- vPortFree( pxTaskStatusArray );\r
- }\r
- }\r
- </pre>\r
- */\r
-UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskList( char *pcWriteBuffer );</PRE>\r
- *\r
- * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must\r
- * both be defined as 1 for this function to be available. See the\r
- * configuration section of the FreeRTOS.org website for more information.\r
- *\r
- * NOTE 1: This function will disable interrupts for its duration. It is\r
- * not intended for normal application runtime use but as a debug aid.\r
- *\r
- * Lists all the current tasks, along with their current state and stack\r
- * usage high water mark.\r
- *\r
- * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or\r
- * suspended ('S').\r
- *\r
- * PLEASE NOTE:\r
- *\r
- * This function is provided for convenience only, and is used by many of the\r
- * demo applications. Do not consider it to be part of the scheduler.\r
- *\r
- * vTaskList() calls uxTaskGetSystemState(), then formats part of the\r
- * uxTaskGetSystemState() output into a human readable table that displays task\r
- * names, states and stack usage.\r
- *\r
- * vTaskList() has a dependency on the sprintf() C library function that might\r
- * bloat the code size, use a lot of stack, and provide different results on\r
- * different platforms. An alternative, tiny, third party, and limited\r
- * functionality implementation of sprintf() is provided in many of the\r
- * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note\r
- * printf-stdarg.c does not provide a full snprintf() implementation!).\r
- *\r
- * It is recommended that production systems call uxTaskGetSystemState()\r
- * directly to get access to raw stats data, rather than indirectly through a\r
- * call to vTaskList().\r
- *\r
- * @param pcWriteBuffer A buffer into which the above mentioned details\r
- * will be written, in ASCII form. This buffer is assumed to be large\r
- * enough to contain the generated report. Approximately 40 bytes per\r
- * task should be sufficient.\r
- *\r
- * \defgroup vTaskList vTaskList\r
- * \ingroup TaskUtils\r
- */\r
-void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskGetRunTimeStats( char *pcWriteBuffer );</PRE>\r
- *\r
- * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS\r
- * must both be defined as 1 for this function to be available. The application\r
- * must also then provide definitions for\r
- * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE()\r
- * to configure a peripheral timer/counter and return the timers current count\r
- * value respectively. The counter should be at least 10 times the frequency of\r
- * the tick count.\r
- *\r
- * NOTE 1: This function will disable interrupts for its duration. It is\r
- * not intended for normal application runtime use but as a debug aid.\r
- *\r
- * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total\r
- * accumulated execution time being stored for each task. The resolution\r
- * of the accumulated time value depends on the frequency of the timer\r
- * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro.\r
- * Calling vTaskGetRunTimeStats() writes the total execution time of each\r
- * task into a buffer, both as an absolute count value and as a percentage\r
- * of the total system execution time.\r
- *\r
- * NOTE 2:\r
- *\r
- * This function is provided for convenience only, and is used by many of the\r
- * demo applications. Do not consider it to be part of the scheduler.\r
- *\r
- * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the\r
- * uxTaskGetSystemState() output into a human readable table that displays the\r
- * amount of time each task has spent in the Running state in both absolute and\r
- * percentage terms.\r
- *\r
- * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function\r
- * that might bloat the code size, use a lot of stack, and provide different\r
- * results on different platforms. An alternative, tiny, third party, and\r
- * limited functionality implementation of sprintf() is provided in many of the\r
- * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note\r
- * printf-stdarg.c does not provide a full snprintf() implementation!).\r
- *\r
- * It is recommended that production systems call uxTaskGetSystemState() directly\r
- * to get access to raw stats data, rather than indirectly through a call to\r
- * vTaskGetRunTimeStats().\r
- *\r
- * @param pcWriteBuffer A buffer into which the execution times will be\r
- * written, in ASCII form. This buffer is assumed to be large enough to\r
- * contain the generated report. Approximately 40 bytes per task should\r
- * be sufficient.\r
- *\r
- * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats\r
- * \ingroup TaskUtils\r
- */\r
-void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/**\r
- * task. h\r
- * <PRE>BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );</PRE>\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this\r
- * function to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * A notification sent to a task will remain pending until it is cleared by the\r
- * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was\r
- * already in the Blocked state to wait for a notification when the notification\r
- * arrives then the task will automatically be removed from the Blocked state\r
- * (unblocked) and the notification cleared.\r
- *\r
- * A task can use xTaskNotifyWait() to [optionally] block to wait for a\r
- * notification to be pending, or ulTaskNotifyTake() to [optionally] block\r
- * to wait for its notification value to have a non-zero value. The task does\r
- * not consume any CPU time while it is in the Blocked state.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.\r
- *\r
- * @param xTaskToNotify The handle of the task being notified. The handle to a\r
- * task can be returned from the xTaskCreate() API function used to create the\r
- * task, and the handle of the currently running task can be obtained by calling\r
- * xTaskGetCurrentTaskHandle().\r
- *\r
- * @param ulValue Data that can be sent with the notification. How the data is\r
- * used depends on the value of the eAction parameter.\r
- *\r
- * @param eAction Specifies how the notification updates the task's notification\r
- * value, if at all. Valid values for eAction are as follows:\r
- *\r
- * eSetBits -\r
- * The task's notification value is bitwise ORed with ulValue. xTaskNofify()\r
- * always returns pdPASS in this case.\r
- *\r
- * eIncrement -\r
- * The task's notification value is incremented. ulValue is not used and\r
- * xTaskNotify() always returns pdPASS in this case.\r
- *\r
- * eSetValueWithOverwrite -\r
- * The task's notification value is set to the value of ulValue, even if the\r
- * task being notified had not yet processed the previous notification (the\r
- * task already had a notification pending). xTaskNotify() always returns\r
- * pdPASS in this case.\r
- *\r
- * eSetValueWithoutOverwrite -\r
- * If the task being notified did not already have a notification pending then\r
- * the task's notification value is set to ulValue and xTaskNotify() will\r
- * return pdPASS. If the task being notified already had a notification\r
- * pending then no action is performed and pdFAIL is returned.\r
- *\r
- * eNoAction -\r
- * The task receives a notification without its notification value being\r
- * updated. ulValue is not used and xTaskNotify() always returns pdPASS in\r
- * this case.\r
- *\r
- * pulPreviousNotificationValue -\r
- * Can be used to pass out the subject task's notification value before any\r
- * bits are modified by the notify function.\r
- *\r
- * @return Dependent on the value of eAction. See the description of the\r
- * eAction parameter.\r
- *\r
- * \defgroup xTaskNotify xTaskNotify\r
- * \ingroup TaskNotifications\r
- */\r
-BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;\r
-#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )\r
-#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) )\r
-\r
-/**\r
- * task. h\r
- * <PRE>BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );</PRE>\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this\r
- * function to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * A version of xTaskNotify() that can be used from an interrupt service routine\r
- * (ISR).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * A notification sent to a task will remain pending until it is cleared by the\r
- * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was\r
- * already in the Blocked state to wait for a notification when the notification\r
- * arrives then the task will automatically be removed from the Blocked state\r
- * (unblocked) and the notification cleared.\r
- *\r
- * A task can use xTaskNotifyWait() to [optionally] block to wait for a\r
- * notification to be pending, or ulTaskNotifyTake() to [optionally] block\r
- * to wait for its notification value to have a non-zero value. The task does\r
- * not consume any CPU time while it is in the Blocked state.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.\r
- *\r
- * @param xTaskToNotify The handle of the task being notified. The handle to a\r
- * task can be returned from the xTaskCreate() API function used to create the\r
- * task, and the handle of the currently running task can be obtained by calling\r
- * xTaskGetCurrentTaskHandle().\r
- *\r
- * @param ulValue Data that can be sent with the notification. How the data is\r
- * used depends on the value of the eAction parameter.\r
- *\r
- * @param eAction Specifies how the notification updates the task's notification\r
- * value, if at all. Valid values for eAction are as follows:\r
- *\r
- * eSetBits -\r
- * The task's notification value is bitwise ORed with ulValue. xTaskNofify()\r
- * always returns pdPASS in this case.\r
- *\r
- * eIncrement -\r
- * The task's notification value is incremented. ulValue is not used and\r
- * xTaskNotify() always returns pdPASS in this case.\r
- *\r
- * eSetValueWithOverwrite -\r
- * The task's notification value is set to the value of ulValue, even if the\r
- * task being notified had not yet processed the previous notification (the\r
- * task already had a notification pending). xTaskNotify() always returns\r
- * pdPASS in this case.\r
- *\r
- * eSetValueWithoutOverwrite -\r
- * If the task being notified did not already have a notification pending then\r
- * the task's notification value is set to ulValue and xTaskNotify() will\r
- * return pdPASS. If the task being notified already had a notification\r
- * pending then no action is performed and pdFAIL is returned.\r
- *\r
- * eNoAction -\r
- * The task receives a notification without its notification value being\r
- * updated. ulValue is not used and xTaskNotify() always returns pdPASS in\r
- * this case.\r
- *\r
- * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the\r
- * task to which the notification was sent to leave the Blocked state, and the\r
- * unblocked task has a priority higher than the currently running task. If\r
- * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should\r
- * be requested before the interrupt is exited. How a context switch is\r
- * requested from an ISR is dependent on the port - see the documentation page\r
- * for the port in use.\r
- *\r
- * @return Dependent on the value of eAction. See the description of the\r
- * eAction parameter.\r
- *\r
- * \defgroup xTaskNotify xTaskNotify\r
- * \ingroup TaskNotifications\r
- */\r
-BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )\r
-#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) )\r
-\r
-/**\r
- * task. h\r
- * <PRE>BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );</pre>\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this\r
- * function to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * A notification sent to a task will remain pending until it is cleared by the\r
- * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was\r
- * already in the Blocked state to wait for a notification when the notification\r
- * arrives then the task will automatically be removed from the Blocked state\r
- * (unblocked) and the notification cleared.\r
- *\r
- * A task can use xTaskNotifyWait() to [optionally] block to wait for a\r
- * notification to be pending, or ulTaskNotifyTake() to [optionally] block\r
- * to wait for its notification value to have a non-zero value. The task does\r
- * not consume any CPU time while it is in the Blocked state.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.\r
- *\r
- * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value\r
- * will be cleared in the calling task's notification value before the task\r
- * checks to see if any notifications are pending, and optionally blocks if no\r
- * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if\r
- * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have\r
- * the effect of resetting the task's notification value to 0. Setting\r
- * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged.\r
- *\r
- * @param ulBitsToClearOnExit If a notification is pending or received before\r
- * the calling task exits the xTaskNotifyWait() function then the task's\r
- * notification value (see the xTaskNotify() API function) is passed out using\r
- * the pulNotificationValue parameter. Then any bits that are set in\r
- * ulBitsToClearOnExit will be cleared in the task's notification value (note\r
- * *pulNotificationValue is set before any bits are cleared). Setting\r
- * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL\r
- * (if limits.h is not included) will have the effect of resetting the task's\r
- * notification value to 0 before the function exits. Setting\r
- * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged\r
- * when the function exits (in which case the value passed out in\r
- * pulNotificationValue will match the task's notification value).\r
- *\r
- * @param pulNotificationValue Used to pass the task's notification value out\r
- * of the function. Note the value passed out will not be effected by the\r
- * clearing of any bits caused by ulBitsToClearOnExit being non-zero.\r
- *\r
- * @param xTicksToWait The maximum amount of time that the task should wait in\r
- * the Blocked state for a notification to be received, should a notification\r
- * not already be pending when xTaskNotifyWait() was called. The task\r
- * will not consume any processing time while it is in the Blocked state. This\r
- * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be\r
- * used to convert a time specified in milliseconds to a time specified in\r
- * ticks.\r
- *\r
- * @return If a notification was received (including notifications that were\r
- * already pending when xTaskNotifyWait was called) then pdPASS is\r
- * returned. Otherwise pdFAIL is returned.\r
- *\r
- * \defgroup xTaskNotifyWait xTaskNotifyWait\r
- * \ingroup TaskNotifications\r
- */\r
-BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );</PRE>\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro\r
- * to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * xTaskNotifyGive() is a helper macro intended for use when task notifications\r
- * are used as light weight and faster binary or counting semaphore equivalents.\r
- * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function,\r
- * the equivalent action that instead uses a task notification is\r
- * xTaskNotifyGive().\r
- *\r
- * When task notifications are being used as a binary or counting semaphore\r
- * equivalent then the task being notified should wait for the notification\r
- * using the ulTaskNotificationTake() API function rather than the\r
- * xTaskNotifyWait() API function.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.\r
- *\r
- * @param xTaskToNotify The handle of the task being notified. The handle to a\r
- * task can be returned from the xTaskCreate() API function used to create the\r
- * task, and the handle of the currently running task can be obtained by calling\r
- * xTaskGetCurrentTaskHandle().\r
- *\r
- * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the\r
- * eAction parameter set to eIncrement - so pdPASS is always returned.\r
- *\r
- * \defgroup xTaskNotifyGive xTaskNotifyGive\r
- * \ingroup TaskNotifications\r
- */\r
-#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL )\r
-\r
-/**\r
- * task. h\r
- * <PRE>void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro\r
- * to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * A version of xTaskNotifyGive() that can be called from an interrupt service\r
- * routine (ISR).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * vTaskNotifyGiveFromISR() is intended for use when task notifications are\r
- * used as light weight and faster binary or counting semaphore equivalents.\r
- * Actual FreeRTOS semaphores are given from an ISR using the\r
- * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses\r
- * a task notification is vTaskNotifyGiveFromISR().\r
- *\r
- * When task notifications are being used as a binary or counting semaphore\r
- * equivalent then the task being notified should wait for the notification\r
- * using the ulTaskNotificationTake() API function rather than the\r
- * xTaskNotifyWait() API function.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.\r
- *\r
- * @param xTaskToNotify The handle of the task being notified. The handle to a\r
- * task can be returned from the xTaskCreate() API function used to create the\r
- * task, and the handle of the currently running task can be obtained by calling\r
- * xTaskGetCurrentTaskHandle().\r
- *\r
- * @param pxHigherPriorityTaskWoken vTaskNotifyGiveFromISR() will set\r
- * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the\r
- * task to which the notification was sent to leave the Blocked state, and the\r
- * unblocked task has a priority higher than the currently running task. If\r
- * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch\r
- * should be requested before the interrupt is exited. How a context switch is\r
- * requested from an ISR is dependent on the port - see the documentation page\r
- * for the port in use.\r
- *\r
- * \defgroup xTaskNotifyWait xTaskNotifyWait\r
- * \ingroup TaskNotifications\r
- */\r
-void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * task. h\r
- * <PRE>uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );</pre>\r
- *\r
- * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this\r
- * function to be available.\r
- *\r
- * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private\r
- * "notification value", which is a 32-bit unsigned integer (uint32_t).\r
- *\r
- * Events can be sent to a task using an intermediary object. Examples of such\r
- * objects are queues, semaphores, mutexes and event groups. Task notifications\r
- * are a method of sending an event directly to a task without the need for such\r
- * an intermediary object.\r
- *\r
- * A notification sent to a task can optionally perform an action, such as\r
- * update, overwrite or increment the task's notification value. In that way\r
- * task notifications can be used to send data to a task, or be used as light\r
- * weight and fast binary or counting semaphores.\r
- *\r
- * ulTaskNotifyTake() is intended for use when a task notification is used as a\r
- * faster and lighter weight binary or counting semaphore alternative. Actual\r
- * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the\r
- * equivalent action that instead uses a task notification is\r
- * ulTaskNotifyTake().\r
- *\r
- * When a task is using its notification value as a binary or counting semaphore\r
- * other tasks should send notifications to it using the xTaskNotifyGive()\r
- * macro, or xTaskNotify() function with the eAction parameter set to\r
- * eIncrement.\r
- *\r
- * ulTaskNotifyTake() can either clear the task's notification value to\r
- * zero on exit, in which case the notification value acts like a binary\r
- * semaphore, or decrement the task's notification value on exit, in which case\r
- * the notification value acts like a counting semaphore.\r
- *\r
- * A task can use ulTaskNotifyTake() to [optionally] block to wait for a\r
- * the task's notification value to be non-zero. The task does not consume any\r
- * CPU time while it is in the Blocked state.\r
- *\r
- * Where as xTaskNotifyWait() will return when a notification is pending,\r
- * ulTaskNotifyTake() will return when the task's notification value is\r
- * not zero.\r
- *\r
- * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details.\r
- *\r
- * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's\r
- * notification value is decremented when the function exits. In this way the\r
- * notification value acts like a counting semaphore. If xClearCountOnExit is\r
- * not pdFALSE then the task's notification value is cleared to zero when the\r
- * function exits. In this way the notification value acts like a binary\r
- * semaphore.\r
- *\r
- * @param xTicksToWait The maximum amount of time that the task should wait in\r
- * the Blocked state for the task's notification value to be greater than zero,\r
- * should the count not already be greater than zero when\r
- * ulTaskNotifyTake() was called. The task will not consume any processing\r
- * time while it is in the Blocked state. This is specified in kernel ticks,\r
- * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time\r
- * specified in milliseconds to a time specified in ticks.\r
- *\r
- * @return The task's notification count before it is either cleared to zero or\r
- * decremented (see the xClearCountOnExit parameter).\r
- *\r
- * \defgroup ulTaskNotifyTake ulTaskNotifyTake\r
- * \ingroup TaskNotifications\r
- */\r
-uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*-----------------------------------------------------------\r
- * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
- *----------------------------------------------------------*/\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
- * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
- * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * Called from the real time kernel tick (either preemptive or cooperative),\r
- * this increments the tick count and checks if any tasks that are blocked\r
- * for a finite period required removing from a blocked list and placing on\r
- * a ready list. If a non-zero value is returned then a context switch is\r
- * required because either:\r
- * + A task was removed from a blocked list because its timeout had expired,\r
- * or\r
- * + Time slicing is in use and there is a task of equal priority to the\r
- * currently running task.\r
- */\r
-BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * Removes the calling task from the ready list and places it both\r
- * on the list of tasks waiting for a particular event, and the\r
- * list of delayed tasks. The task will be removed from both lists\r
- * and replaced on the ready list should either the event occur (and\r
- * there be no higher priority tasks waiting on the same event) or\r
- * the delay period expires.\r
- *\r
- * The 'unordered' version replaces the event list item value with the\r
- * xItemValue value, and inserts the list item at the end of the list.\r
- *\r
- * The 'ordered' version uses the existing event list item value (which is the\r
- * owning tasks priority) to insert the list item into the event list is task\r
- * priority order.\r
- *\r
- * @param pxEventList The list containing tasks that are blocked waiting\r
- * for the event to occur.\r
- *\r
- * @param xItemValue The item value to use for the event list item when the\r
- * event list is not ordered by task priority.\r
- *\r
- * @param xTicksToWait The maximum amount of time that the task should wait\r
- * for the event to occur. This is specified in kernel ticks,the constant\r
- * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time\r
- * period.\r
- */\r
-void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * This function performs nearly the same function as vTaskPlaceOnEventList().\r
- * The difference being that this function does not permit tasks to block\r
- * indefinitely, whereas vTaskPlaceOnEventList() does.\r
- *\r
- */\r
-void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN\r
- * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.\r
- *\r
- * Removes a task from both the specified event list and the list of blocked\r
- * tasks, and places it on a ready queue.\r
- *\r
- * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called\r
- * if either an event occurs to unblock a task, or the block timeout period\r
- * expires.\r
- *\r
- * xTaskRemoveFromEventList() is used when the event list is in task priority\r
- * order. It removes the list item from the head of the event list as that will\r
- * have the highest priority owning task of all the tasks on the event list.\r
- * xTaskRemoveFromUnorderedEventList() is used when the event list is not\r
- * ordered and the event list items hold something other than the owning tasks\r
- * priority. In this case the event list item value is updated to the value\r
- * passed in the xItemValue parameter.\r
- *\r
- * @return pdTRUE if the task being removed has a higher priority than the task\r
- * making the call, otherwise pdFALSE.\r
- */\r
-BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;\r
-BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY\r
- * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS\r
- * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.\r
- *\r
- * Sets the pointer to the current TCB to the TCB of the highest priority task\r
- * that is ready to run.\r
- */\r
-void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY\r
- * THE EVENT BITS MODULE.\r
- */\r
-TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Return the handle of the calling task.\r
- */\r
-TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Capture the current time status for future reference.\r
- */\r
-void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Compare the time status now with that previously captured to see if the\r
- * timeout has expired.\r
- */\r
-BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Shortcut used by the queue implementation to prevent unnecessary call to\r
- * taskYIELD();\r
- */\r
-void vTaskMissedYield( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Returns the scheduler state as taskSCHEDULER_RUNNING,\r
- * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED.\r
- */\r
-BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Raises the priority of the mutex holder to that of the calling task should\r
- * the mutex holder have a priority less than the calling task.\r
- */\r
-void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Set the priority of a task back to its proper priority in the case that it\r
- * inherited a higher priority while it was holding a semaphore.\r
- */\r
-BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Generic version of the task creation function which is in turn called by the\r
- * xTaskCreate() and xTaskCreateRestricted() macros.\r
- */\r
-BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/*\r
- * Get the uxTCBNumber assigned to the task referenced by the xTask parameter.\r
- */\r
-UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Set the uxTaskNumber of the task referenced by the xTask parameter to\r
- * uxHandle.\r
- */\r
-void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Only available when configUSE_TICKLESS_IDLE is set to 1.\r
- * If tickless mode is being used, or a low power mode is implemented, then\r
- * the tick interrupt will not execute during idle periods. When this is the\r
- * case, the tick count value maintained by the scheduler needs to be kept up\r
- * to date with the actual execution time by being skipped forward by a time\r
- * equal to the idle period.\r
- */\r
-void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * Only avilable when configUSE_TICKLESS_IDLE is set to 1.\r
- * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port\r
- * specific sleep function to determine if it is ok to proceed with the sleep,\r
- * and if it is ok to proceed, if it is ok to sleep indefinitely.\r
- *\r
- * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only\r
- * called with the scheduler suspended, not from within a critical section. It\r
- * is therefore possible for an interrupt to request a context switch between\r
- * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being\r
- * entered. eTaskConfirmSleepModeStatus() should be called from a short\r
- * critical section between the timer being stopped and the sleep mode being\r
- * entered to ensure it is ok to proceed into the sleep mode.\r
- */\r
-eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;\r
-\r
-/*\r
- * For internal use only. Increment the mutex held count when a mutex is\r
- * taken and return the handle of the task that has taken the mutex.\r
- */\r
-void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif /* INC_TASK_H */\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
-\r
-\r
-#ifndef TIMERS_H\r
-#define TIMERS_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include timers.h"\r
-#endif\r
-\r
-/*lint -e537 This headers are only multiply included if the application code\r
-happens to also be including task.h. */\r
-#include "task.h"\r
-/*lint +e537 */\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * MACROS AND DEFINITIONS\r
- *----------------------------------------------------------*/\r
-\r
-/* IDs for commands that can be sent/received on the timer queue. These are to\r
-be used solely through the macros that make up the public software timer API,\r
-as defined below. The commands that are sent from interrupts must use the\r
-highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task\r
-or interrupt version of the queue send function should be used. */\r
-#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )\r
-#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )\r
-#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )\r
-#define tmrCOMMAND_START ( ( BaseType_t ) 1 )\r
-#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )\r
-#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )\r
-#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )\r
-#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )\r
-\r
-#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )\r
-#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )\r
-#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )\r
-#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )\r
-#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 )\r
-\r
-\r
-/**\r
- * Type by which software timers are referenced. For example, a call to\r
- * xTimerCreate() returns an TimerHandle_t variable that can then be used to\r
- * reference the subject timer in calls to other software timer API functions\r
- * (for example, xTimerStart(), xTimerReset(), etc.).\r
- */\r
-typedef void * TimerHandle_t;\r
-\r
-/*\r
- * Defines the prototype to which timer callback functions must conform.\r
- */\r
-typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );\r
-\r
-/*\r
- * Defines the prototype to which functions used with the\r
- * xTimerPendFunctionCallFromISR() function must conform.\r
- */\r
-typedef void (*PendedFunction_t)( void *, uint32_t );\r
-\r
-/**\r
- * TimerHandle_t xTimerCreate( const char * const pcTimerName,\r
- * TickType_t xTimerPeriodInTicks,\r
- * UBaseType_t uxAutoReload,\r
- * void * pvTimerID,\r
- * TimerCallbackFunction_t pxCallbackFunction );\r
- *\r
- * Creates a new software timer instance. This allocates the storage required\r
- * by the new timer, initialises the new timers internal state, and returns a\r
- * handle by which the new timer can be referenced.\r
- *\r
- * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
- * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
- * xTimerChangePeriodFromISR() API functions can all be used to transition a\r
- * timer into the active state.\r
- *\r
- * @param pcTimerName A text name that is assigned to the timer. This is done\r
- * purely to assist debugging. The kernel itself only ever references a timer\r
- * by its handle, and never by its name.\r
- *\r
- * @param xTimerPeriodInTicks The timer period. The time is defined in tick\r
- * periods so the constant portTICK_PERIOD_MS can be used to convert a time that\r
- * has been specified in milliseconds. For example, if the timer must expire\r
- * after 100 ticks, then xTimerPeriodInTicks should be set to 100.\r
- * Alternatively, if the timer must expire after 500ms, then xPeriod can be set\r
- * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or\r
- * equal to 1000.\r
- *\r
- * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will\r
- * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.\r
- * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and\r
- * enter the dormant state after it expires.\r
- *\r
- * @param pvTimerID An identifier that is assigned to the timer being created.\r
- * Typically this would be used in the timer callback function to identify which\r
- * timer expired when the same callback function is assigned to more than one\r
- * timer.\r
- *\r
- * @param pxCallbackFunction The function to call when the timer expires.\r
- * Callback functions must have the prototype defined by TimerCallbackFunction_t,\r
- * which is "void vCallbackFunction( TimerHandle_t xTimer );".\r
- *\r
- * @return If the timer is successfully created then a handle to the newly\r
- * created timer is returned. If the timer cannot be created (because either\r
- * there is insufficient FreeRTOS heap remaining to allocate the timer\r
- * structures, or the timer period was set to 0) then NULL is returned.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * #define NUM_TIMERS 5\r
- *\r
- * // An array to hold handles to the created timers.\r
- * TimerHandle_t xTimers[ NUM_TIMERS ];\r
- *\r
- * // An array to hold a count of the number of times each timer expires.\r
- * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 };\r
- *\r
- * // Define a callback function that will be used by multiple timer instances.\r
- * // The callback function does nothing but count the number of times the\r
- * // associated timer expires, and stop the timer once the timer has expired\r
- * // 10 times.\r
- * void vTimerCallback( TimerHandle_t pxTimer )\r
- * {\r
- * int32_t lArrayIndex;\r
- * const int32_t xMaxExpiryCountBeforeStopping = 10;\r
- *\r
- * // Optionally do something if the pxTimer parameter is NULL.\r
- * configASSERT( pxTimer );\r
- *\r
- * // Which timer expired?\r
- * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );\r
- *\r
- * // Increment the number of times that pxTimer has expired.\r
- * lExpireCounters[ lArrayIndex ] += 1;\r
- *\r
- * // If the timer has expired 10 times then stop it from running.\r
- * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )\r
- * {\r
- * // Do not use a block time if calling a timer API function from a\r
- * // timer callback function, as doing so could cause a deadlock!\r
- * xTimerStop( pxTimer, 0 );\r
- * }\r
- * }\r
- *\r
- * void main( void )\r
- * {\r
- * int32_t x;\r
- *\r
- * // Create then start some timers. Starting the timers before the scheduler\r
- * // has been started means the timers will start running immediately that\r
- * // the scheduler starts.\r
- * for( x = 0; x < NUM_TIMERS; x++ )\r
- * {\r
- * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.\r
- * ( 100 * x ), // The timer period in ticks.\r
- * pdTRUE, // The timers will auto-reload themselves when they expire.\r
- * ( void * ) x, // Assign each timer a unique id equal to its array index.\r
- * vTimerCallback // Each timer calls the same callback when it expires.\r
- * );\r
- *\r
- * if( xTimers[ x ] == NULL )\r
- * {\r
- * // The timer was not created.\r
- * }\r
- * else\r
- * {\r
- * // Start the timer. No block time is specified, and even if one was\r
- * // it would be ignored because the scheduler has not yet been\r
- * // started.\r
- * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )\r
- * {\r
- * // The timer could not be set into the Active state.\r
- * }\r
- * }\r
- * }\r
- *\r
- * // ...\r
- * // Create tasks here.\r
- * // ...\r
- *\r
- * // Starting the scheduler will start the timers running as they have already\r
- * // been set into the active state.\r
- * xTaskStartScheduler();\r
- *\r
- * // Should not reach here.\r
- * for( ;; );\r
- * }\r
- * @endverbatim\r
- */\r
-TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/**\r
- * void *pvTimerGetTimerID( TimerHandle_t xTimer );\r
- *\r
- * Returns the ID assigned to the timer.\r
- *\r
- * IDs are assigned to timers using the pvTimerID parameter of the call to\r
- * xTimerCreated() that was used to create the timer, and by calling the\r
- * vTimerSetTimerID() API function.\r
- *\r
- * If the same callback function is assigned to multiple timers then the timer\r
- * ID can be used as time specific (timer local) storage.\r
- *\r
- * @param xTimer The timer being queried.\r
- *\r
- * @return The ID assigned to the timer being queried.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- */\r
-void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );\r
- *\r
- * Sets the ID assigned to the timer.\r
- *\r
- * IDs are assigned to timers using the pvTimerID parameter of the call to\r
- * xTimerCreated() that was used to create the timer.\r
- *\r
- * If the same callback function is assigned to multiple timers then the timer\r
- * ID can be used as time specific (timer local) storage.\r
- *\r
- * @param xTimer The timer being updated.\r
- *\r
- * @param pvNewID The ID to assign to the timer.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- */\r
-void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );\r
- *\r
- * Queries a timer to see if it is active or dormant.\r
- *\r
- * A timer will be dormant if:\r
- * 1) It has been created but not started, or\r
- * 2) It is an expired one-shot timer that has not been restarted.\r
- *\r
- * Timers are created in the dormant state. The xTimerStart(), xTimerReset(),\r
- * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and\r
- * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the\r
- * active state.\r
- *\r
- * @param xTimer The timer being queried.\r
- *\r
- * @return pdFALSE will be returned if the timer is dormant. A value other than\r
- * pdFALSE will be returned if the timer is active.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This function assumes xTimer has already been created.\r
- * void vAFunction( TimerHandle_t xTimer )\r
- * {\r
- * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
- * {\r
- * // xTimer is active, do something.\r
- * }\r
- * else\r
- * {\r
- * // xTimer is not active, do something else.\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
-BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );\r
- *\r
- * xTimerGetTimerDaemonTaskHandle() is only available if\r
- * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.\r
- *\r
- * Simply returns the handle of the timer service/daemon task. It it not valid\r
- * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.\r
- */\r
-TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * through a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerStart() starts a timer that was previously created using the\r
- * xTimerCreate() API function. If the timer had already been started and was\r
- * already in the active state, then xTimerStart() has equivalent functionality\r
- * to the xTimerReset() API function.\r
- *\r
- * Starting a timer ensures the timer is in the active state. If the timer\r
- * is not stopped, deleted, or reset in the mean time, the callback function\r
- * associated with the timer will get called 'n' ticks after xTimerStart() was\r
- * called, where 'n' is the timers defined period.\r
- *\r
- * It is valid to call xTimerStart() before the scheduler has been started, but\r
- * when this is done the timer will not actually start until the scheduler is\r
- * started, and the timers expiry time will be relative to when the scheduler is\r
- * started, not relative to when xTimerStart() was called.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being started/restarted.\r
- *\r
- * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the start command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the start command could not be sent to\r
- * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system, although the\r
- * timers expiry time is relative to when xTimerStart() is actually called. The\r
- * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- *\r
- */\r
-#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )\r
-\r
-/**\r
- * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * through a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerStop() stops a timer that was previously started using either of the\r
- * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),\r
- * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.\r
- *\r
- * Stopping a timer ensures the timer is not in the active state.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being stopped.\r
- *\r
- * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the stop command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the stop command could not be sent to\r
- * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system. The timer\r
- * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerCreate() API function example usage scenario.\r
- *\r
- */\r
-#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )\r
-\r
-/**\r
- * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,\r
- * TickType_t xNewPeriod,\r
- * TickType_t xTicksToWait );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * through a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerChangePeriod() changes the period of a timer that was previously\r
- * created using the xTimerCreate() API function.\r
- *\r
- * xTimerChangePeriod() can be called to change the period of an active or\r
- * dormant state timer.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for\r
- * xTimerChangePeriod() to be available.\r
- *\r
- * @param xTimer The handle of the timer that is having its period changed.\r
- *\r
- * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
- * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time\r
- * that has been specified in milliseconds. For example, if the timer must\r
- * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
- * if the timer must expire after 500ms, then xNewPeriod can be set to\r
- * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than\r
- * or equal to 1000.\r
- *\r
- * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the change period command to be\r
- * successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerChangePeriod() was called. xTicksToWait is ignored if\r
- * xTimerChangePeriod() is called before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the change period command could not be\r
- * sent to the timer command queue even after xTicksToWait ticks had passed.\r
- * pdPASS will be returned if the command was successfully sent to the timer\r
- * command queue. When the command is actually processed will depend on the\r
- * priority of the timer service/daemon task relative to other tasks in the\r
- * system. The timer service/daemon task priority is set by the\r
- * configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This function assumes xTimer has already been created. If the timer\r
- * // referenced by xTimer is already active when it is called, then the timer\r
- * // is deleted. If the timer referenced by xTimer is not active when it is\r
- * // called, then the period of the timer is set to 500ms and the timer is\r
- * // started.\r
- * void vAFunction( TimerHandle_t xTimer )\r
- * {\r
- * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"\r
- * {\r
- * // xTimer is already active - delete it.\r
- * xTimerDelete( xTimer );\r
- * }\r
- * else\r
- * {\r
- * // xTimer is not active, change its period to 500ms. This will also\r
- * // cause the timer to start. Block for a maximum of 100 ticks if the\r
- * // change period command cannot immediately be sent to the timer\r
- * // command queue.\r
- * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS )\r
- * {\r
- * // The command was successfully sent.\r
- * }\r
- * else\r
- * {\r
- * // The command could not be sent, even after waiting for 100 ticks\r
- * // to pass. Take appropriate action here.\r
- * }\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
- #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )\r
-\r
-/**\r
- * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * through a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerDelete() deletes a timer that was previously created using the\r
- * xTimerCreate() API function.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for\r
- * xTimerDelete() to be available.\r
- *\r
- * @param xTimer The handle of the timer being deleted.\r
- *\r
- * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the delete command to be\r
- * successfully sent to the timer command queue, should the queue already be\r
- * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete()\r
- * is called before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the delete command could not be sent to\r
- * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system. The timer\r
- * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- *\r
- * See the xTimerChangePeriod() API function example usage scenario.\r
- */\r
-#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )\r
-\r
-/**\r
- * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );\r
- *\r
- * Timer functionality is provided by a timer service/daemon task. Many of the\r
- * public FreeRTOS timer API functions send commands to the timer service task\r
- * through a queue called the timer command queue. The timer command queue is\r
- * private to the kernel itself and is not directly accessible to application\r
- * code. The length of the timer command queue is set by the\r
- * configTIMER_QUEUE_LENGTH configuration constant.\r
- *\r
- * xTimerReset() re-starts a timer that was previously created using the\r
- * xTimerCreate() API function. If the timer had already been started and was\r
- * already in the active state, then xTimerReset() will cause the timer to\r
- * re-evaluate its expiry time so that it is relative to when xTimerReset() was\r
- * called. If the timer was in the dormant state then xTimerReset() has\r
- * equivalent functionality to the xTimerStart() API function.\r
- *\r
- * Resetting a timer ensures the timer is in the active state. If the timer\r
- * is not stopped, deleted, or reset in the mean time, the callback function\r
- * associated with the timer will get called 'n' ticks after xTimerReset() was\r
- * called, where 'n' is the timers defined period.\r
- *\r
- * It is valid to call xTimerReset() before the scheduler has been started, but\r
- * when this is done the timer will not actually start until the scheduler is\r
- * started, and the timers expiry time will be relative to when the scheduler is\r
- * started, not relative to when xTimerReset() was called.\r
- *\r
- * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()\r
- * to be available.\r
- *\r
- * @param xTimer The handle of the timer being reset/started/restarted.\r
- *\r
- * @param xTicksToWait Specifies the time, in ticks, that the calling task should\r
- * be held in the Blocked state to wait for the reset command to be successfully\r
- * sent to the timer command queue, should the queue already be full when\r
- * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called\r
- * before the scheduler is started.\r
- *\r
- * @return pdFAIL will be returned if the reset command could not be sent to\r
- * the timer command queue even after xTicksToWait ticks had passed. pdPASS will\r
- * be returned if the command was successfully sent to the timer command queue.\r
- * When the command is actually processed will depend on the priority of the\r
- * timer service/daemon task relative to other tasks in the system, although the\r
- * timers expiry time is relative to when xTimerStart() is actually called. The\r
- * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer.\r
- *\r
- * TimerHandle_t xBacklightTimer = NULL;\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( TimerHandle_t pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press event handler.\r
- * void vKeyPressEventHandler( char cKey )\r
- * {\r
- * // Ensure the LCD back-light is on, then reset the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. Wait 10 ticks for the command to be successfully sent\r
- * // if it cannot be sent immediately.\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )\r
- * {\r
- * // The reset command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- * }\r
- *\r
- * void main( void )\r
- * {\r
- * int32_t x;\r
- *\r
- * // Create then start the one-shot timer that is responsible for turning\r
- * // the back-light off if no keys are pressed within a 5 second period.\r
- * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.\r
- * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks.\r
- * pdFALSE, // The timer is a one-shot timer.\r
- * 0, // The id is not used by the callback so can take any value.\r
- * vBacklightTimerCallback // The callback function that switches the LCD back-light off.\r
- * );\r
- *\r
- * if( xBacklightTimer == NULL )\r
- * {\r
- * // The timer was not created.\r
- * }\r
- * else\r
- * {\r
- * // Start the timer. No block time is specified, and even if one was\r
- * // it would be ignored because the scheduler has not yet been\r
- * // started.\r
- * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )\r
- * {\r
- * // The timer could not be set into the Active state.\r
- * }\r
- * }\r
- *\r
- * // ...\r
- * // Create tasks here.\r
- * // ...\r
- *\r
- * // Starting the scheduler will start the timer running as it has already\r
- * // been set into the active state.\r
- * xTaskStartScheduler();\r
- *\r
- * // Should not reach here.\r
- * for( ;; );\r
- * }\r
- * @endverbatim\r
- */\r
-#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )\r
-\r
-/**\r
- * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,\r
- * BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerStart() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer being started/restarted.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerStartFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerStartFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerStartFromISR() function. If\r
- * xTimerStartFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the start command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system, although the timers expiry time is\r
- * relative to when xTimerStartFromISR() is actually called. The timer\r
- * service/daemon task priority is set by the configTIMER_TASK_PRIORITY\r
- * configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This scenario assumes xBacklightTimer has already been created. When a\r
- * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer, and unlike the example given for\r
- * // the xTimerReset() function, the key press event handler is an interrupt\r
- * // service routine.\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( TimerHandle_t pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press interrupt service routine.\r
- * void vKeyPressEventInterruptHandler( void )\r
- * {\r
- * BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // Ensure the LCD back-light is on, then restart the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. This is an interrupt service routine so can only\r
- * // call FreeRTOS API functions that end in "FromISR".\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- *\r
- * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
- * // as both cause the timer to re-calculate its expiry time.\r
- * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
- * // declared (in this function).\r
- * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The start command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used).\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
-#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,\r
- * BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerStop() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer being stopped.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerStopFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerStopFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerStopFromISR() function. If\r
- * xTimerStopFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the stop command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system. The timer service/daemon task\r
- * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This scenario assumes xTimer has already been created and started. When\r
- * // an interrupt occurs, the timer should be simply stopped.\r
- *\r
- * // The interrupt service routine that stops the timer.\r
- * void vAnExampleInterruptServiceRoutine( void )\r
- * {\r
- * BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // The interrupt has occurred - simply stop the timer.\r
- * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
- * // (within this function). As this is an interrupt service routine, only\r
- * // FreeRTOS API functions that end in "FromISR" can be used.\r
- * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The stop command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used).\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
-#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,\r
- * TickType_t xNewPeriod,\r
- * BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerChangePeriod() that can be called from an interrupt\r
- * service routine.\r
- *\r
- * @param xTimer The handle of the timer that is having its period changed.\r
- *\r
- * @param xNewPeriod The new period for xTimer. Timer periods are specified in\r
- * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time\r
- * that has been specified in milliseconds. For example, if the timer must\r
- * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,\r
- * if the timer must expire after 500ms, then xNewPeriod can be set to\r
- * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than\r
- * or equal to 1000.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerChangePeriodFromISR() writes a message to the\r
- * timer command queue, so has the potential to transition the timer service/\r
- * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()\r
- * causes the timer service/daemon task to leave the Blocked state, and the\r
- * timer service/daemon task has a priority equal to or greater than the\r
- * currently executing task (the task that was interrupted), then\r
- * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the\r
- * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets\r
- * this value to pdTRUE then a context switch should be performed before the\r
- * interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the command to change the timers period\r
- * could not be sent to the timer command queue. pdPASS will be returned if the\r
- * command was successfully sent to the timer command queue. When the command\r
- * is actually processed will depend on the priority of the timer service/daemon\r
- * task relative to other tasks in the system. The timer service/daemon task\r
- * priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This scenario assumes xTimer has already been created and started. When\r
- * // an interrupt occurs, the period of xTimer should be changed to 500ms.\r
- *\r
- * // The interrupt service routine that changes the period of xTimer.\r
- * void vAnExampleInterruptServiceRoutine( void )\r
- * {\r
- * BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // The interrupt has occurred - change the period of xTimer to 500ms.\r
- * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined\r
- * // (within this function). As this is an interrupt service routine, only\r
- * // FreeRTOS API functions that end in "FromISR" can be used.\r
- * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The command to change the timers period was not executed\r
- * // successfully. Take appropriate action here.\r
- * }\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used).\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
-#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-/**\r
- * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,\r
- * BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- * A version of xTimerReset() that can be called from an interrupt service\r
- * routine.\r
- *\r
- * @param xTimer The handle of the timer that is to be started, reset, or\r
- * restarted.\r
- *\r
- * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most\r
- * of its time in the Blocked state, waiting for messages to arrive on the timer\r
- * command queue. Calling xTimerResetFromISR() writes a message to the timer\r
- * command queue, so has the potential to transition the timer service/daemon\r
- * task out of the Blocked state. If calling xTimerResetFromISR() causes the\r
- * timer service/daemon task to leave the Blocked state, and the timer service/\r
- * daemon task has a priority equal to or greater than the currently executing\r
- * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will\r
- * get set to pdTRUE internally within the xTimerResetFromISR() function. If\r
- * xTimerResetFromISR() sets this value to pdTRUE then a context switch should\r
- * be performed before the interrupt exits.\r
- *\r
- * @return pdFAIL will be returned if the reset command could not be sent to\r
- * the timer command queue. pdPASS will be returned if the command was\r
- * successfully sent to the timer command queue. When the command is actually\r
- * processed will depend on the priority of the timer service/daemon task\r
- * relative to other tasks in the system, although the timers expiry time is\r
- * relative to when xTimerResetFromISR() is actually called. The timer service/daemon\r
- * task priority is set by the configTIMER_TASK_PRIORITY configuration constant.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- * // This scenario assumes xBacklightTimer has already been created. When a\r
- * // key is pressed, an LCD back-light is switched on. If 5 seconds pass\r
- * // without a key being pressed, then the LCD back-light is switched off. In\r
- * // this case, the timer is a one-shot timer, and unlike the example given for\r
- * // the xTimerReset() function, the key press event handler is an interrupt\r
- * // service routine.\r
- *\r
- * // The callback function assigned to the one-shot timer. In this case the\r
- * // parameter is not used.\r
- * void vBacklightTimerCallback( TimerHandle_t pxTimer )\r
- * {\r
- * // The timer expired, therefore 5 seconds must have passed since a key\r
- * // was pressed. Switch off the LCD back-light.\r
- * vSetBacklightState( BACKLIGHT_OFF );\r
- * }\r
- *\r
- * // The key press interrupt service routine.\r
- * void vKeyPressEventInterruptHandler( void )\r
- * {\r
- * BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
- *\r
- * // Ensure the LCD back-light is on, then reset the timer that is\r
- * // responsible for turning the back-light off after 5 seconds of\r
- * // key inactivity. This is an interrupt service routine so can only\r
- * // call FreeRTOS API functions that end in "FromISR".\r
- * vSetBacklightState( BACKLIGHT_ON );\r
- *\r
- * // xTimerStartFromISR() or xTimerResetFromISR() could be called here\r
- * // as both cause the timer to re-calculate its expiry time.\r
- * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was\r
- * // declared (in this function).\r
- * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )\r
- * {\r
- * // The reset command was not executed successfully. Take appropriate\r
- * // action here.\r
- * }\r
- *\r
- * // Perform the rest of the key processing here.\r
- *\r
- * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch\r
- * // should be performed. The syntax required to perform a context switch\r
- * // from inside an ISR varies from port to port, and from compiler to\r
- * // compiler. Inspect the demos for the port you are using to find the\r
- * // actual syntax required.\r
- * if( xHigherPriorityTaskWoken != pdFALSE )\r
- * {\r
- * // Call the interrupt safe yield function here (actual function\r
- * // depends on the FreeRTOS port being used).\r
- * }\r
- * }\r
- * @endverbatim\r
- */\r
-#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )\r
-\r
-\r
-/**\r
- * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,\r
- * void *pvParameter1,\r
- * uint32_t ulParameter2,\r
- * BaseType_t *pxHigherPriorityTaskWoken );\r
- *\r
- *\r
- * Used from application interrupt service routines to defer the execution of a\r
- * function to the RTOS daemon task (the timer service task, hence this function\r
- * is implemented in timers.c and is prefixed with 'Timer').\r
- *\r
- * Ideally an interrupt service routine (ISR) is kept as short as possible, but\r
- * sometimes an ISR either has a lot of processing to do, or needs to perform\r
- * processing that is not deterministic. In these cases\r
- * xTimerPendFunctionCallFromISR() can be used to defer processing of a function\r
- * to the RTOS daemon task.\r
- *\r
- * A mechanism is provided that allows the interrupt to return directly to the\r
- * task that will subsequently execute the pended callback function. This\r
- * allows the callback function to execute contiguously in time with the\r
- * interrupt - just as if the callback had executed in the interrupt itself.\r
- *\r
- * @param xFunctionToPend The function to execute from the timer service/\r
- * daemon task. The function must conform to the PendedFunction_t\r
- * prototype.\r
- *\r
- * @param pvParameter1 The value of the callback function's first parameter.\r
- * The parameter has a void * type to allow it to be used to pass any type.\r
- * For example, unsigned longs can be cast to a void *, or the void * can be\r
- * used to point to a structure.\r
- *\r
- * @param ulParameter2 The value of the callback function's second parameter.\r
- *\r
- * @param pxHigherPriorityTaskWoken As mentioned above, calling this function\r
- * will result in a message being sent to the timer daemon task. If the\r
- * priority of the timer daemon task (which is set using\r
- * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of\r
- * the currently running task (the task the interrupt interrupted) then\r
- * *pxHigherPriorityTaskWoken will be set to pdTRUE within\r
- * xTimerPendFunctionCallFromISR(), indicating that a context switch should be\r
- * requested before the interrupt exits. For that reason\r
- * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the\r
- * example code below.\r
- *\r
- * @return pdPASS is returned if the message was successfully sent to the\r
- * timer daemon task, otherwise pdFALSE is returned.\r
- *\r
- * Example usage:\r
- * @verbatim\r
- *\r
- * // The callback function that will execute in the context of the daemon task.\r
- * // Note callback functions must all use this same prototype.\r
- * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 )\r
- * {\r
- * BaseType_t xInterfaceToService;\r
- *\r
- * // The interface that requires servicing is passed in the second\r
- * // parameter. The first parameter is not used in this case.\r
- * xInterfaceToService = ( BaseType_t ) ulParameter2;\r
- *\r
- * // ...Perform the processing here...\r
- * }\r
- *\r
- * // An ISR that receives data packets from multiple interfaces\r
- * void vAnISR( void )\r
- * {\r
- * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken;\r
- *\r
- * // Query the hardware to determine which interface needs processing.\r
- * xInterfaceToService = prvCheckInterfaces();\r
- *\r
- * // The actual processing is to be deferred to a task. Request the\r
- * // vProcessInterface() callback function is executed, passing in the\r
- * // number of the interface that needs processing. The interface to\r
- * // service is passed in the second parameter. The first parameter is\r
- * // not used in this case.\r
- * xHigherPriorityTaskWoken = pdFALSE;\r
- * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken );\r
- *\r
- * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context\r
- * // switch should be requested. The macro used is port specific and will\r
- * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to\r
- * // the documentation page for the port being used.\r
- * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
- *\r
- * }\r
- * @endverbatim\r
- */\r
-BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
-\r
- /**\r
- * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,\r
- * void *pvParameter1,\r
- * uint32_t ulParameter2,\r
- * TickType_t xTicksToWait );\r
- *\r
- *\r
- * Used to defer the execution of a function to the RTOS daemon task (the timer\r
- * service task, hence this function is implemented in timers.c and is prefixed\r
- * with 'Timer').\r
- *\r
- * @param xFunctionToPend The function to execute from the timer service/\r
- * daemon task. The function must conform to the PendedFunction_t\r
- * prototype.\r
- *\r
- * @param pvParameter1 The value of the callback function's first parameter.\r
- * The parameter has a void * type to allow it to be used to pass any type.\r
- * For example, unsigned longs can be cast to a void *, or the void * can be\r
- * used to point to a structure.\r
- *\r
- * @param ulParameter2 The value of the callback function's second parameter.\r
- *\r
- * @param xTicksToWait Calling this function will result in a message being\r
- * sent to the timer daemon task on a queue. xTicksToWait is the amount of\r
- * time the calling task should remain in the Blocked state (so not using any\r
- * processing time) for space to become available on the timer queue if the\r
- * queue is found to be full.\r
- *\r
- * @return pdPASS is returned if the message was successfully sent to the\r
- * timer daemon task, otherwise pdFALSE is returned.\r
- *\r
- */\r
-BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-/**\r
- * const char * const pcTimerGetTimerName( TimerHandle_t xTimer );\r
- *\r
- * Returns the name that was assigned to a timer when the timer was created.\r
- *\r
- * @param xTimer The handle of the timer being queried.\r
- *\r
- * @return The name assigned to the timer specified by the xTimer parameter.\r
- */\r
-const char * pcTimerGetTimerName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-\r
-/*\r
- * Functions beyond this part are not part of the public API and are intended\r
- * for use by the kernel only.\r
- */\r
-BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;\r
-BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-#endif /* TIMERS_H */\r
-\r
-\r
-\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-/*
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
- All rights reserved
-
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
- 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. Full license text is available on the following
- link: http://www.freertos.org/a00114.html
-
- ***************************************************************************
- * *
- * FreeRTOS provides completely free yet professionally developed, *
- * robust, strictly quality controlled, supported, and cross *
- * platform software that is more than just the market leader, it *
- * is the industry's de facto standard. *
- * *
- * Help yourself get started quickly while simultaneously helping *
- * to support the FreeRTOS project by purchasing a FreeRTOS *
- * tutorial book, reference manual, or both: *
- * http://www.FreeRTOS.org/Documentation *
- * *
- ***************************************************************************
-
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
- the FAQ page "My application does not run, what could be wrong?". Have you
- defined configASSERT()?
-
- http://www.FreeRTOS.org/support - In return for receiving this top quality
- embedded software for free we request you assist our global community by
- participating in the support forum.
-
- http://www.FreeRTOS.org/training - Investing in training allows your team to
- be as productive as possible as early as possible. Now you can receive
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
- Ltd, and the world's leading authority on the world's leading RTOS.
-
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS
- compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
- licenses offer ticketed support, indemnification and commercial middleware.
-
- 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.
-
- 1 tab == 4 spaces!
-*/
-
-/*
- * This is a very simply blinky style example that can be generated
- * automatically by the Xilinx SDK.
- *
- * The example generates a Tx task, an Rx task, and a queue. The Tx task
- * simply uses the queue to send a value to the Rx task every 500ms. The Rx
- * prints out a message each time it receives the value.
- *
- * The demo does little in the way of hardware configuration. Separate projects
- * are provided that include comprehensive demos which demonstrate additional
- * hardware configuration, and additional FreeRTOS features. See the following
- * link for more details: http://www.freertos.org/a00090.html#XILINX
- */
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/* Xilinx includes. */
-#include "xil_printf.h"
-#include "xparameters.h"
-
-/*-----------------------------------------------------------*/
-
-/* The Tx and Rx tasks as described at the top of this file. */
-static void prvTxTask( void *pvParameters );
-static void prvRxTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used by the Tx and Rx tasks, as described at the top of this
-file. */
-static QueueHandle_t xQueue = NULL;
-
-int main( void )
-{
- xil_printf( "Hello from Freertos\r\n" );
-
- /* Create the two tasks. The Tx task is given a lower priority than the
- Rx task, so the Rx task will leave the Blocked state and pre-empt the Tx
- task as soon as the Tx task places an item in the queue. */
- xTaskCreate( prvTxTask, /* The function that implements the task. */
- ( const char * ) "Tx", /* Text name for the task, provided to assist debugging only. */
- configMINIMAL_STACK_SIZE, /* The stack allocated to the task. */
- NULL, /* The task parameter is not used, so set to NULL. */
- tskIDLE_PRIORITY, /* The task runs at the idle priority. */
- NULL );
-
- xTaskCreate( prvRxTask, ( const char * ) "GB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );
-
- /* Create the queue used by the tasks. The Rx task has a higher priority
- than the Tx task, so will preempt the Tx task and remove values from the
- queue as soon as the Tx task writes to the queue - therefore the queue can
- never have more than one item in it. */
- xQueue = xQueueCreate( 1, /* There is only one space in the queue. */
- sizeof( uint32_t ) ); /* Each space in the queue is large enough to hold a uint32_t. */
-
- /* Check the queue was created. */
- configASSERT( xQueue );
-
- /* Start the tasks and timer running. */
- 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. */
- for( ;; );
-}
-
-
-/*-----------------------------------------------------------*/
-static void prvTxTask( void *pvParameters )
-{
-const TickType_t x500ms = pdMS_TO_TICKS( 500UL );
-uint32_t ulValueToSend = 0;
-
- for( ;; )
- {
- /* Delay for 500ms. */
- vTaskDelay( x500ms );
-
- /* Send the next value on the queue. The queue should always be
- empty at this point so a block time of 0 is used. */
- xQueueSend( xQueue, /* The queue being written to. */
- &ulValueToSend, /* The address of the data being sent. */
- 0UL ); /* The block time. */
- }
-}
-
-/*-----------------------------------------------------------*/
-static void prvRxTask( void *pvParameters )
-{
-uint32_t ulValueReceived;
-
- for( ;; )
- {
- /* Block to wait for data arriving on the queue. */
- xQueueReceive( xQueue, /* The queue being read. */
- &ulValueReceived, /* Data is read into this address. */
- portMAX_DELAY ); /* Wait without a timeout for data. */
-
- /* Print the received data. */
- xil_printf( "Rx task received %u\r\n", ( unsigned int ) ulValueReceived );
- }
-}
-
-
+/*\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ All rights reserved\r
+\r
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+ This file is part of the FreeRTOS distribution.\r
+\r
+ FreeRTOS is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License (version 2) as published by the\r
+ Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+ ***************************************************************************\r
+ >>! NOTE: The modification to the GPL is included to allow you to !<<\r
+ >>! distribute a combined work that includes FreeRTOS without being !<<\r
+ >>! obliged to provide the source code for proprietary components !<<\r
+ >>! outside of the FreeRTOS kernel. !<<\r
+ ***************************************************************************\r
+\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following\r
+ link: http://www.freertos.org/a00114.html\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS provides completely free yet professionally developed, *\r
+ * robust, strictly quality controlled, supported, and cross *\r
+ * platform software that is more than just the market leader, it *\r
+ * is the industry's de facto standard. *\r
+ * *\r
+ * Help yourself get started quickly while simultaneously helping *\r
+ * to support the FreeRTOS project by purchasing a FreeRTOS *\r
+ * tutorial book, reference manual, or both: *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ ***************************************************************************\r
+\r
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
+ the FAQ page "My application does not run, what could be wrong?". Have you\r
+ defined configASSERT()?\r
+\r
+ http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+ embedded software for free we request you assist our global community by\r
+ participating in the support forum.\r
+\r
+ http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+ be as productive as possible as early as possible. Now you can receive\r
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+ Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
+ licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
+ mission critical applications that require provable dependability.\r
+\r
+ 1 tab == 4 spaces!\r
+*/\r
+\r
+/*\r
+ * This is a very simply blinky style example that can be generated\r
+ * automatically by the Xilinx SDK.\r
+ *\r
+ * The example generates a Tx task, an Rx task, and a queue. The Tx task\r
+ * simply uses the queue to send a value to the Rx task every 500ms. The Rx\r
+ * prints out a message each time it receives the value.\r
+ *\r
+ * The demo does little in the way of hardware configuration. Separate projects\r
+ * are provided that include comprehensive demos which demonstrate additional\r
+ * hardware configuration, and additional FreeRTOS features. See the following\r
+ * link for more details: http://www.freertos.org/a00090.html#XILINX\r
+ */\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Xilinx includes. */\r
+#include "xil_printf.h"\r
+#include "xparameters.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The Tx and Rx tasks as described at the top of this file. */\r
+static void prvTxTask( void *pvParameters );\r
+static void prvRxTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The queue used by the Tx and Rx tasks, as described at the top of this\r
+file. */\r
+static QueueHandle_t xQueue = NULL;\r
+\r
+int main( void )\r
+{\r
+ xil_printf( "Hello from Freertos\r\n" );\r
+\r
+ /* Create the two tasks. The Tx task is given a lower priority than the\r
+ Rx task, so the Rx task will leave the Blocked state and pre-empt the Tx\r
+ task as soon as the Tx task places an item in the queue. */\r
+ xTaskCreate( prvTxTask, /* The function that implements the task. */\r
+ ( const char * ) "Tx", /* Text name for the task, provided to assist debugging only. */\r
+ configMINIMAL_STACK_SIZE, /* The stack allocated to the task. */\r
+ NULL, /* The task parameter is not used, so set to NULL. */\r
+ tskIDLE_PRIORITY, /* The task runs at the idle priority. */\r
+ NULL );\r
+\r
+ xTaskCreate( prvRxTask, ( const char * ) "GB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
+\r
+ /* Create the queue used by the tasks. The Rx task has a higher priority\r
+ than the Tx task, so will preempt the Tx task and remove values from the\r
+ queue as soon as the Tx task writes to the queue - therefore the queue can\r
+ never have more than one item in it. */\r
+ xQueue = xQueueCreate( 1, /* There is only one space in the queue. */\r
+ sizeof( uint32_t ) ); /* Each space in the queue is large enough to hold a uint32_t. */\r
+\r
+ /* Check the queue was created. */\r
+ configASSERT( xQueue );\r
+\r
+ /* Start the tasks and timer running. */\r
+ vTaskStartScheduler();\r
+\r
+ /* If all is well, the scheduler will now be running, and the following line\r
+ will never be reached. If the following line does execute, then there was\r
+ insufficient FreeRTOS heap memory available for the idle and/or timer tasks\r
+ to be created. See the memory management section on the FreeRTOS web site\r
+ for more details. */\r
+ for( ;; );\r
+}\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+static void prvTxTask( void *pvParameters )\r
+{\r
+const TickType_t x500ms = pdMS_TO_TICKS( 500UL );\r
+uint32_t ulValueToSend = 0;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Delay for 500ms. */\r
+ vTaskDelay( x500ms );\r
+\r
+ /* Send the next value on the queue. The queue should always be\r
+ empty at this point so a block time of 0 is used. */\r
+ xQueueSend( xQueue, /* The queue being written to. */\r
+ &ulValueToSend, /* The address of the data being sent. */\r
+ 0UL ); /* The block time. */\r
+ }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+static void prvRxTask( void *pvParameters )\r
+{\r
+uint32_t ulValueReceived;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Block to wait for data arriving on the queue. */\r
+ xQueueReceive( xQueue, /* The queue being read. */\r
+ &ulValueReceived, /* Data is read into this address. */\r
+ portMAX_DELAY ); /* Wait without a timeout for data. */\r
+\r
+ /* Print the received data. */\r
+ xil_printf( "Rx task received %u\r\n", ( unsigned int ) ulValueReceived );\r
+ }\r
+}\r
+\r
+\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#/*\r
-# FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+# FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
# \r
#\r
# ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState\r
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle\r
#define uxTaskGetSystemState MPU_uxTaskGetSystemState\r
+ #define xTaskGenericNotify MPU_xTaskGenericNotify\r
+ #define xTaskNotifyWait MPU_xTaskNotifyWait\r
+ #define ulTaskNotifyTake MPU_ulTaskNotifyTake\r
\r
#define xQueueGenericCreate MPU_xQueueGenericCreate\r
#define xQueueCreateMutex MPU_xQueueCreateMutex\r
#define xQueueSelectFromSet MPU_xQueueSelectFromSet\r
#define xQueueAddToSet MPU_xQueueAddToSet\r
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet\r
- #define xQueuePeekFromISR MPU_xQueuePeekFromISR\r
+ #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder\r
#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder\r
\r
#define pvPortMalloc MPU_pvPortMalloc\r
#define vPortFree MPU_vPortFree\r
#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize\r
#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks\r
+ #define xPortGetMinimumEverFreeHeapSize MPU_xPortGetMinimumEverFreeHeapSize\r
\r
#if configQUEUE_REGISTRY_SIZE > 0\r
#define vQueueAddToRegistry MPU_vQueueAddToRegistry\r
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue\r
#endif\r
\r
+ #define xTimerCreate MPU_xTimerCreate\r
+ #define pvTimerGetTimerID MPU_pvTimerGetTimerID\r
+ #define vTimerSetTimerID MPU_vTimerSetTimerID\r
+ #define xTimerIsTimerActive MPU_xTimerIsTimerActive\r
+ #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle\r
+ #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall\r
+ #define pcTimerGetTimerName MPU_pcTimerGetTimerName\r
+ #define xTimerGenericCommand MPU_xTimerGenericCommand\r
+\r
+ #define xEventGroupCreate MPU_xEventGroupCreate\r
+ #define xEventGroupWaitBits MPU_xEventGroupWaitBits\r
+ #define xEventGroupClearBits MPU_xEventGroupClearBits\r
+ #define xEventGroupSetBits MPU_xEventGroupSetBits\r
+ #define xEventGroupSync MPU_xEventGroupSync\r
+ #define vEventGroupDelete MPU_vEventGroupDelete\r
+\r
/* Remove the privileged function macro. */\r
#define PRIVILEGED_FUNCTION\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
* MACROS AND DEFINITIONS\r
*----------------------------------------------------------*/\r
\r
-#define tskKERNEL_VERSION_NUMBER "V8.2.1"\r
+#define tskKERNEL_VERSION_NUMBER "V8.2.2"\r
#define tskKERNEL_VERSION_MAJOR 8\r
#define tskKERNEL_VERSION_MINOR 2\r
-#define tskKERNEL_VERSION_BUILD 1\r
+#define tskKERNEL_VERSION_BUILD 2\r
\r
/**\r
* task. h\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
; VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*****************************************************************************/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*****************************************************************************/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
*****************************************************************************/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
*****************************************************************************/\r
\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
; \r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
;/*\r
-; FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+; FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
; All rights reserved\r
;\r
;\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
REM/*\r
-REM FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+REM FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
REM\r
REM\r
REM ***************************************************************************\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
/*\r
- FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r