Update version of Reliance Edge.

pull/4/head
Richard Barry 8 years ago
parent 7cce089e40
commit 7fcc976248

@ -11,5 +11,5 @@
const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] = const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] =
{ {
{ 512U, 65536U, false, 256U, "" } { 512U, 65536U, false, 256U, 0, "" }
}; };

@ -189,7 +189,6 @@
<ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" /> <ClInclude Include="..\..\..\FreeRTOS\Source\include\task.h" />
<ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" /> <ClInclude Include="..\..\..\FreeRTOS\Source\include\timers.h" />
<ClInclude Include="..\..\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.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\FreeRTOSConfig.h" />
<ClInclude Include="ConfigurationFiles\redconf.h" /> <ClInclude Include="ConfigurationFiles\redconf.h" />
<ClInclude Include="ConfigurationFiles\redtypes.h" /> <ClInclude Include="ConfigurationFiles\redtypes.h" />

@ -209,9 +209,6 @@
<ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h"> <ClInclude Include="ConfigurationFiles\FreeRTOSConfig.h">
<Filter>Configuration Files</Filter> <Filter>Configuration Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\Source\Reliance-Edge\os\freertos\include\ostypes.h">
<Filter>FreeRTOS+\FreeRTOS+Reliance Edge\port</Filter>
</ClInclude>
<ClInclude Include="ConfigurationFiles\redconf.h"> <ClInclude Include="ConfigurationFiles\redconf.h">
<Filter>Configuration Files</Filter> <Filter>Configuration Files</Filter>
</ClInclude> </ClInclude>

