From 2547f3c83d11dfa6e84fa53b95d07a7181487612 Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 24 Oct 2025 12:29:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/StorageOnFlashFlagchip.h | 26 +++++++ Src/StorageOnFlashFlagchip.c | 139 +++++++++++++++++++++++++++++++++++ modular.json | 22 ++++++ 3 files changed, 187 insertions(+) create mode 100644 Inc/StorageOnFlashFlagchip.h create mode 100644 Src/StorageOnFlashFlagchip.c create mode 100644 modular.json diff --git a/Inc/StorageOnFlashFlagchip.h b/Inc/StorageOnFlashFlagchip.h new file mode 100644 index 0000000..a1c8d76 --- /dev/null +++ b/Inc/StorageOnFlashFlagchip.h @@ -0,0 +1,26 @@ +// +// Created by cfif on 07.10.22. +// + +#ifndef STORAGE_ON_FLASH_FLAGCHIP_H +#define STORAGE_ON_FLASH_FLAGCHIP_H + +#include "stddef.h" +#include "StorageIO.h" + +typedef struct { + uint32_t mainFlashPageAddress; + uint32_t recoveryFlashPageAddress; +} tStorageOnFlashFlagchip; + +void vStorageOnFlashFlagchip_Init( + tStorageOnFlashFlagchip *env, + uint32_t mainPage, + uint32_t recoveryPage +); + + +tStorageInterface xStorageOnFlashFlagchip_GetInterface(tStorageOnFlashFlagchip *env); + + +#endif //STORAGE_ON_FLASH_FLAGCHIP_H diff --git a/Src/StorageOnFlashFlagchip.c b/Src/StorageOnFlashFlagchip.c new file mode 100644 index 0000000..52b1c4e --- /dev/null +++ b/Src/StorageOnFlashFlagchip.c @@ -0,0 +1,139 @@ +// +// Created by cfif on 07.10.22. +// +#include "InternalFlashPage.h" +#include "StorageOnFlashFlagchip.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 +xStorageOnFlashFlagchip_DumpOn( + tStorageOnFlashFlagchip *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 xStorageOnFlashFlagchip_Dump(tStorageOnFlashFlagchip *env, void *data, size_t size) { + + uint32_t crc = xStorageOnFlashArtery_Crc(data, size); + + if (xStorageOnFlashFlagchip_DumpOn(env, crc, env->recoveryFlashPageAddress, data, size) != STORAGE_OK) { + return STORAGE_ERR_DEVICE; + } + + if (xStorageOnFlashFlagchip_DumpOn(env, crc, env->mainFlashPageAddress, data, size) != STORAGE_OK) { + return STORAGE_ERR_DEVICE; + } + + return STORAGE_OK; +} + + +eStorageStatus xStorageOnFlashFlagchip_Load(tStorageOnFlashFlagchip *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 xStorageOnFlashFlagchip_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); + } + } else if (recoveryCrcOk || mainCrcOk) { + if (recoveryCrcOk) { + sInternalFlashPage_Read(env->recoveryFlashPageAddress, 0x0, data, size); + return xStorageOnFlashFlagchip_DumpOn(env, recoveryCrcCalc, env->mainFlashPageAddress, data, size); + } else { + sInternalFlashPage_Read(env->mainFlashPageAddress, 0x0, data, size); + return xStorageOnFlashFlagchip_DumpOn(env, mainCrcCalc, env->recoveryFlashPageAddress, data, size); + } + } else { + return STORAGE_ERR_DATA; + } + +} + +void vStorageOnFlashFlagchip_Init( + tStorageOnFlashFlagchip *env, uint32_t mainPage, uint32_t recoveryPage +) { + env->mainFlashPageAddress = mainPage; + env->recoveryFlashPageAddress = recoveryPage; +} + +tStorageInterface xStorageOnFlashFlagchip_GetInterface(tStorageOnFlashFlagchip *env) { + return (tStorageInterface) { + .env = env, + .load = (StorageIOTransaction) xStorageOnFlashFlagchip_Load, + .dump = (StorageIOTransaction) xStorageOnFlashFlagchip_Dump, + }; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..24122af --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "HVAC_M7", + "repo": "StorageInterface" + }, + { + "type": "git", + "provider": "HVAC_M7", + "repo": "InternalFlashPage_Flagchip_FC7240" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file