Initial version

This commit is contained in:
2019-06-28 23:08:36 +02:00
commit 4d8973e20b
2426 changed files with 948029 additions and 0 deletions

View File

@ -0,0 +1,244 @@
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
Copyright (c) 2014-2015 Datalight, Inc.
All Rights Reserved Worldwide.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; use version 2 of the License.
This program is distributed in the hope that it will be useful,
but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Businesses and individuals that for commercial or other reasons cannot
comply with the terms of the GPLv2 license may obtain a commercial license
before incorporating Reliance Edge into proprietary software for
distribution in any form. Visit http://www.datalight.com/reliance-edge for
more information.
*/
/** @file
@brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code.
*/
#ifndef REDOSDEVIATIONS_H
#define REDOSDEVIATIONS_H
#if REDCONF_OUTPUT == 1
/* Needed for PRINT_ASSERT() and OUTPUT_CHARACTER().
*/
#include <stdio.h>
#endif
#if (REDCONF_ASSERTS == 1) && (REDCONF_OUTPUT == 1)
/** Print a formatted message for an assertion.
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using
printf() is the most convenient way to output this information; and the risk
of "unspecified, undefined and implementation-defined" behavior causing
problems (as cited in the rationale for the rule) is small. The driver does
not depend on this string being outputted correctly. Furthermore, use of
printf() disappears when either asserts or output are disabled.
As Rule 21.6 is required, a separate deviation record is required.
*/
#define PRINT_ASSERT(file, line) \
printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line))
#endif
/** Cast a value to unsigned long.
Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is
used in two places to cast a uint64_t value (used by the block device
abstraction for sector numbers) to unsigned long, since third-party code
which is not under the control of this project uses unsigned long for sector
numbers. The cast is guaranteed to not lose any information, since when the
disk is opened the sector count is verified to be less than or equal to an
unsigned long value. The text of the directive mentions that "it might be
desirable not to apply this guideline when interfacing with ... code outside
the project's control", which describes the situation for this deviation.
As Directive 4.6 is advisory, a deviation record is not required. This
notice is the only record of the deviation.
*/
#define CAST_ULONG(ull) ((unsigned long)(ull))
/** Cast a const-qualified pointer to a pointer which is *not* const-qualified.
Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is
used in exactly one place in order to cope with a poorly designed
third-party interface. Reliance Edge, at every level of the stack, uses
const-qualified pointers for buffers used in write operations, since the
data is read from the buffer, and the buffer does not need to be modified
(consistent with Rule 8.13). One of the third-party block device interfaces
that Reliance Edge interfaces with does not follow this convention: it uses
an unqualified pointer for the buffer parameter of its sector write
function. This forces the need for the cast to avoid warnings. The
implementation of the sector write function is provided by the user, so it
is to be hoped that the buffer is not actually modified.
As Rule 11.8 is required, a separate deviation record is required.
*/
#define CAST_AWAY_CONST(type, ptr) ((type *)(ptr))
/** Allocate zero-initialized (cleared) memory.
All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required)
and Rule 21.3 (required). In the context of the single place it is actually
used, this macro also deviates from Rule 22.1 (required).
This macro is used in the FreeRTOS block device code in order to allocate a
RAM disk, when that implementation of the block device is selected. The
primary rationale for all these deviations is that a) the RAM disk cannot be
allocated statically (since the volume information is stored in a
structure), and b) the RAM disk is primarily intended as a temporary testing
tool for users who want to try out Reliance Edge before the real storage
media is available. In most real systems, Reliance Edge is used with
non-volatile storage like SD/MMC or eMMC, not with RAM disks.
Rule 22.1 states that all resources which are allocated must also be
explicitly freed. The RAM disk is allocated and never freed, deviating from
that rule. This is done because the data in the RAM disk is emulating a
non-volatile storage medium, and thus needs to persist even after the block
device is closed, to allow the file system to be ormatted and then mounted,
or unmounted and remounted in the course of a test. Thus the memory will
remain allocated until the target device is rebooted. This is assumed to be
acceptable for the primary purpose of the RAM disk, which is preliminary
testing.
As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate
deviation records are required.
*/
#define ALLOCATE_CLEARED_MEMORY(nelem, elsize) calloc(nelem, elsize)
#if REDCONF_OUTPUT == 1
/** Output a character to a serial port or other display device.
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).
FreeRTOS does not include a standard method of printing characters, so
putchar() is the most convenient and portable way to accomplish the task.
The risk of "unspecified, undefined and implementation-defined" behavior
causing problems (as cited in the rationale for the rule) is small. The
driver does not depend on the character being outputted correctly.
Furthermore, use of putchar() disappears when output is disabled.
As Rule 21.6 is required, a separate deviation record is required.
*/
#define OUTPUT_CHARACTER(ch) (void)putchar(ch)
#endif
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
/** Cast a TaskHandle_t (a pointer type) to uintptr_t.
Usage of this macro deivate from MISRA-C:2012 Rule 11.4 (advisory). This
macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes
natively use an integer for task IDs; others use pointers. RedOsTaskId()
uses integers, FreeRTOS uses pointers; to reconcile this difference, the
pointer must be cast to integer. This is fairly safe, since the resulting
integer is never cast back to a pointer; and although the integer
representation of a pointer is implementation-defined, the representation is
irrelevant provided that unique pointers are converted to unique integers.
As Rule 11.4 is advisory, a deviation record is not required. This notice
is the only record of the deviation.
*/
#define CAST_TASK_PTR_TO_UINTPTR(taskptr) ((uintptr_t)(taskptr))
#endif
/** Ignore the return value of a function (cast to void)
Usages of this macro deviate from MISRA C:2012 Directive 4.7, which states
that error information must be checked immediately after a function returns
potential error information.
If asserts and output are enabled, then this macro is used to document that
the return value of printf() is ignored. A failure of printf() does not
impact the filesystem core, nor is there anything the filesystem can do to
respond to such an error (especially since it occurs within an assert).
Thus, the most reasonable action is to ignore the error.
In the STM32 SDIO block device implementation, errors are also ignored in an
IRQ interrupt handler. This is the most reasonable action to take for two
reasons: (a) it would be dangerous to spend processor time responding to the
error inside the IRQ handler; (b) it has been verified that the same error
is propegated to the DiskRead/Write method, which does return the error to
the core.
In the Atmel SD/MMC block device implementation, error information from
sd_mmc_read_capacity() is ignored. This is a reasonable action because all
of the possible error conditions were eliminated by a previous check.
sd_mmc_read_capacity() fails under the same conditions as
sd_mmc_test_unit_ready(), which was checked ealier in the same function.
In the mutex module, error information returned from the mutex release
function is ignored when asserts are disabled. This is a reasonable action
because the mutex release function (xSemaphoreGive) is documented only to
fail if the mutex was not obtained correctly, which can be demonstrably
avoided.
As Directive 4.7 is required, a separate deviation record is required.
*/
#define IGNORE_ERRORS(fn) ((void) (fn))
/** @brief Determine whether a pointer is aligned on a 32-bit boundary.
This is used to determine whether a data buffer meets the requirements of
the underlying block device implementation. When transferring data via
DMA (Direct Memory Access) on an STM32 device, the data buffer must be cast
as a uint32 pointer, and unexpected behavior may occur if the buffer is not
aligned correctly.
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.
This deviation only occurs when using the STM32 SDIO block device
implementation.
As Rule 11.4 is advisory, a deviation record is not required. This notice
is the only record of deviation.
*/
#define IS_UINT32_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (sizeof(uint32_t) - 1U)) == 0U)
/** @brief Cast a 32-bit aligned void pointer to a uint32 pointer.
Usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). A
cast from a void pointer to an object pointer is discouraged because of
potential alignment issues. However, this macro is only used to cast
pointers that have already been tested to be 32-bit aligned, so the
operation will be safe.
This deviation only occurs when using the STM32 SDIO block device
implementation.
As rule 11.5 is advisory, a deviation record is not required. This notice
is the only record of the deviation.
*/
#define CAST_UINT32_PTR(ptr) ((uint32_t *) (ptr))
#endif

