HVAC_BOOT_M7/APP/main.c

186 lines
5.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 22.09.2025.
//
#include "Clock.h"
#include "LoggerToSerialPort.h"
#include "LoggerInterface.h"
#include "StorageOnFlash.h"
#include "Rtcs.h"
#include "SerialPorts.h"
#include "CmsisRtosThreadUtils.h"
#include "SystemDelayInterface.h"
#include "DeviceStorage.h"
#include "BootJump.h"
#include "FirmwareLoader.h"
#define BOOT_AREA_LENGTH (256 * 1024) // Размер загрузчика
#define FIRMWARE_MAIN_AREA_LENGTH (768 * 1024) // Размер основной программы
#define FIRMWARE_MAIN_ADDR (0x01000000 + BOOT_AREA_LENGTH) // Адрес основной программы
#define FIRMWARE_MAIN_UPDATE_ADDR 0x01100000 // Адрес основной программы (обновление)
typedef struct {
tLoggerToSerialPort slog;
tDeviceStorage storage;
tFirmwareLoader FIRMWARE_HVAC;
struct {
osThreadId_t id;
uint32_t stack[2048];
StaticTask_t controlBlock;
osThreadAttr_t attr;
} thread;
} tBootMma;
tBootMma MAIN_BOOT_ENV;
#define LOGGER &MAIN_ENV.slog.logger
#define LOG_SIGN "Boot"
_Noreturn void stop() {
while (1) {
asm("nop");
}
}
#define STOP stop();
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
void vApplicationStackOverflowHook(TaskHandle_t xTask, const char *pcTaskName) {
PROCESS_UNUSED_VAR(xTask);
PROCESS_UNUSED_VAR(pcTaskName);
STOP
}
#endif
const DMA_InitType dmaInitCfg =
{
.eArbitrationAlgorithm = DMA_ARBITRATION_ALGORITHM_FIXED_PRIORITY,
.bHaltOnError = false
};
static _Noreturn void MainTransmitter_Thread(tBootMma *env) {
DMA_Init(DMA_INSTANCE_0, &dmaInitCfg);
Rtcs_Init();
// Настройка таймера реального времени
time_t set_timestamp = 0;
RtcSet(&RTCS.rtcI0, &set_timestamp);
SerialPorts_Init();
LoggerToSerialPort_Init(
&env->slog,
0,
&SERIAL_PORTS.cliVirtualPortOut_Io,
&SERIAL_PORTS.SerialPortLog_IO,
&RTCS.rtcI0,
SERIAL_LOGGER_SHOW_TIME | SERIAL_LOGGER_SHOW_AUTHOR | SERIAL_LOGGER_SHOW_LOG_LEVEL,
5
);
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Start logging")
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Initialization of subsystems")
// StorageOnFlash_Init(&env->slog.logger);
// NVM_STORAGE.nf_storage_param.logger = &env->slog.logger;
// NVM_STORAGE.nf_storage_calib.logger = &env->slog.logger;
// bool result = DeviceStorage_Init(&env->storage, true, &NVM_STORAGE.interface_calib, &NVM_STORAGE.interface_param,
// &env->slog.logger);
FirmwareLoader_Init(&env->FIRMWARE_HVAC, FIRMWARE_MAIN_AREA_LENGTH, FIRMWARE_MAIN_ADDR,
FIRMWARE_MAIN_UPDATE_ADDR);
bool isMain = FirmwareLoader_CheckBlock(&env->FIRMWARE_HVAC, &env->FIRMWARE_HVAC.main);
if (isMain) {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Main firmware: Checksum is correct")
} else {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Main firmware: Checksum is not correct")
if (*env->FIRMWARE_HVAC.main.metadata.crc == 0) {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Main firmware: Checksum not found (The program may have been flashed using JTAG ?)")
}
}
bool isUpdate = FirmwareLoader_CheckBlock(&env->FIRMWARE_HVAC, &env->FIRMWARE_HVAC.update);
if (isUpdate) {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Recovery firmware: Checksum is correct")
} else {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Recovery firmware: Checksum is not correct")
}
// Есть обновление
if (isUpdate) {
// Если текущая прошивка (isMain) неисправна (не загружена) или в секции обновления находится отличная от текущей прошивка
bool isNewFirmware = FirmwareLoader_IsUpdateAndMainAreDifferent(&env->FIRMWARE_HVAC);
// !isMain - Не совпадает crc основной прошивки isNewFirmware - есть рабочая прошивка в обновлении, которая отличается от основной (main)
if ((!isMain) || (isNewFirmware)) {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Update detected")
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Starting the update process")
// Обновление
// FirmwareLoader_CopyUpdateToMain(&env->FIRMWARE_HVAC);
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Update complete")
// Проверка crc
isMain = FirmwareLoader_CheckBlock(&env->FIRMWARE_HVAC, &env->FIRMWARE_HVAC.main);
if (isMain) {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Main firmware (after update): Checksum is correct")
} else {
LoggerInfoStatic(&env->slog.logger, LOG_SIGN, "Main firmware (after update): Checksum is not correct")
}
}
}
SystemDelayMs(10);
BootJumpToAddress(FIRMWARE_MAIN_ADDR);
for (;;) {
SystemDelayMs(1000);
}
}
void MainTransmitter_StartThread(tBootMma *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (MainTransmitter_Thread), (void *) (env), &env->thread.attr);
}
}
int main(void) {
Bsp_CLOCK_Init();
NVIC_SetPriorityGrouping(NVIC_PRIORITY_GROUP_4);
osKernelInitialize();
tBootMma *env = &MAIN_BOOT_ENV;
InitThreadAtrStatic(&env->thread.attr, "BootMma", env->thread.controlBlock, env->thread.stack,
osPriorityNormal);
MainTransmitter_StartThread(env);
osKernelStart();
STOP
}