изменена логика ожидания посылок по uart. теперь реагируем только на валидные команды, а при получении мусорных байт не реагируем и в конце концов выходим. команда для full erase стала более сложной
This commit is contained in:
parent
dac54a68e3
commit
fbe1a5a3ce
114
src/bootloader.c
114
src/bootloader.c
@ -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,19 +134,17 @@ uint16_t Bootloader_UART_ReadByte()
|
|||||||
/* Обработчик ошибок */
|
/* Обработчик ошибок */
|
||||||
void Bootloader_ErrorHandler()
|
void Bootloader_ErrorHandler()
|
||||||
{
|
{
|
||||||
|
switch (hBootloader.error)
|
||||||
|
{
|
||||||
|
case ERROR_TIMEOUT:
|
||||||
|
if (UART_0->FLAGS & UART_FLAGS_ORE_M)
|
||||||
|
UART_0->FLAGS |= UART_FLAGS_ORE_M;
|
||||||
|
|
||||||
switch (hBootloader.error)
|
go_to_spifi(); // переход в основную программу, если в течение TIMEOUT_VALUE нет принятых данных
|
||||||
{
|
break;
|
||||||
case ERROR_TIMEOUT:
|
}
|
||||||
Bootloader_UART_WriteByte(NACK);
|
|
||||||
if (UART_0->FLAGS & UART_FLAGS_ORE_M)
|
|
||||||
{
|
|
||||||
UART_0->FLAGS |= UART_FLAGS_ORE_M;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hBootloader.error = ERROR_NONE;
|
hBootloader.error = ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPIFI_HandleTypeDef spifi = {.Instance = SPIFI_CONFIG};
|
SPIFI_HandleTypeDef spifi = {.Instance = SPIFI_CONFIG};
|
||||||
@ -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:
|
||||||
Bootloader_UART_WriteByte(ACK); // Подтвердить команду
|
validCommandsTimeout = 0; // Сброс таймаута валидных команд
|
||||||
|
eraseChipBufferIndex = 0;
|
||||||
|
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:
|
||||||
Bootloader_UART_WriteByte(ACK); // Подтвердить команду
|
validCommandsTimeout = 0; // Сброс таймаута валидных команд
|
||||||
Bootloader_UART_ReadPackage(); // Получить пакет и скопировать его в RAM
|
eraseChipBufferIndex = 0;
|
||||||
|
Bootloader_UART_WriteByte(ACK); // Подтвердить команду
|
||||||
|
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;
|
|
||||||
|
|
||||||
case FULL_ERASE:
|
|
||||||
if (erase_chip(&spifi) != HAL_OK)
|
|
||||||
Bootloader_UART_WriteByte(NACK);
|
|
||||||
else
|
|
||||||
Bootloader_UART_WriteByte(ACK);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// Вычислить ожидаемый байт команды 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)
|
||||||
|
Bootloader_UART_WriteByte(NACK);
|
||||||
|
else
|
||||||
|
Bootloader_UART_WriteByte(ACK); // Подтвердить успешную очистку
|
||||||
|
eraseChipBufferIndex = 0; // Сброс индекса для следующего приема
|
||||||
|
}
|
||||||
|
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,23 +367,10 @@ 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)
|
||||||
{
|
{
|
||||||
/* code */
|
/* code */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user