View File

@ -0,0 +1,42 @@
/* ----> 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 OS-specific types for use in common code.
*/
#ifndef REDOSTYPES_H
#define REDOSTYPES_H
/** @brief Implementation-defined timestamp type.
This can be an integer, a structure, or a pointer: anything that is
convenient for the implementation. Since the underlying type is not fixed,
common code should treat this as an opaque type.
*/
typedef uint32_t REDTIMESTAMP;
#endif

View File

@ -0,0 +1,56 @@
/* ----> 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 assertion handling.
*/
#include <redfs.h>
#if REDCONF_ASSERTS == 1
#include <redosdeviations.h>
/** @brief Invoke the native assertion handler.
@param pszFileName Null-terminated string containing the name of the file
where the assertion fired.
@param ulLineNum Line number in @p pszFileName where the assertion
fired.
*/
void RedOsAssertFail(
const char *pszFileName,
uint32_t ulLineNum)
{
#if REDCONF_OUTPUT == 1
IGNORE_ERRORS(PRINT_ASSERT(pszFileName, ulLineNum));
#endif
while(true)
{
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/* ----> 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 real-time clock functions.
*/
#include <redfs.h>
/** @brief Initialize the real time clock.
The behavior of calling this function when the RTC is already initialized
is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsClockInit(void)
{
return 0;
}
/** @brief Uninitialize the real time clock.
The behavior of calling this function when the RTC is not initialized is
undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsClockUninit(void)
{
return 0;
}
/** @brief Get the date/time.
The behavior of calling this function when the RTC is not initialized is
undefined.
@return The number of seconds since January 1, 1970 excluding leap seconds
(in other words, standard Unix time). If the resolution or epoch
of the RTC is different than this, the implementation must convert
it to the expected representation.
*/
uint32_t RedOsClockGetTime(void)
{
/* FreeRTOS does not provide an RTC abstraction since most of the systems
it targets have no RTC hardware. If your hardware includes an RTC that
you would like to use, this function must be customized.
*/
return 0;
}

View File

@ -0,0 +1,134 @@
/* ----> 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 a synchronization object to provide mutual exclusion.
*/
#include <FreeRTOS.h>
#include <semphr.h>
#include <redfs.h>
#include <redosdeviations.h>
#if REDCONF_TASK_COUNT > 1U
static SemaphoreHandle_t xMutex;
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
static StaticSemaphore_t xMutexBuffer;
#endif
/** @brief Initialize the mutex.
After initialization, the mutex is in the released state.
The behavior of calling this function when the mutex is still initialized
is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsMutexInit(void)
{
REDSTATUS ret = 0;
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer);
if(xMutex == NULL)
{
/* The only error case for xSemaphoreCreateMutexStatic is that the mutex
buffer parameter is NULL, which is not the case.
*/
REDERROR();
ret = -RED_EINVAL;
}
#else
xMutex = xSemaphoreCreateMutex();
if(xMutex == NULL)
{
ret = -RED_ENOMEM;
}
#endif
return ret;
}
/** @brief Uninitialize the mutex.
The behavior of calling this function when the mutex is not initialized is
undefined; likewise, the behavior of uninitializing the mutex when it is
in the acquired state is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsMutexUninit(void)
{
vSemaphoreDelete(xMutex);
xMutex = NULL;
return 0;
}
/** @brief Acquire the mutex.
The behavior of calling this function when the mutex is not initialized is
undefined; likewise, the behavior of recursively acquiring the mutex is
undefined.
*/
void RedOsMutexAcquire(void)
{
while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE)
{
}
}
/** @brief Release the mutex.
The behavior is undefined in the following cases:
- Releasing the mutex when the mutex is not initialized.
- Releasing the mutex when it is not in the acquired state.
- Releasing the mutex from a task or thread other than the one which
acquired the mutex.
*/
void RedOsMutexRelease(void)
{
BaseType_t xSuccess;
xSuccess = xSemaphoreGive(xMutex);
REDASSERT(xSuccess == pdTRUE);
IGNORE_ERRORS(xSuccess);
}
#endif

