|
- #include "plsr_persistence.h"
- #include <stddef.h>
- #include <string.h>
-
- #define PLSR_HSD_BACKUP_MAGIC (0x504C4853UL)
- #define PLSR_HSD_BACKUP_VERSION (1U)
- #define PLSR_BACKUP_SLOT_A_OFFSET (0x0100UL)
- #define PLSR_BACKUP_SLOT_STRIDE (0x0200UL)
- #define PLSR_SFD_FLASH_MAGIC (0x504C5346UL)
- #define PLSR_SFD_FLASH_VERSION (1U)
- #define PLSR_SFD_FLASH_SLOT_A_ADDRESS (0x080C0000UL)
- #define PLSR_SFD_FLASH_SLOT_B_ADDRESS (0x080E0000UL)
- #define PLSR_SFD_FLASH_SECTOR_SIZE (0x00020000UL)
- #define PLSR_SFD_AXIS_STRIDE (130U)
- #define PLSR_SFD_PARAMETER_SET_COUNT (4U)
- #define PLSR_SFD_PARAMETER_SET_OFFSET (50U)
- #define PLSR_SFD_PARAMETER_SET_STRIDE (20U)
- #define PLSR_SFD_DEFAULT_MAX_SPEED (100000UL)
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadLength;
- uint32_t generation;
- PLSR_HSD_DATA data;
- uint32_t crc32;
- } PLSR_HSD_BACKUP_RECORD;
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadLength;
- uint32_t generation;
- } PLSR_SFD_FLASH_HEADER;
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadLength;
- uint32_t generation;
- PLSR_SFD_DATA data;
- uint32_t crc32;
- } PLSR_SFD_FLASH_RECORD;
-
- #ifdef PLSR_HOST_TEST
- static PLSR_HSD_BACKUP_RECORD PlsrHostBackupSlots[2];
- static PLSR_SFD_FLASH_RECORD PlsrHostSfdSlots[2];
- static PLSR_TEST_SFD_FAULT PlsrHostSfdFault;
- #else
- #include "stm32f4xx.h"
- #include "stm32f4xx_hal.h"
- #include "stm32f4xx_hal_flash_ex.h"
- #endif
-
- static uint32_t PlsrPersistenceCrc32Update(uint32_t crc,
- const volatile uint8_t *data,
- uint32_t length)
- {
- uint32_t index;
- uint8_t bit;
-
- for (index = 0U; index < length; index++)
- {
- crc ^= data[index];
- for (bit = 0U; bit < 8U; bit++)
- {
- if ((crc & 1UL) != 0UL)
- {
- crc = (crc >> 1U) ^ 0xEDB88320UL;
- }
- else
- {
- crc >>= 1U;
- }
- }
- }
-
- return crc;
- }
-
- static uint32_t PlsrPersistenceCrc32(const volatile uint8_t *data,
- uint32_t length)
- {
- return ~PlsrPersistenceCrc32Update(0xFFFFFFFFUL, data, length);
- }
-
- static volatile PLSR_HSD_BACKUP_RECORD *PlsrPersistenceGetHsdSlot(
- uint8_t slot)
- {
- #ifdef PLSR_HOST_TEST
- return &PlsrHostBackupSlots[slot];
- #else
- uint32_t offset = PLSR_BACKUP_SLOT_A_OFFSET
- + (uint32_t)slot * PLSR_BACKUP_SLOT_STRIDE;
- return (volatile PLSR_HSD_BACKUP_RECORD *)(BKPSRAM_BASE + offset);
- #endif
- }
-
- static uint8_t PlsrPersistenceHsdRecordIsValid(
- const volatile PLSR_HSD_BACKUP_RECORD *record)
- {
- uint32_t expectedCrc;
-
- if ((record->magic != PLSR_HSD_BACKUP_MAGIC)
- || (record->version != PLSR_HSD_BACKUP_VERSION)
- || (record->payloadLength != sizeof(PLSR_HSD_DATA)))
- {
- return 0U;
- }
-
- expectedCrc = PlsrPersistenceCrc32(
- (const volatile uint8_t *)record,
- (uint32_t)offsetof(PLSR_HSD_BACKUP_RECORD, crc32));
-
- return (expectedCrc == record->crc32) ? 1U : 0U;
- }
-
- static uint8_t PlsrPersistenceGenerationIsNewer(uint32_t left,
- uint32_t right)
- {
- return (((int32_t)(left - right)) > 0) ? 1U : 0U;
- }
-
- static volatile PLSR_SFD_FLASH_RECORD *PlsrPersistenceGetSfdSlot(
- uint8_t slot)
- {
- #ifdef PLSR_HOST_TEST
- return &PlsrHostSfdSlots[slot];
- #else
- uint32_t address = (slot == 0U) ? PLSR_SFD_FLASH_SLOT_A_ADDRESS
- : PLSR_SFD_FLASH_SLOT_B_ADDRESS;
- return (volatile PLSR_SFD_FLASH_RECORD *)address;
- #endif
- }
-
- static uint8_t PlsrPersistenceSfdRecordIsValid(
- const volatile PLSR_SFD_FLASH_RECORD *record)
- {
- uint32_t expectedCrc;
-
- if ((record->magic != PLSR_SFD_FLASH_MAGIC)
- || (record->version != PLSR_SFD_FLASH_VERSION)
- || (record->payloadLength != sizeof(PLSR_SFD_DATA)))
- {
- return 0U;
- }
-
- expectedCrc = PlsrPersistenceCrc32(
- (const volatile uint8_t *)record,
- (uint32_t)offsetof(PLSR_SFD_FLASH_RECORD, crc32));
-
- return (expectedCrc == record->crc32) ? 1U : 0U;
- }
-
- static void PlsrPersistenceCopySfdFromVolatile(
- PLSR_SFD_DATA *destination,
- const volatile PLSR_SFD_DATA *source)
- {
- uint16_t index;
-
- for (index = 0U; index < PLSR_SFD_CONFIG_COUNT; index++)
- {
- destination->config[index] = source->config[index];
- }
- }
-
- static void PlsrPersistenceApplySfdDefaults(PLSR_SFD_DATA *data)
- {
- uint16_t axisOffset;
- uint16_t parameterOffset;
- uint8_t axis;
- uint8_t parameterSet;
-
- (void)memset(data, 0, sizeof(*data));
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- axisOffset = (uint16_t)((uint16_t)axis * PLSR_SFD_AXIS_STRIDE);
-
- /* Explicit Xinje defaults from the SFD parameter table. */
- data->config[axisOffset + 7U] = 10;
- data->config[axisOffset + 27U] = 20;
- data->config[axisOffset + 43U] = 0x0201;
-
- for (parameterSet = 0U;
- parameterSet < PLSR_SFD_PARAMETER_SET_COUNT;
- parameterSet++)
- {
- parameterOffset = (uint16_t)(
- axisOffset + PLSR_SFD_PARAMETER_SET_OFFSET
- + (uint16_t)parameterSet * PLSR_SFD_PARAMETER_SET_STRIDE);
- data->config[parameterOffset + 6U] =
- (int32_t)(PLSR_SFD_DEFAULT_MAX_SPEED & 0xFFFFUL);
- data->config[parameterOffset + 7U] =
- (int32_t)(PLSR_SFD_DEFAULT_MAX_SPEED >> 16U);
- }
- }
- }
-
- static PLSR_PERSISTENCE_RESULT PlsrPersistenceBeginSfdOperation(void)
- {
- #ifdef PLSR_HOST_TEST
- return PLSR_PERSISTENCE_OK;
- #else
- if (HAL_FLASH_Unlock() != HAL_OK)
- {
- return PLSR_PERSISTENCE_PROGRAM_FAILED;
- }
-
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR
- | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR
- | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
- return PLSR_PERSISTENCE_OK;
- #endif
- }
-
- static PLSR_PERSISTENCE_RESULT PlsrPersistenceEndSfdOperation(
- PLSR_PERSISTENCE_RESULT result)
- {
- #ifdef PLSR_HOST_TEST
- return result;
- #else
- if ((HAL_FLASH_Lock() != HAL_OK) && (result == PLSR_PERSISTENCE_OK))
- {
- return PLSR_PERSISTENCE_PROGRAM_FAILED;
- }
- return result;
- #endif
- }
-
- static PLSR_PERSISTENCE_RESULT PlsrPersistenceEraseSfdSlot(uint8_t slot)
- {
- #ifdef PLSR_HOST_TEST
- if (PlsrHostSfdFault == PLSR_TEST_SFD_FAULT_ERASE)
- {
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- return PLSR_PERSISTENCE_ERASE_FAILED;
- }
- (void)memset(&PlsrHostSfdSlots[slot],
- 0xFF,
- sizeof(PlsrHostSfdSlots[slot]));
- return PLSR_PERSISTENCE_OK;
- #else
- FLASH_EraseInitTypeDef erase;
- uint32_t sectorError = 0xFFFFFFFFUL;
-
- erase.TypeErase = FLASH_TYPEERASE_SECTORS;
- erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
- erase.Sector = (slot == 0U) ? FLASH_SECTOR_10 : FLASH_SECTOR_11;
- erase.NbSectors = 1U;
-
- return (HAL_FLASHEx_Erase(&erase, §orError) == HAL_OK)
- ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_ERASE_FAILED;
- #endif
- }
-
- static PLSR_PERSISTENCE_RESULT PlsrPersistenceProgramSfdWord(
- volatile uint32_t *destination,
- uint32_t value)
- {
- #ifdef PLSR_HOST_TEST
- if (PlsrHostSfdFault == PLSR_TEST_SFD_FAULT_PROGRAM)
- {
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- return PLSR_PERSISTENCE_PROGRAM_FAILED;
- }
- if ((*destination & value) != value)
- {
- return PLSR_PERSISTENCE_PROGRAM_FAILED;
- }
- *destination &= value;
- return PLSR_PERSISTENCE_OK;
- #else
- return (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
- (uint32_t)destination,
- value)
- == HAL_OK)
- ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_PROGRAM_FAILED;
- #endif
- }
-
- static uint8_t PlsrPersistenceSfdBodyMatches(
- const volatile uint32_t *destination,
- const PLSR_SFD_FLASH_HEADER *header,
- const PLSR_SFD_DATA *data,
- uint32_t crc32)
- {
- const uint32_t *headerWords = (const uint32_t *)header;
- const uint32_t *dataWords = (const uint32_t *)data;
- uint32_t headerWordCount = (uint32_t)(sizeof(*header) / sizeof(uint32_t));
- uint32_t dataWordCount = (uint32_t)(sizeof(*data) / sizeof(uint32_t));
- uint32_t index;
-
- for (index = 1U; index < headerWordCount; index++)
- {
- if (destination[index] != headerWords[index])
- {
- return 0U;
- }
- }
-
- for (index = 0U; index < dataWordCount; index++)
- {
- if (destination[headerWordCount + index] != dataWords[index])
- {
- return 0U;
- }
- }
-
- if (destination[headerWordCount + dataWordCount] != crc32)
- {
- return 0U;
- }
- return 1U;
- }
-
- static void PlsrPersistenceCopyHsdFromVolatile(
- PLSR_HSD_DATA *destination,
- const volatile PLSR_HSD_DATA *source)
- {
- uint16_t index;
-
- for (index = 0U; index < PLSR_HSD_RUNTIME_COUNT; index++)
- {
- destination->runtime[index] = source->runtime[index];
- }
- for (index = 0U; index < PLSR_HSD_CONFIG_COUNT; index++)
- {
- destination->config[index] = source->config[index];
- }
- }
-
- static void PlsrPersistenceWriteRecord(
- volatile PLSR_HSD_BACKUP_RECORD *destination,
- const PLSR_HSD_BACKUP_RECORD *source)
- {
- const uint32_t *sourceWords = (const uint32_t *)source;
- volatile uint32_t *destinationWords = (volatile uint32_t *)destination;
- uint32_t wordCount = (uint32_t)(sizeof(PLSR_HSD_BACKUP_RECORD)
- / sizeof(uint32_t));
- uint32_t index;
-
- destination->magic = 0UL;
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
-
- for (index = 1U; index < wordCount; index++)
- {
- destinationWords[index] = sourceWords[index];
- }
-
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
- destination->magic = PLSR_HSD_BACKUP_MAGIC;
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceLoadHsd(PLSR_HSD_DATA *data)
- {
- volatile PLSR_HSD_BACKUP_RECORD *slotA;
- volatile PLSR_HSD_BACKUP_RECORD *slotB;
- const volatile PLSR_HSD_BACKUP_RECORD *selected;
- uint32_t generationA;
- uint32_t generationB;
- uint8_t validA;
- uint8_t validB;
-
- if (data == NULL)
- {
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
-
- slotA = PlsrPersistenceGetHsdSlot(0U);
- slotB = PlsrPersistenceGetHsdSlot(1U);
- validA = PlsrPersistenceHsdRecordIsValid(slotA);
- validB = PlsrPersistenceHsdRecordIsValid(slotB);
-
- if ((validA == 0U) && (validB == 0U))
- {
- (void)memset(data, 0, sizeof(*data));
- return PLSR_PERSISTENCE_DEFAULTED;
- }
-
- if ((validA != 0U) && (validB != 0U))
- {
- generationA = slotA->generation;
- generationB = slotB->generation;
- selected = (PlsrPersistenceGenerationIsNewer(generationB,
- generationA)
- != 0U)
- ? slotB
- : slotA;
- }
- else
- {
- selected = (validA != 0U) ? slotA : slotB;
- }
-
- PlsrPersistenceCopyHsdFromVolatile(data, &selected->data);
- return PLSR_PERSISTENCE_OK;
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceSaveHsd(const PLSR_HSD_DATA *data)
- {
- volatile PLSR_HSD_BACKUP_RECORD *slotA;
- volatile PLSR_HSD_BACKUP_RECORD *slotB;
- volatile PLSR_HSD_BACKUP_RECORD *target;
- PLSR_HSD_BACKUP_RECORD record;
- uint32_t newestGeneration = 0UL;
- uint32_t generationA;
- uint32_t generationB;
- uint8_t validA;
- uint8_t validB;
-
- if (data == NULL)
- {
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
- if (sizeof(PLSR_HSD_BACKUP_RECORD) > PLSR_BACKUP_SLOT_STRIDE)
- {
- return PLSR_PERSISTENCE_VERIFY_FAILED;
- }
-
- slotA = PlsrPersistenceGetHsdSlot(0U);
- slotB = PlsrPersistenceGetHsdSlot(1U);
- validA = PlsrPersistenceHsdRecordIsValid(slotA);
- validB = PlsrPersistenceHsdRecordIsValid(slotB);
-
- if ((validA != 0U) && (validB != 0U))
- {
- generationA = slotA->generation;
- generationB = slotB->generation;
- if (PlsrPersistenceGenerationIsNewer(generationB,
- generationA)
- != 0U)
- {
- newestGeneration = generationB;
- target = slotA;
- }
- else
- {
- newestGeneration = generationA;
- target = slotB;
- }
- }
- else if (validA != 0U)
- {
- newestGeneration = slotA->generation;
- target = slotB;
- }
- else if (validB != 0U)
- {
- newestGeneration = slotB->generation;
- target = slotA;
- }
- else
- {
- target = slotA;
- }
-
- (void)memset(&record, 0, sizeof(record));
- record.magic = PLSR_HSD_BACKUP_MAGIC;
- record.version = PLSR_HSD_BACKUP_VERSION;
- record.payloadLength = (uint16_t)sizeof(PLSR_HSD_DATA);
- record.generation = newestGeneration + 1UL;
- record.data = *data;
- record.crc32 = PlsrPersistenceCrc32(
- (const volatile uint8_t *)&record,
- (uint32_t)offsetof(PLSR_HSD_BACKUP_RECORD, crc32));
-
- PlsrPersistenceWriteRecord(target, &record);
- return (PlsrPersistenceHsdRecordIsValid(target) != 0U)
- ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_VERIFY_FAILED;
- }
-
- void PlsrPersistenceResetHsd(void)
- {
- PlsrPersistenceGetHsdSlot(0U)->magic = 0UL;
- PlsrPersistenceGetHsdSlot(1U)->magic = 0UL;
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceLoadSfd(PLSR_SFD_DATA *data)
- {
- volatile PLSR_SFD_FLASH_RECORD *slotA;
- volatile PLSR_SFD_FLASH_RECORD *slotB;
- const volatile PLSR_SFD_FLASH_RECORD *selected;
- uint32_t generationA;
- uint32_t generationB;
- uint8_t validA;
- uint8_t validB;
-
- if (data == NULL)
- {
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
-
- slotA = PlsrPersistenceGetSfdSlot(0U);
- slotB = PlsrPersistenceGetSfdSlot(1U);
- validA = PlsrPersistenceSfdRecordIsValid(slotA);
- validB = PlsrPersistenceSfdRecordIsValid(slotB);
-
- if ((validA == 0U) && (validB == 0U))
- {
- PlsrPersistenceApplySfdDefaults(data);
- return PLSR_PERSISTENCE_DEFAULTED;
- }
-
- if ((validA != 0U) && (validB != 0U))
- {
- generationA = slotA->generation;
- generationB = slotB->generation;
- selected = (PlsrPersistenceGenerationIsNewer(generationB,
- generationA)
- != 0U)
- ? slotB
- : slotA;
- }
- else
- {
- selected = (validA != 0U) ? slotA : slotB;
- }
-
- PlsrPersistenceCopySfdFromVolatile(data, &selected->data);
- return PLSR_PERSISTENCE_OK;
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceSaveSfd(const PLSR_SFD_DATA *data)
- {
- volatile PLSR_SFD_FLASH_RECORD *slotA;
- volatile PLSR_SFD_FLASH_RECORD *slotB;
- volatile PLSR_SFD_FLASH_RECORD *target;
- volatile uint32_t *targetWords;
- const uint32_t *headerWords;
- const uint32_t *dataWords;
- PLSR_SFD_FLASH_HEADER header;
- PLSR_PERSISTENCE_RESULT result;
- uint32_t newestGeneration = 0UL;
- uint32_t generationA;
- uint32_t generationB;
- uint32_t headerWordCount;
- uint32_t dataWordCount;
- uint32_t crcState;
- uint32_t crc32;
- uint32_t index;
- uint8_t targetSlot;
- uint8_t validA;
- uint8_t validB;
-
- if (data == NULL)
- {
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
- if (sizeof(PLSR_SFD_FLASH_RECORD) > PLSR_SFD_FLASH_SECTOR_SIZE)
- {
- return PLSR_PERSISTENCE_VERIFY_FAILED;
- }
-
- slotA = PlsrPersistenceGetSfdSlot(0U);
- slotB = PlsrPersistenceGetSfdSlot(1U);
- validA = PlsrPersistenceSfdRecordIsValid(slotA);
- validB = PlsrPersistenceSfdRecordIsValid(slotB);
-
- if ((validA != 0U) && (validB != 0U))
- {
- generationA = slotA->generation;
- generationB = slotB->generation;
- if (PlsrPersistenceGenerationIsNewer(generationB,
- generationA)
- != 0U)
- {
- newestGeneration = generationB;
- target = slotA;
- targetSlot = 0U;
- }
- else
- {
- newestGeneration = generationA;
- target = slotB;
- targetSlot = 1U;
- }
- }
- else if (validA != 0U)
- {
- newestGeneration = slotA->generation;
- target = slotB;
- targetSlot = 1U;
- }
- else if (validB != 0U)
- {
- newestGeneration = slotB->generation;
- target = slotA;
- targetSlot = 0U;
- }
- else
- {
- target = slotA;
- targetSlot = 0U;
- }
-
- header.magic = PLSR_SFD_FLASH_MAGIC;
- header.version = PLSR_SFD_FLASH_VERSION;
- header.payloadLength = (uint16_t)sizeof(PLSR_SFD_DATA);
- header.generation = newestGeneration + 1UL;
- crcState = PlsrPersistenceCrc32Update(
- 0xFFFFFFFFUL,
- (const volatile uint8_t *)&header,
- (uint32_t)sizeof(header));
- crcState = PlsrPersistenceCrc32Update(
- crcState,
- (const volatile uint8_t *)data,
- (uint32_t)sizeof(*data));
- crc32 = ~crcState;
-
- headerWordCount = (uint32_t)(sizeof(header) / sizeof(uint32_t));
- dataWordCount = (uint32_t)(sizeof(*data) / sizeof(uint32_t));
- headerWords = (const uint32_t *)&header;
- dataWords = (const uint32_t *)data;
- targetWords = (volatile uint32_t *)target;
-
- result = PlsrPersistenceBeginSfdOperation();
- if (result != PLSR_PERSISTENCE_OK)
- {
- return result;
- }
-
- result = PlsrPersistenceEraseSfdSlot(targetSlot);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PlsrPersistenceEndSfdOperation(result);
- }
-
- /* The valid magic is committed last so an interrupted write stays invalid. */
- for (index = 1U; index < headerWordCount; index++)
- {
- result = PlsrPersistenceProgramSfdWord(&targetWords[index],
- headerWords[index]);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PlsrPersistenceEndSfdOperation(result);
- }
- }
-
- for (index = 0U; index < dataWordCount; index++)
- {
- result = PlsrPersistenceProgramSfdWord(
- &targetWords[headerWordCount + index],
- dataWords[index]);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PlsrPersistenceEndSfdOperation(result);
- }
- }
-
- result = PlsrPersistenceProgramSfdWord(
- &targetWords[headerWordCount + dataWordCount],
- crc32);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PlsrPersistenceEndSfdOperation(result);
- }
-
- #ifdef PLSR_HOST_TEST
- if (PlsrHostSfdFault == PLSR_TEST_SFD_FAULT_VERIFY)
- {
- targetWords[1] ^= 1UL;
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- }
- #endif
- if (PlsrPersistenceSfdBodyMatches(targetWords,
- &header,
- data,
- crc32)
- == 0U)
- {
- return PlsrPersistenceEndSfdOperation(
- PLSR_PERSISTENCE_VERIFY_FAILED);
- }
-
- #ifdef PLSR_HOST_TEST
- if (PlsrHostSfdFault == PLSR_TEST_SFD_FAULT_BEFORE_COMMIT)
- {
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- return PlsrPersistenceEndSfdOperation(
- PLSR_PERSISTENCE_PROGRAM_FAILED);
- }
- #endif
-
- result = PlsrPersistenceProgramSfdWord(&targetWords[0], headerWords[0]);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PlsrPersistenceEndSfdOperation(result);
- }
-
- result = (PlsrPersistenceSfdRecordIsValid(target) != 0U)
- ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_VERIFY_FAILED;
- return PlsrPersistenceEndSfdOperation(result);
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceEraseSfd(void)
- {
- PLSR_PERSISTENCE_RESULT result;
-
- result = PlsrPersistenceBeginSfdOperation();
- if (result != PLSR_PERSISTENCE_OK)
- {
- return result;
- }
-
- result = PlsrPersistenceEraseSfdSlot(0U);
- if (result == PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEraseSfdSlot(1U);
- }
-
- return PlsrPersistenceEndSfdOperation(result);
- }
-
- #ifdef PLSR_HOST_TEST
- void PlsrPersistenceTestResetStorage(void)
- {
- (void)memset(PlsrHostBackupSlots, 0, sizeof(PlsrHostBackupSlots));
- (void)memset(PlsrHostSfdSlots, 0xFF, sizeof(PlsrHostSfdSlots));
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- }
-
- void PlsrPersistenceTestCorruptNewestHsd(void)
- {
- volatile PLSR_HSD_BACKUP_RECORD *slotA = PlsrPersistenceGetHsdSlot(0U);
- volatile PLSR_HSD_BACKUP_RECORD *slotB = PlsrPersistenceGetHsdSlot(1U);
- uint8_t validA = PlsrPersistenceHsdRecordIsValid(slotA);
- uint8_t validB = PlsrPersistenceHsdRecordIsValid(slotB);
- volatile PLSR_HSD_BACKUP_RECORD *newest;
-
- if ((validA == 0U) && (validB == 0U))
- {
- return;
- }
- if ((validA != 0U) && (validB != 0U))
- {
- newest = (PlsrPersistenceGenerationIsNewer(slotB->generation,
- slotA->generation)
- != 0U)
- ? slotB
- : slotA;
- }
- else
- {
- newest = (validA != 0U) ? slotA : slotB;
- }
-
- newest->crc32 ^= 1UL;
- }
-
- void PlsrPersistenceTestCorruptNewestSfd(void)
- {
- volatile PLSR_SFD_FLASH_RECORD *slotA = PlsrPersistenceGetSfdSlot(0U);
- volatile PLSR_SFD_FLASH_RECORD *slotB = PlsrPersistenceGetSfdSlot(1U);
- uint8_t validA = PlsrPersistenceSfdRecordIsValid(slotA);
- uint8_t validB = PlsrPersistenceSfdRecordIsValid(slotB);
- volatile PLSR_SFD_FLASH_RECORD *newest;
-
- if ((validA == 0U) && (validB == 0U))
- {
- return;
- }
- if ((validA != 0U) && (validB != 0U))
- {
- newest = (PlsrPersistenceGenerationIsNewer(slotB->generation,
- slotA->generation)
- != 0U)
- ? slotB
- : slotA;
- }
- else
- {
- newest = (validA != 0U) ? slotA : slotB;
- }
-
- newest->crc32 ^= 1UL;
- }
-
- void PlsrPersistenceTestSetSfdFault(PLSR_TEST_SFD_FAULT fault)
- {
- PlsrHostSfdFault = fault;
- }
- #endif
|