изменена логика ожидания посылок по uart. теперь реагируем только на валидные команды, а при получении мусорных байт не реагируем и в конце концов выходим. команда для full erase стала более сложной

This commit is contained in:
klassents 2024-09-10 15:31:12 +07:00
parent dac54a68e3
commit fbe1a5a3ce

View File

@ -24,11 +24,12 @@
#define TIMEOUT_VALUE 1000000 /* Время ожидания загрузчика до прыжка по умолчанию в RAM 1000000 */ #define TIMEOUT_VALUE 1000000 /* Время ожидания загрузчика до прыжка по умолчанию в RAM 1000000 */
/* Виды команд */ /* Виды команд */
#define FULL_ERASE_CMD_LEN 4
typedef enum typedef enum
{ {
PACKAGE_SIZE = 0x30, /* Команда размера пакета */ PACKAGE_SIZE = 0x30, /* Команда размера пакета */
SEND_PACKAGE = 0x60, /* Команда отправить пакет */ SEND_PACKAGE = 0x60, /* Команда отправить пакет */
FULL_ERASE = 0xFE /* Команда стирания spifi */ FULL_ERASE = 0xBADC0FEE /* Команда стирания spifi */
} BotloaderComand; } BotloaderComand;
typedef enum typedef enum
@ -51,8 +52,11 @@ typedef struct
uint8_t command; // Текущая принятая загрузчиком команда uint8_t command; // Текущая принятая загрузчиком команда
} Bootloader_attributes; } Bootloader_attributes;
Bootloader_attributes hBootloader = {(uint8_t*) SPIFI_ADDRESS, MAX_PACKAGE_SIZE, ERROR_NONE, 0}; Bootloader_attributes hBootloader = {(uint8_t*) SPIFI_ADDRESS, 0, ERROR_NONE, 0};
uint32_t timeout = 0; uint32_t timeout = 0;
uint32_t validCommandsTimeout = 0;
void go_to_spifi();
/* Инициализация UART */ /* Инициализация UART */
@ -116,6 +120,7 @@ uint16_t Bootloader_UART_ReadByte()
while ((!(UART_0->FLAGS & UART_FLAGS_RXNE_M)) && (timeout != TIMEOUT_VALUE)) while ((!(UART_0->FLAGS & UART_FLAGS_RXNE_M)) && (timeout != TIMEOUT_VALUE))
{ {
timeout++; timeout++;
validCommandsTimeout++; // Увеличить таймаут валидных команд
} }
if (timeout == TIMEOUT_VALUE) if (timeout == TIMEOUT_VALUE)
@ -129,15 +134,13 @@ uint16_t Bootloader_UART_ReadByte()
/* Обработчик ошибок */ /* Обработчик ошибок */
void Bootloader_ErrorHandler() void Bootloader_ErrorHandler()
{ {
switch (hBootloader.error) switch (hBootloader.error)
{ {
case ERROR_TIMEOUT: case ERROR_TIMEOUT:
Bootloader_UART_WriteByte(NACK);
if (UART_0->FLAGS & UART_FLAGS_ORE_M) if (UART_0->FLAGS & UART_FLAGS_ORE_M)
{
UART_0->FLAGS |= UART_FLAGS_ORE_M; UART_0->FLAGS |= UART_FLAGS_ORE_M;
}
go_to_spifi(); // переход в основную программу, если в течение TIMEOUT_VALUE нет принятых данных
break; break;
} }
@ -163,7 +166,6 @@ uint8_t erase_chip(SPIFI_HandleTypeDef *spifi)
/* Загрузить данные пакета в RAM */ /* Загрузить данные пакета в RAM */
#define SIZE_4K 4096 #define SIZE_4K 4096
// разметка строки в хекс-файле // разметка строки в хекс-файле
#define BYTE_COUNT_POS 0 // индекс счетчика байт данных #define BYTE_COUNT_POS 0 // индекс счетчика байт данных
#define ADDRES_POS 1 // индекс адреса #define ADDRES_POS 1 // индекс адреса
@ -171,7 +173,7 @@ uint8_t erase_chip(SPIFI_HandleTypeDef *spifi)
#define RECORD_TYPE_POS 3 // индекс типа записи #define RECORD_TYPE_POS 3 // индекс типа записи
#define DATA_POS 4 // индекс начала данных в команде #define DATA_POS 4 // индекс начала данных в команде
// типы записей в хекс-фйле // типы записей в хекс-файле
#define REC_TYPE_DATA 0x00 #define REC_TYPE_DATA 0x00
#define REC_TYPE_EOF 0x01 #define REC_TYPE_EOF 0x01
#define REC_TYPE_EXT_LIN_ADDR 0x04 #define REC_TYPE_EXT_LIN_ADDR 0x04
@ -182,8 +184,6 @@ uint32_t rel_addr = 0; // адрес от начала области spifi, п
uint8_t page_data[MAX_PACKAGE_SIZE + TAIL_SIZE] = {0}; // сюда собираем распарсенные данные из хекса uint8_t page_data[MAX_PACKAGE_SIZE + TAIL_SIZE] = {0}; // сюда собираем распарсенные данные из хекса
uint16_t page_fill_size = 0; // счетчик, сколько заполнно в page_data. когда page_data заполнена до конца - будем записывать в spifi uint16_t page_fill_size = 0; // счетчик, сколько заполнно в page_data. когда page_data заполнена до конца - будем записывать в spifi
void go_to_spifi();
void mem_write() void mem_write()
{ {
// если адрес дошел до начала нового сектора, стираем новый сектор // если адрес дошел до начала нового сектора, стираем новый сектор
@ -270,47 +270,63 @@ void Bootloader_UART_ReadPackage()
} }
} }
uint8_t eraseChipBufferIndex = 0; // Индекс для накопления команды erase chip
void Bootloader_Commands() void Bootloader_Commands()
{ {
while (1) while (1)
{ {
hBootloader.command = Bootloader_UART_ReadByte(); // Ожидание и считывание команды hBootloader.command = Bootloader_UART_ReadByte(); // Ожидание и считывание команды
// если долго не приходили валидные команды, переход в основную программу
if (validCommandsTimeout >= TIMEOUT_VALUE)
go_to_spifi();
if (hBootloader.error) if (hBootloader.error)
{
Bootloader_ErrorHandler(); // Обработчик ошибок Bootloader_ErrorHandler(); // Обработчик ошибок
}
else else
{ {
switch (hBootloader.command) switch (hBootloader.command)
{ {
case PACKAGE_SIZE: case PACKAGE_SIZE:
validCommandsTimeout = 0; // Сброс таймаута валидных команд
eraseChipBufferIndex = 0;
Bootloader_UART_WriteByte(ACK); // Подтвердить команду Bootloader_UART_WriteByte(ACK); // Подтвердить команду
hBootloader.size_package = Bootloader_UART_ReadByte() + 1; // Прочитать размер пакета hBootloader.size_package = Bootloader_UART_ReadByte() + 1; // Прочитать размер пакета
Bootloader_UART_WriteByte(ACK); // Подтвердить Bootloader_UART_WriteByte(ACK); // Подтвердить
break; break;
case SEND_PACKAGE: case SEND_PACKAGE:
validCommandsTimeout = 0; // Сброс таймаута валидных команд
eraseChipBufferIndex = 0;
Bootloader_UART_WriteByte(ACK); // Подтвердить команду Bootloader_UART_WriteByte(ACK); // Подтвердить команду
Bootloader_UART_ReadPackage(); // Получить пакет и скопировать его в RAM Bootloader_UART_ReadPackage(); // Получить пакет и скопировать его в RAM
if (hBootloader.error) if (hBootloader.error)
{
Bootloader_ErrorHandler(); // Обработчик ошибок Bootloader_ErrorHandler(); // Обработчик ошибок
}
else else
{
Bootloader_UART_WriteByte(ACK); // Подтвердить считывание и копирования пакета в RAM Bootloader_UART_WriteByte(ACK); // Подтвердить считывание и копирования пакета в RAM
}
break; break;
default:
case FULL_ERASE: // Вычислить ожидаемый байт команды FULL_ERASE на основе текущего индекса
uint8_t expectedByte = (FULL_ERASE >> ((FULL_ERASE_CMD_LEN - eraseChipBufferIndex - 1) * 8)) & 0xFF;
// Если полученный байт совпадает с ожидаемым байтом команды FULL_ERASE
if (hBootloader.command == expectedByte)
{
// Переход к следующему байту
eraseChipBufferIndex++;
// Если команда FULL_ERASE полностью получена
if (eraseChipBufferIndex == FULL_ERASE_CMD_LEN)
{
Bootloader_UART_WriteByte(ACK); // Подтвердить получение команды
// Очистка чипа
if (erase_chip(&spifi) != HAL_OK) if (erase_chip(&spifi) != HAL_OK)
Bootloader_UART_WriteByte(NACK); Bootloader_UART_WriteByte(NACK);
else else
Bootloader_UART_WriteByte(ACK); Bootloader_UART_WriteByte(ACK); // Подтвердить успешную очистку
break; eraseChipBufferIndex = 0; // Сброс индекса для следующего приема
default: }
validCommandsTimeout = 0; // Сброс таймаута валидных команд
}
else // Если байт не совпал ни с какими валидными командами
eraseChipBufferIndex = 0; // Сброс индекса команды FULL_ERASE
break; break;
} }
} }
@ -320,7 +336,6 @@ void Bootloader_Commands()
void SystemClock_Config(); void SystemClock_Config();
int main() int main()
{ {
SystemClock_Config(); SystemClock_Config();
@ -352,22 +367,9 @@ int main()
HAL_SPIFI_SendCommand_LL(&spifi, cmd_qpi_disable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT); HAL_SPIFI_SendCommand_LL(&spifi, cmd_qpi_disable, 0, 0, 0, 0, 0, HAL_SPIFI_TIMEOUT);
#endif #endif
Bootloader_UART_Init(); // Инициализация UART. НАстройка выводов и тактирования Bootloader_UART_Init(); // Инициализация UART. Настройка выводов и тактирования
timeout = 0; Bootloader_Commands(); // Обработка и ожидание команд
while ((!(UART_0->FLAGS & UART_FLAGS_RXNE_M)) && (timeout != TIMEOUT_VALUE)) // Загрузчик ожидает команду
{
timeout++;
}
if (timeout == TIMEOUT_VALUE)
{
go_to_spifi();
}
else
{
Bootloader_Commands(); // Обработка и ожидания команд
}
while (1) while (1)
{ {