View File

@ -0,0 +1,70 @@
/* ----> 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 outputting a character string.
*/
#include <redfs.h>
#if REDCONF_OUTPUT == 1
#include <redosdeviations.h>
/** @brief Write a string to a user-visible output location.
Write a null-terminated string to the serial port, console, terminal, or
other display device, such that the text is visible to the user.
@param pszString A null-terminated string.
*/
void RedOsOutputString(
const char *pszString)
{
if(pszString == NULL)
{
REDERROR();
}
else
{
uint32_t ulIdx = 0U;
while(pszString[ulIdx] != '\0')
{
OUTPUT_CHARACTER(pszString[ulIdx]);
/* Serial output often requires a \r to print newlines correctly.
*/
if(pszString[ulIdx] == '\n')
{
OUTPUT_CHARACTER('\r');
}
ulIdx++;
}
}
}
#endif

View File

@ -0,0 +1,68 @@
/* ----> 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 task functions.
*/
#include <FreeRTOS.h>
#include <task.h>
#include <redfs.h>
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
#include <redosdeviations.h>
#if INCLUDE_xTaskGetCurrentTaskHandle != 1
#error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1 and REDCONF_API_POSIX == 1"
#endif
/** @brief Get the current task ID.
This task ID must be unique for all tasks using the file system.
@return The task ID. Must not be 0.
*/
uint32_t RedOsTaskId(void)
{
/* Simply casting the xTaskGetCurrentTaskHandle() return value results in
warnings from some compilers, so use variables.
*/
TaskHandle_t xTask = xTaskGetCurrentTaskHandle();
uintptr_t taskptr = CAST_TASK_PTR_TO_UINTPTR(xTask);
uint32_t ulTaskPtr = (uint32_t)taskptr;
/* Assert no information was lost casting from uintptr_t to uint32_t.
*/
REDASSERT(ulTaskPtr == taskptr);
/* NULL is a valid task handle in FreeRTOS, so add one to all task IDs.
*/
REDASSERT((ulTaskPtr + 1U) != 0U);
return ulTaskPtr + 1U;
}
#endif

