Update version numbers in preparation for new release.

This commit is contained in:
Richard Barry 2015-08-05 12:59:42 +00:00
parent b4c3d91aff
commit 99d4f2c454
1451 changed files with 31767 additions and 11220 deletions

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -0,0 +1,173 @@
/*
FreeRTOS V8.2.2 - 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!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
* http://www.freertos.org/a00110.html
*
* The bottom of this file contains some constants specific to running the UDP
* stack in this demo. Constants specific to FreeRTOS+UDP itself (rather than
* the demo) are contained in FreeRTOSIPConfig.h.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configMAX_PRIORITIES ( 7 )
#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32U * 1024U ) )
#define configMAX_TASK_NAME_LEN ( 7 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
/* Hook function related definitions. */
#define configUSE_TICK_HOOK 0
#define configUSE_IDLE_HOOK 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
/* Run time stats gathering definitions. */
unsigned long ulGetRunTimeCounterValue( void );
void vConfigureTimerForRunTimeStats( void );
#define configGENERATE_RUN_TIME_STATS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerGetTimerTaskHandle 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
/* This demo makes use of one or more example stats formatting functions. These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form. See the notes in the implementation of vTaskList() within
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/* Assert call defined for debug builds. */
#ifdef _DEBUG
extern void vAssertCalled( const char *pcFile, unsigned long ulLine );
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
#endif /* _DEBUG */
/* Application specific definitions follow. **********************************/
/* The UDP port to use for incoming command inputs. The outgoing port is
set to ( configUDP_CLI_PORT_NUMBER + 1 ). */
#define configUDP_CLI_PORT_NUMBER 5001
/* The size of the global output buffer that is available for use when there
are multiple command interpreters running at once (for example, one on a UART
and one on TCP/IP). This is done to prevent an output buffer being defined by
each implementation - which would waste RAM. In this case, there is only one
command interpreter running, and it has its own local output buffer, so the
global buffer is just set to be one byte long as it is not used and should not
take up unnecessary RAM. */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1
#endif /* FREERTOS_CONFIG_H */

View file

@ -0,0 +1,15 @@
/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION
UTILITY. DO NOT MODIFY.
*/
/** @file
*/
#include <redconf.h>
#include <redtypes.h>
#include <redmacs.h>
#include <redvolume.h>
const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] =
{
{ 512U, 65536U, false, 256U, "" }
};

View file

@ -0,0 +1,104 @@
/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION
UTILITY. DO NOT MODIFY.
*/
/** @file
*/
#ifndef REDCONF_H
#define REDCONF_H
#include <string.h>
#define REDCONF_READ_ONLY 0
#define REDCONF_API_POSIX 1
#define REDCONF_API_FSE 0
#define REDCONF_API_POSIX_FORMAT 1
#define REDCONF_API_POSIX_LINK 1
#define REDCONF_API_POSIX_UNLINK 1
#define REDCONF_API_POSIX_MKDIR 1
#define REDCONF_API_POSIX_RMDIR 1
#define REDCONF_API_POSIX_RENAME 1
#define REDCONF_RENAME_ATOMIC 1
#define REDCONF_API_POSIX_FTRUNCATE 1
#define REDCONF_API_POSIX_READDIR 1
#define REDCONF_NAME_MAX 28U
#define REDCONF_PATH_SEPARATOR '/'
#define REDCONF_TASK_COUNT 10U
#define REDCONF_HANDLE_COUNT 10U
#define REDCONF_API_FSE_FORMAT 0
#define REDCONF_API_FSE_TRUNCATE 0
#define REDCONF_API_FSE_TRANSMASKGET 0
#define REDCONF_API_FSE_TRANSMASKSET 0
#define REDCONF_OUTPUT 1
#define REDCONF_ASSERTS 1
#define REDCONF_BLOCK_SIZE 512U
#define REDCONF_VOLUME_COUNT 1U
#define REDCONF_ENDIAN_BIG 0
#define REDCONF_ALIGNMENT_SIZE 4U
#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8
#define REDCONF_INODE_BLOCKS 1
#define REDCONF_INODE_TIMESTAMPS 1
#define REDCONF_ATIME 0
#define REDCONF_DIRECT_POINTERS 4U
#define REDCONF_INDIRECT_POINTERS 32U
#define REDCONF_BUFFER_COUNT 12U
#define RedMemCpyUnchecked memcpy
#define RedMemMoveUnchecked memmove
#define RedMemSetUnchecked memset
#define RedMemCmpUnchecked memcmp
#define RedStrLenUnchecked strlen
#define RedStrCmpUnchecked strcmp
#define RedStrNCmpUnchecked strncmp
#define RedStrNCpyUnchecked strncpy
#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)
#define REDCONF_IMAP_INLINE 0
#define REDCONF_IMAP_EXTERNAL 1
#define REDCONF_IMAGE_BUILDER 0
#define REDCONF_CHECKER 0
#endif

View file

@ -0,0 +1,110 @@
/* ----> 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 Defines basic types used by Reliance Edge.
The following types *must* be defined by this header, either directly (using
typedef) or indirectly (by including other headers, such as the C99 headers
stdint.h and stdbool.h):
- bool: Boolean type, capable of storing true (1) or false (0)
- uint8_t: Unsigned 8-bit integer
- int8_t: Signed 8-bit integer
- uint16_t: Unsigned 16-bit integer
- int16_t: Signed 16-bit integer
- uint32_t: Unsigned 32-bit integer
- int32_t: Signed 32-bit integer
- uint64_t: Unsigned 64-bit integer
- int64_t: Signed 64-bit integer
- uintptr_t: Unsigned integer capable of storing a pointer, preferably the
same size as pointers themselves.
These types deliberately use the same names as the standard C99 types, so
that if the C99 headers stdint.h and stdbool.h are available, they may be
included here.
If the user application defines similar types, those may be reused. For
example, suppose there is an application header apptypes.h which defines
types with a similar purpose but different names. That header could be
reused to define the types Reliance Edge needs:
~~~{.c}
#include <apptypes.h>
typedef BOOL bool;
typedef BYTE uint8_t;
typedef INT8 int8_t;
// And so on...
~~~
If there are neither C99 headers nor suitable types in application headers,
this header should be populated with typedefs that define the required types
in terms of the standard C types. This requires knowledge of the size of
the C types on the target hardware (e.g., how big is an "int" or a pointer).
Below is an example which assumes the target has 8-bit chars, 16-bit shorts,
32-bit ints, 32-bit pointers, and 64-bit long longs:
~~~{.c}
typedef int bool;
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef uint32_t uintptr_t;
~~~
*/
#ifndef REDTYPES_H
#define REDTYPES_H
typedef int bool; /**< @brief Boolean type; either true or false. */
typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */
typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */
typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */
typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */
typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */
typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */
typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */
typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */
/** @brief Unsigned integer capable of storing a pointer.
*/
#ifdef _WIN64
typedef uint64_t uintptr_t;
#else
typedef uint32_t uintptr_t;
#endif
#endif

View file

@ -0,0 +1,331 @@
/*
FreeRTOS V8.2.2 - 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!
*/
/*******************************************************************************
* See the URL in the comments within main.c for the location of the online
* documentation.
******************************************************************************/
/* Standard includes. */
#include <stdio.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
/* File system includes. */
#include <redposix.h>
/* The number of bytes read/written to the example files at a time. */
#define fsRAM_BUFFER_SIZE 200
/* The volume prefix is an empty string, for convenience since there is only one
volume in this demo.
*/
#define fsVOLUME_NAME ""
/*-----------------------------------------------------------*/
/*
* Creates and verifies different files on the volume, demonstrating the use of
* various different API functions.
*/
void vCreateAndVerifySampleFiles( void );
/*
* Create a set of example files in the root directory of the volume using
* f_write().
*/
static void prvCreateDemoFiles( void );
/*
* Use f_read() to read back and verify the files that were created by
* prvCreateDemoFiles().
*/
static void prvVerifyDemoFiles( void );
/*-----------------------------------------------------------*/
/* A buffer used to both create content to write to disk, and read content back
from a disk. Note there is no mutual exclusion on this buffer. */
static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];
/* Names of directories that are created. */
static const char *pcDirectory1 = "/SUB1", *pcDirectory2 = "/SUB1/SUB2";
/*-----------------------------------------------------------*/
void vCreateAndVerifySampleFiles( void )
{
int32_t lStatus;
/* First initialize the Reliance Edge driver. */
lStatus = red_init();
/* Format the volume. */
if( lStatus == 0 )
{
lStatus = red_format( fsVOLUME_NAME );
}
/* Mount the volume. */
if( lStatus == 0 )
{
lStatus = red_mount( fsVOLUME_NAME );
}
if( lStatus == 0 )
{
/* Create a set of files using red_write(). */
prvCreateDemoFiles();
/* Read back and verify the files that were created using red_write(). */
prvVerifyDemoFiles();
}
}
/*-----------------------------------------------------------*/
static void prvCreateDemoFiles( void )
{
BaseType_t xFileNumber, xWriteNumber;
char cFilePath[ 64 ];
const BaseType_t xMaxFiles = 5;
uint32_t ulEventMask;
int32_t lBytesWritten, lFildes, lStatus;
int iByte;
/* Save the current transaction point settings. */
lStatus = red_gettransmask( fsVOLUME_NAME, &ulEventMask );
configASSERT( lStatus == 0 );
/* Disable automatic transaction points so that all of the files can be
created in one atomic operation. */
lStatus = red_settransmask( fsVOLUME_NAME, RED_TRANSACT_MANUAL );
configASSERT( lStatus == 0 );
/* Create xMaxFiles files. Each created file will be
( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled
with a different repeating character. */
for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )
{
/* Generate a file name. */
sprintf( cFilePath, "/root%03d.txt", xFileNumber );
/* Print out the file name and the directory into which the file is
being written. */
printf( "Creating file %s\r\n", cFilePath );
/* Open the file, creating the file if it does not already exist. */
lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY );
configASSERT( lFildes != -1 );
/* Fill the RAM buffer with data that will be written to the file. This
is just a repeating ascii character that indicates the file number. */
memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );
/* Write the RAM buffer to the opened file a number of times. The
number of times the RAM buffer is written to the file depends on the
file number, so the length of each created file will be different. */
for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )
{
lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );
configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE );
}
/* Close the file so another file can be created. */
lStatus = red_close( lFildes );
configASSERT( lStatus == 0 );
}
/* Commit a transaction point, atomically adding the set of files to the
transacted state. */
lStatus = red_transact( fsVOLUME_NAME );
configASSERT( lStatus == 0 );
/* Create a sub directory. */
printf( "Creating directory %s\r\n", pcDirectory1 );
lStatus = red_mkdir( pcDirectory1 );
configASSERT( lStatus == 0 );
/* Create a subdirectory in the new directory. */
printf( "Creating directory %s\r\n", pcDirectory2 );
lStatus = red_mkdir( pcDirectory2 );
configASSERT( lStatus == 0 );
/* Generate the file name. */
sprintf( cFilePath, "%s/file.txt", pcDirectory2 );
/* Print out the file name and the directory into which the file is being
written. */
printf( "Writing file %s\r\n", cFilePath );
lFildes = red_open( cFilePath, RED_O_CREAT|RED_O_TRUNC|RED_O_WRONLY );
/* Write the file. It is filled with incrementing ascii characters starting
from '0'. */
for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ )
{
cRAMBuffer[ iByte ] = ( char ) ( ( int ) '0' + iByte );
}
lBytesWritten = red_write( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );
configASSERT( lBytesWritten == fsRAM_BUFFER_SIZE );
/* Finished so close the file. */
lStatus = red_close( lFildes );
configASSERT( lStatus == 0 );
/* Commit a transaction point, atomically adding the set of files and
directories to the transacted state. */
lStatus = red_transact( fsVOLUME_NAME );
configASSERT( lStatus == 0 );
/* Restore previous transaction point settings. */
lStatus = red_settransmask( fsVOLUME_NAME, ulEventMask );
configASSERT( lStatus == 0 );
}
/*-----------------------------------------------------------*/
static void prvVerifyDemoFiles( void )
{
BaseType_t xFileNumber, xReadNumber;
char cFilePath[ 64 ];
const BaseType_t xMaxFiles = 5;
long lChar;
int32_t lBytesRead, lFildes, lStatus;
int iByte;
/* Read back the files that were created by prvCreateDemoFiles(). */
for( xFileNumber = 1; xFileNumber <= xMaxFiles; xFileNumber++ )
{
/* Generate the file name. */
sprintf( cFilePath, "/root%03d.txt", xFileNumber );
/* Print out the file name and the directory from which the file is
being read. */
printf( "Reading file %s\r\n", cFilePath );
/* Open the file for reading. */
lFildes = red_open( cFilePath, RED_O_RDONLY );
configASSERT( lFildes != -1 );
/* Read the file into the RAM buffer, checking the file contents are as
expected. The size of the file depends on the file number. */
for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )
{
/* Start with the RAM buffer clear. */
memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );
lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );
configASSERT( lBytesRead == fsRAM_BUFFER_SIZE );
/* Check the RAM buffer is filled with the expected data. Each
file contains a different repeating ascii character that indicates
the number of the file. */
for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )
{
configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );
}
}
/* Close the file. */
lStatus = red_close( lFildes );
configASSERT( lStatus == 0 );
}
/* Generate the file name. */
sprintf( cFilePath, "%s/file.txt", pcDirectory2 );
/* Print out the file name and the directory from which the file is being
read. */
printf( "Reading file %s\r\n", cFilePath );
/* This time the file is opened for reading. */
lFildes = red_open( cFilePath, RED_O_RDONLY );
configASSERT( lFildes != -1 );
/* Read the file. */
lBytesRead = red_read( lFildes, cRAMBuffer, fsRAM_BUFFER_SIZE );
configASSERT( lBytesRead == fsRAM_BUFFER_SIZE );
/* Verify the file 1 byte at a time. */
for( iByte = 0; iByte < fsRAM_BUFFER_SIZE; iByte++ )
{
configASSERT( cRAMBuffer[ iByte ] == ( char ) ( ( int ) '0' + iByte ) );
}
/* Finished so close the file. */
lStatus = red_close( lFildes );
configASSERT( lStatus == 0 );
}

View file

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WIN32", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32
{C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,5 @@
[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,2
[InternetShortcut]
URL=http://www.freertos.org/FreeRTOS-Plus/Fail_Safe_File_System/Reliance_Edge_Fail_Safe_File_System.shtml
IDList=

View file

@ -0,0 +1,132 @@
/*
FreeRTOS V8.2.2 - 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!
*/
/*
* Utility functions required to gather run time statistics. See:
* http://www.freertos.org/rtos-run-time-stats.html
*
* Note that this is a simulated port, where simulated time is a lot slower than
* real time, therefore the run time counter values have no real meaningful
* units.
*
* Also note that it is assumed this demo is going to be used for short periods
* of time only, and therefore timer overflows are not handled.
*/
/* FreeRTOS includes. */
#include <FreeRTOS.h>
/* Variables used in the creation of the run time stats time base. Run time
stats record how much time each task spends in the Running state. */
static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL;
/*-----------------------------------------------------------*/
void vConfigureTimerForRunTimeStats( void )
{
LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue;
/* Initialise the variables used to create the run time stats time base.
Run time stats record how much time each task spends in the Running
state. */
if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 )
{
llTicksPerHundedthMillisecond = 1;
}
else
{
/* How many times does the performance counter increment in 1/100th
millisecond. */
llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL;
/* What is the performance counter value now, this will be subtracted
from readings taken at run time. */
QueryPerformanceCounter( &liInitialRunTimeValue );
llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart;
}
}
/*-----------------------------------------------------------*/
unsigned long ulGetRunTimeCounterValue( void )
{
LARGE_INTEGER liCurrentCount;
unsigned long ulReturn;
/* What is the performance counter value now? */
QueryPerformanceCounter( &liCurrentCount );
/* Subtract the performance counter value reading taken when the
application started to get a count from that reference point, then
scale to (simulated) 1/100ths of a millisecond. */
ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond );
return ulReturn;
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,421 @@
/*
FreeRTOS V8.2.2 - 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!
*/
/******************************************************************************
*
* See the following URL for information on the commands defined in this file:
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml
*
******************************************************************************/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS+CLI includes. */
#include "FreeRTOS_CLI.h"
#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
#define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0
#endif
/*
* Implements the run-time-stats command.
*/
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Implements the task-stats command.
*/
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Implements the echo-three-parameters command.
*/
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Implements the echo-parameters command.
*/
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Implements the "trace start" and "trace stop" commands;
*/
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
#endif
/* Structure that defines the "run-time-stats" command line command. This
generates a table that shows how much run time each task has */
static const CLI_Command_Definition_t xRunTimeStats =
{
"run-time-stats", /* The command string to type. */
"\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",
prvRunTimeStatsCommand, /* The function to run. */
0 /* No parameters are expected. */
};
/* Structure that defines the "task-stats" command line command. This generates
a table that gives information on each task in the system. */
static const CLI_Command_Definition_t xTaskStats =
{
"task-stats", /* The command string to type. */
"\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",
prvTaskStatsCommand, /* The function to run. */
0 /* No parameters are expected. */
};
/* Structure that defines the "echo_3_parameters" command line command. This
takes exactly three parameters that the command simply echos back one at a
time. */
static const CLI_Command_Definition_t xThreeParameterEcho =
{
"echo-3-parameters",
"\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",
prvThreeParameterEchoCommand, /* The function to run. */
3 /* Three parameters are expected, which can take any value. */
};
/* Structure that defines the "echo_parameters" command line command. This
takes a variable number of parameters that the command simply echos back one at
a time. */
static const CLI_Command_Definition_t xParameterEcho =
{
"echo-parameters",
"\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",
prvParameterEchoCommand, /* The function to run. */
-1 /* The user can enter any number of commands. */
};
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
/* Structure that defines the "trace" command line command. This takes a single
parameter, which can be either "start" or "stop". */
static const CLI_Command_Definition_t xStartStopTrace =
{
"trace",
"\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",
prvStartStopTraceCommand, /* The function to run. */
1 /* One parameter is expected. Valid values are "start" and "stop". */
};
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
/*-----------------------------------------------------------*/
void vRegisterSampleCLICommands( void )
{
/* Register all the command line commands defined immediately above. */
FreeRTOS_CLIRegisterCommand( &xTaskStats );
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );
FreeRTOS_CLIRegisterCommand( &xParameterEcho );
#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )
{
FreeRTOS_CLIRegisterCommand( & xStartStopTrace );
}
#endif
}
/*-----------------------------------------------------------*/
static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char *const pcHeader = "Task State Priority Stack #\r\n************************************************\r\n";
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
/* Generate a table of task stats. */
strcpy( pcWriteBuffer, pcHeader );
vTaskList( pcWriteBuffer + strlen( pcHeader ) );
/* There is no more data to return after this single string, so return
pdFALSE. */
return pdFALSE;
}
/*-----------------------------------------------------------*/
static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char * const pcHeader = "Task Abs Time % Time\r\n****************************************\r\n";
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
/* Generate a table of task stats. */
strcpy( pcWriteBuffer, pcHeader );
vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );
/* There is no more data to return after this single string, so return
pdFALSE. */
return pdFALSE;
}
/*-----------------------------------------------------------*/
static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char *pcParameter;
BaseType_t xParameterStringLength, xReturn;
static BaseType_t lParameterNumber = 0;
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
if( lParameterNumber == 0 )
{
/* The first time the function is called after the command has been
entered just a header string is returned. */
sprintf( pcWriteBuffer, "The three parameters were:\r\n" );
/* Next time the function is called the first parameter will be echoed
back. */
lParameterNumber = 1L;
/* There is more data to be returned as no parameters have been echoed
back yet. */
xReturn = pdPASS;
}
else
{
/* Obtain the parameter string. */
pcParameter = FreeRTOS_CLIGetParameter
(
pcCommandString, /* The command string itself. */
lParameterNumber, /* Return the next parameter. */
&xParameterStringLength /* Store the parameter string length. */
);
/* Sanity check something was returned. */
configASSERT( pcParameter );
/* Return the parameter string. */
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
strncat( pcWriteBuffer, pcParameter, xParameterStringLength );
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
/* If this is the last of the three parameters then there are no more
strings to return after this one. */
if( lParameterNumber == 3L )
{
/* If this is the last of the three parameters then there are no more
strings to return after this one. */
xReturn = pdFALSE;
lParameterNumber = 0L;
}
else
{
/* There are more parameters to return after this one. */
xReturn = pdTRUE;
lParameterNumber++;
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char *pcParameter;
BaseType_t xParameterStringLength, xReturn;
static BaseType_t lParameterNumber = 0;
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
if( lParameterNumber == 0 )
{
/* The first time the function is called after the command has been
entered just a header string is returned. */
sprintf( pcWriteBuffer, "The parameters were:\r\n" );
/* Next time the function is called the first parameter will be echoed
back. */
lParameterNumber = 1L;
/* There is more data to be returned as no parameters have been echoed
back yet. */
xReturn = pdPASS;
}
else
{
/* Obtain the parameter string. */
pcParameter = FreeRTOS_CLIGetParameter
(
pcCommandString, /* The command string itself. */
lParameterNumber, /* Return the next parameter. */
&xParameterStringLength /* Store the parameter string length. */
);
if( pcParameter != NULL )
{
/* Return the parameter string. */
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
sprintf( pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
strncat( pcWriteBuffer, pcParameter, xParameterStringLength );
strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
/* There might be more parameters to return after this one. */
xReturn = pdTRUE;
lParameterNumber++;
}
else
{
/* No more parameters were found. Make sure the write buffer does
not contain a valid string. */
pcWriteBuffer[ 0 ] = 0x00;
/* No more data to return. */
xReturn = pdFALSE;
/* Start over the next time this command is executed. */
lParameterNumber = 0;
}
}
return xReturn;
}
/*-----------------------------------------------------------*/
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
const char *pcParameter;
BaseType_t lParameterStringLength;
/* Remove compile time warnings about unused parameters, and check the
write buffer is not NULL. NOTE - for simplicity, this example assumes the
write buffer length is adequate, so does not check for buffer overflows. */
( void ) pcCommandString;
( void ) xWriteBufferLen;
configASSERT( pcWriteBuffer );
/* Obtain the parameter string. */
pcParameter = FreeRTOS_CLIGetParameter
(
pcCommandString, /* The command string itself. */
1, /* Return the first parameter. */
&lParameterStringLength /* Store the parameter string length. */
);
/* Sanity check something was returned. */
configASSERT( pcParameter );
/* There are only two valid parameter values. */
if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )
{
/* Start or restart the trace. */
vTraceStop();
vTraceClear();
vTraceStart();
sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );
}
else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )
{
/* End the trace, if one is running. */
vTraceStop();
sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" );
}
else
{
sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );
}
/* There is no more data to return after this single string, so return
pdFALSE. */
return pdFALSE;
}
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */

