UKSVEP_23550.2/Core/Bootloader/Inc/bootloader.h
Razvalyaev 0e834dfe3d структуризирован бутлоадер. работает
надо по протоколу подумать еще, доработать его и описать
2025-09-15 14:48:13 +03:00

145 lines
5.8 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.

#ifndef __BOOTLOADER_H
#define __BOOTLOADER_H
#include "boot_project_setup.h"
#include "string.h"
/* --- Настройка: подставьте значения для вашей MCU --- */
/* Адрес начала приложения (используется в вашем коде) */
#ifndef MAIN_APP_START_ADR
#error "MAIN_APP_START_ADR must be defined"
#endif
/* Flash boundaries: подставьте реальные границы флеш-памяти вашего MCU */
#ifndef FLASH_START_ADR
#define FLASH_START_ADR MAIN_APP_START_ADR
#endif
#ifndef FLASH_END_ADR
#define FLASH_END_ADR FLASH_BASE + (*((uint16_t*)FLASHSIZE_BASE) * 1024U)
#endif
/* SRAM boundaries: подставьте реальные адреса SRAM вашей MCU */
#ifndef SRAM_START_ADR
#define SRAM_START_ADR 0x20000000UL
#endif
#ifndef SRAM_END_ADR
#define SRAM_END_ADR 0x2003FFFFUL
#endif
/**
* @brief Значение ключа, указывающее что основное приложение записано
*/
#define BL_KEY_APP_WRITTEN 0xAAAA5555
/** @brief Получить сохранённый код ошибки из BKP */
#define GetErrorCode() BKP->DR1
/** @brief Получить счетчик ошибок из BKP */
#define GetErrorCnt() BKP->DR2
/**
* @brief Сохранение кода ошибки и инкремент счетчика
* @param code Код ошибки
* @details
* Включаем тактирование PWR и BKP (APB1) и разрешаем доступ к BKP domain
* Записываем напрямую в регистры RCC/APB1ENR и PWR->CR
* Записываем код ошибки и счётчик ошибок
*/
#define SaveErrorCode(code) do{ \
RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); \
PWR->CR |= PWR_CR_DBP; \
GetErrorCode() = code; \
GetErrorCnt() = GetErrorCnt() + 1; \
}while(0u);
/**
* @brief Очистка кода ошибки и счетчика ошибок
*/
#define ClearErrorCode(code) do{ \
RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); \
PWR->CR |= PWR_CR_DBP; \
GetErrorCode() = 0; \
GetErrorCnt() = 0; \
}while(0u);
/**
* @brief Команды для управления бутлоадером
*/
typedef enum {
CMD_ERASE = 0x01, ///< Команда на стирание прошивки
CMD_START_RECEIVE, ///< Команда на старт приема прошивки
CMD_WRITE, ///< Команда на запись блока прошивки
CMD_GOTOAPP, ///< Команда на переход в приложение
CMD_RESET, ///< Команда на переход в приложение
CMD_GOTOBOOT, ///< Команда на переход в приложение
}BootloaderCommand_t;
/**
* @brief Состояния конечного автомата бутлоадера
*/
typedef enum {
BL_STATE_INIT = 0, ///< Состояние: инициализация
BL_STATE_JUMP_TO_APP, ///< Состояние: запуск приложения
BL_STATE_IDLE, ///< Состояние: ожидание команд
BL_STATE_ERASE, ///< Состояние: стирание флеша
BL_STATE_RECEIVE_UART, ///< Состояние: прием прошивки по UART
BL_STATE_RECEIVE_CAN, ///< Состояние: прием прошивки по CAN
BL_STATE_WRITE, ///< Состояние: запись данных
BL_STATE_ERROR, ///< Состояние: ошибка
BL_STATE_RESET, ///< Состояние: сброс контролллера
BL_STATE_JUMP_TO_BOOT, ///< Состояние: запуск приложения
} BootloaderState_t;
/**
* @brief Ошибки бутлоадера
*/
typedef union {
uint16_t all; ///< Все ошибки одним числом
struct {
unsigned hardfault_cycle:1; ///< Прерывание HardFault
unsigned memmanage_cycle:1; ///< Прерывание MemManage
unsigned watchdog_reset:1; ///< Watchdog сброс
unsigned unknown_cmd:1; ///< Неизвестная команда
unsigned erase_err:1; ///< Ошибка стирания
unsigned write_err:1; ///< Ошибка записи
unsigned verify_err:1; ///< Ошибка проверки прошивки
unsigned timeout_receive:1; ///< Таймаут приёма
unsigned crc_err:1; ///< Ошибка CRC
} bit;
} BootloaderError_t;
/**
* @brief Дескриптор бутлоадера
*/
typedef struct {
BootloaderState_t state; ///< текущее состояние бутлоадера
BootloaderError_t error;
uint32_t addr; ///< текущий адрес прошивки
uint8_t fw_size; ///< размер прошивки
uint8_t fw_buffer[PAGE_SIZE]; ///< буфер для приема прошивки (UART/CAN)
uint32_t fw_len; ///< длина принятого пакета
uint32_t fw_crc; ///< контрольная сумма прошивки
UART_HandleTypeDef *huart; ///< хендлер UART
CAN_HandleTypeDef *hcan; ///< хендер CAN
CAN_TxHeaderTypeDef TxHeader; ///< Заголовок CAN сообщения для отправки
BootloaderState_t prev_state; ///< предыдущее состояние бутлоадера
} Bootloader_t;
/* Основная задача бутлоадера */
void Bootloader_Task(Bootloader_t *bl);
/* Настройка тактирования */
void Boot_SystemClock_Config(void);
/* Хендлер ошибки */
void Error_Handler(void);
#endif //__BOOTLOADER_H