отправка ошибок бутлоадера по uart/can проверка crc принятой страницы проверка на бесконечное попадание в hardfault в целом структура бута все еще в процессе разработки
98 lines
2.8 KiB
C
98 lines
2.8 KiB
C
#include "boot_uart.h"
|
||
|
||
UART_HandleTypeDef huart_boot;
|
||
|
||
/**
|
||
* @brief Инициализация UART для бутлоадера
|
||
* @note Использует USART3, PB10 (TX), PB11 (RX)
|
||
*/
|
||
void MX_BOOT_UART_Init(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||
|
||
/* Включаем тактирование */
|
||
__RCC_UART_BOOT_CLK_ENABLE();
|
||
__RCC_UART_PORT_CLK_ENABLE();
|
||
|
||
/* Настройка GPIO TX/RX */
|
||
GPIO_InitStruct.Pin = UART_PIN_TX | UART_PIN_RX;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||
HAL_GPIO_Init(UART_PORT, &GPIO_InitStruct);
|
||
|
||
/* Настройка UART */
|
||
huart_boot.Instance = UART_BOOT;
|
||
huart_boot.Init.BaudRate = UART_SPEED;
|
||
huart_boot.Init.WordLength = UART_WORDLENGTH_8B;
|
||
huart_boot.Init.StopBits = UART_STOPBITS_1;
|
||
huart_boot.Init.Parity = UART_PARITY_NONE;
|
||
huart_boot.Init.Mode = UART_MODE_TX_RX;
|
||
huart_boot.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||
huart_boot.Init.OverSampling = UART_OVERSAMPLING_16;
|
||
|
||
if (HAL_UART_Init(&huart_boot) != HAL_OK)
|
||
{
|
||
Error_Handler(); // твоя функция обработки ошибок
|
||
}
|
||
}
|
||
|
||
// -----------------------------
|
||
// UART: приём страницы + CRC
|
||
// -----------------------------
|
||
void Bootloader_UART_Receive_Page(Bootloader_t *bl)
|
||
{
|
||
uint16_t bytes_received = 0;
|
||
uint8_t crc_buf[4];
|
||
HAL_StatusTypeDef res;
|
||
uint32_t start_tick = HAL_GetTick(); // старт таймера
|
||
|
||
// Приём данных страницы
|
||
while(bytes_received < PAGE_SIZE)
|
||
{
|
||
uint8_t byte = 0;
|
||
res = HAL_UART_Receive(bl->huart, &byte, 1, 100); // блокирующий приём 100ms
|
||
|
||
if(res == HAL_OK)
|
||
{
|
||
bl->fw_buffer[bytes_received++] = byte;
|
||
start_tick = HAL_GetTick(); // сброс таймера при успешном приёме
|
||
}
|
||
else
|
||
{
|
||
// проверка таймаута
|
||
if(HAL_GetTick() - start_tick >= FW_RECEIVE_TIMEOUT_MS)
|
||
{
|
||
bl->error.bit.timeout_receive = 1;
|
||
bl->state = BL_STATE_ERROR; // превышен таймаут
|
||
return;
|
||
}
|
||
// иначе просто ждем следующего байта
|
||
}
|
||
}
|
||
|
||
// Приём CRC (4 байта)
|
||
for(uint8_t i = 0; i < 4; i++)
|
||
{
|
||
res = HAL_UART_Receive(bl->huart, &crc_buf[i], 1, 100);
|
||
if(res == HAL_OK)
|
||
{
|
||
start_tick = HAL_GetTick(); // сброс таймера
|
||
}
|
||
else
|
||
{
|
||
if(HAL_GetTick() - start_tick >= FW_RECEIVE_TIMEOUT_MS)
|
||
{
|
||
bl->error.bit.timeout_receive = 1;
|
||
bl->state = BL_STATE_ERROR;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Сохраняем CRC в структуру
|
||
bl->fw_crc = (crc_buf[0] << 24) | (crc_buf[1] << 16) | (crc_buf[2] << 8) | crc_buf[3];
|
||
bl->fw_len = bytes_received;
|
||
bl->state = BL_STATE_IDLE;
|
||
}
|