View file

@ -0,0 +1,271 @@
/*
FreeRTOS V8.2.2 - 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!
*/
#pragma comment( lib, "ws2_32.lib" )
/* Win32 includes. */
#include <WinSock2.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
/* FreeRTOS+CLI includes. */
#include "FreeRTOS_CLI.h"
/* Dimensions the buffer into which input characters are placed. */
#define cmdMAX_INPUT_SIZE 60
/* Dimensions the buffer into which string outputs can be placed. */
#define cmdMAX_OUTPUT_SIZE 1024
/* Dimensions the buffer passed to the recvfrom() call. */
#define cmdSOCKET_INPUT_BUFFER_SIZE 60
/* DEL acts as a backspace. */
#define cmdASCII_DEL ( 0x7F )
/*
* Open and configure the UDP socket.
*/
static SOCKET prvOpenUDPSocket( void );
/*-----------------------------------------------------------*/
/*
* Task that provides the input and output for the FreeRTOS+CLI command
* interpreter. In this case a WinSock UDP port is used for convenience as this
* demo runs in a simulated environment on a Windows PC. See the URL in the
* comments within main.c for the location of the online documentation.
*/
void vUDPCommandInterpreterTask( void *pvParameters )
{
long lBytes, lByte;
signed char cInChar, cInputIndex = 0;
static signed char cInputString[ cmdMAX_INPUT_SIZE ], cOutputString[ cmdMAX_OUTPUT_SIZE ], cLocalBuffer[ cmdSOCKET_INPUT_BUFFER_SIZE ];
BaseType_t xMoreDataToFollow;
volatile int iErrorCode = 0;
struct sockaddr_in xClient;
int xClientAddressLength = sizeof( struct sockaddr_in );
SOCKET xSocket;
/* Just to prevent compiler warnings. */
( void ) pvParameters;
/* Attempt to open the socket. */
xSocket = prvOpenUDPSocket();
if( xSocket != INVALID_SOCKET )
{
for( ;; )
{
/* Wait for incoming data on the opened socket. */
lBytes = recvfrom( xSocket, cLocalBuffer, sizeof( cLocalBuffer ), 0, ( struct sockaddr * ) &xClient, &xClientAddressLength );
if( lBytes == SOCKET_ERROR )
{
/* Something went wrong, but it is not handled by this simple
example. */
iErrorCode = WSAGetLastError();
}
else
{
/* Process each received byte in turn. */
lByte = 0;
while( lByte < lBytes )
{
/* The next character in the input buffer. */
cInChar = cLocalBuffer[ lByte ];
lByte++;
/* Newline characters are taken as the end of the command
string. */
if( cInChar == '\n' )
{
/* Process the input string received prior to the
newline. */
do
{
/* Pass the string to FreeRTOS+CLI. */
xMoreDataToFollow = FreeRTOS_CLIProcessCommand( cInputString, cOutputString, cmdMAX_OUTPUT_SIZE );
/* Send the output generated by the command's
implementation. */
sendto( xSocket, cOutputString, strlen( cOutputString ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );
} while( xMoreDataToFollow != pdFALSE ); /* Until the command does not generate any more output. */
/* All the strings generated by the command processing
have been sent. Clear the input string ready to receive
the next command. */
cInputIndex = 0;
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
/* Transmit a spacer, just to make the command console
easier to read. */
sendto( xSocket, "\r\n", strlen( "\r\n" ), 0, ( SOCKADDR * ) &xClient, xClientAddressLength );
}
else
{
if( cInChar == '\r' )
{
/* Ignore the character. Newlines are used to
detect the end of the input string. */
}
else if( ( cInChar == '\b' ) || ( cInChar == cmdASCII_DEL ) )
{
/* Backspace was pressed. Erase the last character
in the string - if any. */
if( cInputIndex > 0 )
{
cInputIndex--;
cInputString[ cInputIndex ] = '\0';
}
}
else
{
/* A character was entered. Add it to the string
entered so far. When a \n is entered the complete
string will be passed to the command interpreter. */
if( cInputIndex < cmdMAX_INPUT_SIZE )
{
cInputString[ cInputIndex ] = cInChar;
cInputIndex++;
}
}
}
}
}
}
}
else
{
/* The socket could not be opened. */
vTaskDelete( NULL );
}
}
/*-----------------------------------------------------------*/
static SOCKET prvOpenUDPSocket( void )
{
WSADATA xWSAData;
WORD wVersionRequested;
struct sockaddr_in xServer;
SOCKET xSocket = INVALID_SOCKET;
wVersionRequested = MAKEWORD( 2, 2 );
/* Prepare to use WinSock. */
if( WSAStartup( wVersionRequested, &xWSAData ) != 0 )
{
fprintf( stderr, "Could not open Windows connection.\n" );
}
else
{
xSocket = socket( AF_INET, SOCK_DGRAM, 0 );
if( xSocket == INVALID_SOCKET)
{
fprintf( stderr, "Could not create socket.\n" );
WSACleanup();
}
else
{
/* Zero out the server structure. */
memset( ( void * ) &xServer, 0x00, sizeof( struct sockaddr_in ) );
/* Set family and port. */
xServer.sin_family = AF_INET;
xServer.sin_port = htons( configUDP_CLI_PORT_NUMBER );
/* Assign the loopback address */
xServer.sin_addr.S_un.S_un_b.s_b1 = 127;
xServer.sin_addr.S_un.S_un_b.s_b2 = 0;
xServer.sin_addr.S_un.S_un_b.s_b3 = 0;
xServer.sin_addr.S_un.S_un_b.s_b4 = 1;
/* Bind the address to the socket. */
if( bind( xSocket, ( struct sockaddr * ) &xServer, sizeof( struct sockaddr_in ) ) == -1 )
{
fprintf( stderr, "Could not socket to port %d.\n", configUDP_CLI_PORT_NUMBER );
closesocket( xSocket );
xSocket = INVALID_SOCKET;
WSACleanup();
}
}
}
return xSocket;
}

View file

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>
<ProjectName>RTOSDemo</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\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>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c09</Culture>
</ResourceCompile>
<Link>
<OutputFile>.\Debug/RTOSDemo.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/WIN32.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c09</Culture>
</ResourceCompile>
<Link>
<OutputFile>.\Release/RTOSDemo.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>
<AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/WIN32.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />
<ClCompile Include="..\..\..\FreeRTOS\Source\list.c" />
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />
<ClCompile Include="..\..\..\FreeRTOS\Source\queue.c" />
<ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c" />
<ClCompile Include="..\..\..\FreeRTOS\Source\timers.c" />
<ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\blockio.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\buffer.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\core.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\dir.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\format.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imap.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapextern.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapinline.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inode.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inodedata.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\volume.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\fse\fse.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osassert.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osbdev.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osclock.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osmutex.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osoutput.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostask.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostimestamp.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\posix\path.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\posix\posix.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\posix\fsstress.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\atoi.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\math.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\printf.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\rand.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\getopt.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\toolcmn.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\bitmap.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\crc.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\endian.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\memory.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\namelen.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\sign.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\util\string.c" />
<ClCompile Include="ConfigurationFiles\redconf.c" />
<ClCompile Include="File-Related-CLI-commands.c" />
<ClCompile Include="File-system-demo.c" />
<ClCompile Include="main.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="Run-time-stats-utils.c" />
<ClCompile Include="Sample-CLI-commands.c" />
<ClCompile Include="UDPCommandServer.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" />
<ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h" />
<ClInclude Include="..\..\Source\Reliance-Edge\os\freertos\include\ostypes.h" />
<ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h" />
<ClInclude Include="ConfigurationFiles\redconf.h" />
<ClInclude Include="ConfigurationFiles\redtypes.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resource Files">
<UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
<Filter Include="FreeRTOS">
<UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS\Source">
<UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>
<Extensions>*.c</Extensions>
</Filter>
<Filter Include="FreeRTOS\Source\Portable">
<UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+">
<UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+CLI">
<UniqueIdentifier>{fd43c0ed-fdbc-437f-a5a3-c50399690bd7}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+CLI\include">
<UniqueIdentifier>{c5889fe2-af0f-4cea-927f-6a6935ec5e14}</UniqueIdentifier>
</Filter>
<Filter Include="Configuration Files">
<UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="FreeRTOS\Source\include">
<UniqueIdentifier>{ab23827c-126c-4e5a-bc99-8efa44d8a8bd}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge">
<UniqueIdentifier>{9c9c3b2d-6958-407d-b742-23fbf73678ed}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\test">
<UniqueIdentifier>{e47b8f1d-1582-4e56-9c2f-ca2cdbea1b86}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\port">
<UniqueIdentifier>{9ecfe142-5bd2-472b-9568-243fa6169874}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\driver">
<UniqueIdentifier>{28ee3d7e-231b-4094-8a10-ad89fc82f705}</UniqueIdentifier>
</Filter>
<Filter Include="FreeRTOS+\FreeRTOS+Reliance Edge\util">
<UniqueIdentifier>{a955d01e-1f95-4c34-9558-14c52b75576f}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">
<Filter>FreeRTOS\Source\Portable</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS\Source\timers.c">
<Filter>FreeRTOS\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS\Source\list.c">
<Filter>FreeRTOS\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS\Source\queue.c">
<Filter>FreeRTOS\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS\Source\tasks.c">
<Filter>FreeRTOS\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">
<Filter>FreeRTOS\Source\Portable</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c">
<Filter>FreeRTOS+\FreeRTOS+CLI</Filter>
</ClCompile>
<ClCompile Include="UDPCommandServer.c" />
<ClCompile Include="File-system-demo.c" />
<ClCompile Include="main.c" />
<ClCompile Include="Run-time-stats-utils.c" />
<ClCompile Include="Sample-CLI-commands.c" />
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\printf.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\rand.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\tests\posix\fsstress.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostimestamp.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osassert.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osbdev.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osclock.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osmutex.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\osoutput.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\os\freertos\services\ostask.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\volume.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\blockio.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\buffer.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\core.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\dir.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\format.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\fse\fse.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imap.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapextern.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\imapinline.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inode.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\core\driver\inodedata.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\posix\path.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\posix\posix.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\driver</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\bitmap.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\string.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\crc.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\endian.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\memory.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\namelen.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\util\sign.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\util</Filter>
</ClCompile>
<ClCompile Include="File-Related-CLI-commands.c" />
<ClCompile Include="ConfigurationFiles\redconf.c">
<Filter>Configuration Files</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\atoi.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\tests\util\math.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\getopt.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Reliance-Edge\toolcmn\toolcmn.c">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\test</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.h">
<Filter>FreeRTOS+\FreeRTOS+CLI\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\FreeRTOS.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\projdefs.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\queue.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\semphr.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h">
<Filter>FreeRTOS\Source\include</Filter>
</ClInclude>
<ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h">
<Filter>Configuration Files</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Reliance-Edge\os\freertos\include\ostypes.h">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClInclude>
<ClInclude Include="ConfigurationFiles\redconf.h">
<Filter>Configuration Files</Filter>
</ClInclude>
<ClInclude Include="ConfigurationFiles\redtypes.h">
<Filter>Configuration Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

View file

@ -0,0 +1,204 @@
/*
FreeRTOS V8.2.2 - 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 demo is described on the following web page:
* TODO: This link describes the FAT version of this demo.
* http://FreeRTOS-Plus/Fail_Safe_File_System/Fail_Safe_Embedded_File_System_demo.shtml
*
******************************************************************************/
/* Standard includes. */
#include <stdio.h>
#include <stdint.h>
/* FreeRTOS includes. */
#include <FreeRTOS.h>
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Priorities at which the tasks are created. */
#define mainUDP_CLI_TASK_PRIORITY ( tskIDLE_PRIORITY )
/*-----------------------------------------------------------*/
/*
* Register the generic commands that can be used with FreeRTOS+CLI.
*/
extern void vRegisterSampleCLICommands( void );
/*
* Register the file system commands that can be used with FreeRTOS+CLI.
*/
extern void vRegisterFileSystemCLICommands( void );
/*
* The task that implements the UDP command interpreter using FreeRTOS+CLI.
*/
extern void vUDPCommandInterpreterTask( void *pvParameters );
/*
* Creates and verifies different files on the volume, demonstrating the use of
* various different API functions.
*/
extern void vCreateAndVerifySampleFiles( void );
/*-----------------------------------------------------------*/
#pragma warning - add link to documentation page
int main( void )
{
const uint32_t ulLongTime_ms = 250UL;
/* Initialise the drive and file system, then create a few example
files. The output from this function just goes to the stdout window,
allowing the output to be viewed when the UDP command console is not
connected. */
vCreateAndVerifySampleFiles();
/* Register generic commands with the FreeRTOS+CLI command interpreter. */
vRegisterSampleCLICommands();
/* Register file system related commands with the FreeRTOS+CLI command
interpreter. */
vRegisterFileSystemCLICommands();
/* Create the task that handles the CLI on a UDP port. The port number
is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */
xTaskCreate( vUDPCommandInterpreterTask, /* The function that implements the command interpreter IO handling. */
"CLI", /* The name of the task - just to assist debugging. */
configMINIMAL_STACK_SIZE, NULL, /* The size of the stack allocated to the task. */
mainUDP_CLI_TASK_PRIORITY, /* The priority at which the task will run. */
NULL ); /* A handle to the task is not required, so NULL is passed. */
/* Start the RTOS scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
line will never be reached. If the following line does execute, then
there was insufficient FreeRTOS heap memory available for the idle and/or
timer tasks to be created. See the memory management section on the
FreeRTOS web site for more details (this is standard text that is not not
really applicable to the Win32 simulator port). */
for( ;; )
{
Sleep( ulLongTime_ms );
}
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
const unsigned long ulMSToSleep = 5;
/* This function is called on each cycle of the idle task if
configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h. Sleep to reduce CPU
load. */
Sleep( ulMSToSleep );
}
/*-----------------------------------------------------------*/
void vAssertCalled( const char *pcFile, unsigned long ulLine )
{
volatile uint32_t ulSetToNonZeroToExitLoop = 0;
printf( "ASSERT FAILED: File %s, line %u\r\n", pcFile, ulLine );
taskENTER_CRITICAL();
{
while( ulSetToNonZeroToExitLoop == 0 )
{
/* Do not leave the assert function unless the debugger is used to
set ulSetToNonZeroToExitLoop to a non-zero value. */
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c, heap_2.c or heap_4.c are used, then the
size of the heap available to pvPortMalloc() is defined by
configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
API function can be used to query the size of free heap space that remains
(although it does not provide information on how the remaining heap might
be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
}

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -1,5 +1,5 @@
/*
FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

View file

@ -53,8 +53,8 @@
/* If the application writer needs to place the buffer used by the CLI at a
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
FreeRTOSConfig.h, and provide then declare an array as follows with the
following name and size in one of the application files:
FreeRTOSConfig.h, then declare an array with the following name and size in
one of the application files:
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
*/
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer

View file

@ -0,0 +1,18 @@
Reliance Edge Credits
=====================
This is a list (or partial list) of people who have made non-trivial or
noteworthy contributions to the Reliance Edge project. It is sorted by name.
Entries are formatted as below:
Real Name (githubaccount)
Short description of how Real Name contributed to Reliance Edge.
The real name may be withheld by request and the GitHub account name might be
missing if the contributor does not use GitHub.
Credits
-------
None yet! ;)

View file

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -0,0 +1,115 @@
# Reliance Edge
Reliance Edge is a small, portable, highly reliable power-fail safe file system
for resource-constrained embedded systems like microcontrollers. It is written
in C and provides a familiar POSIX-like file system API, making it easy to use
in your application; or an alternate minimalist API if your application has
simple storage needs. Reliance Edge is highly configurable and can be tuned to
the precise needs of your application.
## Documentation
The complete documentation for Reliance Edge is distributed separately. It
includes an API reference and detailed discussions of various aspects of using
Reliance Edge, including porting, building, configuring, and testing. This
complete documentation, called the _Developer's Guide_, can be obtained for free
from here:
<http://www.datalight.com/reliance-edge>
In addition this README, see [doc/release_notes.md](doc/release_notes.md) for a
list of updates to Reliance Edge and a list of known issues. There is also a
quick-start guide in the doc/ directory that describes step-by-step how to
compile and run Reliance Edge in a simulated Windows environment.
## Why Use Reliance Edge?
Reliance Edge is ideal for small embedded systems with data storage
requirements, especially if there is a chance of sudden power loss or other
system failures. Compared to "raw" disk access, using a file system like
Reliance Edge removes the burden of tracking which sectors belong to which
objects, and allows data to be updated more reliably. Compared to the FAT file
system, using Reliance Edge eliminates the possibility that file system data
will be left in an inconsistent state, corrupting the disk; Reliance Edge does
not need a fsck/CHKDSK utility. Compared to journaling file systems, Reliance
Edge has less overhead and results in less storage media wear for longer device
lifetimes.
Reliance Edge uses a unique transactional model that not only prevents file
system corruption but also allows a set of changes to be made in an atomic "all
or nothing" fashion. This is very useful for applications that make sets of
interrelated changes. By using the features of Reliance Edge, a set of changes
can be incorporated into a single atomic transaction, which is committed in its
entirety or not at all even if interrupted by power loss; this means the
application does not need code to recover from partially-finished updates.
## Hardware
The typical hardware for Reliance Edge is a 32-bit microcontroller, but other
targets are possible. In its typical configurations, Reliance Edge needs at
least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the ROM or NOR flash),
and 500 to 700 bytes of stack.
Reliance Edge is not designed for high-end embedded systems that run complicated
operating systems like Linux or Windows Embedded Compact. Embedded systems of
that variety are better served by other file systems, like Datalight's
[Reliance Nitro](http://www.datalight.com/products/embedded-file-systems/reliance-nitro).
## Getting Reliance Edge Working
Before you can use Reliance Edge, it must be ported and configured. At a
minimum, porting includes filling-in functions so that Reliance Edge can issue
commands to your storage medium; depending on your needs, other functions may
need to be filled in as well. These functions reside in a subdirectory in the
os/ directory; see os/stub/ for a blank set of functions. Configuring includes
creating a project directory (start by copying projects/newproj) and creating
the two configuration files (redconf.h/redconf.c) using the Reliance Edge
Configuration Utility (which can be downloaded from
<http://www.datalight.com/reliance-edge>).
These topics are covered in much greater detail in the _Developer's Guide_,
linked above.
## Using Reliance Edge
Using Reliance Edge is a simple matter of including the primary Reliance Edge
application header in your application (either include/redposix.h or
include/redfse.h) and compiling and linking against Reliance Edge binaries.
The Reliance Edge driver must be initialized before it is used (via the
red\_init() or RedFseInit() functions) and then volumes can be mounted and file
and directory functions invoked. The Reliance Edge API is documented in the
_Developer's Guide_ (linked above) and also via comments in the source code.
## Licensing
Reliance Edge is an open-source project licensed under the GNU General Public
License v2 (GPLv2). 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. The commercial distribution also includes extra tests and
tools not distributed with the GPLv2 version.
See LICENSE.txt for the full license terms of this distribution of the product.
## Getting Help
If you need assistance using Reliance Edge, and you have already consulted the
_Developer's Guide_, contact <RelianceEdgeSupport@datalight.com>.
In the near future, a community forum or message board will be set up to
facilitate discussion of Reliance Edge and allow users to get help from
Datalight and from each other. In the meantime, please use the email address
given above.
## Contributing
Contributions to Reliance Edge are welcome. Our policy is that Datalight must
own the copyright of all code incorporated into Reliance Edge; if contributing a
significant amount of code, you will be asked to file a copyright assignment
agreement. See CONTRIBUTING.txt for further details and contribution
guidelines.
To report bugs, please create a GitHub issue or contact
<RelianceEdgeSupport@datalight.com>.

View file

@ -0,0 +1,131 @@
RELIANCE EDGE
Reliance Edge is a small, portable, highly reliable power-fail safe file
system for resource-constrained embedded systems like microcontrollers.
It is written in C and provides a familiar POSIX-like file system API,
making it easy to use in your application; or an alternate minimalist
API if your application has simple storage needs. Reliance Edge is
highly configurable and can be tuned to the precise needs of your
application.
Documentation
The complete documentation for Reliance Edge is distributed separately.
It includes an API reference and detailed discussions of various aspects
of using Reliance Edge, including porting, building, configuring, and
testing. This complete documentation, called the _Developer's Guide_,
can be obtained for free from here:
http://www.datalight.com/reliance-edge
In addition this README, see doc/release_notes.md for a list of updates
to Reliance Edge and a list of known issues. There is also a quick-start
guide in the doc/ directory that describes step-by-step how to compile
and run Reliance Edge in a simulated Windows environment.
Why Use Reliance Edge?
Reliance Edge is ideal for small embedded systems with data storage
requirements, especially if there is a chance of sudden power loss or
other system failures. Compared to "raw" disk access, using a file
system like Reliance Edge removes the burden of tracking which sectors
belong to which objects, and allows data to be updated more reliably.
Compared to the FAT file system, using Reliance Edge eliminates the
possibility that file system data will be left in an inconsistent state,
corrupting the disk; Reliance Edge does not need a fsck/CHKDSK utility.
Compared to journaling file systems, Reliance Edge has less overhead and
results in less storage media wear for longer device lifetimes.
Reliance Edge uses a unique transactional model that not only prevents
file system corruption but also allows a set of changes to be made in an
atomic "all or nothing" fashion. This is very useful for applications
that make sets of interrelated changes. By using the features of
Reliance Edge, a set of changes can be incorporated into a single atomic
transaction, which is committed in its entirety or not at all even if
interrupted by power loss; this means the application does not need code
to recover from partially-finished updates.
Hardware
The typical hardware for Reliance Edge is a 32-bit microcontroller, but
other targets are possible. In its typical configurations, Reliance Edge
needs at least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the
ROM or NOR flash), and 500 to 700 bytes of stack.
Reliance Edge is not designed for high-end embedded systems that run
complicated operating systems like Linux or Windows Embedded Compact.
Embedded systems of that variety are better served by other file
systems, like Datalight's Reliance Nitro.
Getting Reliance Edge Working
Before you can use Reliance Edge, it must be ported and configured. At a
minimum, porting includes filling-in functions so that Reliance Edge can
issue commands to your storage medium; depending on your needs, other
functions may need to be filled in as well. These functions reside in a
subdirectory in the os/ directory; see os/stub/ for a blank set of
functions. Configuring includes creating a project directory (start by
copying projects/newproj) and creating the two configuration files
(redconf.h/redconf.c) using the Reliance Edge Configuration Utility
(which can be downloaded from http://www.datalight.com/reliance-edge).
These topics are covered in much greater detail in the _Developer's
Guide_, linked above.
Using Reliance Edge
Using Reliance Edge is a simple matter of including the primary Reliance
Edge application header in your application (either include/redposix.h
or include/redfse.h) and compiling and linking against Reliance Edge
binaries. The Reliance Edge driver must be initialized before it is used
(via the red_init() or RedFseInit() functions) and then volumes can be
mounted and file and directory functions invoked. The Reliance Edge API
is documented in the _Developer's Guide_ (linked above) and also via
comments in the source code.
Licensing
Reliance Edge is an open-source project licensed under the GNU General
Public License v2 (GPLv2). 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. The
commercial distribution also includes extra tests and tools not
distributed with the GPLv2 version.
See LICENSE.txt for the full license terms of this distribution of the
product.
Getting Help
If you need assistance using Reliance Edge, and you have already
consulted the _Developer's Guide_, contact
RelianceEdgeSupport@datalight.com.
In the near future, a community forum or message board will be set up to
facilitate discussion of Reliance Edge and allow users to get help from
Datalight and from each other. In the meantime, please use the email
address given above.
Contributing
Contributions to Reliance Edge are welcome. Our policy is that Datalight
must own the copyright of all code incorporated into Reliance Edge; if
contributing a significant amount of code, you will be asked to file a
copyright assignment agreement. See CONTRIBUTING.txt for further details
and contribution guidelines.
To report bugs, please create a GitHub issue or contact
RelianceEdgeSupport@datalight.com.

View file

@ -0,0 +1,164 @@
/* ----> 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 Implements block device I/O using logical blocks as the units.
The OS block device implementations operate on sectors. The core does I/O
in terms of logical blocks: this module translates from logical blocks to
sectors.
*/
#include <redfs.h>
#include <redcore.h>
/** @brief Read a range of logical blocks.
@param bVolNum The volume whose block device is being read from.
@param ulBlockStart The first block to read.
@param ulBlockCount The number of blocks to read.
@param pBuffer The buffer to populate with the data read.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedIoRead(
uint8_t bVolNum,
uint32_t ulBlockStart,
uint32_t ulBlockCount,
void *pBuffer)
{
REDSTATUS ret;
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|| (ulBlockCount == 0U)
|| (pBuffer == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Write a range of logical blocks.
@param bVolNum The volume whose block device is being written to.
@param ulBlockStart The first block to write.
@param ulBlockCount The number of blocks to write.
@param pBuffer The buffer containing the data to write.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EINVAL Invalid parameters.
*/
REDSTATUS RedIoWrite(
uint8_t bVolNum,
uint32_t ulBlockStart,
uint32_t ulBlockCount,
const void *pBuffer)
{
REDSTATUS ret;
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|| (ulBlockCount == 0U)
|| (pBuffer == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
/** @brief Flush any caches beneath the file system.
@param bVolNum The volume number of the volume whose block device is being
flushed.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedIoFlush(
uint8_t bVolNum)
{
REDSTATUS ret;
if(bVolNum >= REDCONF_VOLUME_COUNT)
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
ret = RedOsBDevFlush(bVolNum);
}
CRITICAL_ASSERT(ret == 0);
return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,950 @@
/* ----> 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 Implements directory operations.
*/
#include <redfs.h>
#if REDCONF_API_POSIX == 1
#include <redcore.h>
#define DIR_INDEX_INVALID UINT32_MAX
#if (REDCONF_NAME_MAX % 4U) != 0U
#define DIRENT_PADDING (4U - (REDCONF_NAME_MAX % 4U))
#else
#define DIRENT_PADDING (0U)
#endif
#define DIRENT_SIZE (4U + REDCONF_NAME_MAX + DIRENT_PADDING)
#define DIRENTS_PER_BLOCK (REDCONF_BLOCK_SIZE / DIRENT_SIZE)
#define DIRENTS_MAX (uint32_t)REDMIN(UINT32_MAX, UINT64_SUFFIX(1) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK)
/** @brief On-disk directory entry.
*/
typedef struct
{
/** The inode number that the directory entry points at. If the directory
entry is available, this holds INODE_INVALID.
*/
uint32_t ulInode;
/** The name of the directory entry. For names shorter than
REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of
the maximum length, the string is not null terminated.
*/
char acName[REDCONF_NAME_MAX];
#if DIRENT_PADDING > 0U
/** Unused padding so that ulInode is always aligned on a four-byte
boundary.
*/
uint8_t abPadding[DIRENT_PADDING];
#endif
} DIRENT;
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode);
#endif
#if REDCONF_READ_ONLY == 0
static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen);
static uint64_t DirEntryIndexToOffset(uint32_t ulIdx);
#endif
static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset);
#if REDCONF_READ_ONLY == 0
/** @brief Create a new entry in a directory.
@param pPInode A pointer to the cached inode structure of the directory
to which the new entry will be added.
@param pszName The name to be given to the new entry, terminated by a
null or a path separator.
@param ulInode The inode number the new name will point at.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC There is not enough space on the volume to
create the new directory entry; or the directory
is full.
@retval -RED_ENOTDIR @p pPInode is not a directory.
@retval -RED_ENAMETOOLONG @p pszName is too long.
@retval -RED_EEXIST @p pszName already exists in @p ulPInode.
@retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode
structure; or @p pszName is not a valid name.
*/
REDSTATUS RedDirEntryCreate(
CINODE *pPInode,
const char *pszName,
uint32_t ulInode)
{
REDSTATUS ret;
if(!CINODE_IS_DIRTY(pPInode) || (pszName == NULL) || !INODE_IS_VALID(ulInode))
{
ret = -RED_EINVAL;
}
else if(!pPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
uint32_t ulNameLen = RedNameLen(pszName);
if(ulNameLen == 0U)
{
ret = -RED_EINVAL;
}
else if(ulNameLen > REDCONF_NAME_MAX)
{
ret = -RED_ENAMETOOLONG;
}
else
{
uint32_t ulEntryIdx;
ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL);
if(ret == 0)
{
ret = -RED_EEXIST;
}
else if(ret == -RED_ENOENT)
{
if(ulEntryIdx == DIR_INDEX_INVALID)
{
ret = -RED_ENOSPC;
}
else
{
ret = 0;
}
}
else
{
/* Unexpected error, no action.
*/
}
if(ret == 0)
{
ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen);
}
}
}
return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */
#if DELETE_SUPPORTED
/** @brief Delete an existing directory entry.
@param pPInode A pointer to the cached inode structure of the directory
containing the entry to be deleted.
@param ulDeleteIdx Position within the directory of the entry to be
deleted.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC The file system does not have enough space to modify
the parent directory to perform the deletion.
@retval -RED_ENOTDIR @p pPInode is not a directory.
@retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode
structure; or @p ulIdx is out of range.
*/
REDSTATUS RedDirEntryDelete(
CINODE *pPInode,
uint32_t ulDeleteIdx)
{
REDSTATUS ret = 0;
if(!CINODE_IS_DIRTY(pPInode) || (ulDeleteIdx >= DIRENTS_MAX))
{
ret = -RED_EINVAL;
}
else if(!pPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pInodeBuf->ullSize)
{
uint32_t ulTruncIdx = ulDeleteIdx;
bool fDone = false;
/* We are deleting the last dirent in the directory, so search
backwards to find the last populated dirent, allowing us to truncate
the directory to that point.
*/
while((ret == 0) && (ulTruncIdx > 0U) && !fDone)
{
ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK);
if(ret == 0)
{
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
uint32_t ulBlockIdx = (ulTruncIdx - 1U) % DIRENTS_PER_BLOCK;
do
{
if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
{
fDone = true;
break;
}
ulTruncIdx--;
ulBlockIdx--;
} while(ulBlockIdx != UINT32_MAX);
}
else if(ret == -RED_ENODATA)
{
ret = 0;
REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U);
ulTruncIdx -= DIRENTS_PER_BLOCK;
}
else
{
/* Unexpected error, loop will terminate; nothing else
to be done.
*/
}
}
/* Truncate the directory, deleting the requested entry and any empty
dirents at the end of the directory.
*/
if(ret == 0)
{
ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx));
}
}
else
{
/* The dirent to delete is not the last entry in the directory, so just
zero it.
*/
ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U);
}
return ret;
}
#endif /* DELETE_SUPPORTED */
/** @brief Perform a case-sensitive search of a directory for a given name.
If found, then position of the entry within the directory and the inode
number it points to are returned. As an optimization for directory entry
creation, in the case where the requested entry does not exist, the position
of the first available (unused) entry is returned.
@param pPInode A pointer to the cached inode structure of the directory
to search.
@param pszName The name of the desired entry, terminated by either a
null or a path separator.
@param pulEntryIdx On successful return, meaning that the desired entry
exists, populated with the position of the entry. If
returning an -RED_ENOENT error, populated with the
position of the first available entry, or set to
DIR_INDEX_INVALID if the directory is full. Optional.
@param pulInode On successful return, populated with the inode number
that the name points to. Optional; may be `NULL`.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOENT @p pszName does not name an existing file or
directory.
@retval -RED_ENOTDIR @p pPInode is not a directory.
@retval -RED_EINVAL @p pPInode is not a mounted cached inode
structure; or @p pszName is not a valid name; or
@p pulEntryIdx is `NULL`.
@retval -RED_ENAMETOOLONG @p pszName is too long.
*/
REDSTATUS RedDirEntryLookup(
CINODE *pPInode,
const char *pszName,
uint32_t *pulEntryIdx,
uint32_t *pulInode)
{
REDSTATUS ret = 0;
if(!CINODE_IS_MOUNTED(pPInode) || (pszName == NULL))
{
ret = -RED_EINVAL;
}
else if(!pPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
uint32_t ulNameLen = RedNameLen(pszName);
if(ulNameLen == 0U)
{
ret = -RED_EINVAL;
}
else if(ulNameLen > REDCONF_NAME_MAX)
{
ret = -RED_ENAMETOOLONG;
}
else
{
uint32_t ulIdx = 0U;
uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);
uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */
/* Loop over the directory blocks, searching each block for a
dirent that matches the given name.
*/
while((ret == 0) && (ulIdx < ulDirentCount))
{
ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK);
if(ret == 0)
{
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx);
uint32_t ulBlockIdx;
for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
{
const DIRENT *pDirent = &pDirents[ulBlockIdx];
if(pDirent->ulInode != INODE_INVALID)
{
/* The name in the dirent will not be null
terminated if it is of the maximum length, so
use a bounded string compare and then make sure
there is nothing more to the name.
*/
if( (RedStrNCmp(pDirent->acName, pszName, ulNameLen) == 0)
&& ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->acName[ulNameLen] == '\0')))
{
/* Found a matching dirent, stop and return its
information.
*/
if(pulInode != NULL)
{
*pulInode = pDirent->ulInode;
#ifdef REDCONF_ENDIAN_SWAP
*pulInode = RedRev32(*pulInode);
#endif
}
ulIdx += ulBlockIdx;
break;
}
}
else if(ulFreeIdx == DIR_INDEX_INVALID)
{
ulFreeIdx = ulIdx + ulBlockIdx;
}
else
{
/* The directory entry is free, but we already found a free one, so there's
nothing to do here.
*/
}
}
if(ulBlockIdx < ulBlockLastIdx)
{
/* If we broke out of the for loop, we found a matching
dirent and can stop the search.
*/
break;
}
ulIdx += ulBlockLastIdx;
}
else if(ret == -RED_ENODATA)
{
if(ulFreeIdx == DIR_INDEX_INVALID)
{
ulFreeIdx = ulIdx;
}
ret = 0;
ulIdx += DIRENTS_PER_BLOCK;
}
else
{
/* Unexpected error, let the loop terminate, no action
here.
*/
}
}
if(ret == 0)
{
/* If we made it all the way to the end of the directory
without stopping, then the given name does not exist in the
directory.
*/
if(ulIdx == ulDirentCount)
{
/* If the directory had no sparse dirents, then the first
free dirent is beyond the end of the directory. If the
directory is already the maximum size, then there is no
free dirent.
*/
if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX))
{
ulFreeIdx = ulDirentCount;
}
ulIdx = ulFreeIdx;
ret = -RED_ENOENT;
}
if(pulEntryIdx != NULL)
{
*pulEntryIdx = ulIdx;
}
}
}
}
return ret;
}
#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
/** @brief Read the next entry from a directory, given a starting index.
@param pInode A pointer to the cached inode structure of the directory to
read from.
@param pulIdx On entry, the directory index to start reading from. On
successful return, populated with the directory index to use
for subsequent reads. On -RED_ENOENT return, populated with
the directory index immediately following the last valid
one.
@param pszName On successful return, populated with the name of the next
directory entry. Buffer must be at least
REDCONF_NAME_MAX + 1 in size, to store the maximum name
length plus a null terminator.
@param pulInode On successful return, populated with the inode number
pointed at by the next directory entry.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOENT There are no more entries in the directory.
@retval -RED_ENOTDIR @p pPInode is not a directory.
@retval -RED_EINVAL @p pPInode is not a mounted cached inode structure;
or @p pszName is `NULL`; or @p pulIdx is `NULL`; or
@p pulInode is `NULL`.
*/
REDSTATUS RedDirEntryRead(
CINODE *pPInode,
uint32_t *pulIdx,
char *pszName,
uint32_t *pulInode)
{
REDSTATUS ret = 0;
if(!CINODE_IS_MOUNTED(pPInode) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL))
{
ret = -RED_EINVAL;
}
else if(!pPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
uint32_t ulIdx = *pulIdx;
uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);
/* Starting either at the beginning of the directory or where we left
off, loop over the directory blocks, searching each block for a
non-sparse dirent to return as the next entry in the directory.
*/
while((ret == 0) && (ulIdx < ulDirentCount))
{
uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK;
ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset);
if(ret == 0)
{
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK));
uint32_t ulBlockIdx;
for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
{
if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
{
*pulIdx = ulIdx + 1U;
RedStrNCpy(pszName, pDirents[ulBlockIdx].acName, REDCONF_NAME_MAX);
pszName[REDCONF_NAME_MAX] = '\0';
*pulInode = pDirents[ulBlockIdx].ulInode;
#ifdef REDCONF_ENDIAN_SWAP
*pulInode = RedRev32(*pulInode);
#endif
break;
}
ulIdx++;
}
if(ulBlockIdx < ulBlockLastIdx)
{
REDASSERT(ulIdx <= ulDirentCount);
break;
}
}
else if(ret == -RED_ENODATA)
{
ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK);
ret = 0;
}
else
{
/* Unexpected error, loop will terminate; nothing else to do.
*/
}
REDASSERT(ulIdx <= ulDirentCount);
}
if((ret == 0) && (ulIdx >= ulDirentCount))
{
*pulIdx = ulDirentCount;
ret = -RED_ENOENT;
}
}
return ret;
}
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
/** Rename a directory entry.
@param pSrcPInode The inode of the directory containing @p pszSrcName.
@param pszSrcName The name of the directory entry to be renamed.
@param pSrcInode On successful return, populated with the inode of the
source entry.
@param pDstPInode The inode of the directory in which @p pszDstName will
be created or replaced.
@param pszDstName The name of the directory entry to be created or
replaced.
@param pDstInode On successful return, if the destination previously
existed, populated with the inode previously pointed to
by the destination. This may be the same as the source
inode. If the destination did not exist, populated with
INODE_INVALID.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EEXIST #REDCONF_RENAME_ATOMIC is false and the
destination name exists.
@retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached
inode structure; or @p pSrcInode is `NULL`; or
@p pszSrcName is not a valid name; or
@p pDstPInode is not a mounted dirty cached
inode structure; or @p pDstInode is `NULL`; or
@p pszDstName is not a valid name.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EISDIR The destination name exists and is a directory,
and the source name is a non-directory.
@retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer
than #REDCONF_NAME_MAX.
@retval -RED_ENOENT The source name is not an existing entry; or
either @p pszSrcName or @p pszDstName point to
an empty string.
@retval -RED_ENOTDIR @p pSrcPInode is not a directory; or
@p pDstPInode is not a directory; or the source
name is a directory and the destination name is
a file.
@retval -RED_ENOTEMPTY The destination name is a directory which is not
empty.
@retval -RED_ENOSPC The file system does not have enough space to
extend the @p ulDstPInode directory.
@retval -RED_EROFS The directory to be removed resides on a
read-only file system.
*/
REDSTATUS RedDirEntryRename(
CINODE *pSrcPInode,
const char *pszSrcName,
CINODE *pSrcInode,
CINODE *pDstPInode,
const char *pszDstName,
CINODE *pDstInode)
{
REDSTATUS ret;
if( !CINODE_IS_DIRTY(pSrcPInode)
|| (pszSrcName == NULL)
|| (pSrcInode == NULL)
|| !CINODE_IS_DIRTY(pDstPInode)
|| (pszDstName == NULL)
|| (pDstInode == NULL))
{
ret = -RED_EINVAL;
}
else if(!pSrcPInode->fDirectory || !pDstPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */
uint32_t ulSrcIdx;
/* Look up the source and destination names.
*/
ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode);
if(ret == 0)
{
ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode);
if(ret == -RED_ENOENT)
{
if(ulDstIdx == DIR_INDEX_INVALID)
{
ret = -RED_ENOSPC;
}
else
{
#if REDCONF_RENAME_ATOMIC == 1
pDstInode->ulInode = INODE_INVALID;
#endif
ret = 0;
}
}
#if REDCONF_RENAME_ATOMIC == 0
else if(ret == 0)
{
ret = -RED_EEXIST;
}
else
{
/* Nothing to do here, just propagate the error.
*/
}
#endif
}
#if REDCONF_RENAME_ATOMIC == 1
/* If both names point to the same inode, POSIX says to do nothing to
either name.
*/
if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode))
#else
if(ret == 0)
#endif
{
ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true);
#if REDCONF_RENAME_ATOMIC == 1
if((ret == 0) && (pDstInode->ulInode != INODE_INVALID))
{
/* Source and destination must be the same type (file/dir).
*/
ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true);
/* If renaming directories, the destination must be empty.
*/
if((ret == 0) && pDstInode->fDirectory && (pDstInode->pInodeBuf->ullSize > 0U))
{
ret = -RED_ENOTEMPTY;
}
}
#endif
/* If we are renaming a directory, make sure the rename isn't
cyclic (e.g., renaming "foo" into "foo/bar").
*/
if((ret == 0) && pSrcInode->fDirectory)
{
ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode);
}
if(ret == 0)
{
ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName));
}
if(ret == 0)
{
ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx);
if(ret == -RED_ENOSPC)
{
REDSTATUS ret2;
/* If there was not enough space to branch the parent
directory inode and data block containin the source
entry, revert destination directory entry to its
previous state.
*/
#if REDCONF_RENAME_ATOMIC == 1
if(pDstInode->ulInode != INODE_INVALID)
{
ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName));
}
else
#endif
{
ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx);
}
if(ret2 != 0)
{
ret = ret2;
CRITICAL_ERROR();
}
}
}
if(ret == 0)
{
pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode;
}
}
}
return ret;
}
/** @brief Check for a cyclic rename.
A cyclic rename is renaming a directory into a subdirectory of itself. For
example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be
allowed since they would corrupt the directory tree.
@param ulSrcInode The inode number of the directory being renamed.
@param pDstPInode A pointer to the cached inode structure of the directory
into which the source is being renamed.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EINVAL The rename is cyclic; or invalid parameters.
@retval -RED_ENOTDIR @p pDstPInode is not a directory.
*/
static REDSTATUS DirCyclicRenameCheck(
uint32_t ulSrcInode,
const CINODE *pDstPInode)
{
REDSTATUS ret = 0;
if(!INODE_IS_VALID(ulSrcInode) || !CINODE_IS_MOUNTED(pDstPInode))
{
REDERROR();
ret = -RED_EINVAL;
}
else if(ulSrcInode == pDstPInode->ulInode)
{
ret = -RED_EINVAL;
}
else if(!pDstPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
CINODE NextParent;
/* Used to prevent infinite loop in case of corrupted directory
structure.
*/
uint32_t ulIteration = 0U;
NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode;
while( (NextParent.ulInode != ulSrcInode)
&& (NextParent.ulInode != INODE_ROOTDIR)
&& (NextParent.ulInode != INODE_INVALID)
&& (ulIteration < gpRedVolConf->ulInodeCount))
{
ret = RedInodeMount(&NextParent, FTYPE_DIR, false);
if(ret != 0)
{
break;
}
NextParent.ulInode = NextParent.pInodeBuf->ulPInode;
RedInodePut(&NextParent, 0U);
ulIteration++;
}
if((ret == 0) && (ulIteration == gpRedVolConf->ulInodeCount))
{
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
if((ret == 0) && (ulSrcInode == NextParent.ulInode))
{
ret = -RED_EINVAL;
}
}
return ret;
}
#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */
#if REDCONF_READ_ONLY == 0
/** @brief Update the contents of a directory entry.
@param pPInode A pointer to the cached inode structure of the directory
whose entry is being written.
@param ulIdx The index of the directory entry to write.
@param ulInode The inode number the directory entry is to point at.
@param pszName The name of the directory entry.
@param ulNameLen The length of @p pszName.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC There is not enough space on the volume to write the
directory entry.
@retval -RED_ENOTDIR @p pPInode is not a directory.
@retval -RED_EINVAL Invalid parameters.
*/
static REDSTATUS DirEntryWrite(
CINODE *pPInode,
uint32_t ulIdx,
uint32_t ulInode,
const char *pszName,
uint32_t ulNameLen)
{
REDSTATUS ret;
if( !CINODE_IS_DIRTY(pPInode)
|| (ulIdx >= DIRENTS_MAX)
|| (!INODE_IS_VALID(ulInode) && (ulInode != INODE_INVALID))
|| (pszName == NULL)
|| (ulNameLen > REDCONF_NAME_MAX)
|| ((ulNameLen == 0U) != (ulInode == INODE_INVALID)))
{
REDERROR();
ret = -RED_EINVAL;
}
else if(!pPInode->fDirectory)
{
ret = -RED_ENOTDIR;
}
else
{
uint64_t ullOffset = DirEntryIndexToOffset(ulIdx);
uint32_t ulLen = DIRENT_SIZE;
static DIRENT de;
RedMemSet(&de, 0U, sizeof(de));
de.ulInode = ulInode;
#ifdef REDCONF_ENDIAN_SWAP
de.ulInode = RedRev32(de.ulInode);
#endif
RedStrNCpy(de.acName, pszName, ulNameLen);
ret = RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de);
}
return ret;
}
/** @brief Convert a directory entry index to a byte offset.
@param ulIdx Directory entry index.
@return Byte offset in the directory corresponding with ulIdx.
*/
static uint64_t DirEntryIndexToOffset(
uint32_t ulIdx)
{
uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK;
uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK;
uint64_t ullOffset;
REDASSERT(ulIdx < DIRENTS_MAX);
ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2;
ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE;
return ullOffset;
}
#endif /* REDCONF_READ_ONLY == 0 */
/** @brief Convert a byte offset to a directory entry index.
@param ullOffset Byte offset in the directory.
@return Directory entry index corresponding with @p ullOffset.
*/
static uint32_t DirOffsetToEntryIndex(
uint64_t ullOffset)
{
uint32_t ulIdx;
REDASSERT(ullOffset < INODE_SIZE_MAX);
REDASSERT(((uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) % DIRENT_SIZE) == 0U);
/* Avoid doing any 64-bit divides.
*/
ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK;
ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE;
return ulIdx;
}
#endif /* REDCONF_API_POSIX == 1 */

