git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10998 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
Giovanni Di Sirio 2017-11-14 13:18:59 +00:00
parent 1935d28be9
commit ed415bb76f
4 changed files with 373 additions and 424 deletions

View File

@ -154,7 +154,7 @@ static mfs_error_t mfs_flash_read(MFSDriver *mfsp, flash_offset_t offset,
ferr = flashRead(mfsp->config->flashp, offset, n, rp); ferr = flashRead(mfsp->config->flashp, offset, n, rp);
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
@ -182,7 +182,7 @@ static mfs_error_t mfs_flash_write(MFSDriver *mfsp,
ferr = flashProgram(mfsp->config->flashp, offset, n, wp); ferr = flashProgram(mfsp->config->flashp, offset, n, wp);
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
@ -192,7 +192,7 @@ static mfs_error_t mfs_flash_write(MFSDriver *mfsp,
size_t chunk = n <= MFS_CFG_BUFFER_SIZE ? n : MFS_CFG_BUFFER_SIZE; size_t chunk = n <= MFS_CFG_BUFFER_SIZE ? n : MFS_CFG_BUFFER_SIZE;
RET_ON_ERROR(mfs_flash_read(mfsp, offset, chunk, mfsp->buffer.data8)); RET_ON_ERROR(mfs_flash_read(mfsp, offset, chunk, mfsp->buffer.data8));
if (memcmp((void *)mfsp->buffer.data8, (void *)wp, chunk)) { if (memcmp((void *)mfsp->buffer.data8, (void *)wp, chunk)) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
n -= chunk; n -= chunk;
@ -314,17 +314,17 @@ static mfs_error_t mfs_bank_erase(MFSDriver *mfsp, mfs_bank_t bank) {
ferr = flashStartEraseSector(mfsp->config->flashp, sector); ferr = flashStartEraseSector(mfsp->config->flashp, sector);
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
ferr = flashWaitErase(mfsp->config->flashp); ferr = flashWaitErase(mfsp->config->flashp);
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
ferr = flashVerifyErase(mfsp->config->flashp, sector); ferr = flashVerifyErase(mfsp->config->flashp, sector);
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
@ -363,7 +363,7 @@ static mfs_error_t mfs_bank_verify_erase(MFSDriver *mfsp, mfs_bank_t bank) {
return MFS_ERR_NOT_ERASED; return MFS_ERR_NOT_ERASED;
} }
if (ferr != FLASH_NO_ERROR) { if (ferr != FLASH_NO_ERROR) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
@ -795,17 +795,48 @@ void mfsObjectInit(MFSDriver *mfsp) {
* *
* @param[in] mfsp pointer to the @p MFSDriver object * @param[in] mfsp pointer to the @p MFSDriver object
* @param[in] config pointer to the configuration * @param[in] config pointer to the configuration
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_WARN_GC if the operation triggered a garbage collection.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Makes the driver enter the @p MFS_ERROR state.
* @retval MFS_ERR_INTERNAL if an internal logic failure is detected.
* *
* @api * @api
*/ */
void mfsStart(MFSDriver *mfsp, const MFSConfig *config) { mfs_error_t mfsStart(MFSDriver *mfsp, const MFSConfig *config) {
unsigned i;
osalDbgCheck((mfsp != NULL) && (config != NULL)); osalDbgCheck((mfsp != NULL) && (config != NULL));
osalDbgAssert((mfsp->state == MFS_STOP) || (mfsp->state == MFS_READY), osalDbgAssert((mfsp->state == MFS_STOP) || (mfsp->state == MFS_READY) ||
"invalid state"); (mfsp->state == MFS_ERROR), "invalid state");
/* Storing configuration.*/
mfsp->config = config; mfsp->config = config;
/* Resetting previous state.*/
mfs_state_reset(mfsp);
/* Attempting to mount the managed partition.*/
for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) {
mfs_error_t err;
err = mfs_try_mount(mfsp);
if (err == MFS_ERR_INTERNAL) {
/* Special case, do not retry on internal errors but report
immediately.*/
mfsp->state = MFS_ERROR;
return err;
}
if (!MFS_IS_ERROR(err)) {
mfsp->state = MFS_READY; mfsp->state = MFS_READY;
return err;
}
}
/* Driver start failed.*/
mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE;
} }
/** /**
@ -818,99 +849,28 @@ void mfsStart(MFSDriver *mfsp, const MFSConfig *config) {
void mfsStop(MFSDriver *mfsp) { void mfsStop(MFSDriver *mfsp) {
osalDbgCheck(mfsp != NULL); osalDbgCheck(mfsp != NULL);
osalDbgAssert((mfsp->state == MFS_STOP) || (mfsp->state == MFS_READY), osalDbgAssert((mfsp->state == MFS_STOP) || (mfsp->state == MFS_READY) ||
"invalid state"); (mfsp->state == MFS_ERROR), "invalid state");
mfsp->config = NULL; mfsp->config = NULL;
mfsp->state = MFS_STOP; mfsp->state = MFS_STOP;
} }
/**
* @brief Mounts a managed flash storage.
* @details This functions checks the storage internal state and eventually
* performs the required initialization or repair operations.
*
* @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_WARN_REPAIR if the operation has been completed but a
* repair has been performed.
* @retval MFS_ERR_INV_STATE if the volume is mounted.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted.
*
* @api
*/
mfs_error_t mfsMount(MFSDriver *mfsp) {
unsigned i;
osalDbgCheck(mfsp != NULL);
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE;
}
/* Clearing state.*/
mfs_state_reset(mfsp);
/* Attempting to mount the managed partition.*/
for (i = 0; i < MFS_CFG_MAX_REPAIR_ATTEMPTS; i++) {
mfs_error_t err;
err = mfs_try_mount(mfsp);
if (!MFS_IS_ERROR(err)) {
mfsp->state = MFS_MOUNTED;
return err;
}
}
return MFS_ERR_FLASH_FAILURE;
}
/**
* @brief Unmounts a managed flash storage.
*
* @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_INV_STATE if the volume is not mounted.
*
* @api
*/
mfs_error_t mfsUnmount(MFSDriver *mfsp) {
osalDbgCheck(mfsp != NULL);
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_MOUNTED) {
return MFS_ERR_INV_STATE;
}
mfsp->state = MFS_READY;
return MFS_NO_ERROR;
}
/** /**
* @brief Destroys the state of the managed storage by erasing the flash. * @brief Destroys the state of the managed storage by erasing the flash.
* *
* @param[in] mfsp pointer to the @p MFSDriver object * @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status. * @return The operation status.
* @retval MFS_ERR_INV_STATE if the volume is mounted. * @retval MFS_ERR_INV_STATE if the driver is in not in @p MSG_READY state.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted. * failures. Makes the driver enter the @p MFS_ERROR state.
* *
* @api * @api
*/ */
mfs_error_t mfsErase(MFSDriver *mfsp) { mfs_error_t mfsErase(MFSDriver *mfsp) {
osalDbgCheck(mfsp != NULL); osalDbgCheck(mfsp != NULL);
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_READY) { if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE; return MFS_ERR_INV_STATE;
@ -918,6 +878,7 @@ mfs_error_t mfsErase(MFSDriver *mfsp) {
RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0)); RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_0));
RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1)); RET_ON_ERROR(mfs_bank_erase(mfsp, MFS_BANK_1));
/* TODO: Remount.*/
return MFS_NO_ERROR; return MFS_NO_ERROR;
} }
@ -933,12 +894,12 @@ mfs_error_t mfsErase(MFSDriver *mfsp) {
* @param[out] buffer pointer to a buffer for record data * @param[out] buffer pointer to a buffer for record data
* @return The operation status. * @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_INV_STATE if the driver is in not in @p MSG_READY state.
* @retval MFS_ERR_INV_SIZE if the passed buffer is not large enough to * @retval MFS_ERR_INV_SIZE if the passed buffer is not large enough to
* contain the record data. * contain the record data.
* @retval MFS_ERR_NOT_FOUND if the specified id does not exists. * @retval MFS_ERR_NOT_FOUND if the specified id does not exists.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted. * failures. Makes the driver enter the @p MFS_ERROR state.
* *
* @api * @api
*/ */
@ -948,10 +909,8 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) && osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) &&
(np != NULL) && (buffer != NULL)); (np != NULL) && (buffer != NULL));
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_MOUNTED) { if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE; return MFS_ERR_INV_STATE;
} }
@ -975,7 +934,7 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
/* Checking CRC.*/ /* Checking CRC.*/
crc = crc16(0xFFFFU, buffer, *np); crc = crc16(0xFFFFU, buffer, *np);
if (crc != mfsp->buffer.dhdr.fields.crc) { if (crc != mfsp->buffer.dhdr.fields.crc) {
mfsp->state = MFS_READY; mfsp->state = MFS_ERROR;
return MFS_ERR_FLASH_FAILURE; return MFS_ERR_FLASH_FAILURE;
} }
@ -993,11 +952,11 @@ mfs_error_t mfsReadRecord(MFSDriver *mfsp, uint32_t id,
* @return The operation status. * @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_WARN_GC if the operation triggered a garbage collection. * @retval MFS_WARN_GC if the operation triggered a garbage collection.
* @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_INV_STATE if the driver is in not in @p MSG_READY state.
* @retval MFS_ERR_OUT_OF_MEM if there is not enough flash space for the * @retval MFS_ERR_OUT_OF_MEM if there is not enough flash space for the
* operation. * operation.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted. * failures. Makes the driver enter the @p MFS_ERROR state.
* *
* @api * @api
*/ */
@ -1008,10 +967,8 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) && osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS) &&
(n > 0U) && (buffer != NULL)); (n > 0U) && (buffer != NULL));
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_MOUNTED) { if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE; return MFS_ERR_INV_STATE;
} }
@ -1082,9 +1039,9 @@ mfs_error_t mfsWriteRecord(MFSDriver *mfsp, uint32_t id,
* @return The operation status. * @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_WARN_GC if the operation triggered a garbage collection. * @retval MFS_WARN_GC if the operation triggered a garbage collection.
* @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_INV_STATE if the driver is in not in @p MSG_READY state.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted. * failures. Makes the driver enter the @p MFS_ERROR state.
* @retval MFS_ERR_INTERNAL if an internal logic failure is detected. * @retval MFS_ERR_INTERNAL if an internal logic failure is detected.
* *
* @api * @api
@ -1094,10 +1051,8 @@ mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) {
bool warning = false; bool warning = false;
osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS)); osalDbgCheck((mfsp != NULL) && (id >= 1) && (id <= MFS_CFG_MAX_RECORDS));
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_MOUNTED) { if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE; return MFS_ERR_INV_STATE;
} }
@ -1151,19 +1106,17 @@ mfs_error_t mfsEraseRecord(MFSDriver *mfsp, uint32_t id) {
* @param[in] mfsp pointer to the @p MFSDriver object * @param[in] mfsp pointer to the @p MFSDriver object
* @return The operation status. * @return The operation status.
* @retval MFS_NO_ERROR if the operation has been successfully completed. * @retval MFS_NO_ERROR if the operation has been successfully completed.
* @retval MFS_ERR_INV_STATE if the volume is not mounted. * @retval MFS_ERR_INV_STATE if the driver is in not in @p MSG_READY state.
* @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW * @retval MFS_ERR_FLASH_FAILURE if the flash memory is unusable because HW
* failures. Causes the volume to be unmounted. * failures. Makes the driver enter the @p MFS_ERROR state.
* *
* @api * @api
*/ */
mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) { mfs_error_t mfsPerformGarbageCollection(MFSDriver *mfsp) {
osalDbgCheck(mfsp != NULL); osalDbgCheck(mfsp != NULL);
osalDbgAssert((mfsp->state == MFS_READY) || (mfsp->state == MFS_MOUNTED),
"invalid state");
if (mfsp->state != MFS_MOUNTED) { if (mfsp->state != MFS_READY) {
return MFS_ERR_INV_STATE; return MFS_ERR_INV_STATE;
} }

View File

@ -132,7 +132,7 @@ typedef enum {
MFS_UNINIT = 0, MFS_UNINIT = 0,
MFS_STOP = 1, MFS_STOP = 1,
MFS_READY = 2, MFS_READY = 2,
MFS_MOUNTED = 3 MFS_ERROR = 3
} mfs_state_t; } mfs_state_t;
/** /**
@ -349,10 +349,8 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void mfsObjectInit(MFSDriver *devp); void mfsObjectInit(MFSDriver *devp);
void mfsStart(MFSDriver *devp, const MFSConfig *config); mfs_error_t mfsStart(MFSDriver *devp, const MFSConfig *config);
void mfsStop(MFSDriver *devp); void mfsStop(MFSDriver *devp);
mfs_error_t mfsMount(MFSDriver *devp);
mfs_error_t mfsUnmount(MFSDriver *devp);
mfs_error_t mfsErase(MFSDriver *mfsp); mfs_error_t mfsErase(MFSDriver *mfsp);
mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id, mfs_error_t mfsReadRecord(MFSDriver *devp, uint32_t id,
size_t *np, uint8_t *buffer); size_t *np, uint8_t *buffer);

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<SPC5-Config version="1.0.0"> <SPC5-Config version="1.0.0">
<application name="ChibiOS/NIL Test Suite" version="1.0.0" standalone="true" locked="false"> <application name="ChibiOS/HAL MFS Test Suite" version="1.0.0" standalone="true" locked="false">
<description>Test Specification for ChibiOS/HAL MFS Complex Driver.</description> <description>Test Specification for ChibiOS/HAL MFS Complex Driver.</description>
<component id="org.chibios.spc5.components.portable.generic_startup"> <component id="org.chibios.spc5.components.portable.generic_startup">
<component id="org.chibios.spc5.components.portable.chibios_unitary_tests_engine" /> <component id="org.chibios.spc5.components.portable.chibios_unitary_tests_engine" />
@ -35,10 +35,10 @@
</description> </description>
<global_data_and_code> <global_data_and_code>
<code_prefix> <code_prefix>
<value>nil_</value> <value>mfs_</value>
</code_prefix> </code_prefix>
<global_definitions> <global_definitions>
<value><![CDATA[#define TEST_SUITE_NAME "ChibiOS/NIL Test Suite" <value><![CDATA[#define TEST_SUITE_NAME "ChibiOS/HAL MFS Test Suite"
#define TEST_REPORT_HOOK_HEADER test_print_port_info(); #define TEST_REPORT_HOOK_HEADER test_print_port_info();
@ -114,6 +114,9 @@ THD_FUNCTION(test_support, arg) {
<description> <description>
<value>The APIs are tested for functionality, correct cases and expected error cases are tested.</value> <value>The APIs are tested for functionality, correct cases and expected error cases are tested.</value>
</description> </description>
<condition>
<value />
</condition>
<shared_code> <shared_code>
<value><![CDATA[#include <string.h> <value><![CDATA[#include <string.h>
#include "key_storage.h" #include "key_storage.h"

View File

@ -93,7 +93,6 @@ static THD_FUNCTION(Thread1, arg) {
*/ */
int main(void) { int main(void) {
mfs_error_t err; mfs_error_t err;
uint8_t *addr;
/* /*
* System initializations. * System initializations.
@ -121,11 +120,8 @@ int main(void) {
/* Mounting the MFS volume defined in the configuration.*/ /* Mounting the MFS volume defined in the configuration.*/
mfsObjectInit(&mfs); mfsObjectInit(&mfs);
mfsStart(&mfs, &mfscfg1); err = mfsStart(&mfs, &mfscfg1);
err = mfsUnmount(&mfs);
err = mfsErase(&mfs); err = mfsErase(&mfs);
err = mfsMount(&mfs);
err = mfsWriteRecord(&mfs, 1, 64, pattern); err = mfsWriteRecord(&mfs, 1, 64, pattern);
err = mfsWriteRecord(&mfs, 2, 64, pattern); err = mfsWriteRecord(&mfs, 2, 64, pattern);
@ -134,10 +130,9 @@ int main(void) {
err = mfsPerformGarbageCollection(&mfs); err = mfsPerformGarbageCollection(&mfs);
/* Reading.*/ mfsStop(&mfs);
flashRead(&m25q, 0, 128, buffer);
err = mfsUnmount(&mfs); (void)err;
/* /*
* Normal main() thread activity, in this demo it does nothing. * Normal main() thread activity, in this demo it does nothing.