Updated memory storage functionality

- cachedStorage is functional
- Presets can be loaded from FLASH
- CRC32 added and applied
- Presets with corrputed data will be replaced by default preset

Next: Preset update functionality from menu 

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@269 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
mmi
2017-11-02 12:58:27 +00:00
parent 76783a6061
commit 4901cb1a09
27 changed files with 894 additions and 144 deletions

View File

@@ -0,0 +1,320 @@
// -----------------------------------------------------------------------------
/// @file RepairPresets.c
/// @brief Description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @file RepairPresets.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include "hsb-mrts.h"
#include "RepairPresets.h"
#include "CachedStorage.h"
#include "crc32.h"
#include "MemoryDevice.h"
#include "Logger.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
struct RepairPresets
{
bool initialized;
bool presetsLoaded;
REPAIR_PRESETS_ID currentPresetID;
struct CachedStorage* presetStorage;
struct MemoryDevice* memoryDevice;
};
struct RepairPresetStorageClass
{
uint32_t crc;
struct RepairPreset preset;
};
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
static struct RepairPresets _self = {.initialized = false, .presetsLoaded = false};
struct RepairPresets* const self = &_self;
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static ErrorStatus RepairPresets_verifyCRCs(void);
static ErrorStatus RepairPresets_verifyPresetCRC(struct RepairPresetStorageClass* repairPreset);
static ErrorStatus RepairPresets_writePreset(struct RepairPreset* preset);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus RepairPresets_construct(struct CachedStorage* presetStorage, struct MemoryDevice* memoryDevice)
{
ErrorStatus returnValue = SUCCESS;
if (!self->initialized)
{
if (returnValue == SUCCESS)
{
if (presetStorage != NULL)
{
self->presetStorage = presetStorage;
}
else
{
returnValue = ERROR;
}
}
if (returnValue == SUCCESS)
{
if (memoryDevice != NULL)
{
if (memoryDevice->initialized)
{
self->memoryDevice = memoryDevice;
}
else
{
returnValue = ERROR;
}
}
else
{
returnValue = ERROR;
}
}
self->initialized = true;
self->presetsLoaded = false;
}
else
{
returnValue = ERROR;
}
return returnValue;
}
void RepairPresets_destruct(void)
{
if (self->initialized)
{
self->initialized = false;
self->presetsLoaded = false;
}
}
ErrorStatus RepairPresets_loadPresets(REPAIR_PRESETS_ID presetID)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
// Destruct the cachedStorage to remove all previous data
CachedStorage_destruct(self->presetStorage);
// Get the new preset ID
self->currentPresetID = presetID;
// Construct new cached Storage with base address defined by the preset ID
unsigned int pageNumber;
switch (self->currentPresetID)
{
case REPAIR_PRESETS_ANODE:
{
pageNumber = APP_FLASH_PRESET_ANODE_PAGE;
break;
}
case REPAIR_PRESETS_CATHODE:
{
pageNumber = APP_FLASH_PRESET_CATHODE_PAGE;
break;
}
case REPAIR_PRESETS_MCP:
{
pageNumber = APP_FLASH_PRESET_MCP_PAGE;
break;
}
case REPAIR_PRESETS_TESLA:
{
pageNumber = APP_FLASH_PRESET_TESLA_PAGE;
break;
}
default:
{
LOGGER_ERROR(mainLog, "Unknown preset ID");
returnValue = ERROR;
}
}
// If Preset ID was valid, go on loading presets from memory
if (returnValue == SUCCESS)
{
// Create new cachedStorage with preset page number
returnValue = CachedStorage_construct(self->presetStorage, self->memoryDevice, pageNumber);
}
else
{
self->presetsLoaded = false;
}
// Check the CRC on the loaded presets
if (returnValue == SUCCESS)
{
returnValue = RepairPresets_verifyCRCs();
}
// CRCs are verified
// If CRCs are correct on all presets, returnValue will still be SUCCESS
if (returnValue == SUCCESS)
{
self->presetsLoaded = true;
}
// If any CRC is wrong
}
else
{
returnValue = ERROR;
}
return returnValue;
}
const struct RepairPreset* RepairPresets_getPreset(unsigned int index)
{
const struct RepairPreset* returnValue = NULL;
if (self->initialized)
{
if (self->presetsLoaded)
{
// Index is human-readable, thus starting with 1
if ((index > 0) || (index <= REPAIR_PRESETS_NUMBER_OF_PRESETS))
{
struct RepairPresetStorageClass* tempPreset;
tempPreset = CachedStorage_readBlob(self->presetStorage, (index - 1) * sizeof(struct RepairPresetStorageClass));
returnValue = (const struct RepairPreset*)&tempPreset->preset;
}
}
}
return returnValue;
}
static ErrorStatus RepairPresets_verifyCRCs(void)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
int loopCounter;
struct RepairPresetStorageClass _tempPresetStorage;
struct RepairPresetStorageClass* tempPresetStorage = &_tempPresetStorage;
for (loopCounter = 0; loopCounter < REPAIR_PRESETS_NUMBER_OF_PRESETS; loopCounter++)
{
// Load next preset from cache
tempPresetStorage = CachedStorage_readBlob(self->presetStorage, loopCounter * sizeof(struct RepairPresetStorageClass));
// Verify CRC
returnValue = RepairPresets_verifyPresetCRC(tempPresetStorage);
// Check CRC verification
if (returnValue != SUCCESS)
{
// CRC was not correct - replace corrupted preset with a DEFAULT preset
RepairPreset_generateDefaultPreset(&tempPresetStorage->preset, loopCounter + 1);
LOGGER_DEBUG(mainLog, "PRESET %d: Softstart: %d, Duration: %d, Voltage: %d", tempPresetStorage->preset.presetNumber, tempPresetStorage->preset.preset[0].softstartDuration, tempPresetStorage->preset.preset[0].duration, tempPresetStorage->preset.preset[0].voltage);
// Write default preset to Cache
RepairPresets_writePreset(&tempPresetStorage->preset);
}
}
// Commit cache to memory - will not write if no changes have been made
CachedStorage_commit(self->presetStorage);
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus RepairPresets_verifyPresetCRC(struct RepairPresetStorageClass* repairPreset)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
// Calculate the CRC of the given repair preset
uint32_t tempCRC;
tempCRC = crc32_calculate(0, &repairPreset->preset, sizeof(struct RepairPreset));
// Compare loaded and calculated CRC values - must be equal
if (repairPreset->crc != tempCRC)
{
// CRCs do not match
returnValue = ERROR;
LOGGER_ERROR(mainLog, "CRC ERROR at repair preset %d (calculated %X but loaded %X)", repairPreset->preset.presetNumber, (unsigned int)tempCRC, (unsigned int)repairPreset->crc);
}
else
{
LOGGER_INFO(mainLog, "CRC OK at repair preset %d (calculated %X and loaded %X)", repairPreset->preset.presetNumber, (unsigned int)tempCRC, (unsigned int)repairPreset->crc);
}
}
else
{
returnValue = ERROR;
}
return returnValue;
}
static ErrorStatus RepairPresets_writePreset(struct RepairPreset* preset)
{
ErrorStatus returnValue = SUCCESS;
if (self->initialized)
{
struct RepairPresetStorageClass tempPresetStorage;
tempPresetStorage.preset = *preset;
// Calculate CRC over preset
tempPresetStorage.crc = crc32_calculate(0, &tempPresetStorage.preset, sizeof(struct RepairPreset));
// Put default preset on Cache
CachedStorage_writeBlob(self->presetStorage, (tempPresetStorage.preset.presetNumber - 1) * sizeof(struct RepairPresetStorageClass), &tempPresetStorage, sizeof(struct RepairPresetStorageClass));
}
else
{
returnValue = ERROR;
}
return returnValue;
}