View file

@ -0,0 +1,235 @@
/* ----> 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 Implements the Reliance Edge file system formatter.
*/
#include <redfs.h>
#include <redcoreapi.h>
#include <redcore.h>
#if FORMAT_SUPPORTED
/** @brief Format a file system volume.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EBUSY Volume is mounted.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedVolFormat(void)
{
REDSTATUS ret;
if(gpRedVolume->fMounted)
{
ret = -RED_EBUSY;
}
else
{
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);
}
if(ret == 0)
{
MASTERBLOCK *pMB;
REDSTATUS ret2;
/* Overwrite the master block with zeroes, so that if formatting is
interrupted, the volume will not be mountable.
*/
ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB));
if(ret == 0)
{
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
RedBufferDiscard(pMB);
}
if(ret == 0)
{
ret = RedIoFlush(gbRedVolNum);
}
#if REDCONF_IMAP_EXTERNAL == 1
if((ret == 0) && !gpRedCoreVol->fImapInline)
{
uint32_t ulImapBlock;
uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U);
uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY);
/* Technically it is only necessary to create one copy of each imap
node (the copy the metaroot points at), but creating them both
avoids headaches during disk image analysis from stale imaps
left over from previous formats.
*/
for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++)
{
IMAPNODE *pImap;
ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap));
if(ret != 0)
{
break;
}
RedBufferPut(pImap);
}
}
#endif
/* Write the first metaroot.
*/
if(ret == 0)
{
RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR));
gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable;
#if REDCONF_API_POSIX == 1
gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount;
#endif
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
/* The branched flag is typically set automatically when bits in
the imap change. It is set here explicitly because the imap has
only been initialized, not changed.
*/
gpRedCoreVol->fBranched = true;
ret = RedVolTransact();
}
#if REDCONF_API_POSIX == 1
/* Create the root directory.
*/
if(ret == 0)
{
CINODE rootdir;
rootdir.ulInode = INODE_ROOTDIR;
ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR);
if(ret == 0)
{
RedInodePut(&rootdir, 0U);
}
}
#endif
#if REDCONF_API_FSE == 1
/* The FSE API does not support creating or deletes files, so all the
inodes are created during setup.
*/
if(ret == 0)
{
uint32_t ulInodeIdx;
for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++)
{
CINODE ino;
ino.ulInode = INODE_FIRST_FREE + ulInodeIdx;
ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG);
if(ret == 0)
{
RedInodePut(&ino, 0U);
}
}
}
#endif
/* Write the second metaroot.
*/
if(ret == 0)
{
ret = RedVolTransact();
}
/* Populate and write out the master block.
*/
if(ret == 0)
{
ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB));
}
if(ret == 0)
{
pMB->ulVersion = RED_DISK_LAYOUT_VERSION;
RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum));
pMB->ulFormatTime = RedOsClockGetTime();
pMB->ulInodeCount = gpRedVolConf->ulInodeCount;
pMB->ulBlockCount = gpRedVolume->ulBlockCount;
pMB->uMaxNameLen = REDCONF_NAME_MAX;
pMB->uDirectPointers = REDCONF_DIRECT_POINTERS;
pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS;
pMB->bBlockSizeP2 = BLOCK_SIZE_P2;
#if REDCONF_API_POSIX == 1
pMB->bFlags |= MBFLAG_API_POSIX;
#endif
#if REDCONF_INODE_TIMESTAMPS == 1
pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS;
#endif
#if REDCONF_INODE_BLOCKS == 1
pMB->bFlags |= MBFLAG_INODE_BLOCKS;
#endif
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
pMB->bFlags |= MBFLAG_INODE_NLINK;
#endif
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
RedBufferPut(pMB);
}
if(ret == 0)
{
ret = RedIoFlush(gbRedVolNum);
}
ret2 = RedOsBDevClose(gbRedVolNum);
if(ret == 0)
{
ret = ret2;
}
}
/* Discard the buffers so a subsequent format will not run into blocks it
does not expect.
*/
if(ret == 0)
{
ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount);
}
return ret;
}
#endif /* FORMAT_SUPPORTED */

