Перенос на новую организацию GONEC
This commit is contained in:
commit
8cdedf770b
|
|
@ -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
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue