#ifndef __BOOTLOADER_H #define __BOOTLOADER_H #include "boot_project_setup.h" #include "string.h" #define BL_KEY_APP_WRITTEN 0xAAAA5555 /* --- Настройка: подставьте значения для вашей MCU --- */ /* Адрес начала приложения (используется в вашем коде) */ #ifndef MAIN_APP_START_ADR #error "MAIN_APP_START_ADR must be defined" #endif /* Если нужен другой полином/поведение CRC, используйте вашу функцию CRC32_Compute. В вашем коде уже есть CRC32_Compute, поэтому будем её использовать. */ #define GetErrorCode() BKP->DR1 #define GetErrorCnt() BKP->DR2 #define SaveErrorCode(code) do{ \ RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); \ PWR->CR |= PWR_CR_DBP; \ GetErrorCode() = code; \ GetErrorCnt() = GetErrorCnt() + 1; \ }while(0u); #define ClearErrorCode(code) do{ \ RCC->APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); \ PWR->CR |= PWR_CR_DBP; \ GetErrorCode() = 0; \ GetErrorCnt() = 0; \ }while(0u); // ERROR DEFINES /** * @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; unsigned memmanage_cycle:1; unsigned watchdog_reset:1; unsigned unknown_cmd:1; unsigned erase_err:1; unsigned write_err:1; unsigned verify_err:1; unsigned timeout_receive:1; unsigned crc_err:1; }bit; } BootloaderError_t; 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; extern uint32_t TxMailBoxBoot; extern uint8_t TXDataBoot[8]; void ResetKey(void); void JumpToBootloader(void); void App_Init(void); void Bootloader_Task(Bootloader_t *bl); void Error_Handler(void); #endif //__BOOTLOADER_H