View file

@ -0,0 +1,348 @@
/* ----> 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 Implements allocation routines.
This module implements routines for working with the imap, a bitmap which
tracks which blocks are allocated or free. Some of the functionality is
delegated to imapinline.c and imapextern.c.
*/
#include <redfs.h>
#include <redcore.h>
/** @brief Get the allocation bit of a block from either metaroot.
Will pass the call down either to the inline imap or to the external imap
implementation, whichever is appropriate for the current volume.
@param bMR The metaroot index: either 0 or 1.
@param ulBlock The block number to query.
@param pfAllocated On successful return, populated with the allocation bit
of the block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
or @p pfAllocated is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockGet(
uint8_t bMR,
uint32_t ulBlock,
bool *pfAllocated)
{
REDSTATUS ret;
if( (bMR > 1U)
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pfAllocated == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
if(gpRedCoreVol->fImapInline)
{
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
}
else
{
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
}
#elif REDCONF_IMAP_INLINE == 1
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
#else
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
#endif
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Set the allocation bit of a block in the working metaroot.
Will pass the call down either to the inline imap or to the external imap
implementation, whichever is appropriate for the current volume.
@param ulBlock The block number to allocate or free.
@param fAllocated Whether to allocate the block (true) or free it (false).
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable
and @p fAllocated is 1.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockSet(
uint32_t ulBlock,
bool fAllocated)
{
REDSTATUS ret;
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount))
{
REDERROR();
ret = -RED_EINVAL;
}
else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)
&& ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U))
|| ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable))))
{
/* Attempting either to free more blocks than are allocable, or
allocate a block when there are none available. This could indicate
metadata corruption.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else
{
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
if(gpRedCoreVol->fImapInline)
{
ret = RedImapIBlockSet(ulBlock, fAllocated);
}
else
{
ret = RedImapEBlockSet(ulBlock, fAllocated);
}
#elif REDCONF_IMAP_INLINE == 1
ret = RedImapIBlockSet(ulBlock, fAllocated);
#else
ret = RedImapEBlockSet(ulBlock, fAllocated);
#endif
/* Any change to the allocation state of a block indicates that the
volume is now branched.
*/
gpRedCoreVol->fBranched = true;
}
/* If a block was marked as no longer in use, discard it from the buffers.
*/
if((ret == 0) && (!fAllocated))
{
ret = RedBufferDiscardRange(ulBlock, 1U);
CRITICAL_ASSERT(ret == 0);
}
/* Adjust the free/almost free block count if the block was allocable.
*/
if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN))
{
if(fAllocated)
{
gpRedMR->ulFreeBlocks--;
}
else
{
bool fWasAllocated;
/* Whether the block became free or almost free depends on its
previous allocation state. If it was used, then it is now
almost free. Otherwise, it was new and is now free.
*/
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated);
CRITICAL_ASSERT(ret == 0);
if(ret == 0)
{
if(fWasAllocated)
{
gpRedCoreVol->ulAlmostFreeBlocks++;
}
else
{
gpRedMR->ulFreeBlocks++;
}
}
}
}
return ret;
}
/** @brief Allocate one block.
@param pulBlock On successful return, populated with the allocated block
number.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p pulBlock is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC Insufficient free space to perform the allocation.
*/
REDSTATUS RedImapAllocBlock(
uint32_t *pulBlock)
{
REDSTATUS ret;
if(pulBlock == NULL)
{
REDERROR();
ret = -RED_EINVAL;
}
else if(gpRedMR->ulFreeBlocks == 0U)
{
ret = -RED_ENOSPC;
}
else
{
uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock;
bool fAllocated = false;
do
{
ALLOCSTATE state;
ret = RedImapBlockState(gpRedMR->ulAllocNextBlock, &state);
CRITICAL_ASSERT(ret == 0);
if(ret == 0)
{
if(state == ALLOCSTATE_FREE)
{
ret = RedImapBlockSet(gpRedMR->ulAllocNextBlock, true);
CRITICAL_ASSERT(ret == 0);
*pulBlock = gpRedMR->ulAllocNextBlock;
fAllocated = true;
}
/* Increment the next block number, wrapping it when the end of
the volume is reached.
*/
gpRedMR->ulAllocNextBlock++;
if(gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount)
{
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
}
}
}
while((ret == 0) && !fAllocated && (gpRedMR->ulAllocNextBlock != ulStopBlock));
if((ret == 0) && !fAllocated)
{
/* The free block count was already determined to be non-zero, no
error occurred while looking for free blocks, but no free blocks
were found. This indicates metadata corruption.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
}
return ret;
}
#endif /* REDCONF_READ_ONLY == 0 */
/** @brief Get the allocation state of a block.
Takes into account the allocation bits from both metaroots, and returns one
of four possible allocation state values:
- ::ALLOCSTATE_FREE Free and may be allocated; writeable.
- ::ALLOCSTATE_USED In-use and transacted; not writeable.
- ::ALLOCSTATE_NEW In-use but not transacted; writeable.
- ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable.
@param ulBlock The block number to query.
@param pState On successful return, populated with the state of the block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapBlockState(
uint32_t ulBlock,
ALLOCSTATE *pState)
{
REDSTATUS ret;
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pState == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
bool fBitCurrent;
ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent);
if(ret == 0)
{
bool fBitOld;
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld);
if(ret == 0)
{
if(fBitCurrent)
{
if(fBitOld)
{
*pState = ALLOCSTATE_USED;
}
else
{
*pState = ALLOCSTATE_NEW;
}
}
else
{
if(fBitOld)
{
*pState = ALLOCSTATE_AFREE;
}
else
{
*pState = ALLOCSTATE_FREE;
}
}
}
}
}
return ret;
}

View file

@ -0,0 +1,316 @@
/* ----> 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 Implements routines for the external imap.
The external imap is used on volumes that are too big for the imap bitmap
to be stored entirely in the metaroot, so instead the bitmap is stored in
imap nodes on disk, and the metaroot bitmap is used to toggle between imap
nodes.
*/
#include <redfs.h>
#if REDCONF_IMAP_EXTERNAL == 1
#include <redcore.h>
#if REDCONF_READ_ONLY == 0
static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap);
static bool ImapNodeIsBranched(uint32_t ulImapNode);
#endif
/** @brief Get the allocation bit of a block from the imap as it exists in
either metaroot.
@param bMR The metaroot index: either 0 or 1.
@param ulBlock The block number to query.
@param pfAllocated On successful exit, populated with the allocation bit
of the block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
or @p pfAllocated is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapEBlockGet(
uint8_t bMR,
uint32_t ulBlock,
bool *pfAllocated)
{
REDSTATUS ret;
if( gpRedCoreVol->fImapInline
|| (bMR > 1U)
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pfAllocated == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
uint8_t bMRToRead = bMR;
IMAPNODE *pImap;
#if REDCONF_READ_ONLY == 0
/* If the imap node is not branched, then both copies of the imap are
identical. If the old metaroot copy is requested, use the current
copy instead, since it is more likely to be buffered.
*/
if(bMR == (1U - gpRedCoreVol->bCurMR))
{
if(!ImapNodeIsBranched(ulImapNode))
{
bMRToRead = 1U - bMR;
}
}
#endif
ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap));
if(ret == 0)
{
*pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES);
RedBufferPut(pImap);
}
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Set the allocation bit of a block in the working-state imap.
@param ulBlock The block number to allocate or free.
@param fAllocated Whether to allocate the block (true) or free it (false).
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulBlock is out of range.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedImapEBlockSet(
uint32_t ulBlock,
bool fAllocated)
{
REDSTATUS ret;
if( gpRedCoreVol->fImapInline
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
IMAPNODE *pImap;
ret = ImapNodeBranch(ulImapNode, &pImap);
if(ret == 0)
{
uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES;
if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated)
{
/* The driver shouldn't ever set a bit in the imap to its
current value. That shouldn't ever be needed, and it
indicates that the driver is doing unnecessary I/O, or
that the imap is corrupt.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else if(fAllocated)
{
RedBitSet(pImap->abEntries, ulImapEntry);
}
else
{
RedBitClear(pImap->abEntries, ulImapEntry);
}
RedBufferPut(pImap);
}
}
return ret;
}
/** @brief Branch an imap node and get a buffer for it.
If the imap node is already branched, it can be overwritten in its current
location, and this function just gets it buffered dirty. If the node is not
already branched, the metaroot must be updated to toggle the imap node to
its alternate location, thereby preserving the committed state copy of the
imap node.
@param ulImapNode The imap node to branch and buffer.
@param ppImap On successful return, populated with the imap node
buffer, which will be marked dirty.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`.
@retval -RED_EIO A disk I/O error occurred.
*/
static REDSTATUS ImapNodeBranch(
uint32_t ulImapNode,
IMAPNODE **ppImap)
{
REDSTATUS ret;
if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else if(ImapNodeIsBranched(ulImapNode))
{
/* Imap node is already branched, so just get it buffered dirty.
*/
ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap));
}
else
{
uint32_t ulBlockCurrent;
uint32_t ulBlockOld;
/* The metaroot currently points to the committed state imap node.
Toggle the metaroot to point at the alternate, writeable location.
*/
if(RedBitGet(gpRedMR->abEntries, ulImapNode))
{
RedBitClear(gpRedMR->abEntries, ulImapNode);
}
else
{
RedBitSet(gpRedMR->abEntries, ulImapNode);
}
ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode);
ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode);
ret = RedBufferDiscardRange(ulBlockCurrent, 1U);
/* Buffer the committed copy then reassign the block number to the
writeable location. This also dirties the buffer.
*/
if(ret == 0)
{
ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap));
if(ret == 0)
{
RedBufferBranch(*ppImap, ulBlockCurrent);
}
}
}
return ret;
}
/** @brief Determine whether an imap node is branched.
If the imap node is branched, it can be overwritten in its current location.
@param ulImapNode The imap node to examine.
@return Whether the imap node is branched.
*/
static bool ImapNodeIsBranched(
uint32_t ulImapNode)
{
bool fNodeBitSetInMetaroot0 = RedBitGet(gpRedCoreVol->aMR[0U].abEntries, ulImapNode);
bool fNodeBitSetInMetaroot1 = RedBitGet(gpRedCoreVol->aMR[1U].abEntries, ulImapNode);
/* If the imap node is not branched, both metaroots will point to the same
copy of the node.
*/
return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1;
}
#endif /* REDCONF_READ_ONLY == 0 */
/** @brief Calculate the block number of the imap node location indicated by the
given metaroot.
An imap node has two locations on disk. A bit in the metaroot bitmap
indicates which location is the valid one, according to that metaroot. This
function returns the block number of the imap node which is valid in the
given metaroot.
@param bMR Which metaroot to examine.
@param ulImapNode The imap node for which to calculate the block number.
@return Block number of the imap node, as indicated by the given metaroot.
*/
uint32_t RedImapNodeBlock(
uint8_t bMR,
uint32_t ulImapNode)
{
uint32_t ulBlock;
REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount);
ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U);
if(bMR > 1U)
{
REDERROR();
}
else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode))
{
/* Bit is set, so point ulBlock at the second copy of the node.
*/
ulBlock++;
}
else
{
/* ulBlock already points at the first copy of the node.
*/
}
return ulBlock;
}
#endif /* REDCONF_IMAP_EXTERNAL == 1 */

View file

