From 6bf375cea860c0e8bdfe56df1d1e6a9f6b8d2afd Mon Sep 17 00:00:00 2001 From: cfif Date: Mon, 26 May 2025 14:41:45 +0300 Subject: [PATCH] Init --- Inc/FirmwareLoader.h | 60 +++++++++++++++++ Src/FirmwareLoader.c | 153 +++++++++++++++++++++++++++++++++++++++++++ modular.json | 22 +++++++ 3 files changed, 235 insertions(+) create mode 100644 Inc/FirmwareLoader.h create mode 100644 Src/FirmwareLoader.c create mode 100644 modular.json diff --git a/Inc/FirmwareLoader.h b/Inc/FirmwareLoader.h new file mode 100644 index 0000000..8a40e35 --- /dev/null +++ b/Inc/FirmwareLoader.h @@ -0,0 +1,60 @@ +// +// Created by zemon on 28.05.2022. +// + +#ifndef TERMINAL_MOTO_0_0_1_UPDATE_FIRMWARE_H +#define TERMINAL_MOTO_0_0_1_UPDATE_FIRMWARE_H + +#include "stdint.h" +#include "stdbool.h" +#include "assert.h" + +#define FIRMWARE_META_LENGTH (0x100) + + +typedef struct { + uint32_t *size; + uint32_t *crc; + + uint8_t *nameLength; + uint8_t *name; +} tFirmwareMetaMap; + +typedef struct { + uint32_t address; + uint8_t metadataMem[FIRMWARE_META_LENGTH]; + tFirmwareMetaMap metadata; + +} tFirmwareBlock; + +typedef struct { + tFirmwareBlock main; + tFirmwareBlock update; + + uint32_t fwSize; + uint32_t metadataOffset; +} tFirmwareLoader; + +void FirmwareLoader_Init(tFirmwareLoader *env, uint32_t fwSize, uint32_t mainFwAddr, uint32_t updateFwAddr); + +bool FirmwareLoader_CheckUpdate(tFirmwareLoader *env); + +bool FirmwareLoader_IsLoadUpdate(tFirmwareLoader *env); + +bool FirmwareLoader_CheckAndUpdate(tFirmwareLoader *env); + +bool FirmwareLoader_PrepareNewUpdate(tFirmwareLoader *env, uint32_t size, uint32_t crc, uint8_t *name, uint8_t nameLen); + +bool FirmwareLoader_WriteUpdatePortion(tFirmwareLoader *env, uint32_t offset, uint8_t *data, uint16_t dataSize); + +void FirmwareLoader_RunFirmware(tFirmwareLoader *env); + +bool FirmwareLoader_CheckBlock(tFirmwareLoader *env, tFirmwareBlock *block); + +bool FirmwareLoader_ClearUpdateFlash(tFirmwareLoader *env); + +void FirmwareLoader_LoadMetadata(tFirmwareLoader *env, tFirmwareBlock *block); + +bool FirmwareLoader_IsUpdateAndMainAreDifferent(tFirmwareLoader *env); + +#endif //TERMINAL_MOTO_0_0_1_UPDATE_FIRMWARE_H diff --git a/Src/FirmwareLoader.c b/Src/FirmwareLoader.c new file mode 100644 index 0000000..4ae3302 --- /dev/null +++ b/Src/FirmwareLoader.c @@ -0,0 +1,153 @@ +// +// Created by zemon on 28.05.2022. +// +#include +#include +#include "FirmwareLoader.h" +#include "stdint.h" +#include "BootJump.h" + +void FirmwareLoader_MapMetadata(tFirmwareBlock *block) { + block->metadata.crc = (uint32_t *) (block->metadataMem + 0); + block->metadata.size = (uint32_t *) (block->metadataMem + 4); + + block->metadata.nameLength = (uint8_t *) (block->metadataMem + 8); + block->metadata.name = (uint8_t *) (block->metadataMem + 9); +} + +void FirmwareLoader_Init(tFirmwareLoader *env, uint32_t fwSize, uint32_t mainFwAddr, uint32_t updateFwAddr) { + env->fwSize = fwSize; + env->main.address = mainFwAddr; + env->update.address = updateFwAddr; + + env->metadataOffset = fwSize - FIRMWARE_META_LENGTH; + + FirmwareLoader_MapMetadata(&env->main); + FirmwareLoader_MapMetadata(&env->update); +} + +void FirmwareLoader_LoadMetadata(tFirmwareLoader *env, tFirmwareBlock *block) { + sInternalFlashPage_Read(block->address + env->metadataOffset, 0, block->metadataMem, FIRMWARE_META_LENGTH); +} + +void FirmwareLoader_CopyUpdateToMain(tFirmwareLoader *env) { + bInternalFlashPage_CopyRange( + env->main.address, + env->update.address, + env->fwSize + ); +} + +uint32_t FirmwareLoader_crc32(uint8_t *data, uint32_t size) { + uint32_t crc = 0; + + uint8_t *dataEnd = data + size; + + while (data < dataEnd) { + crc += *data; + ++data; + } + + return crc; +} + +bool FirmwareLoader_CheckBlock(tFirmwareLoader *env, tFirmwareBlock *block) { + FirmwareLoader_LoadMetadata(env, block); + + if ((*block->metadata.size <= env->metadataOffset) && (*block->metadata.size > 0)) { + + uint32_t calcCrc = FirmwareLoader_crc32((uint8_t *) block->address, *block->metadata.size); + + if (calcCrc == *block->metadata.crc) { + return true; + } + + } + + return false; +} + + +bool FirmwareLoader_IsUpdateAndMainAreDifferent(tFirmwareLoader *env) { + //meta data must be loaded first with FirmwareLoader_LoadMetadata + //метаданные должны быть подгружены заранее с использованием FirmwareLoader_LoadMetadata + + bool sameNames = + (*env->main.metadata.nameLength == *env->update.metadata.nameLength) && + memcmp(env->main.metadata.name, env->update.metadata.name, *env->update.metadata.nameLength) == 0; + + bool sameSrc = *env->main.metadata.crc == *env->update.metadata.crc; + + return !sameSrc || !sameNames; +} + +bool FirmwareLoader_CheckUpdate(tFirmwareLoader *env) { + return FirmwareLoader_CheckBlock(env, &env->update); +} + +bool FirmwareLoader_IsLoadUpdate(tFirmwareLoader *env) { + + //грузим метаданные и проверяем контрольные суммы для обоих блоков прошивки + bool mainFwOk = FirmwareLoader_CheckBlock(env, &env->main); + bool updateFwOk = FirmwareLoader_CheckBlock(env, &env->update); + + //если у нас есть целая(не битая) прошивка в секции обновления + if (updateFwOk) { + //то смотрим нужно ли ее накатить + //а имеено, накатываем в том случае если текущая прошивка неисправна/отсутствует + //или если в секции обновления лежит другая (считаем что более новая) прошивка + if ((!mainFwOk) || (FirmwareLoader_IsUpdateAndMainAreDifferent(env))) { + return true; + } + } + + return false; +} + +bool FirmwareLoader_CheckAndUpdate(tFirmwareLoader *env) { + + //если обновление есть (оно валидно) и глная прошивка битая или отличаеться от обновления + if(FirmwareLoader_IsLoadUpdate(env)){ + //то гурзим обновление в основню область памяти + FirmwareLoader_CopyUpdateToMain(env); + } + + //и финальная проверка, а что у нас теперь лежит в секции основной прошивки ( валидная ли прошивка там ) + return FirmwareLoader_CheckBlock(env, &env->main); +} + + +//Загружаем основную прошивку +void FirmwareLoader_RunFirmware(tFirmwareLoader *env) { + BootJumpToAddress(env->main.address); +} + +bool FirmwareLoader_ClearUpdateFlash(tFirmwareLoader *env) { + return bInternalFlashPage_ClearRange(env->update.address, env->fwSize); +} + + +bool FirmwareLoader_WriteUpdatePortion(tFirmwareLoader *env, uint32_t offset, uint8_t *data, uint16_t dataSize) { + return sInternalFlashPage_Write(env->update.address + offset, 0, data, dataSize) == dataSize; +} + +static bool FirmwareLoader_DumpUpdateMetadata(tFirmwareLoader *env) { +// return true; + return FirmwareLoader_WriteUpdatePortion(env, env->metadataOffset, env->update.metadataMem, FIRMWARE_META_LENGTH); +} + +bool FirmwareLoader_PrepareNewUpdate( + tFirmwareLoader *env, uint32_t size, uint32_t crc, uint8_t *name, uint8_t nameLen +) { + + if (!FirmwareLoader_ClearUpdateFlash(env)) { + return false; + } + + *env->update.metadata.crc = crc; + *env->update.metadata.size = size; + *env->update.metadata.nameLength = nameLen; + memcpy(env->update.metadata.name, name, nameLen); + + return FirmwareLoader_DumpUpdateMetadata(env); +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..cdfa53b --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC_NEW", + "repo": "BootJump_ARTERY_AT32" + }, + { + "type": "git", + "provider": "GONEC_NEW", + "repo": "InternalFlashPage_ARTERY_AT32" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file