|
- #include "plsr_persistence.h"
- #include "plsr_build_config.h"
- #include <stddef.h>
- #include <string.h>
-
- #define PLSR_HSD_BACKUP_MAGIC (0x504C4853UL)
- #define PLSR_HSD_BACKUP_VERSION (2U)
- #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)
- #define PLSR_SFD_DEFAULT_SPEED (1000UL)
- #define PLSR_SFD_DEFAULT_ACCEL_MS (100U)
- #define PLSR_SFD_DEFAULT_DECEL_MS (100U)
- #define PLSR_SFD_DEFAULT_FOLLOW (50U)
- #define PLSR_HSD_PARAMETER_SET_STRIDE (20U)
- #define PLSR_HSD_DEFAULT_BASE (460U)
-
- static const uint32_t PlsrPersistenceCrc32Nibble[16] =
- {
- 0x00000000UL, 0x1DB71064UL, 0x3B6E20C8UL, 0x26D930ACUL,
- 0x76DC4190UL, 0x6B6B51F4UL, 0x4DB26158UL, 0x5005713CUL,
- 0xEDB88320UL, 0xF00F9344UL, 0xD6D6A3E8UL, 0xCB61B38CUL,
- 0x9B64C2B0UL, 0x86D3D2D4UL, 0xA00AE278UL, 0xBDBDF21CUL
- };
-
- 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;
- static uint32_t PlsrHostHsdSaveCount;
- #else
- #include "stm32f4xx.h"
- #include "stm32f4xx_hal.h"
- #include "stm32f4xx_hal_flash_ex.h"
- #endif
-
- static PLSR_PERSISTENCE_DIAGNOSTICS PlsrPersistenceDiagnostics;
- static uint8_t PlsrPersistenceDiagnosticsInitialized;
-
- static void PlsrPersistenceEnsureDiagnostics(void)
- {
- if (PlsrPersistenceDiagnosticsInitialized == 0U)
- {
- (void)memset(&PlsrPersistenceDiagnostics,
- 0,
- sizeof(PlsrPersistenceDiagnostics));
- PlsrPersistenceDiagnostics.lastHsdLoadResult =
- PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- PlsrPersistenceDiagnostics.lastSfdLoadResult =
- PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- PlsrPersistenceDiagnostics.lastHsdSaveResult =
- PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- PlsrPersistenceDiagnostics.lastSfdSaveResult =
- PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- PlsrPersistenceDiagnostics.lastSfdEraseResult =
- PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- #if PLSR_ENABLE_DESTRUCTIVE_PERSISTENCE_DIAG != 0U
- PlsrPersistenceDiagnostics.destructiveDiagnosticEnabled = 1U;
- #endif
- PlsrPersistenceDiagnosticsInitialized = 1U;
- }
- }
-
- static uint32_t PlsrPersistenceCrc32Update(uint32_t crc,
- const volatile uint8_t *data,
- uint32_t length)
- {
- uint32_t index;
-
- for (index = 0U; index < length; index++)
- {
- crc ^= data[index];
- crc = (crc >> 4U)
- ^ PlsrPersistenceCrc32Nibble[crc & 0x0FUL];
- crc = (crc >> 4U)
- ^ PlsrPersistenceCrc32Nibble[crc & 0x0FUL];
- }
-
- 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 uint8_t PlsrPersistenceNewestMask(uint8_t validA,
- uint8_t validB,
- uint32_t generationA,
- uint32_t generationB)
- {
- if ((validA != 0U) && (validB != 0U))
- {
- return (PlsrPersistenceGenerationIsNewer(generationB, generationA)
- != 0U)
- ? 2U
- : 1U;
- }
- if (validA != 0U)
- {
- return 1U;
- }
- return (validB != 0U) ? 2U : 0U;
- }
-
- static void PlsrPersistenceUpdateHsdDiagnostics(
- const volatile PLSR_HSD_BACKUP_RECORD *slotA,
- const volatile PLSR_HSD_BACKUP_RECORD *slotB,
- uint8_t validA,
- uint8_t validB)
- {
- uint8_t newestMask;
-
- PlsrPersistenceEnsureDiagnostics();
- PlsrPersistenceDiagnostics.hsdValidMask =
- (uint8_t)((validA != 0U ? 1U : 0U) | (validB != 0U ? 2U : 0U));
- PlsrPersistenceDiagnostics.hsdGeneration[0] =
- (validA != 0U) ? slotA->generation : 0UL;
- PlsrPersistenceDiagnostics.hsdGeneration[1] =
- (validB != 0U) ? slotB->generation : 0UL;
- newestMask = PlsrPersistenceNewestMask(
- validA,
- validB,
- PlsrPersistenceDiagnostics.hsdGeneration[0],
- PlsrPersistenceDiagnostics.hsdGeneration[1]);
- PlsrPersistenceDiagnostics.hsdNewestMask = newestMask;
- PlsrPersistenceDiagnostics.selectedHsdCrc32 =
- (newestMask == 1U) ? slotA->crc32
- : (newestMask == 2U) ? slotB->crc32
- : 0UL;
- }
-
- static void PlsrPersistenceUpdateSfdDiagnostics(
- const volatile PLSR_SFD_FLASH_RECORD *slotA,
- const volatile PLSR_SFD_FLASH_RECORD *slotB,
- uint8_t validA,
- uint8_t validB)
- {
- uint8_t newestMask;
-
- PlsrPersistenceEnsureDiagnostics();
- PlsrPersistenceDiagnostics.sfdValidMask =
- (uint8_t)((validA != 0U ? 1U : 0U) | (validB != 0U ? 2U : 0U));
- PlsrPersistenceDiagnostics.sfdGeneration[0] =
- (validA != 0U) ? slotA->generation : 0UL;
- PlsrPersistenceDiagnostics.sfdGeneration[1] =
- (validB != 0U) ? slotB->generation : 0UL;
- newestMask = PlsrPersistenceNewestMask(
- validA,
- validB,
- PlsrPersistenceDiagnostics.sfdGeneration[0],
- PlsrPersistenceDiagnostics.sfdGeneration[1]);
- PlsrPersistenceDiagnostics.sfdNewestMask = newestMask;
- PlsrPersistenceDiagnostics.selectedSfdCrc32 =
- (newestMask == 1U) ? slotA->crc32
- : (newestMask == 2U) ? slotB->crc32
- : 0UL;
- }
-
- static void PlsrPersistenceRefreshSfdDiagnostics(void)
- {
- volatile PLSR_SFD_FLASH_RECORD *slotA =
- PlsrPersistenceGetSfdSlot(0U);
- volatile PLSR_SFD_FLASH_RECORD *slotB =
- PlsrPersistenceGetSfdSlot(1U);
-
- PlsrPersistenceUpdateSfdDiagnostics(
- slotA,
- slotB,
- PlsrPersistenceSfdRecordIsValid(slotA),
- PlsrPersistenceSfdRecordIsValid(slotB));
- }
-
- static PLSR_PERSISTENCE_RESULT PlsrPersistenceCompleteSfdSave(
- PLSR_PERSISTENCE_RESULT result)
- {
- PlsrPersistenceEnsureDiagnostics();
- PlsrPersistenceDiagnostics.lastSfdSaveResult = result;
- PlsrPersistenceRefreshSfdDiagnostics();
- if (result == PLSR_PERSISTENCE_OK)
- {
- PlsrPersistenceDiagnostics.sfdSaveCount++;
- }
- return result;
- }
-
- 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 PlsrPersistenceApplyParameterSetDefaults(uint16_t *config,
- uint16_t base)
- {
- /* 与信捷出厂默认一致:默认速度1000、加减速100ms、最大速度100000、
- * 起始/终止速度0、FOLLOW 50、前馈0、1ms刷新。 */
- config[base + 0U] = (uint16_t)(PLSR_SFD_DEFAULT_SPEED & 0xFFFFUL);
- config[base + 1U] = (uint16_t)(PLSR_SFD_DEFAULT_SPEED >> 16U);
- config[base + 2U] = (uint16_t)PLSR_SFD_DEFAULT_ACCEL_MS;
- config[base + 3U] = (uint16_t)PLSR_SFD_DEFAULT_DECEL_MS;
- config[base + 4U] = 0U;
- config[base + 5U] = 0U;
- config[base + 6U] = (uint16_t)(PLSR_SFD_DEFAULT_MAX_SPEED & 0xFFFFUL);
- config[base + 7U] = (uint16_t)(PLSR_SFD_DEFAULT_MAX_SPEED >> 16U);
- config[base + 8U] = 0U;
- config[base + 9U] = 0U;
- config[base + 10U] = 0U;
- config[base + 11U] = 0U;
- config[base + 12U] = (uint16_t)PLSR_SFD_DEFAULT_FOLLOW;
- config[base + 13U] = 0U;
- config[base + 14U] = 0U;
- config[base + 16U] = 0U;
- config[base + 17U] = 0U;
- config[base + 18U] = 0U;
- config[base + 19U] = 0U;
- }
-
- 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);
-
- /* 公共参数(与信捷出厂默认一致)。 */
- data->config[axisOffset + 0U] = 0; /* SFD900 方向逻辑/单位等 */
- data->config[axisOffset + 1U] = 0; /* SFD901 完成模式 */
- data->config[axisOffset + 2U] = 1; /* SFD902 脉冲数/1转=1 */
- data->config[axisOffset + 3U] = 0;
- data->config[axisOffset + 4U] = 1; /* SFD904 移动量/1转=1 */
- data->config[axisOffset + 5U] = 0;
- data->config[axisOffset + 6U] = 0xFF; /* SFD906 方向端子:无 */
- data->config[axisOffset + 7U] = 10; /* SFD907 方向延时10ms */
- data->config[axisOffset + 8U] = 0; /* SFD908 正向齿隙 */
- data->config[axisOffset + 9U] = 0; /* SFD909 负向齿隙 */
- data->config[axisOffset + 12U] = 0; /* SFD912 端子开关状态 */
- data->config[axisOffset + 13U] = 0xFF; /* SFD913 原点端子:无 */
- data->config[axisOffset + 14U] = 0xFF; /* SFD914 Z相端子:无 */
- data->config[axisOffset + 15U] = 0xFFFF; /* SFD915 极限端子:无 */
- data->config[axisOffset + 17U] = 0xFF; /* SFD917 CLR端子:无 */
- data->config[axisOffset + 18U] = 0; /* SFD918 VH */
- data->config[axisOffset + 19U] = 0;
- data->config[axisOffset + 22U] = 0; /* SFD922 VC */
- data->config[axisOffset + 23U] = 0;
- data->config[axisOffset + 24U] = 0; /* SFD924 机械原点位置 */
- data->config[axisOffset + 25U] = 0;
- data->config[axisOffset + 26U] = 0; /* SFD926 Z相个数 */
- data->config[axisOffset + 27U] = 20; /* SFD927 CLR延时20ms */
- data->config[axisOffset + 30U] = 0; /* SFD930 软限位正 */
- data->config[axisOffset + 31U] = 0;
- data->config[axisOffset + 32U] = 0; /* SFD932 软限位负 */
- data->config[axisOffset + 33U] = 0;
- data->config[axisOffset + 43U] = 0x0201; /* SFD943 默认参数块 */
-
- 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);
- PlsrPersistenceApplyParameterSetDefaults(data->config,
- parameterOffset);
- }
- }
- }
-
- static void PlsrPersistenceApplyHsdDefaults(PLSR_HSD_DATA *data)
- {
- uint8_t axis;
-
- (void)memset(data, 0, sizeof(*data));
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- /* config 数组索引 = HSD地址 - PLSR_HSD_CONFIG_START。 */
- PlsrPersistenceApplyParameterSetDefaults(
- data->config,
- (uint16_t)((uint16_t)axis * PLSR_HSD_PARAMETER_SET_STRIDE));
- }
- }
-
- 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;
-
- destination->metadata = source->metadata;
- 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;
-
- PlsrPersistenceEnsureDiagnostics();
- if (data == NULL)
- {
- PlsrPersistenceDiagnostics.lastHsdLoadResult =
- PLSR_PERSISTENCE_INVALID_ARGUMENT;
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
-
- slotA = PlsrPersistenceGetHsdSlot(0U);
- slotB = PlsrPersistenceGetHsdSlot(1U);
- validA = PlsrPersistenceHsdRecordIsValid(slotA);
- validB = PlsrPersistenceHsdRecordIsValid(slotB);
- PlsrPersistenceUpdateHsdDiagnostics(slotA, slotB, validA, validB);
-
- if ((validA == 0U) && (validB == 0U))
- {
- PlsrPersistenceApplyHsdDefaults(data);
- PlsrPersistenceDiagnostics.lastHsdLoadResult =
- PLSR_PERSISTENCE_DEFAULTED;
- 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);
- PlsrPersistenceDiagnostics.lastHsdLoadResult = PLSR_PERSISTENCE_OK;
- 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;
- uint8_t targetSlot;
- uint8_t targetValid;
-
- PlsrPersistenceEnsureDiagnostics();
- if (data == NULL)
- {
- PlsrPersistenceDiagnostics.lastHsdSaveResult =
- PLSR_PERSISTENCE_INVALID_ARGUMENT;
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
- #ifdef PLSR_HOST_TEST
- PlsrHostHsdSaveCount++;
- #endif
- if (sizeof(PLSR_HSD_BACKUP_RECORD) > PLSR_BACKUP_SLOT_STRIDE)
- {
- PlsrPersistenceDiagnostics.lastHsdSaveResult =
- PLSR_PERSISTENCE_VERIFY_FAILED;
- 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;
- 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;
- }
-
- (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);
- targetValid = PlsrPersistenceHsdRecordIsValid(target);
- if (targetSlot == 0U)
- {
- validA = targetValid;
- }
- else
- {
- validB = targetValid;
- }
- PlsrPersistenceUpdateHsdDiagnostics(slotA, slotB, validA, validB);
- PlsrPersistenceDiagnostics.lastHsdSaveResult =
- (targetValid != 0U) ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_VERIFY_FAILED;
- if (targetValid != 0U)
- {
- PlsrPersistenceDiagnostics.hsdSaveCount++;
- }
- return PlsrPersistenceDiagnostics.lastHsdSaveResult;
- }
-
- void PlsrPersistenceResetHsd(void)
- {
- volatile PLSR_HSD_BACKUP_RECORD *slotA =
- PlsrPersistenceGetHsdSlot(0U);
- volatile PLSR_HSD_BACKUP_RECORD *slotB =
- PlsrPersistenceGetHsdSlot(1U);
-
- slotA->magic = 0UL;
- slotB->magic = 0UL;
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
- PlsrPersistenceUpdateHsdDiagnostics(slotA, slotB, 0U, 0U);
- }
-
- 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;
-
- PlsrPersistenceEnsureDiagnostics();
- if (data == NULL)
- {
- PlsrPersistenceDiagnostics.lastSfdLoadResult =
- PLSR_PERSISTENCE_INVALID_ARGUMENT;
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
-
- slotA = PlsrPersistenceGetSfdSlot(0U);
- slotB = PlsrPersistenceGetSfdSlot(1U);
- validA = PlsrPersistenceSfdRecordIsValid(slotA);
- validB = PlsrPersistenceSfdRecordIsValid(slotB);
- PlsrPersistenceUpdateSfdDiagnostics(slotA, slotB, validA, validB);
-
- if ((validA == 0U) && (validB == 0U))
- {
- PlsrPersistenceApplySfdDefaults(data);
- PlsrPersistenceDiagnostics.lastSfdLoadResult =
- PLSR_PERSISTENCE_DEFAULTED;
- 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);
- PlsrPersistenceDiagnostics.lastSfdLoadResult = PLSR_PERSISTENCE_OK;
- 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;
-
- PlsrPersistenceEnsureDiagnostics();
- if (data == NULL)
- {
- PlsrPersistenceDiagnostics.lastSfdSaveResult =
- PLSR_PERSISTENCE_INVALID_ARGUMENT;
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- }
- if (sizeof(PLSR_SFD_FLASH_RECORD) > PLSR_SFD_FLASH_SECTOR_SIZE)
- {
- PlsrPersistenceDiagnostics.lastSfdSaveResult =
- PLSR_PERSISTENCE_VERIFY_FAILED;
- 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 PlsrPersistenceCompleteSfdSave(result);
- }
-
- result = PlsrPersistenceEraseSfdSlot(targetSlot);
- if (result != PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(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)
- {
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(result);
- }
- }
-
- for (index = 0U; index < dataWordCount; index++)
- {
- result = PlsrPersistenceProgramSfdWord(
- &targetWords[headerWordCount + index],
- dataWords[index]);
- if (result != PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(result);
- }
- }
-
- result = PlsrPersistenceProgramSfdWord(
- &targetWords[headerWordCount + dataWordCount],
- crc32);
- if (result != PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(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)
- {
- result = PlsrPersistenceEndSfdOperation(
- PLSR_PERSISTENCE_VERIFY_FAILED);
- return PlsrPersistenceCompleteSfdSave(result);
- }
-
- #ifdef PLSR_HOST_TEST
- if (PlsrHostSfdFault == PLSR_TEST_SFD_FAULT_BEFORE_COMMIT)
- {
- PlsrHostSfdFault = PLSR_TEST_SFD_FAULT_NONE;
- result = PlsrPersistenceEndSfdOperation(
- PLSR_PERSISTENCE_PROGRAM_FAILED);
- return PlsrPersistenceCompleteSfdSave(result);
- }
- #endif
-
- result = PlsrPersistenceProgramSfdWord(&targetWords[0], headerWords[0]);
- if (result != PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(result);
- }
-
- result = (PlsrPersistenceSfdRecordIsValid(target) != 0U)
- ? PLSR_PERSISTENCE_OK
- : PLSR_PERSISTENCE_VERIFY_FAILED;
- result = PlsrPersistenceEndSfdOperation(result);
- return PlsrPersistenceCompleteSfdSave(result);
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceEraseSfd(void)
- {
- PLSR_PERSISTENCE_RESULT result;
-
- PlsrPersistenceEnsureDiagnostics();
- result = PlsrPersistenceBeginSfdOperation();
- if (result != PLSR_PERSISTENCE_OK)
- {
- PlsrPersistenceDiagnostics.lastSfdEraseResult = result;
- return result;
- }
-
- result = PlsrPersistenceEraseSfdSlot(0U);
- if (result == PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceEraseSfdSlot(1U);
- }
-
- result = PlsrPersistenceEndSfdOperation(result);
- PlsrPersistenceDiagnostics.lastSfdEraseResult = result;
- PlsrPersistenceRefreshSfdDiagnostics();
- return result;
- }
-
- void PlsrPersistenceGetDiagnostics(
- PLSR_PERSISTENCE_DIAGNOSTICS *diagnostics)
- {
- if (diagnostics == NULL)
- {
- return;
- }
- PlsrPersistenceEnsureDiagnostics();
- *diagnostics = PlsrPersistenceDiagnostics;
- }
-
- PLSR_PERSISTENCE_RESULT PlsrPersistenceDiagnosticInvalidateNewest(
- PLSR_PERSISTENCE_DIAG_TARGET target)
- {
- #if PLSR_ENABLE_DESTRUCTIVE_PERSISTENCE_DIAG != 0U
- uint32_t generationA;
- uint32_t generationB;
- uint8_t validA;
- uint8_t validB;
-
- PlsrPersistenceEnsureDiagnostics();
- if (target == PLSR_PERSISTENCE_DIAG_TARGET_HSD)
- {
- volatile PLSR_HSD_BACKUP_RECORD *slotA =
- PlsrPersistenceGetHsdSlot(0U);
- volatile PLSR_HSD_BACKUP_RECORD *slotB =
- PlsrPersistenceGetHsdSlot(1U);
- volatile PLSR_HSD_BACKUP_RECORD *newest;
-
- validA = PlsrPersistenceHsdRecordIsValid(slotA);
- validB = PlsrPersistenceHsdRecordIsValid(slotB);
- PlsrPersistenceUpdateHsdDiagnostics(slotA, slotB, validA, validB);
- if ((validA == 0U) || (validB == 0U))
- {
- return PLSR_PERSISTENCE_VERIFY_FAILED;
- }
- generationA = slotA->generation;
- generationB = slotB->generation;
- newest = (PlsrPersistenceGenerationIsNewer(generationB, generationA)
- != 0U)
- ? slotB
- : slotA;
- newest->magic = 0UL;
- #ifndef PLSR_HOST_TEST
- __DMB();
- #endif
- PlsrPersistenceUpdateHsdDiagnostics(
- slotA,
- slotB,
- (newest == slotA) ? 0U : 1U,
- (newest == slotB) ? 0U : 1U);
- return PLSR_PERSISTENCE_OK;
- }
- if (target == PLSR_PERSISTENCE_DIAG_TARGET_SFD)
- {
- volatile PLSR_SFD_FLASH_RECORD *slotA =
- PlsrPersistenceGetSfdSlot(0U);
- volatile PLSR_SFD_FLASH_RECORD *slotB =
- PlsrPersistenceGetSfdSlot(1U);
- volatile PLSR_SFD_FLASH_RECORD *newest;
- PLSR_PERSISTENCE_RESULT result;
-
- validA = PlsrPersistenceSfdRecordIsValid(slotA);
- validB = PlsrPersistenceSfdRecordIsValid(slotB);
- PlsrPersistenceUpdateSfdDiagnostics(slotA, slotB, validA, validB);
- if ((validA == 0U) || (validB == 0U))
- {
- return PLSR_PERSISTENCE_VERIFY_FAILED;
- }
- generationA = slotA->generation;
- generationB = slotB->generation;
- newest = (PlsrPersistenceGenerationIsNewer(generationB, generationA)
- != 0U)
- ? slotB
- : slotA;
- result = PlsrPersistenceBeginSfdOperation();
- if (result == PLSR_PERSISTENCE_OK)
- {
- result = PlsrPersistenceProgramSfdWord(
- (volatile uint32_t *)&newest->magic,
- 0UL);
- result = PlsrPersistenceEndSfdOperation(result);
- }
- PlsrPersistenceRefreshSfdDiagnostics();
- return result;
- }
- return PLSR_PERSISTENCE_INVALID_ARGUMENT;
- #else
- (void)target;
- return PLSR_PERSISTENCE_NOT_IMPLEMENTED;
- #endif
- }
-
- #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;
- PlsrHostHsdSaveCount = 0UL;
- PlsrPersistenceDiagnosticsInitialized = 0U;
- PlsrPersistenceEnsureDiagnostics();
- PlsrPersistenceUpdateHsdDiagnostics(
- PlsrPersistenceGetHsdSlot(0U),
- PlsrPersistenceGetHsdSlot(1U),
- 0U,
- 0U);
- PlsrPersistenceRefreshSfdDiagnostics();
- }
-
- uint32_t PlsrPersistenceTestGetHsdSaveCount(void)
- {
- return PlsrHostHsdSaveCount;
- }
-
- uint32_t PlsrPersistenceTestCrc32(const uint8_t *data, uint32_t length)
- {
- if ((data == NULL) && (length != 0UL))
- {
- return 0UL;
- }
- return PlsrPersistenceCrc32(data, length);
- }
-
- 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
|