@ -0,0 +1,133 @@
/* ----> 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 Implements routines for the inline imap.
The inline imap is used on volumes that are small enough for the imap bitmap
to be entirely contained within the metaroot.
*/
#include <redfs.h>
#if REDCONF_IMAP_INLINE == 1
#include <redcore.h>
/** @brief Get the allocation bit of a block from either metaroot.
@param bMR The metaroot index: either 0 or 1.
@param ulBlock The block number to query.
@param pfAllocated On successful return, populated with the allocation bit
of the block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
@p pfAllocated is `NULL`; or the current volume does not
use the inline imap.
*/
REDSTATUS RedImapIBlockGet(
uint8_t bMR,
uint32_t ulBlock,
bool *pfAllocated)
{
REDSTATUS ret;
if( (!gpRedCoreVol->fImapInline)
|| (bMR > 1U)
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount)
|| (pfAllocated == NULL))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
*pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN);
ret = 0;
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Set the allocation bit of a block in the working metaroot.
@param ulBlock The block number to allocate or free.
@param fAllocated Whether to allocate the block (true) or free it (false).
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p ulBlock is out of range; or the current volume does
not use the inline imap.
*/
REDSTATUS RedImapIBlockSet(
uint32_t ulBlock,
bool fAllocated)
{
REDSTATUS ret;
if( (!gpRedCoreVol->fImapInline)
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|| (ulBlock >= gpRedVolume->ulBlockCount))
{
REDERROR();
ret = -RED_EINVAL;
}
else
{
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated)
{
/* The driver shouldn't ever set a bit in the imap to its current
value. This is more of a problem with the external imap, but it
is checked here for consistency.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else if(fAllocated)
{
RedBitSet(gpRedMR->abEntries, ulOffset);
ret = 0;
}
else
{
RedBitClear(gpRedMR->abEntries, ulOffset);
ret = 0;
}
}
return ret;
}
#endif
#endif /* REDCONF_IMAP_INLINE == 1 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,536 @@
/* ----> 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 Implements core volume operations.
*/
#include <redfs.h>
#include <redcore.h>
static bool MetarootIsValid(METAROOT *pMR, bool *pfSectorCRCIsValid);
#ifdef REDCONF_ENDIAN_SWAP
static void MetaRootEndianSwap(METAROOT *pMetaRoot);
#endif
/** @brief Mount a file system volume.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.
*/
REDSTATUS RedVolMount(void)
{
REDSTATUS ret;
#if REDCONF_READ_ONLY == 0
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);
#else
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDONLY);
#endif
if(ret == 0)
{
ret = RedVolMountMaster();
if(ret == 0)
{
ret = RedVolMountMetaroot();
}
if(ret != 0)
{
(void)RedOsBDevClose(gbRedVolNum);
}
}
return ret;
}
/** @brief Mount the master block.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO Master block missing, corrupt, or inconsistent with the
compile-time driver settings.
*/
REDSTATUS RedVolMountMaster(void)
{
REDSTATUS ret;
MASTERBLOCK *pMB;
/* Read the master block, to ensure that the disk was formatted with
Reliance Edge.
*/
ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_META_MASTER, CAST_VOID_PTR_PTR(&pMB));
if(ret == 0)
{
/* Verify that the driver was compiled with the same settings that
the disk was formatted with. If not, the user has made a
mistake: either the driver settings are wrong, or the disk needs
to be reformatted.
*/
if( (pMB->ulVersion != RED_DISK_LAYOUT_VERSION)
|| (pMB->ulInodeCount != gpRedVolConf->ulInodeCount)
|| (pMB->ulBlockCount != gpRedVolume->ulBlockCount)
|| (pMB->uMaxNameLen != REDCONF_NAME_MAX)
|| (pMB->uDirectPointers != REDCONF_DIRECT_POINTERS)
|| (pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS)
|| (pMB->bBlockSizeP2 != BLOCK_SIZE_P2)
|| (((pMB->bFlags & MBFLAG_API_POSIX) != 0U) != (REDCONF_API_POSIX == 1))
|| (((pMB->bFlags & MBFLAG_INODE_TIMESTAMPS) != 0U) != (REDCONF_INODE_TIMESTAMPS == 1))
|| (((pMB->bFlags & MBFLAG_INODE_BLOCKS) != 0U) != (REDCONF_INODE_BLOCKS == 1)))
{
ret = -RED_EIO;
}
#if REDCONF_API_POSIX == 1
else if(((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) != (REDCONF_API_POSIX_LINK == 1))
{
ret = -RED_EIO;
}
#else
else if((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U)
{
ret = -RED_EIO;
}
#endif
else
{
/* Master block configuration is valid.
Save the sequence number of the master block in the volume,
since we need it later (see RedVolMountMetaroot()) and we do
not want to re-buffer the master block.
*/
gpRedVolume->ullSequence = pMB->hdr.ullSequence;
}
RedBufferPut(pMB);
}
return ret;
}
/** @brief Mount the latest metaroot.
This function also populates the volume contexts.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO Both metaroots are missing or corrupt.
*/
REDSTATUS RedVolMountMetaroot(void)
{
REDSTATUS ret;
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[0U]);
if(ret == 0)
{
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[1U]);
}
/* Determine which metaroot is the most recent copy that was written
completely.
*/
if(ret == 0)
{
uint8_t bMR = UINT8_MAX;
bool fSectorCRCIsValid;
if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid))
{
bMR = 0U;
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]);
#endif
}
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
{
ret = -RED_EIO;
}
else
{
/* Metaroot is not valid, so it is ignored and there's nothing
to do here.
*/
}
if(ret == 0)
{
if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid))
{
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]);
#endif
if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence))
{
bMR = 1U;
}
}
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
{
ret = -RED_EIO;
}
else
{
/* Metaroot is not valid, so it is ignored and there's nothing
to do here.
*/
}
}
if(ret == 0)
{
if(bMR == UINT8_MAX)
{
/* Neither metaroot was valid.
*/
ret = -RED_EIO;
}
else
{
gpRedCoreVol->bCurMR = bMR;
gpRedMR = &gpRedCoreVol->aMR[bMR];
}
}
}
if(ret == 0)
{
/* Normally the metaroot contains the highest sequence number, but the
master block is the last block written during format, so on a
freshly formatted volume the master block sequence number (stored in
gpRedVolume->ullSequence) will be higher than that in the metaroot.
*/
if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence)
{
gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence;
}
/* gpRedVolume->ullSequence stores the *next* sequence number; to avoid
giving the next node written to disk the same sequence number as the
metaroot, increment it here.
*/
ret = RedVolSeqNumIncrement();
}
if(ret == 0)
{
gpRedVolume->fMounted = true;
#if REDCONF_READ_ONLY == 0
gpRedVolume->fReadOnly = false;
#endif
#if RESERVED_BLOCKS > 0U
gpRedCoreVol->fUseReservedBlocks = false;
#endif
gpRedCoreVol->ulAlmostFreeBlocks = 0U;
gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR;
gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR;
gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];
}
return ret;
}
/** @brief Determine whether the metaroot is valid.
@param pMR The metaroot buffer.
@param pfSectorCRCIsValid Populated with whether the first sector of the
metaroot buffer is valid.
@return Whether the metaroot is valid.
@retval true The metaroot buffer is valid.
@retval false The metaroot buffer is invalid.
*/
static bool MetarootIsValid(
METAROOT *pMR,
bool *pfSectorCRCIsValid)
{
bool fRet = false;
if(pfSectorCRCIsValid == NULL)
{
REDERROR();
}
else if(pMR == NULL)
{
REDERROR();
*pfSectorCRCIsValid = false;
}
#ifdef REDCONF_ENDIAN_SWAP
else if(RedRev32(pMR->hdr.ulSignature) != META_SIG_METAROOT)
#else
else if(pMR->hdr.ulSignature != META_SIG_METAROOT)
#endif
{
*pfSectorCRCIsValid = false;
}
else
{
const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMR);
uint32_t ulSectorCRC = pMR->ulSectorCRC;
uint32_t ulCRC;
#ifdef REDCONF_ENDIAN_SWAP
ulSectorCRC = RedRev32(ulSectorCRC);
#endif
/* The sector CRC was zero when the CRC was computed during the
transaction, so it must be zero here.
*/
pMR->ulSectorCRC = 0U;
ulCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);
fRet = ulCRC == ulSectorCRC;
*pfSectorCRCIsValid = fRet;
if(fRet)
{
if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)
{
ulCRC = RedCrc32Update(ulCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);
}
#ifdef REDCONF_ENDIAN_SWAP
ulCRC = RedRev32(ulCRC);
#endif
fRet = ulCRC == pMR->hdr.ulCRC;
}
}
return fRet;
}
#if REDCONF_READ_ONLY == 0
/** @brief Commit a transaction point.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
*/
REDSTATUS RedVolTransact(void)
{
REDSTATUS ret = 0;
REDASSERT(!gpRedVolume->fReadOnly); /* Should be checked by caller. */
if(gpRedCoreVol->fBranched)
{
gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks;
gpRedCoreVol->ulAlmostFreeBlocks = 0U;
ret = RedBufferFlush(0U, gpRedVolume->ulBlockCount);
if(ret == 0)
{
gpRedMR->hdr.ulSignature = META_SIG_METAROOT;
gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence;
ret = RedVolSeqNumIncrement();
}
if(ret == 0)
{
const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(gpRedMR);
uint32_t ulSectorCRC;
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(gpRedMR);
#endif
gpRedMR->ulSectorCRC = 0U;
ulSectorCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);
if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)
{
gpRedMR->hdr.ulCRC = RedCrc32Update(ulSectorCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);
}
else
{
gpRedMR->hdr.ulCRC = ulSectorCRC;
}
gpRedMR->ulSectorCRC = ulSectorCRC;
#ifdef REDCONF_ENDIAN_SWAP
gpRedMR->hdr.ulCRC = RedRev32(gpRedMR->hdr.ulCRC);
gpRedMR->ulSectorCRC = RedRev32(gpRedMR->ulSectorCRC);
#endif
/* Flush the block device before writing the metaroot, so that all
previously written blocks are guaranteed to be on the media before
the metaroot is written. Otherwise, if the block device reorders
the writes, the metaroot could reach the media before metadata it
points at, creating a window for disk corruption if power is lost.
*/
ret = RedIoFlush(gbRedVolNum);
}
if(ret == 0)
{
ret = RedIoWrite(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + gpRedCoreVol->bCurMR, 1U, gpRedMR);
#ifdef REDCONF_ENDIAN_SWAP
MetaRootEndianSwap(gpRedMR);
#endif
}
/* Flush the block device to force the metaroot write to the media. This
guarantees the transaction point is really complete before we return.
*/
if(ret == 0)
{
ret = RedIoFlush(gbRedVolNum);
}
/* Toggle to the other metaroot buffer. The working state and committed
state metaroot buffers exchange places.
*/
if(ret == 0)
{
uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR;
gpRedCoreVol->aMR[bNextMR] = *gpRedMR;
gpRedCoreVol->bCurMR = bNextMR;
gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];
gpRedCoreVol->fBranched = false;
}
CRITICAL_ASSERT(ret == 0);
}
return ret;
}
#endif
#ifdef REDCONF_ENDIAN_SWAP
static void MetaRootEndianSwap(
METAROOT *pMetaRoot)
{
if(pMetaRoot == NULL)
{
REDERROR();
}
else
{
pMetaRoot->ulSectorCRC = RedRev32(pMetaRoot->ulSectorCRC);
pMetaRoot->ulFreeBlocks = RedRev32(pMetaRoot->ulFreeBlocks);
#if REDCONF_API_POSIX == 1
pMetaRoot->ulFreeInodes = RedRev32(pMetaRoot->ulFreeInodes);
#endif
pMetaRoot->ulAllocNextBlock = RedRev32(pMetaRoot->ulAllocNextBlock);
}
}
#endif
/** @brief Process a critical file system error.
@param pszFileName The file in which the error occurred.
@param ulLineNum The line number at which the error occurred.
*/
void RedVolCriticalError(
const char *pszFileName,
uint32_t ulLineNum)
{
#if REDCONF_OUTPUT == 1
#if REDCONF_READ_ONLY == 0
if(!gpRedVolume->fReadOnly)
{
RedOsOutputString("Critical file system error in Reliance Edge, setting volume to READONLY\n");
}
else
#endif
{
RedOsOutputString("Critical file system error in Reliance Edge (volume already READONLY)\n");
}
#endif
#if REDCONF_READ_ONLY == 0
gpRedVolume->fReadOnly = true;
#endif
#if REDCONF_ASSERTS == 1
RedOsAssertFail(pszFileName, ulLineNum);
#else
(void)pszFileName;
(void)ulLineNum;
#endif
}
/** @brief Increment the sequence number.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL Cannot increment sequence number: maximum value reached.
This should not ever happen.
*/
REDSTATUS RedVolSeqNumIncrement(void)
{
REDSTATUS ret;
if(gpRedVolume->ullSequence == UINT64_MAX)
{
/* In practice this should never, ever happen; to get here, there would
need to be UINT64_MAX disk writes, which would take eons: longer
than the lifetime of any product or storage media. If this assert
fires and the current year is still written with four digits,
suspect memory corruption.
*/
CRITICAL_ERROR();
ret = -RED_EFUBAR;
}
else
{
gpRedVolume->ullSequence++;
ret = 0;
}
return ret;
}

View file

@ -0,0 +1,257 @@
/* ----> 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
*/
#ifndef REDCORE_H
#define REDCORE_H
#include <redstat.h>
#include <redvolume.h>
#include "rednodes.h"
#include "redcoremacs.h"
#include "redcorevol.h"
#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */
#define META_SIG_METAROOT (0x4154454DU) /* 'META' */
#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */
#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */
#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */
#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */
REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer);
REDSTATUS RedIoFlush(uint8_t bVolNum);
#endif
/** Indicates a block buffer is dirty (its contents are different than the
contents of the corresponding block on disk); or, when passed into
RedBufferGet(), indicates that the buffer should be marked dirty.
*/
#define BFLAG_DIRTY ((uint16_t) 0x0001U)
/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its
contents should be zeroed instead of being read from disk. Always used in
combination with BFLAG_DIRTY.
*/
#define BFLAG_NEW ((uint16_t) 0x0002U)
/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node.
*/
#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META))
/** Indicates that a block buffer is an imap (IMAPNODE) metadata node.
*/
#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META))
/** Indicates that a block buffer is an inode (INODE) metadata node.
*/
#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META))
/** Indicates that a block buffer is an indirect (INDIR) metadata node.
*/
#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META))
/** Indicates that a block buffer is a double indirect (DINDIR) metadata node.
*/
#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META))
/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet()
should not use this flag; instead, use one of the BFLAG_META_* flags.
*/
#define BFLAG_META ((uint16_t) 0x8000U)
void RedBufferInit(void);
REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer);
void RedBufferPut(const void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount);
void RedBufferDirty(const void *pBuffer);
void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew);
#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED
void RedBufferDiscard(const void *pBuffer);
#endif
#endif
REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount);
/** @brief Allocation state of a block.
*/
typedef enum
{
ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */
ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */
ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */
ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */
} ALLOCSTATE;
REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated);
REDSTATUS RedImapAllocBlock(uint32_t *pulBlock);
#endif
REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState);
#if REDCONF_IMAP_INLINE == 1
REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated);
#endif
#if REDCONF_IMAP_EXTERNAL == 1
REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated);
uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode);
#endif
/** @brief Cached inode structure.
*/
typedef struct
{
uint32_t ulInode; /**< The inode number of the cached inode. */
#if REDCONF_API_POSIX == 1
bool fDirectory; /**< True if the inode is a directory. */
#endif
#if REDCONF_READ_ONLY == 0
bool fBranched; /**< True if the inode is branched (writeable). */
bool fDirty; /**< True if the inode buffer is dirty. */
#endif
bool fCoordInited; /**< True after the first seek. */
INODE *pInodeBuf; /**< Pointer to the inode buffer. */
#if DINDIR_POINTERS > 0U
DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
INDIR *pIndir; /**< Pointer to the indirect node buffer. */
#endif
uint8_t *pbData; /**< Pointer to the data block buffer. */
/* All the members below this point are part of the seek coordinates; see
RedInodeDataSeek().
*/
uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */
#if DINDIR_POINTERS > 0U
uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */
#endif
uint32_t ulDataBlock; /**< Physical block number of the file data block. */
uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */
#if DINDIR_POINTERS > 0U
uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */
#endif
} CINODE;
#define CINODE_IS_MOUNTED(pInode) (((pInode) != NULL) && INODE_IS_VALID((pInode)->ulInode) && ((pInode)->pInodeBuf != NULL))
#define CINODE_IS_DIRTY(pInode) (CINODE_IS_MOUNTED(pInode) && (pInode)->fDirty)
#define IPUT_UPDATE_ATIME (0x01U)
#define IPUT_UPDATE_MTIME (0x02U)
#define IPUT_UPDATE_CTIME (0x04U)
#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME)
REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedInodeBranch(CINODE *pInode);
#endif
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)
REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode);
#endif
#if DELETE_SUPPORTED
REDSTATUS RedInodeDelete(CINODE *pInode);
REDSTATUS RedInodeLinkDec(CINODE *pInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
REDSTATUS RedInodeFree(CINODE *pInode);
#endif
void RedInodePut(CINODE *pInode, uint8_t bTimeFields);
void RedInodePutCoord(CINODE *pInode);
#if DINDIR_POINTERS > 0U
void RedInodePutDindir(CINODE *pInode);
#endif
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
void RedInodePutIndir(CINODE *pInode);
#endif
void RedInodePutData(CINODE *pInode);
#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1)
REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree);
#endif
REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated);
REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED
REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize);
#endif
#endif
REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock);
REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock);
#if REDCONF_API_POSIX == 1
#if REDCONF_READ_ONLY == 0
REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode);
#endif
#if DELETE_SUPPORTED
REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx);
#endif
REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode);
#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode);
#endif
#endif
REDSTATUS RedVolMount(void);
REDSTATUS RedVolMountMaster(void);
REDSTATUS RedVolMountMetaroot(void);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedVolTransact(void);
#endif
void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum);
REDSTATUS RedVolSeqNumIncrement(void);
#if FORMAT_SUPPORTED
REDSTATUS RedVolFormat(void);
#endif
#endif

View file

@ -0,0 +1,92 @@
/* ----> 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
*/
#ifndef REDCOREMACS_H
#define REDCOREMACS_H
#define BLOCK_NUM_MASTER (0UL) /* Block number of the master block. */
#define BLOCK_NUM_FIRST_METAROOT (1UL) /* Block number of the first metaroot. */
#define BLOCK_SPARSE (0U)
#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS)
#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES)
#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES)
#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS)
#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS)
#define INODE_SIZE_MAX (UINT64_SUFFIX(1) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS)
/* First inode number that can be allocated.
*/
#if REDCONF_API_POSIX == 1
#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U)
#else
#define INODE_FIRST_FREE (INODE_FIRST_VALID)
#endif
/** @brief Determine if an inode number is valid.
*/
#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)))
/* The number of blocks reserved to allow a truncate or delete operation to
complete when the disk is otherwise full.
The more expensive of the two operations is delete, which has to actually
write to a file data block to remove the directory entry.
*/
#if REDCONF_READ_ONLY == 1
#define RESERVED_BLOCKS 0U
#elif (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
#if DINDIR_POINTERS > 0U
#define RESERVED_BLOCKS 3U
#elif REDCONF_INDIRECT_POINTERS > 0U
#define RESERVED_BLOCKS 2U
#else
#define RESERVED_BLOCKS 1U
#endif
#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))
#if DINDIR_POINTERS > 0U
#define RESERVED_BLOCKS 2U
#elif REDCONF_INDIRECT_POINTERS > 0U
#define RESERVED_BLOCKS 1U
#else
#define RESERVED_BLOCKS 0U
#endif
#else
#define RESERVED_BLOCKS 0U
#endif
#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR())
#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__)
#endif

View file

@ -0,0 +1,95 @@
/* ----> 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
*/
#ifndef REDCOREVOL_H
#define REDCOREVOL_H
/** @brief Per-volume run-time data specific to the core.
*/
typedef struct
{
/** Whether this volume uses the inline imap (true) or external imap
(false). Computed at initialization time based on the block count.
*/
bool fImapInline;
#if REDCONF_IMAP_EXTERNAL == 1
/** First block number of the on-disk imap. Valid only when fImapInline
is false.
*/
uint32_t ulImapStartBN;
/** The number of double-allocated imap nodes that make up the imap.
*/
uint32_t ulImapNodeCount;
#endif
/** Block number where the inode table starts.
*/
uint32_t ulInodeTableStartBN;
/** First block number that can be allocated.
*/
uint32_t ulFirstAllocableBN;
/** The two metaroot structures, committed and working state.
*/
METAROOT aMR[2U];
/** The index of the current metaroot; must be 0 or 1.
*/
uint8_t bCurMR;
/** Whether the volume has been branched or not.
*/
bool fBranched;
/** The number of blocks which will become free after the next transaction.
*/
uint32_t ulAlmostFreeBlocks;
#if RESERVED_BLOCKS > 0U
/** Whether to use the blocks reserved for operations that create free
space.
*/
bool fUseReservedBlocks;
#endif
} COREVOLUME;
/* Pointer to the core volume currently being accessed; populated during
RedCoreVolSetCurrent().
*/
extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol;
/* Pointer to the metaroot currently being accessed; populated during
RedCoreVolSetCurrent() and RedCoreVolTransact().
*/
extern METAROOT *gpRedMR;
#endif

View file