View File

@ -0,0 +1,109 @@
/* ----> 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 timestamp functions.
The functionality implemented herein is not needed for the file system
driver, only to provide accurate results with performance tests.
*/
#include <FreeRTOS.h>
#include <task.h>
#include <redfs.h>
/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If
1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a
little inaccurate.
*/
#define MICROSECS_PER_TICK (1000000U / configTICK_RATE_HZ)
/** @brief Initialize the timestamp service.
The behavior of invoking this function when timestamps are already
initialized is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_ENOSYS The timestamp service has not been implemented.
*/
REDSTATUS RedOsTimestampInit(void)
{
return 0;
}
/** @brief Uninitialize the timestamp service.
The behavior of invoking this function when timestamps are not initialized
is undefined.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
REDSTATUS RedOsTimestampUninit(void)
{
return 0;
}
/** @brief Retrieve a timestamp.
The behavior of invoking this function when timestamps are not initialized
is undefined
@return A timestamp which can later be passed to RedOsTimePassed() to
determine the amount of time which passed between the two calls.
*/
REDTIMESTAMP RedOsTimestamp(void)
{
return xTaskGetTickCount();
}
/** @brief Determine how much time has passed since a timestamp was retrieved.
The behavior of invoking this function when timestamps are not initialized
is undefined.
@param tsSince A timestamp acquired earlier via RedOsTimestamp().
@return The number of microseconds which have passed since @p tsSince.
*/
uint64_t RedOsTimePassed(
REDTIMESTAMP tsSince)
{
/* This works even if the tick count has wrapped around, provided it has
only wrapped around once.
*/
uint32_t ulTicksPassed = (uint32_t)xTaskGetTickCount() - tsSince;
uint64_t ullMicrosecs = (uint64_t)ulTicksPassed * MICROSECS_PER_TICK;
return ullMicrosecs;
}