@ -28,6 +28,12 @@
The OS block device implementations operate on sectors. The core does I/O 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 in terms of logical blocks: this module translates from logical blocks to
sectors. sectors.
If bBlockIoRetries is greater than 0 for the current volume, then this
module will retry block device calls on failure up to the configured number
of times. This behavior caters to the type of unreliable hardware and
drivers that are sometimes found in the IoT world, where one operation may
fail but the next may still succeed.
*/ */
#include <redfs.h> #include <redfs.h>
#include <redcore.h> #include <redcore.h>
@ -52,7 +58,7 @@ REDSTATUS RedIoRead(
uint32_t ulBlockCount, uint32_t ulBlockCount,
void *pBuffer) void *pBuffer)
{ {
REDSTATUS ret; REDSTATUS ret = 0;
if( (bVolNum >= REDCONF_VOLUME_COUNT) if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
@ -68,11 +74,20 @@ REDSTATUS RedIoRead(
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift; uint32_t ulSectorCount = ulBlockCount << bSectorShift;
uint8_t bRetryIdx;
REDASSERT(bSectorShift < 32U); REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
{
ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
if(ret == 0)
{
break;
}
}
} }
CRITICAL_ASSERT(ret == 0); CRITICAL_ASSERT(ret == 0);
@ -101,7 +116,7 @@ REDSTATUS RedIoWrite(
uint32_t ulBlockCount, uint32_t ulBlockCount,
const void *pBuffer) const void *pBuffer)
{ {
REDSTATUS ret; REDSTATUS ret = 0;
if( (bVolNum >= REDCONF_VOLUME_COUNT) if( (bVolNum >= REDCONF_VOLUME_COUNT)
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
@ -117,11 +132,20 @@ REDSTATUS RedIoWrite(
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
uint32_t ulSectorCount = ulBlockCount << bSectorShift; uint32_t ulSectorCount = ulBlockCount << bSectorShift;
uint8_t bRetryIdx;
REDASSERT(bSectorShift < 32U); REDASSERT(bSectorShift < 32U);
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
{
ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
if(ret == 0)
{
break;
}
}
} }
CRITICAL_ASSERT(ret == 0); CRITICAL_ASSERT(ret == 0);
@ -144,7 +168,7 @@ REDSTATUS RedIoWrite(
REDSTATUS RedIoFlush( REDSTATUS RedIoFlush(
uint8_t bVolNum) uint8_t bVolNum)
{ {
REDSTATUS ret; REDSTATUS ret = 0;
if(bVolNum >= REDCONF_VOLUME_COUNT) if(bVolNum >= REDCONF_VOLUME_COUNT)
{ {
@ -152,8 +176,18 @@ REDSTATUS RedIoFlush(
ret = -RED_EINVAL; ret = -RED_EINVAL;
} }
else else
{
uint8_t bRetryIdx;
for(bRetryIdx = 0U; bRetryIdx <= gpRedVolConf->bBlockIoRetries; bRetryIdx++)
{ {
ret = RedOsBDevFlush(bVolNum); ret = RedOsBDevFlush(bVolNum);
if(ret == 0)
{
break;
}
}
} }
CRITICAL_ASSERT(ret == 0); CRITICAL_ASSERT(ret == 0);

@ -311,7 +311,7 @@ REDSTATUS RedBufferGet(
mounted; that condition is expected and should mounted; that condition is expected and should
not result in an assertion. not result in an assertion.
*/ */
CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) != 0U); CRITICAL_ASSERT((uFlags & BFLAG_META_MASTER) == BFLAG_META_MASTER);
ret = -RED_EIO; ret = -RED_EIO;
} }
} }

@ -5,6 +5,47 @@ recent releases and a list of known issues.
## Release History and Changes ## Release History and Changes
### Reliance Edge v1.0.4, July 2016
- Added ARM mbed and ARM mbed OS support in the commercial kit, with an example
projects for ARM mbed OS on the NXP FRDM-K64F board.
- Some minor deficiencies in the POSIX-like API test suite have been addressed.
### Reliance Edge v1.0.3, June 2016
- Added support for static memory allocation configuration in FreeRTOS
version 9. No common code changes.
### Reliance Edge v1.0.2, February 2016
#### Common Code Changes
- A new per-volume configuration option has been added: users can specify a
number of times to retry a block device read, write or flush operation before
returning a failure. The configuration tool has been updated to version 1.0.2
with this change.
- This added a new field to the volume configuration in to redconf.c: existing
redconf.c files from v1.0.1 and earlier must be updated to work with v1.0.2.
Open redconf.h and redconf.c with the configuration tool, enable
"Retry block device I/O on failure" for any volumes if desired, and save the
redconf files.
#### FreeRTOS Port Changes
- Added support for the STM32 HAL SD card driver in the FreeRTOS block device
interface. Two boards are supported out-of-the-box: the STM324xG-EVAL and the
STM32F746NG-Discovery. A sample project is included for the STM324xG-EVAL.
#### MQX Port Changes
- Fixed a bug which prevented Reliance Edge from compiling if the File System
Essentials API was selected in the configuration.
- Fixed a bug which would have returned an uninitialized value from
`RedOsBDevFlush()` for block devices that support flushing.
### Reliance Edge v1.0.1, October 2015
- Added MQX RTOS support in the commercial kit, with example projects for
the Kinetis Design Studio.
- Bug fix in the F_DRIVER implementation of the FreeRTOS block device service.
### Reliance Edge v1.0, July 2015 ### Reliance Edge v1.0, July 2015
#### Common Code Changes #### Common Code Changes

@ -9,6 +9,53 @@ course of recent releases and a list of known issues.
Release History and Changes Release History and Changes
Reliance Edge v1.0.4, July 2016
- Added ARM mbed and ARM mbed OS support in the commercial kit, with
an example projects for ARM mbed OS on the NXP FRDM-K64F board.
- Some minor deficiencies in the POSIX-like API test suite have
been addressed.
Reliance Edge v1.0.3, June 2016
- Added support for static memory allocation configuration in FreeRTOS
version 9. No common code changes.
Reliance Edge v1.0.2, February 2016
Common Code Changes
- A new per-volume configuration option has been added: users can
specify a number of times to retry a block device read, write or
flush operation before returning a failure. The configuration tool
has been updated to version 1.0.2 with this change.
- This added a new field to the volume configuration in to redconf.c:
existing redconf.c files from v1.0.1 and earlier must be updated to
work with v1.0.2. Open redconf.h and redconf.c with the
configuration tool, enable "Retry block device I/O on failure" for
any volumes if desired, and save the redconf files.
FreeRTOS Port Changes
- Added support for the STM32 HAL SD card driver in the FreeRTOS block
device interface. Two boards are supported out-of-the-box: the
STM324xG-EVAL and the STM32F746NG-Discovery. A sample project is
included for the STM324xG-EVAL.
MQX Port Changes
- Fixed a bug which prevented Reliance Edge from compiling if the File
System Essentials API was selected in the configuration.
- Fixed a bug which would have returned an uninitialized value from
RedOsBDevFlush() for block devices that support flushing.
Reliance Edge v1.0.1, October 2015
- Added MQX RTOS support in the commercial kit, with example projects
for the Kinetis Design Studio.
- Bug fix in the F_DRIVER implementation of the FreeRTOS block
device service.
Reliance Edge v1.0, July 2015 Reliance Edge v1.0, July 2015
Common Code Changes Common Code Changes

@ -156,6 +156,22 @@ int RedPosixTestStart(const POSIXTESTPARAM *pParam);
#endif #endif
#if POSIX_API_TEST_SUPPORTED
typedef struct
{
const char *pszVolume; /**< Volume path prefix. */
bool fQuick; /**< --quick */
bool fVerbose; /**< --verbose */
bool fQuitOnFailure; /**< --quit-on-failure */
bool fDebugErrors; /**< --debug */
} OSAPITESTPARAM;
PARAMSTATUS RedOsApiTestParseParams(int argc, char *argv[], OSAPITESTPARAM *pParam, const char **ppszDevice);
void RedOsApiTestDefaultParams(OSAPITESTPARAM *pParam);
int RedOsApiTestStart(const OSAPITESTPARAM *pParam);
#endif
#if FSE_API_TEST_SUPPORTED #if FSE_API_TEST_SUPPORTED
typedef struct typedef struct
{ {

@ -33,7 +33,7 @@
<!-- This macro is updated automatically: do not edit! --> <!-- This macro is updated automatically: do not edit! -->
*/ */
#define RED_BUILD_NUMBER "664" #define RED_BUILD_NUMBER "677"
#define RED_KIT_GPL 0U /* Open source GPL kit. */ #define RED_KIT_GPL 0U /* Open source GPL kit. */
#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */ #define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */
@ -48,7 +48,7 @@
/** @brief Version number to display in output. /** @brief Version number to display in output.
*/ */
#define RED_VERSION "v1.0" #define RED_VERSION "v1.0.4"
/** @brief On-disk version number. /** @brief On-disk version number.
@ -83,7 +83,7 @@
/** @brief Product copyright. /** @brief Product copyright.
*/ */
#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2015 Datalight, Inc. All Rights Reserved Worldwide." #define RED_PRODUCT_LEGAL "Copyright (c) 2014-2016 Datalight, Inc. All Rights Reserved Worldwide."
/** @brief Product patents. /** @brief Product patents.

@ -62,6 +62,13 @@ typedef struct
*/ */
uint32_t ulInodeCount; uint32_t ulInodeCount;
/** This is the maximum number of times a block device I/O operation will
be retried. If a block device read, write, or flush fails, Reliance
Edge will try again up to this number of times until the operation is
successful. Set this to 0 to disable retries.
*/
uint8_t bBlockIoRetries;
#if REDCONF_API_POSIX == 1 #if REDCONF_API_POSIX == 1
/** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc. /** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc.
*/ */

@ -36,8 +36,7 @@
#endif #endif
#if REDCONF_ASSERTS == 1 #if (REDCONF_ASSERTS == 1) && (REDCONF_OUTPUT == 1)
#if REDCONF_OUTPUT == 1
/** Print a formatted message for an assertion. /** Print a formatted message for an assertion.
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using
@ -50,11 +49,8 @@
As Rule 21.6 is required, a separate deviation record is required. As Rule 21.6 is required, a separate deviation record is required.
*/ */
#define PRINT_ASSERT(file, line) \ #define PRINT_ASSERT(file, line) \
(void)printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line)) printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line))
#else #endif
#define PRINT_ASSERT(file, line) do { (void)(file); (void)(line); } while(false)
#endif /* REDCONF_OUTPUT == 1 */
#endif /* REDCONF_ASSERTS == 1 */
/** Cast a value to unsigned long. /** Cast a value to unsigned long.
@ -161,5 +157,88 @@
#endif #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 #endif

@ -43,9 +43,11 @@ void RedOsAssertFail(
const char *pszFileName, const char *pszFileName,
uint32_t ulLineNum) uint32_t ulLineNum)
{ {
PRINT_ASSERT(pszFileName, ulLineNum); #if REDCONF_OUTPUT == 1
IGNORE_ERRORS(PRINT_ASSERT(pszFileName, ulLineNum));
#endif
for( ;; ) while(true)
{ {
} }
} }

@ -54,7 +54,7 @@
multi-sector requests, and servicing these one sector at a time will multi-sector requests, and servicing these one sector at a time will
significantly slow down the file system. significantly slow down the file system.
*/ */
#define BDEV_F_DRIVER 0U #define BDEV_F_DRIVER (0U)
/** @brief The FatFs example implementation. /** @brief The FatFs example implementation.
@ -63,7 +63,7 @@
in and used immediately. The FatFs `diskio.h` header must be in the include in and used immediately. The FatFs `diskio.h` header must be in the include
directory path. directory path.
*/ */
#define BDEV_FATFS 1U #define BDEV_FATFS (1U)
/** @brief The Atmel Studio Framework SD/MMC driver example implementation. /** @brief The Atmel Studio Framework SD/MMC driver example implementation.
@ -83,7 +83,15 @@
advantages to issuing real multi-sector requests, so using the modified advantages to issuing real multi-sector requests, so using the modified
driver is recommended. driver is recommended.
*/ */
#define BDEV_ATMEL_SDMMC 2U #define BDEV_ATMEL_SDMMC (2U)
/** @brief The ST Microelectronics STM32 SDIO driver example implementation.
This implementation accesses the microSD card through the BSP utilities
provided as part of the STM32Cube package, used with the STM32 HAL drivers.
The STM3240G-EVAL and STM32F746NG-Discovery boards are currently supported.
*/
#define BDEV_STM32_SDIO (3U)
/** @brief The RAM disk example implementation. /** @brief The RAM disk example implementation.
@ -92,7 +100,7 @@
target hardware, the amount of spare RAM will be limited so generally only target hardware, the amount of spare RAM will be limited so generally only
very small disks will be available. very small disks will be available.
*/ */
#define BDEV_RAM_DISK 3U #define BDEV_RAM_DISK (4U)
/** @brief Pick which example implementation is compiled. /** @brief Pick which example implementation is compiled.
@ -100,6 +108,7 @@
- #BDEV_F_DRIVER - #BDEV_F_DRIVER
- #BDEV_FATFS - #BDEV_FATFS
- #BDEV_ATMEL_SDMMC - #BDEV_ATMEL_SDMMC
- #BDEV_STM32_SDIO
- #BDEV_RAM_DISK - #BDEV_RAM_DISK
*/ */
#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK #define BDEV_EXAMPLE_IMPLEMENTATION BDEV_RAM_DISK
@ -468,7 +477,7 @@ static REDSTATUS DiskRead(
for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
{ {
iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize], iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize],
CAST_ULONG(ullSectorStart + ulSectorCount)); CAST_ULONG(ullSectorStart + ulSectorIdx));
if(iErr != 0) if(iErr != 0)
{ {
ret = -RED_EIO; ret = -RED_EIO;
@ -522,7 +531,7 @@ static REDSTATUS DiskWrite(
prototype is flawed, using a non-const pointer for the buffer. prototype is flawed, using a non-const pointer for the buffer.
*/ */
iErr = pDriver->writesector(pDriver, CAST_AWAY_CONST(uint8_t, &pbBuffer[ulSectorIdx * ulSectorSize]), iErr = pDriver->writesector(pDriver, CAST_AWAY_CONST(uint8_t, &pbBuffer[ulSectorIdx * ulSectorSize]),
CAST_ULONG(ullSectorStart + ulSectorCount)); CAST_ULONG(ullSectorStart + ulSectorIdx));
if(iErr != 0) if(iErr != 0)
{ {
ret = -RED_EIO; ret = -RED_EIO;
@ -868,7 +877,7 @@ static REDSTATUS DiskOpen(
{ {
uint32_t ulSectorLast; uint32_t ulSectorLast;
(void)sd_mmc_read_capacity(bVolNum, &ulSectorLast); IGNORE_ERRORS(sd_mmc_read_capacity(bVolNum, &ulSectorLast));
/* The ASF SD/MMC driver only supports 512-byte sectors. /* The ASF SD/MMC driver only supports 512-byte sectors.
*/ */
@ -1027,6 +1036,337 @@ static REDSTATUS DiskFlush(
} }
#endif /* REDCONF_READ_ONLY == 0 */ #endif /* REDCONF_READ_ONLY == 0 */
#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_STM32_SDIO
#ifdef USE_STM324xG_EVAL
#include <stm324xg_eval.h>
#include <stm324xg_eval_sd.h>
#elif defined(USE_STM32746G_DISCO)
#include <stm32746g_discovery.h>
#include <stm32746g_discovery_sd.h>
#else
/* If you are using a compatible STM32 device other than the two listed above
and you have SD card driver headers, you can try adding them to the above
list.
*/
#error "Unsupported device."
#endif
#if REDCONF_VOLUME_COUNT > 1
#error "The STM32 SDIO block device implementation does not support multiple volumes."
#endif
#ifndef USE_HAL_DRIVER
#error "The STM32 StdPeriph driver is not supported. Please use the HAL driver or modify the Reliance Edge block device interface."
#endif
/** @brief Number of times to call BSP_SD_GetStatus() before timing out and
returning an error.
See ::CheckStatus().
NOTE: Datalight has not observed a scenario where BSP_SD_GetStatus()
returns SD_TRANSFER_BUSY after a transfer command returns successfully.
Set SD_STATUS_TIMEOUT to 0U to skip checking BSP_SD_GetStatus().
*/
#define SD_STATUS_TIMEOUT (100000U)
/** @brief 4-byte aligned buffer to use for DMA transfers when passed in
an unaligned buffer.
*/
static uint32_t gaulAlignedBuffer[512U / sizeof(uint32_t)];
#if SD_STATUS_TIMEOUT > 0U
static REDSTATUS CheckStatus(void);
#endif
/** @brief Initialize a disk.
@param bVolNum The volume number of the volume whose block device is being
initialized.
@param mode The open mode, indicating the type of access required.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO No SD card was found; or BSP_SD_Init() failed.
@retval -RED_EINVAL The SD card's block size is not the same as the
configured sector size; or the SD card is not large
enough for the volume; or the volume size is above
4GiB, meaning that part of it cannot be accessed
through the STM32 SDIO driver.
*/
static REDSTATUS DiskOpen(
uint8_t bVolNum,
BDEVOPENMODE mode)
{
REDSTATUS ret = 0;
static bool fSdInitted = false;
(void) mode;
if(!fSdInitted)
{
if(BSP_SD_Init() == MSD_OK)
{
fSdInitted = true;
}
}
if(!fSdInitted)
{
/* Above initialization attempt failed.
*/
ret = -RED_EIO;
}
else if(BSP_SD_IsDetected() == SD_NOT_PRESENT)
{
ret = -RED_EIO;
}
else
{
uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
HAL_SD_CardInfoTypedef sdCardInfo = {{0}};
BSP_SD_GetCardInfo(&sdCardInfo);
/* Note: the actual card block size is sdCardInfo.CardBlockSize,
but the interface only supports a 512 byte block size. Further,
one card has been observed to report a 1024-byte block size,
but it worked fine with a 512-byte Reliance Edge ulSectorSize.
*/
if( (ulSectorSize != 512U)
|| (sdCardInfo.CardCapacity < (gaRedVolConf[bVolNum].ullSectorCount * ulSectorSize)))
{
ret = -RED_EINVAL;
}
}
return ret;
}
/** @brief Uninitialize a disk.
@param bVolNum The volume number of the volume whose block device is being
uninitialized.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
*/
static REDSTATUS DiskClose(
uint8_t bVolNum)
{
(void)bVolNum;
return 0;
}
/** @brief Read sectors from a disk.
@param bVolNum The volume number of the volume whose block device
is being read from.
@param ullSectorStart The starting sector number.
@param ulSectorCount The number of sectors to read.
@param pBuffer The buffer into which to read the sector data.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
*/
static REDSTATUS DiskRead(
uint8_t bVolNum,
uint64_t ullSectorStart,
uint32_t ulSectorCount,
void *pBuffer)
{
REDSTATUS redStat = 0;
uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
uint8_t bSdError;
if(IS_UINT32_ALIGNED_PTR(pBuffer))
{
bSdError = BSP_SD_ReadBlocks_DMA(CAST_UINT32_PTR(pBuffer), ullSectorStart * ulSectorSize, ulSectorSize, ulSectorCount);
if(bSdError != MSD_OK)
{
redStat = -RED_EIO;
}
#if SD_STATUS_TIMEOUT > 0U
else
{
redStat = CheckStatus();
}
#endif
}
else
{
uint32_t ulSectorIdx;
for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
{
bSdError = BSP_SD_ReadBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U);
if(bSdError != MSD_OK)
{
redStat = -RED_EIO;
}
#if SD_STATUS_TIMEOUT > 0U
else
{
redStat = CheckStatus();
}
#endif
if(redStat == 0)
{
uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer);
RedMemCpy(&pbBuffer[ulSectorIdx * ulSectorSize], gaulAlignedBuffer, ulSectorSize);
}
else
{
break;
}
}
}
return redStat;
}
#if REDCONF_READ_ONLY == 0
/** @brief Write sectors to a disk.
@param bVolNum The volume number of the volume whose block device
is being written to.
@param ullSectorStart The starting sector number.
@param ulSectorCount The number of sectors to write.
@param pBuffer The buffer from which to write the sector data.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 Operation was successful.
@retval -RED_EIO A disk I/O error occurred.
*/
static REDSTATUS DiskWrite(
uint8_t bVolNum,
uint64_t ullSectorStart,
uint32_t ulSectorCount,
const void *pBuffer)
{
REDSTATUS redStat = 0;
uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize;
uint8_t bSdError;
if(IS_UINT32_ALIGNED_PTR(pBuffer))
{
bSdError = BSP_SD_WriteBlocks_DMA(CAST_UINT32_PTR(CAST_AWAY_CONST(void, pBuffer)), ullSectorStart * ulSectorSize,
ulSectorSize, ulSectorCount);
if(bSdError != MSD_OK)
{
redStat = -RED_EIO;
}
#if SD_STATUS_TIMEOUT > 0U
else
{
redStat = CheckStatus();
}
#endif
}
else
{
uint32_t ulSectorIdx;
for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++)
{
const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
RedMemCpy(gaulAlignedBuffer, &pbBuffer[ulSectorIdx * ulSectorSize], ulSectorSize);
bSdError = BSP_SD_WriteBlocks_DMA(gaulAlignedBuffer, (ullSectorStart + ulSectorIdx) * ulSectorSize, ulSectorSize, 1U);
if(bSdError != MSD_OK)
{
redStat = -RED_EIO;
}
#if SD_STATUS_TIMEOUT > 0U
else
{
redStat = CheckStatus();
}
#endif
if(redStat != 0)
{
break;
}
}
}
return redStat;
}
/** @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.
*/
static REDSTATUS DiskFlush(
uint8_t bVolNum)
{
/* Disk transfer is synchronous; nothing to flush.
*/
(void) bVolNum;
return 0;
}
#if SD_STATUS_TIMEOUT > 0U
/** @brief Wait until BSP_SD_GetStatus returns SD_TRANSFER_OK.
This function calls BSP_SD_GetStatus repeatedly as long as it returns
SD_TRANSFER_BUSY up to SD_STATUS_TIMEOUT times.
@return A negated ::REDSTATUS code indicating the operation result.
@retval 0 SD_TRANSFER_OK was returned.
@retval -RED_EIO SD_TRANSFER_ERROR received, or timed out waiting for
SD_TRANSFER_OK.
*/
static REDSTATUS CheckStatus(void)
{
REDSTATUS redStat = 0;
uint32_t ulTimeout = SD_STATUS_TIMEOUT;
HAL_SD_TransferStateTypedef transferState;
do
{
transferState = BSP_SD_GetStatus();
ulTimeout--;
} while((transferState == SD_TRANSFER_BUSY) && (ulTimeout > 0U));
if(transferState != SD_TRANSFER_OK)
{
redStat = -RED_EIO;
}
return redStat;
}
#endif
#endif /* REDCONF_READ_ONLY == 0 */
#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK #elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK
@ -1204,7 +1544,6 @@ static REDSTATUS DiskFlush(
} }
#endif /* REDCONF_READ_ONLY == 0 */ #endif /* REDCONF_READ_ONLY == 0 */
#else #else
#error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value" #error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value"

@ -29,11 +29,15 @@
#include <semphr.h> #include <semphr.h>
#include <redfs.h> #include <redfs.h>
#include <redosdeviations.h>
#if REDCONF_TASK_COUNT > 1U #if REDCONF_TASK_COUNT > 1U
static SemaphoreHandle_t xMutex; static SemaphoreHandle_t xMutex;
#if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
static StaticSemaphore_t xMutexBuffer;
#endif
/** @brief Initialize the mutex. /** @brief Initialize the mutex.
@ -49,17 +53,27 @@ static SemaphoreHandle_t xMutex;
*/ */
REDSTATUS RedOsMutexInit(void) REDSTATUS RedOsMutexInit(void)
{ {
REDSTATUS ret; REDSTATUS ret = 0;
xMutex = xSemaphoreCreateMutex(); #if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
if(xMutex != NULL) xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer);
if(xMutex == NULL)
{ {
ret = 0; /* The only error case for xSemaphoreCreateMutexStatic is that the mutex
buffer parameter is NULL, which is not the case.
*/
REDERROR();
ret = -RED_EINVAL;
} }
else
#else
xMutex = xSemaphoreCreateMutex();
if(xMutex == NULL)
{ {
ret = -RED_ENOMEM; ret = -RED_ENOMEM;
} }
#endif
return ret; return ret;
} }
@ -113,7 +127,7 @@ void RedOsMutexRelease(void)
xSuccess = xSemaphoreGive(xMutex); xSuccess = xSemaphoreGive(xMutex);
REDASSERT(xSuccess == pdTRUE); REDASSERT(xSuccess == pdTRUE);
(void)xSuccess; IGNORE_ERRORS(xSuccess);
} }
#endif #endif

@ -891,6 +891,7 @@ static PRINTTYPE ParseFormatType(
case 'u': case 'u':
fmtType = MAPULONGLONG; fmtType = MAPULONGLONG;
break; break;
case 'x':
case 'X': case 'X':
fmtType = MAPHEXULONGLONG; fmtType = MAPHEXULONGLONG;
break; break;

Loading…
Cancel
Save