@ -0,0 +1,195 @@
/* ----> 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
*/
#ifndef REDNODES_H
#define REDNODES_H
#define NODEHEADER_SIZE (16U)
#define NODEHEADER_OFFSET_SIG (0U)
#define NODEHEADER_OFFSET_CRC (4U)
#define NODEHEADER_OFFSET_SEQ (8U)
/** @brief Common header for all metadata nodes.
*/
typedef struct
{
uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */
uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */
uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */
} NODEHEADER;
/** Flag set in the master block when REDCONF_API_POSIX == 1. */
#define MBFLAG_API_POSIX (0x01U)
/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */
#define MBFLAG_INODE_TIMESTAMPS (0x02U)
/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */
#define MBFLAG_INODE_BLOCKS (0x04U)
/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */
#define MBFLAG_INODE_NLINK (0x08U)
/** @brief Node which identifies the volume and stores static volume information.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulVersion; /**< On-disk layout version number. */
char acBuildNum[8U]; /**< Build number of the product (not null terminated). */
uint32_t ulFormatTime; /**< Date and time the volume was formatted. */
uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */
uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */
uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */
uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */
uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */
uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */
uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */
} MASTERBLOCK;
#if REDCONF_API_POSIX == 1
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */
#else
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */
#endif
#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */
#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U)
/** @brief Metadata root node; each volume has two.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */
uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */
#if REDCONF_API_POSIX == 1
uint32_t ulFreeInodes; /**< Number of inode slots that are free. */
#endif
uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */
/** Imap bitmap. With inline imaps, this is the imap bitmap that indicates
which inode blocks are used and which allocable blocks are used.
Otherwise, this bitmap toggles nodes in the external imap between one
of two possible block locations.
*/
uint8_t abEntries[METAROOT_ENTRY_BYTES];
} METAROOT;
#if REDCONF_IMAP_EXTERNAL == 1
#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */
#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */
#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U)
/** @brief One node of the external imap.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
/** Bitmap which indicates which inode blocks are used and which allocable
blocks are used.
*/
uint8_t abEntries[IMAPNODE_ENTRY_BYTES];
} IMAPNODE;
#endif
#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \
((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U))
#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U)
#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS))
#error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS"
#endif
#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS))
#error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS"
#endif
/** @brief Stores metadata for a file or directory.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint64_t ullSize; /**< Size of the inode, in bytes. */
#if REDCONF_INODE_BLOCKS == 1
uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */
#endif
#if REDCONF_INODE_TIMESTAMPS == 1
uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */
uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */
uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */
#endif
uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
uint16_t uNLink; /**< Link count, number of names pointing to the inode. */
#else
uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */
#endif
#if REDCONF_API_POSIX == 1
uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */
#endif
/** Block numbers for lower levels of the file metadata structure. Some
fraction of these entries are for direct pointers (file data block
numbers), some for indirect pointers, some for double-indirect
pointers; the number allocated to each is static but user-configurable.
For all types, an array slot is zero if the range is sparse or beyond
the end of file.
*/
uint32_t aulEntries[INODE_ENTRIES];
} INODE;
#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U)
#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U)
/** @brief Node for storing block pointers.
*/
typedef struct
{
NODEHEADER hdr; /**< Common node header. */
uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */
/** For indirect nodes, stores block numbers of file data. For double
indirect nodes, stores block numbers of indirect nodes. An array
slot is zero if the corresponding block or indirect range is beyond
the end of file or entirely sparse.
*/
uint32_t aulEntries[INDIR_ENTRIES];
} INDIR, DINDIR;
#endif

View file

@ -0,0 +1,389 @@
Datalight Coding Style
======================
This is a description of the Datalight Coding Style intended for third parties
who want to contribute code to Reliance Edge. This document is derived from the
DDSS Coding Guidelines, but only contains a subset of the content which is most
likely to be relevant to third party contributors.
Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes
many rules that affect coding style. Unfortunately the MISRA-C:2012 document is
not freely available, and is much too long to be effectively summarized, but if
you are familiar with the rules, adhere to them. A few important rules of
thumb: avoid the goto and continue keywords; avoid using more than one break
in a loop; and avoid having more than one return from a function (single point
of exit); default cases in every switch statement; avoid recursion; and make
generous use of parentheses. Outside of the file system driver, in tests and
host tools, the MISRA-C rules are relaxed.
Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this
style are matters of preference, but when contributing code to Datalight an
effort should be made to use this style for the sake of consistency.
Below is an example function, which illustrates several key points of Datalight
Coding Style:
/** @brief One-sentence description of what this function does.
Additional description.
@param ulFirstParameter Description of the parameter.
@param pszPointer Description of the parameter.
@return Describe the return value.
@retval true Optional description of specific return value.
@retval false Optional description of specific return value.
*/
bool ExampleFunction(
uint32_t ulFirstParameter,
char *pszPointer)
{
bool fStatus = true;
/* This is a single-line comment.
*/
if(ulFirstParameter > 0U)
{
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit
amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
*/
FunctionCall();
while(fStatus)
{
fStatus = AnotherFunction(ulFirstParameter, pszPointer);
}
}
return fStatus;
}
Tab Stop Conventions
--------------------
In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in
other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a
tab width of 8.
Naming
------
Datalight uses CamelCase for functions and variables. Type names are generally
UPPERCASE, except for standard types like uint32_t. Preprocessor macros are
UPPERCASE, with words separated by underscores (for example, INODE_INVALID).
Doxygen Documentation
---------------------
Doxygen is used to document functions (including static functions), along with
types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash
(thus "@param" not "\param").
Function Declarations
---------------------
Multi-line function declarations are preferred, as they tend to be more
readable. Use the following form:
static bool ExampleFunctionDeclaration(
uint32_t ulFirstParameter,
char *pszPointer,
uint8_t **ppbBuffer)
{
uint16_t uLocalVar; /* descriptive comment */
uint8_t *pbBuffer = NULL; /* descriptive comment */
Function body...
}
The following guidelines should be used:
- Align both the data-type and the variable names, for parameters and locals, at
the same level if practical.
- For pointer types, the '*' belongs to the variable name---it's not part of the
data-type, so keep it with the variable name.
- If useful, single line comments may be used to describe local variables (not
a requirement).
- For functions with no parameters, the "void" declaration does not need to be
on a separate line.
- Generally each variable should be declared on a separate line. This promotes
readability, and facilitates having a comment for each variable.
Function declarations should be spaced apart by two blank lines between the
closing brace which ends a function and the Doxygen comment which starts the
next.
Curly Braces
------------
Datalight lines up all curly braces vertically. As per MISRA-C, curly braces
are never omitted, even if the braces contain only a single statement.
For consistency, even structure declarations and initializations should use the
same style, with the curly braces lined up vertically. One exception is for
structure initializations where both the opening and closing curly braces can
fit on the same line. If so, do it.
Code Comments
-------------
Datalight uses the standard C style /* comments */. C++ style comments (//) are
never used. The Datalight standard comment style is shown below. This style
applies to all general comments within the code.
/* This is a single-line comment.
*/
if(ulFirstParameter > 0U)
{
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua.
*/
while(fStatus)
{
}
}
Note the characteristics:
- The /* and */ align with the natural 4 character indentation.
- The comment text is exactly indented another 4 characters.
- The comment text starts on the same line as the opening /*.
- The terminating */ is on its own line.
- There is usually a single blank line preceding the comment, however if the
preceding line is an opening curly brace, then an extra blank line is not
necessary.
- There is usually no blank line after the comment, but rather the closing */
"attaches" the comment to the code about which the comment refers.
- These comments should always fit with the standard 80 character margin.
Comments where the /* and */ are on the same line may be used in a few places:
- For variable or parameter descriptions, where the comment fits on the same
line as the declaration.
- For structure member declarations, where the comment fits on the same line as
the declaration.
- For macros or preprocessor logic, where the comment fits on the same line.
It is OK for such comments to exceed the 80 character margin by a small amount,
if necessary, as this sometimes promotes code readability.
Indentation Style
-----------------
The general paradigm used in Datalight code is that curly braces line up
vertically, and everything in between them is indented. This should include all
comments, labels, and preprocessor symbols. The only things which are aligned
at the left-most columns are:
- Symbols, variables, declarations, and preprocessor logic which are at the
module-scope (outside of a function)
- Comments which are outside of a function
- Function declarations
- Function open and closing curly braces
Typically comments are always lined up directly with the code to which they
apply.
Labels (when used; gotos are disallowed in driver code) are lined up two
characters to the left of the code they reside in, to make them stand out, while
as the same time, still remaining subservient to the level of curly braces in
which they reside. For example:
bool ExampleLabelUsage(void)
{
MutexLock();
Lots of complicated code...
Unlock:
MutexUnlock();
return fSuccess;
}
Preprocessor logic, such as controlling features which are conditionally
compiled in or out, should not disrupt the flow of the code, but rather should
be indented in similar fashion to the code it controls, but positioned two
characters to the left. For example, consider the following code snippet. The
preprocessor conditions are both indented relative to the outer curly braces,
but do not disrupt the normal code flow.
int32_t red_statvfs(
const char *pszVolume,
REDSTATFS *pStatvfs)
{
REDSTATUS ret;
ret = PosixEnter();
if(ret == 0)
{
uint8_t bVolNum;
ret = RedPathSplit(pszVolume, &bVolNum, NULL);
#if REDCONF_VOLUME_COUNT > 1U
if(ret == 0)
{
ret = RedCoreVolSetCurrent(bVolNum);
}
#endif
if(ret == 0)
{
ret = RedCoreVolStat(pStatvfs);
}
PosixLeave();
}
return PosixReturn(ret);
}
Note that, like anything else between curly brackets, the contents of a switch
statement are indented:
switch(ulSignature)
{
case META_SIG_MASTER:
fValid = (uFlags == BFLAG_META_MASTER);
break;
case META_SIG_IMAP:
fValid = (uFlags == BFLAG_META_IMAP);
break;
case META_SIG_INODE:
fValid = (uFlags == BFLAG_META_INODE);
break;
case META_SIG_DINDIR:
fValid = (uFlags == BFLAG_META_DINDIR);
break;
case META_SIG_INDIR:
fValid = (uFlags == BFLAG_META_INDIR);
break;
default:
fValid = false;
break;
}
Maximum Line Length
-------------------
The maximum line length for code need not be rigidly limited to the traditional
80 characters. Nevertheless the line lengths should be kept reasonable.
Anything longer than 100 to 120 characters should probably be broken up. The
most important consideration is readability---fitting on the screen is important
for readability, but equally important is facilitating an easy understanding of
the logical code flow.
There are a few exceptions on both sides of the issue. Generally comments
should be limited to 80 characters always. Some lines of code may exceed the
120 character length by a large margin, if it makes the code more understandable
and maintainable. This is especially true when dealing with code that generates
output which needs to be lined up.
Regardless of everything else, no lines should exceed 250 characters because
some editors cannot handle anything larger.
Maximum Display Output Line Length
----------------------------------
Any code which displays TTY style output, whether on a screen or a terminal,
should be constructed so the output is readable and wraps properly on an 80
character wide display. This primarily applies to the "standard" output from
various tests and tools as well as syntax output for those tests and tools;
debug output can violate this rule.
Preprocessor Notation
---------------------
Don't use preprocessor notation where the # is separated from the keyword by one
or more white spaces. For example, don't do:
#ifndef SYMBOL1
# define SYMBOL1
#endif
Instead, do:
#ifndef SYMBOL1
#define SYMBOL1
#endif
Hexadecimal Notation
--------------------
Use uppercase for any alphabetic hexadecimal digits, and lower case for the
notational element. For example:
#define HEXNUM 0x123abd /* Bad */
#define HEXNUM 0X123ABD /* Bad */
#define HEXNUM 0x123ABD /* Good */
Hungarian Notation
------------------
Datalight uses Hungarian notation. The following type prefixes are used:
Type Prefix | Meaning
----------- | -------
c | char
uc | unsigned char
i | int
n | unsigned int or size_t
b | uint8_t
u | uint16_t
ul | uint32_t
ull | uint64_t
sz | array of char that will be null-terminated
f | bool
h | A handle
fn | A function (always used with the "p" modifier)
There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t,
although some code uses unofficial variants (like "ll" for int64_t).
The following modifiers may be used in combination with the type prefixes
defined above, or in combination with other types:
Modifier | Meaning
-------- | -------
a | An array
p | A pointer
g | A global variable
Notes:
- There is no standard Hungarian for structure declarations, however the use of
the "a" and "p" modifiers is completely appropriate (and expected).
- For those data types which do not have any standard defined Hungarian prefix,
using none is preferable to misusing another prefix which would lead to
confusion.
- The "p" pointer modifier must be used such that a variable which is a pointer
to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the
variable name should have the same number of "p" prefixes as the declaration
has asterisks. This allows pointer expressions to be easily decoded using
cancellation.
Variable Scope
--------------
Declare a variable in the narrowest scope in which it is meaningful.
Unnecessarily declaring all variables at the beginning of a function, where they
may be physically far from where they are actually used, makes the code harder
to maintain.
When multiple blocks of code share a variable, but not its value, declare the
variable separately for each code block.
For example, if two separate blocks contain loops indexed by a variable ulIndex
declare it separately in each block rather than declaring it once in a wider
scope and using it in both places.
Using distinct declarations in the two blocks allows the compiler to check for
failure to initialize the variable in the second block. If there is a single
declaration, the (now meaningless) value left over from the first block can be
used erroneously in the second block.

View file

@ -0,0 +1,61 @@
# Reliance Edge Release Notes
This file contains a list of updates made to Reliance Edge over the course of
recent releases and a list of known issues.
## Release History and Changes
### Reliance Edge v1.0, July 2015
#### Common Code Changes
- First release of commercial kit and MISRA C:2012 Design Assurance Package.
The commercial kit includes many new tools and tests which were not previously
available.
- Overhauled parsing of command-line parameters to be consistent for all tools
and tests. Command-line tools now use Unix-style short and long options (such
as `-H` and `--help`) instead of DOS-style switches (such as `/?`).
- Renamed all os/\*/include/ostypes.h headers to os/\*/include/redostypes.h, so
that all headers use the product prefix. If you created a port using v0.9,
this header needs to be renamed and its header guard (#ifndef OSTYPES_H etc.)
should also be updated.
- Add a new header for OS-specific MISRA C:2012 deviation macros, located at
os/\*/include/redosdeviations.h. If you created a port using v0.9, copy the
template from os/stub/include/redosdeviations.h into the include directory.
- Eliminated support for sector sizes less than 256. If using a smaller sector
size (say for a RAM disk), this must now be emulated in the implementation of
the block device OS service.
- Added RedFseFormat() as an optional FSE API, allowing FSE applications to
format the volume at run-time.
- This added a new macro to redconf.h: existing redconf.h files from v0.9 must
be updated to work with v1.0. Open redconf.h with the configuration tool,
ignore the warning about the missing macro, and save it.
- Internal restructuring has renamed the macros for the string and memory
functions used in redconf.h. An existing redconf.h file from v0.9 will need
to be updated; for a file containing the old names, the new config tool will
default to using the (slow) Reliance Edge string/memory functions; to use the
C library or custom versions, this will need to be selected in the
configuration utility.
- Fix a bug which would result in an error when attempting to create a name with
one or more trailing path separators (such as `red_mkdir("/foo/bar/")`).
- Fix a bug where an open handle for an inode on one volume would prevent the
same inode number from being deleted on a different volume.
#### FreeRTOS Port Changes
- The implementation of the timestamp OS service no longer requires that
`configUSE_TIMERS` be set to `1`.
### Reliance Edge v0.9 (Beta), April 2015
First public release.
## Known Issues
### Visual Studio 2005
The Reliance Edge Win32 port (used for the host tools and the Win32 test
project) cannot be compiled by Visual Studio 2005. This is not going to be
fixed since VS2005 is an old toolset. Newer versions of Visual Studio, starting
with Visual Studio 2008, work just fine.

View file

@ -0,0 +1,71 @@
RELIANCE EDGE RELEASE NOTES
This file contains a list of updates made to Reliance Edge over the
course of recent releases and a list of known issues.
Release History and Changes
Reliance Edge v1.0, July 2015
Common Code Changes
- First release of commercial kit and MISRA C:2012 Design
Assurance Package. The commercial kit includes many new tools and
tests which were not previously available.
- Overhauled parsing of command-line parameters to be consistent for
all tools and tests. Command-line tools now use Unix-style short and
long options (such as -H and --help) instead of DOS-style switches
(such as /?).
- Renamed all os/*/include/ostypes.h headers to
os/*/include/redostypes.h, so that all headers use the
product prefix. If you created a port using v0.9, this header needs
to be renamed and its header guard (#ifndef OSTYPES_H etc.) should
also be updated.
- Add a new header for OS-specific MISRA C:2012 deviation macros,
located at os/*/include/redosdeviations.h. If you created a port
using v0.9, copy the template from os/stub/include/redosdeviations.h
into the include directory.
- Eliminated support for sector sizes less than 256. If using a
smaller sector size (say for a RAM disk), this must now be emulated
in the implementation of the block device OS service.
- Added RedFseFormat() as an optional FSE API, allowing FSE
applications to format the volume at run-time.
- This added a new macro to redconf.h: existing redconf.h files from
v0.9 must be updated to work with v1.0. Open redconf.h with the
configuration tool, ignore the warning about the missing macro, and
save it.
- Internal restructuring has renamed the macros for the string and
memory functions used in redconf.h. An existing redconf.h file from
v0.9 will need to be updated; for a file containing the old names,
the new config tool will default to using the (slow) Reliance Edge
string/memory functions; to use the C library or custom versions,
this will need to be selected in the configuration utility.
- Fix a bug which would result in an error when attempting to create a
name with one or more trailing path separators (such as
red_mkdir("/foo/bar/")).
- Fix a bug where an open handle for an inode on one volume would
prevent the same inode number from being deleted on a
different volume.
FreeRTOS Port Changes
- The implementation of the timestamp OS service no longer requires
that configUSE_TIMERS be set to 1.
Reliance Edge v0.9 (Beta), April 2015
First public release.
Known Issues
Visual Studio 2005
The Reliance Edge Win32 port (used for the host tools and the Win32 test
project) cannot be compiled by Visual Studio 2005. This is not going to
be fixed since VS2005 is an old toolset. Newer versions of Visual
Studio, starting with Visual Studio 2008, work just fine.

View file

@ -0,0 +1,690 @@
/* ----> 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 Implementation of the Reliance Edge FSE API.
*/
#include <redfs.h>
#if REDCONF_API_FSE == 1
/** @defgroup red_group_fse The File System Essentials Interface
@{
*/
#include <redvolume.h>
#include <redcoreapi.h>
#include <redfse.h>
static REDSTATUS FseEnter(uint8_t bVolNum);
static void FseLeave(void);
static bool gfFseInited; /* Whether driver is initialized. */
/** @brief Initialize the Reliance Edge file system driver.
Prepares the Reliance Edge file system driver to be used. Must be the first
Reliance Edge function to be invoked: no volumes can be mounted until the
driver has been initialized.
If this function is called when the Reliance Edge driver is already
initialized, it does nothing and returns success.
This function is not thread safe: attempting to initialize from multiple
threads could leave things in a bad state.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedFseInit(void)
{
REDSTATUS ret;
if(gfFseInited)
{
ret = 0;
}
else
{
ret = RedCoreInit();
if(ret == 0)
{
gfFseInited = true;
}
}
return ret;
}
/** @brief Uninitialize the Reliance Edge file system driver.
Tears down the Reliance Edge file system driver. Cannot be used until all
Reliance Edge volumes are unmounted. A subsequent call to RedFseInit()
will initialize the driver again.
If this function is called when the Reliance Edge driver is already
uninitialized, it does nothing and returns success.
This function is not thread safe: attempting to uninitialize from multiple
threads could leave things in a bad state.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EBUSY At least one volume is still mounted.
*/
REDSTATUS RedFseUninit(void)
{
REDSTATUS ret = 0;
if(!gfFseInited)
{
ret = 0;
}
else
{
uint8_t bVolNum;
#if REDCONF_TASK_COUNT > 1U
RedOsMutexAcquire();
#endif
for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)
{
if(gaRedVolume[bVolNum].fMounted)
{
ret = -RED_EBUSY;
break;
}
}
if(ret == 0)
{
gfFseInited = false;
}
#if REDCONF_TASK_COUNT > 1U
RedOsMutexRelease();
#endif
if(ret == 0)
{
ret = RedCoreUninit();
}
}
return ret;
}
/** @brief Mount a file system volume.
Prepares the file system volume to be accessed. Mount will fail if the
volume has never been formatted, or if the on-disk format is inconsistent
with the compile-time configuration.
If the volume is already mounted, this function does nothing and returns
success.
@param bVolNum The volume number of the volume to be mounted.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
uninitialized.
@retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.
*/
REDSTATUS RedFseMount(
uint8_t bVolNum)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
if(!gpRedVolume->fMounted)
{
ret = RedCoreVolMount();
}
FseLeave();
}
return ret;
}
/** @brief Unmount a file system volume.
This function discards the in-memory state for the file system and marks it
as unmounted. Subsequent attempts to access the volume will fail until the
volume is mounted again.
If unmount automatic transaction points are enabled, this function will
commit a transaction point prior to unmounting. If unmount automatic
transaction points are disabled, this function will unmount without
transacting, effectively discarding the working state.
Before unmounting, this function will wait for any active file system
thread to complete by acquiring the FS mutex. The volume will be marked as
unmounted before the FS mutex is released, so subsequent FS threads will
possibly block and then see an error when attempting to access a volume
which is unmounting or unmounted.
If the volume is already unmounted, this function does nothing and returns
success.
@param bVolNum The volume number of the volume to be unmounted.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
uninitialized.
@retval -RED_EIO I/O error during unmount automatic transaction point.
*/
REDSTATUS RedFseUnmount(
uint8_t bVolNum)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
if(gpRedVolume->fMounted)
{
ret = RedCoreVolUnmount();
}
FseLeave();
}
return ret;
}
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)
/** @brief Format a file system volume.
Uses the statically defined volume configuration. After calling this
function, the volume needs to be mounted -- see RedFseMount().
An error is returned if the volume is mounted.
@param bVolNum The volume number of the volume to be formatted.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EBUSY The volume is mounted.
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
uninitialized.
@retval -RED_EIO I/O error formatting the volume.
*/
REDSTATUS RedFseFormat(
uint8_t bVolNum)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
ret = RedCoreVolFormat();
FseLeave();
}
return ret;
}
#endif
/** @brief Read from a file.
Data which has not yet been written, but which is before the end-of-file
(sparse data), shall read as zeroes. A short read -- where the number of
bytes read is less than requested -- indicates that the requested read was
partially or, if zero bytes were read, entirely beyond the end-of-file.
If @p ullFileOffset is at or beyond the maximum file size, it is treated
like any other read entirely beyond the end-of-file: no data is read and
zero is returned.
@param bVolNum The volume number of the file to read.
@param ulFileNum The file number of the file to read.
@param ullFileOffset The file offset to read from.
@param ulLength The number of bytes to read.
@param pBuffer The buffer to populate with the data read. Must be
at least ulLength bytes in size.
@return The number of bytes read (nonnegative) or a negated ::REDSTATUS
code indicating the operation result (negative).
@retval >=0 The number of bytes read from the file.
@retval -RED_EBADF @p ulFileNum is not a valid file number.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
or @p pBuffer is `NULL`; or @p ulLength exceeds
INT32_MAX and cannot be returned properly.
@retval -RED_EIO A disk I/O error occurred.
*/
int32_t RedFseRead(
uint8_t bVolNum,
uint32_t ulFileNum,
uint64_t ullFileOffset,
uint32_t ulLength,
void *pBuffer)
{
int32_t ret;
if(ulLength > (uint32_t)INT32_MAX)
{
ret = -RED_EINVAL;
}
else
{
ret = FseEnter(bVolNum);
}
if(ret == 0)
{
uint32_t ulReadLen = ulLength;
ret = RedCoreFileRead(ulFileNum, ullFileOffset, &ulReadLen, pBuffer);
FseLeave();
if(ret == 0)
{
ret = (int32_t)ulReadLen;
}
}
return ret;
}
#if REDCONF_READ_ONLY == 0
/** @brief Write to a file.
If the write extends beyond the end-of-file, the file size will be
increased.
A short write -- where the number of bytes written is less than requested
-- indicates either that the file system ran out of space but was still
able to write some of the request; or that the request would have caused
the file to exceed the maximum file size, but some of the data could be
written prior to the file size limit.
If an error is returned (negative return), either none of the data was
written or a critical error occurred (like an I/O error) and the file
system volume will be read-only.
@param bVolNum The volume number of the file to write.
@param ulFileNum The file number of the file to write.
@param ullFileOffset The file offset to write at.
@param ulLength The number of bytes to write.
@param pBuffer The buffer containing the data to be written. Must
be at least ulLength bytes in size.
@return The number of bytes written (nonnegative) or a negated ::REDSTATUS
code indicating the operation result (negative).
@retval >0 The number of bytes written to the file.
@retval -RED_EBADF @p ulFileNum is not a valid file number.
@retval -RED_EFBIG No data can be written to the given file offset since
the resulting file size would exceed the maximum file
size.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
or @p pBuffer is `NULL`; or @p ulLength exceeds
INT32_MAX and cannot be returned properly.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC No data can be written because there is insufficient
free space.
@retval -RED_EROFS The file system volume is read-only.
*/
int32_t RedFseWrite(
uint8_t bVolNum,
uint32_t ulFileNum,
uint64_t ullFileOffset,
uint32_t ulLength,
const void *pBuffer)
{
int32_t ret;
if(ulLength > (uint32_t)INT32_MAX)
{
ret = -RED_EINVAL;
}
else
{
ret = FseEnter(bVolNum);
}
if(ret == 0)
{
uint32_t ulWriteLen = ulLength;
ret = RedCoreFileWrite(ulFileNum, ullFileOffset, &ulWriteLen, pBuffer);
FseLeave();
if(ret == 0)
{
ret = (int32_t)ulWriteLen;
}
}
return ret;
}
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)
/** @brief Truncate a file (set the file size).
Allows the file size to be increased, decreased, or to remain the same. If
the file size is increased, the new area is sparse (will read as zeroes).
If the file size is decreased, the data beyond the new end-of-file will
return to free space once it is no longer part of the committed state
(either immediately or after the next transaction point).
This function can fail when the disk is full if @p ullNewFileSize is
non-zero. If decreasing the file size, this can be fixed by transacting and
trying again: Reliance Edge guarantees that it is possible to perform a
truncate of at least one file that decreases the file size after a
transaction point. If disk full transactions are enabled, this will happen
automatically.
@param bVolNum The volume number of the file to truncate.
@param ulFileNum The file number of the file to truncate.
@param ullNewFileSize The new file size, in bytes.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EBADF @p ulFileNum is not a valid file number.
@retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_ENOSPC Insufficient free space to perform the truncate.
@retval -RED_EROFS The file system volume is read-only.
*/
REDSTATUS RedFseTruncate(
uint8_t bVolNum,
uint32_t ulFileNum,
uint64_t ullNewFileSize)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
ret = RedCoreFileTruncate(ulFileNum, ullNewFileSize);
FseLeave();
}
return ret;
}
#endif
/** @brief Retrieve the size of a file.
@param bVolNum The volume number of the file whose size is being read.
@param ulFileNum The file number of the file whose size is being read.
@return The size of the file (nonnegative) or a negated ::REDSTATUS code
indicating the operation result (negative).
@retval >=0 The size of the file.
@retval -RED_EBADF @p ulFileNum is not a valid file number.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
@retval -RED_EIO A disk I/O error occurred.
*/
int64_t RedFseSizeGet(
uint8_t bVolNum,
uint32_t ulFileNum)
{
int64_t ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
uint64_t ullSize;
ret = RedCoreFileSizeGet(ulFileNum, &ullSize);
FseLeave();
if(ret == 0)
{
/* Unless there is an on-disk format change, the maximum file size
is guaranteed to be less than INT64_MAX, and so it can be safely
returned in an int64_t.
*/
REDASSERT(ullSize < (uint64_t)INT64_MAX);
ret = (int64_t)ullSize;
}
}
return ret;
}
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)
/** @brief Update the transaction mask.
The following events are available:
- #RED_TRANSACT_UMOUNT
- #RED_TRANSACT_WRITE
- #RED_TRANSACT_TRUNCATE
- #RED_TRANSACT_VOLFULL
The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all
automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of
all transaction flags, excluding those representing excluded functionality.
Attempting to enable events for excluded functionality will result in an
error.
@param bVolNum The volume number of the volume whose transaction mask
is being changed.
@param ulEventMask A bitwise-OR'd mask of automatic transaction events to
be set as the current transaction mode.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
or @p ulEventMask contains invalid bits.
@retval -RED_EROFS The file system volume is read-only.
*/
REDSTATUS RedFseTransMaskSet(
uint8_t bVolNum,
uint32_t ulEventMask)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
ret = RedCoreTransMaskSet(ulEventMask);
FseLeave();
}
return ret;
}
#endif
#if REDCONF_API_FSE_TRANSMASKGET == 1
/** @brief Read the transaction mask.
If the volume is read-only, the returned event mask is always zero.
@param bVolNum The volume number of the volume whose transaction mask
is being retrieved.
@param pulEventMask Populated with a bitwise-OR'd mask of automatic
transaction events which represent the current
transaction mode for the volume.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
or @p pulEventMask is `NULL`.
*/
REDSTATUS RedFseTransMaskGet(
uint8_t bVolNum,
uint32_t *pulEventMask)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
ret = RedCoreTransMaskGet(pulEventMask);
FseLeave();
}
return ret;
}
#endif
#if REDCONF_READ_ONLY == 0
/** @brief Commit a transaction point.
Reliance Edge is a transactional file system. All modifications, of both
metadata and filedata, are initially working state. A transaction point
is a process whereby the working state atomically becomes the committed
state, replacing the previous committed state. Whenever Reliance Edge is
mounted, including after power loss, the state of the file system after
mount is the most recent committed state. Nothing from the committed
state is ever missing, and nothing from the working state is ever included.
@param bVolNum The volume number of the volume to transact.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
@retval -RED_EIO A disk I/O error occurred.
@retval -RED_EROFS The file system volume is read-only.
*/
REDSTATUS RedFseTransact(
uint8_t bVolNum)
{
REDSTATUS ret;
ret = FseEnter(bVolNum);
if(ret == 0)
{
ret = RedCoreVolTransact();
FseLeave();
}
return ret;
}
#endif
/** @} */
/** @brief Enter the file system driver.
@param bVolNum The volume to be accessed.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum
is not a valid volume number.
*/
static REDSTATUS FseEnter(
uint8_t bVolNum)
{
REDSTATUS ret;
if(gfFseInited)
{
#if REDCONF_TASK_COUNT > 1U
RedOsMutexAcquire();
#endif
/* This also serves to range-check the volume number (even in single
volume configurations).
*/
ret = RedCoreVolSetCurrent(bVolNum);
#if REDCONF_TASK_COUNT > 1U
if(ret != 0)
{
RedOsMutexRelease();
}
#endif
}
else
{
ret = -RED_EINVAL;
}
return ret;
}
/** @brief Leave the file system driver.
*/
static void FseLeave(void)
{
REDASSERT(gfFseInited);
#if REDCONF_TASK_COUNT > 1U
RedOsMutexRelease();
#endif
}
#endif /* REDCONF_API_FSE == 1 */

