SMART_COMPONENTS_BOOT_AURUS/APP/main.c

421 lines
14 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.

#include "cmsis_os.h"
#include "at32f435_437_clock.h"
#include "FirmwareLoader.h"
#include "FirmwareMetadataSection.h"
#include "StorageOnFlash.h"
#include "DeviceStorage.h"
#include "string.h"
#include "stdlib.h"
#include "SystemDelayInterface.h"
#include "ld_adr.h"
#include "BootJump.h"
#include "BaseTypes.h"
/*
#include "Gpios.h"
#include "Rtcs.h"
#include "SerialPorts.h"
#include "CmsisRtosThreadUtils.h"
#include "LoggerToSerialPort.h"
#include "EgtsProcessing.h"
#include "ComInt.h"
#include "aes.h"
#include "ext_telematica.h"
*/
#define FIRMWARE_MAIN_ADDR (0x08000000 + BOOT_AREA_LENGTH)
#define FIRMWARE_MAIN_RECOVERY_ADDR (FIRMWARE_MAIN_ADDR + FIRMWARE_MAIN_AREA_LENGTH)
#define FIRMWARE_TELE_MAIN_ADDR (FIRMWARE_MAIN_RECOVERY_ADDR + FIRMWARE_MAIN_UPDATE_AREA_LENGTH)
#define FIRMWARE_TELE_RECOVERY_ADDR (FIRMWARE_MAIN_ADDR + FIRMWARE_MAIN_AREA_LENGTH)
tFirmwareLoader FIRMWARE_UVEOS_LOADER;
tFirmwareLoader FIRMWARE_TELE_LOADER;
tFirmwareLoader FIRMWARE_UPDATE_LOADER;
tDeviceStorage deviceStorage;
bool resultStorage;
uint8_t findDelimiter(tString32 *address, char ch) {
for (uint8_t i = 0; i < address->length; ++i) {
if (address->data[i] == ch)
return i;
}
return 0;
}
void run() {
// if (FirmwareLoader_IsLoadUpdate(&FIRMWARE_UVEOS_LOADER)) {
// bool result = FirmwareLoader_CheckAndUpdate(&FIRMWARE_UVEOS_LOADER);
// }
// if (!FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.main)) {
// Сбой прошивки
// asm("nop");
// }
// FirmwareLoader_RunFirmware(&FIRMWARE_UVEOS_LOADER);
BootJumpToAddress(FIRMWARE_MAIN_ADDR);
}
/*
_Noreturn void stop() {
while (1) {
asm("nop");
}
}
#define STOP stop();
tStaticThreadBlock(1024) mainThread;
tLoggerToSerialPort slog;
tDeviceStorage deviceStorage;
tEgtsProcessing EgtsProcessing;
tGsmWithGnss gsm;
tComInt comInt;
#define LOG_SIGN "BOOT"
#define LOGGER &slog.logger
struct {
uint8_t gsmRx[1024];
uint8_t gsmTx[1024];
} mem;
tAtCmd gsmAt;
void run() {
// if (FirmwareLoader_IsLoadUpdate(&FIRMWARE_UVEOS_LOADER)) {
// bool result = FirmwareLoader_CheckAndUpdate(&FIRMWARE_UVEOS_LOADER);
// }
// if (!FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.main)) {
// Сбой прошивки
// asm("nop");
// }
// FirmwareLoader_RunFirmware(&FIRMWARE_UVEOS_LOADER);
BootJumpToAddress(FIRMWARE_MAIN_ADDR);
}
bool GsmWithGnssWaitStartup(tGsmWithGnss *env) {
volatile AtCommandResult res = AT_ERROR;
if (osMutexAcquire(env->gsmAt->access, 1000) == osOK) {
res = AtCmdWaitOk(env->gsmAt, 1000, 20000);
osMutexRelease(env->gsmAt->access);
return res;
}
return res;
}
tStringStatic teDeviceModesNames[] = {
StringStaticInit("Загрузчик")
};
#define timeOutWaitConnect 30
#define timeOutWaitLoading (5 * 60)
bool resultStorage;
_Noreturn void MainThread(void *env) {
for (;;) {
LoggerToSerialPort_Init(
&slog,
0,
&SERIAL_PORTS.cliVirtualInIo,
&RTCS.rtcI0,
SERIAL_LOGGER_SHOW_AUTHOR | SERIAL_LOGGER_SHOW_LOG_LEVEL |
SERIAL_LOGGER_SHOW_TIME// | SERIAL_LOGGER_SHOW_TIME
);
tStringLink currentModeName = StringStaticGetLink(&teDeviceModesNames[0]);
tString16 alertId;
String16CopyStatic(&alertId, "BOOT");
ComInt_Init(
&comInt,
&SERIAL_PORTS.Rs485_HalfDuplexIo,
&alertId,
&SERIAL_PORTS.Modem_snif_IO,
&SERIAL_PORTS.cliVirtualOutIo,
&currentModeName
);
ComInt_StartThread(&comInt);
LoggerInfoStatic(LOGGER, LOG_SIGN, "Загрузчик. Начало логирования")
// bool resultStorage = DeviceStorage_Init(&deviceStorage, &NVM_STORAGE.interface);
if (!resultStorage) {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Первый запуск. Не введен адрес сервера")
}
if ((deviceStorage.nvm.SettingsServerConnection.EGTS_SERVER_ADDRESS.length == 0) ||
(deviceStorage.nvm.SettingsServerConnection.EGTS_GPRS_APN.length == 0)) {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход. Не введен адрес сервера или apn")
run();
}
if (deviceStorage.nvm.SettingsServerConnection.EGTS_FLEET_ON == 0) {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход. Телематика отключена")
run();
}
uint32_t timeOutWaitAuth = 30;
if (deviceStorage.nvm.SettingsServerConnection.EGTS_TIME_WAIT_FIRMWARE > timeOutWaitAuth)
timeOutWaitAuth = deviceStorage.nvm.SettingsServerConnection.EGTS_TIME_WAIT_FIRMWARE;
GpioPinEnable(&GPIOS.standby);
GpioPinEnable(&GPIOS.enable);
GpioPinEnable(&GPIOS.PowerRS485);
AtCmdInit(
&gsmAt, &SERIAL_PORTS.Modem_IO,
mem.gsmTx, sizeof(mem.gsmTx),
mem.gsmRx, sizeof(mem.gsmRx),
2000, 2000
);
GsmWithGnssInit(&gsm,
&slog,
&gsmAt,
&RTCS.rtcI0);
EgtsProcessing_Init(
&EgtsProcessing,
&gsm,
&deviceStorage,
&RTCS.rtcI0,
&slog
);
PwmSim7600e_Startup(&GPIOS.sim7600);
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание загрузки модема")
bool result = GsmWithGnssWaitStartup(&gsm);
if (result) {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ответ от модема получен")
} else {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка. Нет ответа от модема")
run();
}
GsmWithGnss_start(&gsm);
EgtsProcessing_Start(&EgtsProcessing);
uint32_t timeWaitConnect = SystemGetMs() + timeOutWaitConnect * 1000;
uint32_t timeWaitAuth = SystemGetMs() + timeOutWaitAuth * 1000;
uint32_t timeWaitLoad = SystemGetMs() + timeOutWaitLoading * 1000;
for (;;) {
// Если не было соединения
if (EgtsProcessing.egtsLoaderUpdate == EGTS_LOADER_INIT) {
uint32_t time = SystemGetMs();
if (timeWaitConnect < SystemGetMs()) {
LoggerFormatInfo(LOGGER, LOG_SIGN,
"Выход по таймеру: Не было соединения с сервером в течении %d сек",
timeOutWaitConnect)
run();
}
}
// Если не было соединения
if (EgtsProcessing.egtsLoaderUpdate == EGTS_LOADER_ERR_CON) {
LoggerInfoStatic(LOGGER, LOG_SIGN,
"Выход: Не было соединения с сервером. Все попытки соединения были исчерпаны")
run();
}
// Если не было обновления после соединения
if (EgtsProcessing.egtsLoaderUpdate == EGTS_LOADER_AUTH) {
if (timeWaitAuth < SystemGetMs()) {
LoggerFormatInfo(LOGGER, LOG_SIGN,
"Выход по таймеру: Не было обновления после соединения с сервером в течении %d сек",
timeOutWaitAuth)
EgtsProcessingCloseConnection(&EgtsProcessing);
run();
}
}
// Если в процессе обновления больше
if (EgtsProcessing.egtsLoaderUpdate == EGTS_LOADER_LOADING) {
if (timeWaitLoad < SystemGetMs()) {
LoggerFormatInfo(LOGGER, LOG_SIGN, "Выход по таймеру: Процесс обновления занял больше, %d сек",
timeOutWaitLoading)
EgtsProcessingCloseConnection(&EgtsProcessing);
run();
}
}
if (EgtsProcessing.egtsLoaderUpdate == EGTS_LOADER_END_LOADING) {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Выход по обновлению")
SystemDelayMs(1000);
EgtsProcessingCloseConnection(&EgtsProcessing);
run();
}
SystemDelayMs(1000);
}
}
}
*/
int main(void) {
system_clock_config();
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
/*
gpio_init_type GPIOInit;
gpio_default_para_init(&GPIOInit);
GPIOInit.gpio_mode = GPIO_MODE_OUTPUT;
GPIOInit.gpio_pull = GPIO_PULL_NONE;
GPIOInit.gpio_pins = GPIO_PINS_3;
gpio_init(GPIOD, &GPIOInit);
gpio_bits_reset(GPIOD, GPIO_PINS_3);
gpio_default_para_init(&GPIOInit);
GPIOInit.gpio_mode = GPIO_MODE_OUTPUT;
GPIOInit.gpio_pull = GPIO_PULL_NONE;
GPIOInit.gpio_pins = GPIO_PINS_7;
gpio_init(GPIOB, &GPIOInit);
gpio_bits_reset(GPIOB, GPIO_PINS_7);
*/
// osKernelInitialize();
// Gpios_Init();
// SerialPorts_Init(&GPIOS.comIntDir);
StorageOnFlash_Init();
// Rtcs_Init();
resultStorage = DeviceStorage_Init(&deviceStorage, &NVM_STORAGE.interface);
if (deviceStorage.nvm.SettingsServerConnection.REGION_SIZE_UPDATE <= FIRMWARE_MAIN_AREA_LENGTH) {
FirmwareLoader_Init(&FIRMWARE_UVEOS_LOADER, FIRMWARE_MAIN_AREA_LENGTH, FIRMWARE_MAIN_ADDR,
FIRMWARE_TELE_RECOVERY_ADDR);
FirmwareLoader_Init(&FIRMWARE_TELE_LOADER, FIRMWARE_TELE_AREA_LENGTH, FIRMWARE_TELE_MAIN_ADDR,
FIRMWARE_TELE_RECOVERY_ADDR);
bool is_FW_UVEOS_main = FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.main);
bool is_FW_TELE_main = FirmwareLoader_CheckBlock(&FIRMWARE_TELE_LOADER, &FIRMWARE_TELE_LOADER.main);
FirmwareLoader_Init(&FIRMWARE_UPDATE_LOADER, deviceStorage.nvm.SettingsServerConnection.REGION_SIZE_UPDATE, 0,
FIRMWARE_TELE_RECOVERY_ADDR);
bool is_update = FirmwareLoader_CheckBlock(&FIRMWARE_UPDATE_LOADER, &FIRMWARE_UVEOS_LOADER.update);
// Есть обновление
if (is_update) {
tString32 FW_NAME;
FW_NAME.length = *FIRMWARE_UVEOS_LOADER.update.metadata.nameLength;
memcpy(FW_NAME.data, FIRMWARE_UVEOS_LOADER.update.metadata.name, FW_NAME.length);
uint8_t posDel = findDelimiter(&FW_NAME, '_') + 1;
// Получена прошивка телематики
if (memcmp(&FW_NAME.data[posDel], "TELE", 4) == 0) {
bool is_FW_TELE_update = FirmwareLoader_CheckBlock(&FIRMWARE_TELE_LOADER, &FIRMWARE_TELE_LOADER.update);
// Если текущая прошивка неисправна (не загружена) или в секции обновления находится отличная от текущей прошивка
bool isNewFirmware = FirmwareLoader_IsUpdateAndMainAreDifferent(&FIRMWARE_TELE_LOADER);
if ((!is_FW_TELE_main) || (isNewFirmware)) {
FirmwareLoader_CopyUpdateToMain(&FIRMWARE_TELE_LOADER);
is_FW_TELE_main = FirmwareLoader_CheckBlock(&FIRMWARE_TELE_LOADER, &FIRMWARE_TELE_LOADER.main);
if (is_FW_TELE_main == false) {
// Ошибка обновления Телематики
}
asm("nop");
}
asm("nop");
// Получена прошивка УВЭОС
} else if (memcmp(&FW_NAME.data[posDel], "UVEOS", 5) == 0) {
bool is_FW_UVEOS_update = FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.update);
// Если текущая прошивка неисправна (не загружена) или в секции обновления находится отличная от текущей прошивка
bool isNewFirmware = FirmwareLoader_IsUpdateAndMainAreDifferent(&FIRMWARE_UVEOS_LOADER);
// Если текущая прошивка неисправна (не загружена) или в секции обновления находится отличная от текущей прошивка
if ((!is_FW_UVEOS_main) || (isNewFirmware)) {
FirmwareLoader_CopyUpdateToMain(&FIRMWARE_UVEOS_LOADER);
is_FW_UVEOS_main = FirmwareLoader_CheckBlock(&FIRMWARE_UVEOS_LOADER, &FIRMWARE_UVEOS_LOADER.main);
if (is_FW_UVEOS_main == false) {
// Ошибка обновления УВЭОС
}
asm("nop");
}
asm("nop");
// Получена прошивка ключей
} else if (memcmp(&FW_NAME.data[0], "CERT", 4) == 0) {
asm("nop");
// Получена неизвестная прошивка
} else {
}
}
}
run();
/*
if (deviceStorage.nvm.SettingsServerConnection.EGTS_FLEET_ON == true) {
bool isTelematica = loadMetaTelematica();
if (isTelematica) {
run();
} else {
}
} else {
run();
}
// Если включен модуль телематики, пытаемся загрузить телематику из загрузчика
FirmwareLoader_Init(&FIRMWARE_TELE_LOADER, FIRMWARE_TELE_AREA_LENGTH, FIRMWARE_TELE_MAIN_ADDR,
FIRMWARE_TELE_RECOVERY_ADDR);
InitThreadBlock(mainThread, "main", osPriorityNormal);
ThreadBlock_Start(mainThread, 0, MainThread);
osKernelStart();
*/
}