commit 6f4e90e15c710b7b386140a79b01725ec37e7a5a Author: cfif Date: Mon May 26 14:41:45 2025 +0300 Init diff --git a/Inc/StorageOnFlashArtery.h b/Inc/StorageOnFlashArtery.h new file mode 100644 index 0000000..6bb303a --- /dev/null +++ b/Inc/StorageOnFlashArtery.h @@ -0,0 +1,27 @@ +// +// Created by cfif on 07.10.22. +// + +#ifndef STORAGE_ON_FLASH_NATION_H +#define STORAGE_ON_FLASH_NATION_H + +#include CMSIS_device_header +#include "stddef.h" +#include "StorageIO.h" + +typedef struct { + uint32_t mainFlashPageAddress; + uint32_t recoveryFlashPageAddress; +} tStorageOnFlashArtery; + +void vStorageOnFlashArtery_Init( + tStorageOnFlashArtery *env, + uint32_t mainPage, + uint32_t recoveryPage +); + + +tStorageInterface xStorageOnFlashArtery_GetInterface(tStorageOnFlashArtery *env); + + +#endif //STORAGE_ON_FLASH_NATION_H diff --git a/Src/StorageOnFlashArtery.c b/Src/StorageOnFlashArtery.c new file mode 100644 index 0000000..8338b72 --- /dev/null +++ b/Src/StorageOnFlashArtery.c @@ -0,0 +1,140 @@ +// +// Created by cfif on 07.10.22. +// +#include +#include "InternalFlashPage.h" +#include "StorageOnFlashArtery.h" + +static uint32_t xStorageOnFlashArtery_Crc(uint8_t *data, size_t len) { + uint32_t crc = 0; + + uint8_t *end = data + len; + while (data < end) { + crc += *data; + ++data; + } + + return crc; +} + +static uint32_t xStorageOnFlashArtery_CrcFlash(uint8_t *addressOnFlash, size_t len) { + uint32_t crc = 0; + + size_t left = len; + uint8_t *end = addressOnFlash + len; + + uint32_t word; + while (addressOnFlash < end) { + word = iInternalFlashPage_ReadWord((uint32_t) addressOnFlash); + + for (uint8_t sub_byte = 0; (sub_byte < 4) && (left); ++sub_byte) { + crc += ((uint8_t *) &word)[sub_byte]; + --left; + } + addressOnFlash += 4; + } + + return crc; +} + +static eStorageStatus +xStorageOnFlashArtery_DumpOn( + tStorageOnFlashArtery *env, + uint32_t dataCrc, + uint32_t pageAddress, + void *data, + size_t size +) { + +// if (!bInternalFlashPage_Clear(pageAddress)) { +// return STORAGE_ERR_DEVICE; +// } +// +// size_t dataSizeOnFlash = sInternalFlashPage_Write(pageAddress, 0x0, env->data, env->size); + + size_t dataSizeOnFlash = bInternalFlashPage_DumpFromRam(pageAddress, data, size); + + if (dataSizeOnFlash < size) { + return STORAGE_ERR_DEVICE; + } + + if (sInternalFlashPage_Write(pageAddress, dataSizeOnFlash, (uint8_t *) &dataCrc, 4) != 4) { + return STORAGE_ERR_DEVICE; + } + + uint32_t flashCalcCrc = xStorageOnFlashArtery_CrcFlash((uint8_t *) pageAddress, size); + uint32_t flashReedCrc = iInternalFlashPage_ReadWord(pageAddress + dataSizeOnFlash); + + if ((flashCalcCrc == flashReedCrc) && (flashCalcCrc == dataCrc)) { + return STORAGE_OK; + } else { + return STORAGE_ERR_DATA; + } + +} + +static uint8_t xStorageOnFlashArtery_Dump(tStorageOnFlashArtery *env, void *data, size_t size) { + + uint32_t crc = xStorageOnFlashArtery_Crc(data, size); + + if (xStorageOnFlashArtery_DumpOn(env, crc, env->recoveryFlashPageAddress, data, size) != STORAGE_OK) { + return STORAGE_ERR_DEVICE; + } + + if (xStorageOnFlashArtery_DumpOn(env, crc, env->mainFlashPageAddress, data, size) != STORAGE_OK) { + return STORAGE_ERR_DEVICE; + } + + return STORAGE_OK; +} + + +eStorageStatus xStorageOnFlashArtery_Load(tStorageOnFlashArtery *env, void *data, size_t size) { + + size_t dataSizeOnFlash = size;//(size + 3) & (~3); // выравниваем до кратного 4 (целое количество слов) + + uint32_t recoveryCrcCalc = xStorageOnFlashArtery_CrcFlash((uint8_t *) env->recoveryFlashPageAddress, size); + uint32_t recoveryCrcReed = iInternalFlashPage_ReadWord(env->recoveryFlashPageAddress + dataSizeOnFlash); + + uint32_t mainCrcCalc = xStorageOnFlashArtery_CrcFlash((uint8_t *) env->mainFlashPageAddress, size); + uint32_t mainCrcReed = iInternalFlashPage_ReadWord(env->mainFlashPageAddress + dataSizeOnFlash); + + bool recoveryCrcOk = (recoveryCrcCalc == recoveryCrcReed); + bool mainCrcOk = (mainCrcReed == mainCrcCalc); + + if (recoveryCrcOk && mainCrcOk) { + if (recoveryCrcReed == mainCrcReed) { + sInternalFlashPage_Read(env->mainFlashPageAddress, 0x0, data, size); + return STORAGE_OK; + } else { + sInternalFlashPage_Read(env->recoveryFlashPageAddress, 0x0, data, size); + return xStorageOnFlashArtery_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); + } + } else if (recoveryCrcOk || mainCrcOk) { + if (recoveryCrcOk) { + sInternalFlashPage_Read(env->recoveryFlashPageAddress, 0x0, data, size); + return xStorageOnFlashArtery_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); + } else { + sInternalFlashPage_Read(env->mainFlashPageAddress, 0x0, data, size); + return xStorageOnFlashArtery_DumpOn(env, mainCrcCalc, env->recoveryFlashPageAddress, data, size); + } + } else { + return STORAGE_ERR_DATA; + } + +} + +void vStorageOnFlashArtery_Init( + tStorageOnFlashArtery *env, uint32_t mainPage, uint32_t recoveryPage +) { + env->mainFlashPageAddress = mainPage; + env->recoveryFlashPageAddress = recoveryPage; +} + +tStorageInterface xStorageOnFlashArtery_GetInterface(tStorageOnFlashArtery *env) { + return (tStorageInterface) { + .env = env, + .load = (StorageIOTransaction) xStorageOnFlashArtery_Load, + .dump = (StorageIOTransaction) xStorageOnFlashArtery_Dump, + }; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..3dbda08 --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC_NEW", + "repo": "StorageInterface" + }, + { + "type": "git", + "provider": "GONEC_NEW", + "repo": "InternalFlashPage_ARTERY_AT32" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file