View file

@ -0,0 +1,112 @@
/* ----> 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 Defines macros used to interact with the Reliance Edge API.
*/
#ifndef REDAPIMACS_H
#define REDAPIMACS_H
/** Clear all events: manual transactions only. */
#define RED_TRANSACT_MANUAL 0x00000000U
/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */
#define RED_TRANSACT_UMOUNT 0x00000001U
/** Transact after a successful red_open() which created a file. */
#define RED_TRANSACT_CREAT 0x00000002U
/** Transact after a successful red_unlink() or red_rmdir(). */
#define RED_TRANSACT_UNLINK 0x00000004U
/** Transact after a successful red_mkdir(). */
#define RED_TRANSACT_MKDIR 0x00000008U
/** Transact after a successful red_rename(). */
#define RED_TRANSACT_RENAME 0x00000010U
/** Transact after a successful red_link(). */
#define RED_TRANSACT_LINK 0x00000020U
/** Transact after a successful red_close(). */
#define RED_TRANSACT_CLOSE 0x00000040U
/** Transact after a successful red_write() or RedFseWrite(). */
#define RED_TRANSACT_WRITE 0x00000080U
/** Transact after a successful red_fsync(). */
#define RED_TRANSACT_FSYNC 0x00000100U
/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */
#define RED_TRANSACT_TRUNCATE 0x00000200U
/** Transact to free space in disk full situations. */
#define RED_TRANSACT_VOLFULL 0x00000400U
#if REDCONF_READ_ONLY == 1
/** Mask of all supported automatic transaction events. */
#define RED_TRANSACT_MASK 0U
#elif REDCONF_API_POSIX == 1
/** @brief Mask of all supported automatic transaction events.
*/
#define RED_TRANSACT_MASK \
( \
RED_TRANSACT_UMOUNT | \
RED_TRANSACT_CREAT | \
((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \
((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \
((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \
((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \
RED_TRANSACT_CLOSE | \
RED_TRANSACT_WRITE | \
RED_TRANSACT_FSYNC | \
((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
RED_TRANSACT_VOLFULL \
)
#else /* REDCONF_API_FSE == 1 */
/** @brief Mask of all supported automatic transaction events.
*/
#define RED_TRANSACT_MASK \
( \
RED_TRANSACT_UMOUNT | \
RED_TRANSACT_WRITE | \
((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
RED_TRANSACT_VOLFULL \
)
#endif /* REDCONF_READ_ONLY */
#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT
#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT"
#endif
#endif

View file

@ -0,0 +1,317 @@
/* ----> 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 Compile-time validity checks for the REDCONF macros.
*/
#ifndef REDCONFIGCHK_H
#define REDCONFIGCHK_H
#ifndef REDCONF_READ_ONLY
#error "Configuration error: REDCONF_READ_ONLY must be defined."
#endif
#ifndef REDCONF_API_POSIX
#error "Configuration error: REDCONF_API_POSIX must be defined."
#endif
#ifndef REDCONF_API_FSE
#error "Configuration error: REDCONF_API_FSE must be defined."
#endif
#if REDCONF_API_POSIX == 1
#ifndef REDCONF_API_POSIX_FORMAT
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined."
#endif
#ifndef REDCONF_API_POSIX_UNLINK
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined."
#endif
#ifndef REDCONF_API_POSIX_MKDIR
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined."
#endif
#ifndef REDCONF_API_POSIX_RMDIR
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined."
#endif
#ifndef REDCONF_API_POSIX_RENAME
#error "Configuration error: REDCONF_API_POSIX_RENAME must be defined."
#endif
#ifndef REDCONF_API_POSIX_LINK
#error "Configuration error: REDCONF_API_POSIX_LINK must be defined."
#endif
#ifndef REDCONF_API_POSIX_FTRUNCATE
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined."
#endif
#ifndef REDCONF_API_POSIX_READDIR
#error "Configuration error: REDCONF_API_POSIX_READDIR must be defined."
#endif
#ifndef REDCONF_NAME_MAX
#error "Configuration error: REDCONF_NAME_MAX must be defined."
#endif
#ifndef REDCONF_PATH_SEPARATOR
#error "Configuration error: REDCONF_PATH_SEPARATOR must be defined."
#endif
#ifndef REDCONF_RENAME_ATOMIC
#error "Configuration error: REDCONF_RENAME_ATOMIC must be defined."
#endif
#ifndef REDCONF_HANDLE_COUNT
#error "Configuration error: REDCONF_HANDLE_COUNT must be defined."
#endif
#endif
#if REDCONF_API_FSE == 1
#ifndef REDCONF_API_FSE_FORMAT
#error "Configuration error: REDCONF_API_FSE_FORMAT must be defined."
#endif
#ifndef REDCONF_API_FSE_TRUNCATE
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined."
#endif
#ifndef REDCONF_API_FSE_TRANSMASKSET
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined."
#endif
#ifndef REDCONF_API_FSE_TRANSMASKGET
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined."
#endif
#endif
#ifndef REDCONF_TASK_COUNT
#error "Configuration error: REDCONF_TASK_COUNT must be defined."
#endif
#ifndef REDCONF_ENDIAN_BIG
#error "Configuration error: REDCONF_ENDIAN_BIG must be defined."
#endif
#ifndef REDCONF_ALIGNMENT_SIZE
#error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined."
#endif
#ifndef REDCONF_CRC_ALGORITHM
#error "Configuration error: REDCONF_CRC_ALGORITHM must be defined."
#endif
#ifndef REDCONF_INODE_TIMESTAMPS
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined."
#endif
#ifndef REDCONF_ATIME
#error "Configuration error: REDCONF_ATIME must be defined."
#endif
#ifndef REDCONF_DIRECT_POINTERS
#error "Configuration error: REDCONF_DIRECT_POINTERS must be defined."
#endif
#ifndef REDCONF_INDIRECT_POINTERS
#error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined."
#endif
#ifndef REDCONF_INODE_BLOCKS
#error "Configuration error: REDCONF_INODE_BLOCKS must be defined."
#endif
#ifndef REDCONF_IMAP_EXTERNAL
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined."
#endif
#ifndef REDCONF_IMAP_INLINE
#error "Configuration error: REDCONF_IMAP_INLINE must be defined."
#endif
#ifndef REDCONF_OUTPUT
#error "Configuration error: REDCONF_OUTPUT must be defined."
#endif
#ifndef REDCONF_ASSERTS
#error "Configuration error: REDCONF_ASSERTS must be defined."
#endif
#ifndef REDCONF_TRANSACT_DEFAULT
#error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined."
#endif
#ifndef REDCONF_BUFFER_COUNT
#error "Configuration error: REDCONF_BUFFER_COUNT must be defined."
#endif
#ifndef REDCONF_BLOCK_SIZE
#error "Configuration error: REDCONF_BLOCK_SIZE must be defined."
#endif
#ifndef REDCONF_VOLUME_COUNT
#error "Configuration error: REDCONF_VOLUME_COUNT must be defined."
#endif
#ifndef REDCONF_IMAGE_BUILDER
#error "Configuration error: REDCONF_IMAGE_BUILDER must be defined."
#endif
#ifndef REDCONF_CHECKER
#error "Configuration error: REDCONF_CHECKER must be defined."
#endif
#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1)
#error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1"
#endif
#if (REDCONF_API_POSIX != 0) && (REDCONF_API_POSIX != 1)
#error "Configuration error: REDCONF_API_POSIX must be either 0 or 1."
#endif
#if (REDCONF_API_FSE != 0) && (REDCONF_API_FSE != 1)
#error "Configuration error: REDCONF_API_FSE must be either 0 or 1."
#endif
#if (REDCONF_API_FSE == 0) && (REDCONF_API_POSIX == 0)
#error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1."
#endif
#if REDCONF_API_POSIX == 1
#if REDCONF_API_FSE != 0
#error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1"
#endif
#if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1)
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1)
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1)
#error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1)
#error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1)
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1."
#endif
#if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1)
#error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1."
#endif
#if (REDCONF_NAME_MAX < 1U) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4U))
#error "Configuration error: invalid value of REDCONF_NAME_MAX"
#endif
#if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127)
#error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR"
#endif
#if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1)
#error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1."
#endif
#if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U)
#error "Configuration error: invalid value of REDCONF_HANDLE_COUNT"
#endif
#endif
#if REDCONF_API_FSE == 1
#if (REDCONF_API_FSE_FORMAT != 0) && (REDCONF_API_FSE_FORMAT != 1)
#error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1)
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1)
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1."
#endif
#if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1)
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1."
#endif
#endif
#if REDCONF_TASK_COUNT < 1U
#error "Configuration error: invalid value of REDCONF_TASK_COUNT"
#endif
#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1)
#error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1."
#endif
#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U)
#error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE"
#endif
/* REDCONF_CRC_ALGORITHM checked in crc.c
*/
#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1)
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1."
#endif
#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1)
#error "Configuration error: REDCONF_ATIME must be either 0 or 1."
#endif
#if (REDCONF_INODE_TIMESTAMPS == 0) && (REDCONF_ATIME == 1)
#error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0."
#endif
/* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h
*/
#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1)
#error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1."
#endif
/* Further validity checking of imap specs done in RelCoreInit()
*/
#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1)
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1."
#endif
#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1)
#error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1."
#endif
#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0)
#error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set"
#endif
#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1)
#error "Configuration error: REDCONF_OUTPUT must be either 0 or 1."
#endif
#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1)
#error "Configuration error: REDCONF_ASSERTS must be either 0 or 1."
#endif
/* REDCONF_BLOCK_SIZE checked in redmacs.h
*/
#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U)
#error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255"
#endif
/* REDCONF_BUFFER_COUNT lower limit checked in buffer.c
*/
#if REDCONF_BUFFER_COUNT > 255U
#error "REDCONF_BUFFER_COUNT cannot be greater than 255"
#endif
#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1)
#error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1."
#endif
#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1)
#error "Configuration error: REDCONF_CHECKER must be either 0 or 1."
#endif
#endif

View file

@ -0,0 +1,97 @@
/* ----> 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
*/
#ifndef REDCOREAPI_H
#define REDCOREAPI_H
#include <redstat.h>
REDSTATUS RedCoreInit(void);
REDSTATUS RedCoreUninit(void);
REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum);
#if FORMAT_SUPPORTED
REDSTATUS RedCoreVolFormat(void);
#endif
#if REDCONF_CHECKER == 1
REDSTATUS RedCoreVolCheck(void);
#endif
REDSTATUS RedCoreVolMount(void);
REDSTATUS RedCoreVolUnmount(void);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedCoreVolTransact(void);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS);
#endif
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1))
REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask);
#endif
#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1)
REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)
REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName);
#endif
#if REDCONF_API_POSIX == 1
REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat);
#endif
#if REDCONF_API_FSE == 1
REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize);
#endif
REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
#endif
#if TRUNCATE_SUPPORTED
REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize);
#endif
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1)
REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode);
#endif
#endif

View file

