Перенос на новую организацию GONEC

This commit is contained in:
cfif 2025-01-24 13:22:32 +03:00
commit 8cdedf770b
3 changed files with 235 additions and 0 deletions

60
Inc/FirmwareLoader.h Normal file
View File

@ -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

153
Src/FirmwareLoader.c Normal file
View File

@ -0,0 +1,153 @@
//
// Created by zemon on 28.05.2022.
//
#include <InternalFlashPage.h>
#include <memory.h>
#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);
}

22
modular.json Normal file
View File

@ -0,0 +1,22 @@
{
"dep": [
{
"type": "git",
"provider": "GONEC",
"repo": "BootJump_ARTERY_AT32"
},
{
"type": "git",
"provider": "GONEC",
"repo": "InternalFlashPage_ARTERY_AT32"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}