UKSVEP_23550.2/Core/Bootloader/boot_uart.c
Razvalyaev 320cce09ec сделано (проверено на can):
отправка ошибок бутлоадера по uart/can
проверка crc принятой страницы
проверка на бесконечное попадание в hardfault

в целом структура бута все еще в процессе разработки
2025-09-11 16:57:20 +03:00

98 lines
2.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.

#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;
}