@ -0,0 +1,224 @@
/* ----> 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 This header contains macros which deviate from MISRA C:2012
*/
#ifndef REDDEVIATIONS_H
#define REDDEVIATIONS_H
/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value.
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The
rule prohibits the use of language extensions. The ULL suffix became part
of the C standard with C99. Since this code base adheres to C89, use of
this suffix is a language extension. Reliance Edge needs to deal with
64-bit quantities, which by convention are explicitly suffixed. In at
least one case, with the INODE_SIZE_MAX macro, the code needs a way to force
a constant to be 64-bits even though its value is not so large that it would
be automatically promoted to 64-bits. Thus the need for this macro and the
deviation. In practice, the ULL suffix has proven to be a nearly universal
extension among C89 compilers.
As rule 19.2 is advisory, a deviation record is not required. This notice
is the only record of the deviation. PC-Lint does not issue an error for
this deviation so there is no error inhibition option.
Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory).
The rule prohibits use of the ## preprocessor operator. The code is not
obscure, and the operator is used only once, so this is deemed to be safe.
As rule 20.10 is advisory, a deviation record is not required. This notice
is the only record of the deviation.
Consistent use of this macro, even in non MISRA C code, is encouraged to
make it easier to search for 64-bit values.
*/
#define UINT64_SUFFIX(number) (number##ULL)
/** @brief Append a suffix to a constant so that it is a signed 64-bit value.
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the
description of UINT64_SUFFIX() for details.
Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See
the description of UINT64_SUFFIX() for details.
*/
#define INT64_SUFFIX(number) (number##LL)
/** @brief Cast a pointer to a const uint8_t pointer.
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
Because there are no alignment requirements for a uint8_t pointer, this is
safe. However, it is technically a deviation from the rule.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR))
/** @brief Cast a pointer to a uint8_t pointer.
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
Because there are no alignment requirements for a uint8_t pointer, this is
safe. However, it is technically a deviation from the rule.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR))
/** @brief Cast a pointer to a const uint32_t pointer.
Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory).
It is only used in cases where the pointer is known to be aligned, and thus
it is safe to do so.
As Rule 11.5 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required).
As Rule 11.3 is required, a separate deviation record is required.
Regarding the cast to (const void *): this is there to placate some
compilers which emit warnings when a type with lower alignment requirements
(such as const uint8_t *) is cast to a type with higher alignment
requirements. In the places where this macro is used, the pointer is
checked to be of sufficient alignment.
*/
#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR))
/** @brief Cast a pointer to a pointer to (void **).
Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required).
It is only used for populating a node structure pointer with a buffer
pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so.
As Rule 11.3 is required, a separate deviation record is required.
*/
#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR))
/** @brief Create a two-dimensional byte array which is safely aligned.
Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory).
A union is required to force alignment of the block buffers, which are used
to access metadata nodes, which must be safely aligned for 64-bit types.
As rule 19.2 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
*/
#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \
union \
{ \
uint8_t nam[size1][size2]; \
uint64_t DummyAlign; \
} un
/** @brief Determine whether RedMemMove() must copy memory in the forward
direction, instead of in the reverse.
In order to copy between overlapping memory regions, RedMemMove() must copy
forward if the destination memory is lower, and backward if the destination
memory is higher. Failure to do so would yield incorrect results.
The only way to make this determination without gross inefficiency is to
use pointer comparison. Pointer comparisons are undefined unless both
pointers point within the same object or array (or one element past the end
of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is
normally only used when memory regions overlap, which would not result in
undefined behavior, it (like memmove()) is supposed to work even for non-
overlapping regions, which would make this function invoke undefined
behavior. Experience has shown the pointer comparisons of this sort behave
intuitively on common platforms, even though the behavior is undefined. For
those platforms where this is not the case, this implementation of memmove()
should be replaced with an alternate one.
Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As
Rule 18.3 is required, a separate deviation record is required.
*/
#define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src))
/** @brief Cast a pointer to a (const DIRENT *).
Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required).
It is used for populating a directory entry structure pointer with a
buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only
requires 4-byte alignment, thus the typecast is safe.
As Rule 11.3 is required, a separate deviation record is required.
*/
#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR))
/** @brief Determine whether a pointer is aligned.
A pointer is aligned if its address is an even multiple of
::REDCONF_ALIGNMENT_SIZE.
This is used in the slice-by-8 RedCrc32Update() function, which needs to
know whether a pointer is aligned, since the slice-by-8 algorithm needs to
access the memory in an aligned fashion, and if the pointer is not aligned,
this can result in faults or suboptimal performance (depending on platform).
There is no way to perform this check without deviating from MISRA C rules
against casting pointers to integer types. Usage of this macro deviates
from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites
against converting pointers to integers is that the chosen integer type may
not be able to represent the pointer; this is a non-issue here since we use
uintptr_t. The text says the rule still applies when using uintptr_t due to
concern about unaligned pointers, but that is not an issue here since the
integer value of the pointer is not saved and not converted back into a
pointer and dereferenced. The result of casting a pointer to a sufficiently
large integer is implementation-defined, but macros similar to this one have
been used by Datalight for a long time in a wide variety of environments and
they have always worked as expected.
As Rule 11.4 is advisory, a deviation record is not required. This notice
and the PC-Lint error inhibition option are the only records of the
deviation.
@note PC-Lint also thinks this macro as it is used below violates Rule 11.6
(required). This is a false positive, since Rule 11.6 only applies to
void pointers. Below, we use it on a pointer-to-object (uint8_t *),
which is covered by Rule 11.4.
*/
#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U)
#endif

View file

@ -0,0 +1,114 @@
/* ----> 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 Error values for Reliance Edge APIs
*/
#ifndef REDERRNO_H
#define REDERRNO_H
/** @brief Return type for Reliance Edge error values.
*/
typedef int32_t REDSTATUS;
/* The errno numbers are the same as Linux.
*/
/** Operation not permitted. */
#define RED_EPERM 1
/** No such file or directory. */
#define RED_ENOENT 2
/** I/O error. */
#define RED_EIO 5
/** Bad file number. */
#define RED_EBADF 9
/** Out of memory */
#define RED_ENOMEM 12
/** Device or resource busy. */
#define RED_EBUSY 16
/** File exists. */
#define RED_EEXIST 17
/** Cross-device link. */
#define RED_EXDEV 18
/** Not a directory. */
#define RED_ENOTDIR 20
/** Is a directory. */
#define RED_EISDIR 21
/** Invalid argument. */
#define RED_EINVAL 22
/** File table overflow. */
#define RED_ENFILE 23
/** Too many open files. */
#define RED_EMFILE 24
/** File too large. */
#define RED_EFBIG 27
/** No space left on device. */
#define RED_ENOSPC 28
/** Read-only file system. */
#define RED_EROFS 30
/** Too many links. */
#define RED_EMLINK 31
/** Math result not representable. */
#define RED_ERANGE 34
/** File name too long. */
#define RED_ENAMETOOLONG 36
/** Function not implemented. */
#define RED_ENOSYS 38
/** Directory not empty. */
#define RED_ENOTEMPTY 39
/** No data available. */
#define RED_ENODATA 61
/** Too many users. */
#define RED_EUSERS 87
/** Nothing will be okay ever again. */
#define RED_EFUBAR RED_EINVAL
#endif

View file

@ -0,0 +1,54 @@
/* ----> 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
*/
#ifndef REDEXCLUDE_H
#define REDEXCLUDE_H
#define DELETE_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( (REDCONF_API_POSIX == 1) \
&& ( (REDCONF_API_POSIX_RMDIR == 1) \
|| (REDCONF_API_POSIX_UNLINK == 1) \
|| ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))))
#define TRUNCATE_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))))
#define FORMAT_SUPPORTED \
( \
(REDCONF_READ_ONLY == 0) \
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) \
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_FORMAT == 1)) \
|| (REDCONF_IMAGE_BUILDER == 1)))
#endif

View file

@ -0,0 +1,46 @@
/* ----> 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
*/
#ifndef REDFS_H
#define REDFS_H
#include <redconf.h>
#include "redconfigchk.h"
#include <redtypes.h>
#include "rederrno.h"
#include "reddeviations.h"
#include "redmacs.h"
#include "redapimacs.h"
#include "redutils.h"
#include "redosserv.h"
#include "redmisc.h"
#include "redver.h"
#include "redexclude.h"
#endif

View file

@ -0,0 +1,105 @@
/* ----> 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 Interface for the Reliance Edge FSE API.
The FSE (File Systems Essentials) API is a minimalist file system API
intended for simple use cases with a fixed number of statically-defined
files. It does not support creating or deleting files dynamically. Files
are referenced by a fixed file number, rather than by name; there are no
file names and no directories. There are also no file handles: files are
not opened or closed, and file offsets are given explicitly.
If the FSE API is too limited to meet the needs of your application,
consider using the more feature-rich POSIX-like file system API instead.
*/
#ifndef REDFSE_H
#define REDFSE_H
/* This header is intended for application use; some applications are written
in C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <redconf.h>
#if REDCONF_API_FSE == 1
#include <redtypes.h>
#include "redapimacs.h"
#include "rederrno.h"
/** @brief First valid file number.
This macro can be used to statically define file numbers for given files,
as in the below example:
~~~{.c}
#define LOG_FILE (RED_FILENUM_FIRST_VALID)
#define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U)
#define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U)
#define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U)
~~~
*/
#define RED_FILENUM_FIRST_VALID (2U)
REDSTATUS RedFseInit(void);
REDSTATUS RedFseUninit(void);
REDSTATUS RedFseMount(uint8_t bVolNum);
REDSTATUS RedFseUnmount(uint8_t bVolNum);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)
REDSTATUS RedFseFormat(uint8_t bVolNum);
#endif
int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer);
#if REDCONF_READ_ONLY == 0
int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)
REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize);
#endif
int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)
REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask);
#endif
#if REDCONF_API_FSE_TRANSMASKGET == 1
REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask);
#endif
#if REDCONF_READ_ONLY == 0
REDSTATUS RedFseTransact(uint8_t bVolNum);
#endif
#endif /* REDCONF_API_FSE == 1 */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,77 @@
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** @file
@brief Interfaces for getopt() and getopt_long() work-alike functions.
This code was taken from FreeBSD and slightly modified, mostly to rename
symbols with external linkage to avoid naming conflicts in systems where
there are real getopt()/getopt_long() implementations. Changed to use
fixed-width types to allow code using these interfaces to be consistent
with the rest of the product.
*/
#ifndef REDGETOPT_H
#define REDGETOPT_H
#define red_no_argument 0
#define red_required_argument 1
#define red_optional_argument 2
/** @brief Specifies a long option.
*/
typedef struct
{
/* name of long option */
const char *name;
/*
* one of red_no_argument, red_required_argument, and red_optional_argument:
* whether option takes an argument
*/
int32_t has_arg;
/* if not NULL, set *flag to val when option found */
int32_t *flag;
/* if flag not NULL, value to set *flag to; else return value */
int32_t val;
} REDOPTION;
int32_t RedGetopt(int32_t nargc, char * const *nargv, const char *options);
int32_t RedGetoptLong(int32_t nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx);
extern const char *red_optarg;
extern int32_t red_optind;
extern int32_t red_opterr;
extern int32_t red_optopt;
extern int32_t red_optreset;
#endif

View file

@ -0,0 +1,103 @@
/* ----> 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
*/
#ifndef REDMACS_H
#define REDMACS_H
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (0xFFU)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (0xFFFFU)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (0xFFFFFFFFU)
#endif
#ifndef UINT64_MAX
#define UINT64_MAX UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)
#endif
#ifndef INT32_MAX
#define INT32_MAX (0x7FFFFFFF)
#endif
#ifndef INT64_MAX
#define INT64_MAX INT64_SUFFIX(0x7FFFFFFFFFFFFFFF)
#endif
#ifndef true
#define true (1)
#endif
#ifndef false
#define false (0)
#endif
#define SECTOR_SIZE_MIN (256U)
#if REDCONF_BLOCK_SIZE == 256U
#define BLOCK_SIZE_P2 8U
#elif REDCONF_BLOCK_SIZE == 512U
#define BLOCK_SIZE_P2 9U
#elif REDCONF_BLOCK_SIZE == 1024U
#define BLOCK_SIZE_P2 10U
#elif REDCONF_BLOCK_SIZE == 2048U
#define BLOCK_SIZE_P2 11U
#elif REDCONF_BLOCK_SIZE == 4096U
#define BLOCK_SIZE_P2 12U
#elif REDCONF_BLOCK_SIZE == 8192U
#define BLOCK_SIZE_P2 13U
#elif REDCONF_BLOCK_SIZE == 16384U
#define BLOCK_SIZE_P2 14U
#elif REDCONF_BLOCK_SIZE == 32768U
#define BLOCK_SIZE_P2 15U
#elif REDCONF_BLOCK_SIZE == 65536U
#define BLOCK_SIZE_P2 16U
#else
#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536"
#endif
#define REDMIN(a, b) (((a) < (b)) ? (a) : (b))
#define INODE_INVALID (0U) /* General-purpose invalid inode number (must be zero). */
#define INODE_FIRST_VALID (2U) /* First valid inode number. */
#define INODE_ROOTDIR (INODE_FIRST_VALID) /* Inode number of the root directory. */
/* Expands to a "const" qualifier when the volume count is one, otherwise
expands to nothing. This is useful for variables that never change in
single-volume configurations but do change in multi-volume configurations.
*/
#if REDCONF_VOLUME_COUNT == 1U
#define CONST_IF_ONE_VOLUME const
#else
#define CONST_IF_ONE_VOLUME
#endif
#endif

View file

@ -0,0 +1,48 @@
/* ----> 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
*/
#ifndef REDMISC_H
#define REDMISC_H
/** @brief Type of an inode or handle.
Used to indicate the actual or expected type of an inode or handle.
*/
typedef enum
{
FTYPE_FILE, /**< Type is file. */
FTYPE_DIR, /**< Type is directory. */
/** Type is either file or directory: used only to indicate an expected
type, never as an actual type.
*/
FTYPE_EITHER
} FTYPE;
#endif

View file

@ -0,0 +1,86 @@
/* ----> 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
*/
#ifndef REDOSSERV_H
#define REDOSSERV_H
#include <redostypes.h>
/** @brief Type of access requested when opening a block device.
*/
typedef enum
{
BDEV_O_RDONLY, /**< Open block device for read access. */
BDEV_O_WRONLY, /**< Open block device for write access. */
BDEV_O_RDWR /**< Open block device for read and write access. */
} BDEVOPENMODE;
REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode);
REDSTATUS RedOsBDevClose(uint8_t bVolNum);
REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);
#if REDCONF_READ_ONLY == 0
REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);
REDSTATUS RedOsBDevFlush(uint8_t bVolNum);
#endif
/* Non-standard API: for host machines only.
*/
REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec);
#if REDCONF_TASK_COUNT > 1U
REDSTATUS RedOsMutexInit(void);
REDSTATUS RedOsMutexUninit(void);
void RedOsMutexAcquire(void);
void RedOsMutexRelease(void);
#endif
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
uint32_t RedOsTaskId(void);
#endif
REDSTATUS RedOsClockInit(void);
REDSTATUS RedOsClockUninit(void);
uint32_t RedOsClockGetTime(void);
REDSTATUS RedOsTimestampInit(void);
REDSTATUS RedOsTimestampUninit(void);
REDTIMESTAMP RedOsTimestamp(void);
uint64_t RedOsTimePassed(REDTIMESTAMP tsSince);
#if REDCONF_OUTPUT == 1
void RedOsOutputString(const char *pszString);
#endif
#if REDCONF_ASSERTS == 1
void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum);
#endif
#endif

View file

@ -0,0 +1,196 @@
/* ----> 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 Interface for the Reliance Edge POSIX-like API.
The POSIX-like file system API is the primary file system API for
Reliance Edge, which supports the full functionality of the file system.
This API aims to be compatible with POSIX where reasonable, but it is
simplified considerably to meet the needs of resource-constrained embedded
systems. The API has also been extended to provide access to the unique
features of Reliance Edge, and to cover areas (like mountins and formatting)
which do not have APIs in the POSIX specification.
*/
#ifndef REDPOSIX_H
#define REDPOSIX_H
/* This header is intended for application use; some applications are written
in C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <redconf.h>
#if REDCONF_API_POSIX == 1
#include <redtypes.h>
#include "redapimacs.h"
#include "rederrno.h"
#include "redstat.h"
/** Open for reading only. */
#define RED_O_RDONLY 0x00000001U
/** Open for writing only. */
#define RED_O_WRONLY 0x00000002U
/** Open for reading and writing. */
#define RED_O_RDWR 0x00000004U
/** File offset for all writes is end-of-file. */
#define RED_O_APPEND 0x00000008U
/** Create the file. */
#define RED_O_CREAT 0x00000010U
/** Error if path already exists. */
#define RED_O_EXCL 0x00000020U
/** Truncate file to size zero. */
#define RED_O_TRUNC 0x00000040U
/** @brief Last file system error (errno).
Under normal circumstances, each task using the file system has an
independent `red_errno` value. Applications do not need to worry about
one task obliterating an error value that another task needed to read. The
value is initially zero. When one of the POSIX-like APIs return an
indication of error, `red_errno` is set to an error value.
In some circumstances, `red_errno` will be a global errno location which
is shared by multiple tasks. If the calling task is not registered as a
file system user and all of the task slots are full, there can be no
task-specific errno, so the global errno is used. Likewise, if the file
system driver is uninitialized, there are no registered file system users
and `red_errno` always refers to the global errno. Under these
circumstances, multiple tasks manipulating `red_errno` could be
problematic. When the task count is set to one, `red_errno` always refers
to the global errno.
Note that `red_errno` is usable as an lvalue; i.e., in addition to reading
the error value, the error value can be set:
~~~{.c}
red_errno = 0;
~~~
*/
#define red_errno (*red_errnoptr())
/** @brief Positions from which to seek within a file.
*/
typedef enum
{
/* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior
to the release of Unix System V in 1983, the SEEK_* symbols did not
exist and C programs hard-coded the 0/1/2 values with those meanings.
*/
RED_SEEK_SET = 0, /**< Set file offset to given offset. */
RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */
RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */
} REDWHENCE;
#if REDCONF_API_POSIX_READDIR == 1
/** @brief Opaque directory handle.
*/
typedef struct sREDHANDLE REDDIR;
/** @brief Directory entry information.
*/
typedef struct
{
uint32_t d_ino; /**< File serial number (inode number). */
char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */
REDSTAT d_stat; /**< File information (POSIX extension). */
} REDDIRENT;
#endif
int32_t red_init(void);
int32_t red_uninit(void);
int32_t red_mount(const char *pszVolume);
int32_t red_umount(const char *pszVolume);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)
int32_t red_format(const char *pszVolume);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_transact(const char *pszVolume);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask);
#endif
int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask);
int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs);
int32_t red_open(const char *pszPath, uint32_t ulOpenMode);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1)
int32_t red_unlink(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1)
int32_t red_mkdir(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1)
int32_t red_rmdir(const char *pszPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
int32_t red_rename(const char *pszOldPath, const char *pszNewPath);
#endif
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1)
int32_t red_link(const char *pszPath, const char *pszHardLink);
#endif
int32_t red_close(int32_t iFildes);
int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength);
#if REDCONF_READ_ONLY == 0
int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength);
#endif
#if REDCONF_READ_ONLY == 0
int32_t red_fsync(int32_t iFildes);
#endif
int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence);
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)
int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize);
#endif
int32_t red_fstat(int32_t iFildes, REDSTAT *pStat);
#if REDCONF_API_POSIX_READDIR == 1
REDDIR *red_opendir(const char *pszPath);
REDDIRENT *red_readdir(REDDIR *pDirStream);
void red_rewinddir(REDDIR *pDirStream);
int32_t red_closedir(REDDIR *pDirStream);
#endif
REDSTATUS *red_errnoptr(void);
#endif /* REDCONF_API_POSIX */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,94 @@
/* ----> 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
*/
#ifndef REDSTAT_H
#define REDSTAT_H
/** Mode bit for a directory. */
#define RED_S_IFDIR 0x4000U
/** Mode bit for a regular file. */
#define RED_S_IFREG 0x8000U
/** @brief Test for a directory.
*/
#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U)
/** @brief Test for a regular file.
*/
#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U)
/** File system is read-only. */
#define RED_ST_RDONLY 0x00000001U
/** File system ignores suid and sgid bits. */
#define RED_ST_NOSUID 0x00000002U
/** @brief Status information on an inode.
*/
typedef struct
{
uint8_t st_dev; /**< Volume number of volume containing file. */
uint32_t st_ino; /**< File serial number (inode number). */
uint16_t st_mode; /**< Mode of file. */
uint16_t st_nlink; /**< Number of hard links to the file. */
uint64_t st_size; /**< File size in bytes. */
#if REDCONF_INODE_TIMESTAMPS == 1
uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */
uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */
uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */
#endif
#if REDCONF_INODE_BLOCKS == 1
uint32_t st_blocks; /**< Number of blocks allocated for this object. */
#endif
} REDSTAT;
/** @brief Status information on a file system volume.
*/
typedef struct
{
uint32_t f_bsize; /**< File system block size. */
uint32_t f_frsize; /**< Fundamental file system block size. */
uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */
uint32_t f_bfree; /**< Total number of free blocks. */
uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */
uint32_t f_files; /**< Total number of file serial numbers. */
uint32_t f_ffree; /**< Total number of free file serial numbers. */
uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */
uint32_t f_fsid; /**< File system ID (useless, populated with zero). */
uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */
uint32_t f_namemax; /**< Maximum filename length. */
uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */
uint32_t f_dev; /**< Volume number (POSIX extension). */
} REDSTATFS;
#endif

Some files were not shown because too many files have changed in this diff Show more