добавлена проверка - действительно ли страница данных записана во flash память. Если не записана, загрузчику отправляется NACK
This commit is contained in:
parent
f287926a95
commit
a72731ad2b
@ -42,7 +42,7 @@ typedef enum
|
|||||||
{
|
{
|
||||||
ERROR_NONE = 0,
|
ERROR_NONE = 0,
|
||||||
ERROR_TIMEOUT = 1, // Время ожидания истекло
|
ERROR_TIMEOUT = 1, // Время ожидания истекло
|
||||||
ERROR_CRC
|
ERROR_CRC, // Ошибка при получении строки hex от ПК или при записи страницы данных на flash
|
||||||
} Bootloader_error;
|
} Bootloader_error;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -192,6 +192,22 @@ uint32_t rel_addr = 0; // адрес от начала области spifi, п
|
|||||||
#define TAIL_SIZE 15 // если попадутся строки хекса, в которых не 16 байт, то мы рискуем записать данные уарта мимо буфера package_data. а если больше 16 байт, то это проблема завтрашнего дня
|
#define TAIL_SIZE 15 // если попадутся строки хекса, в которых не 16 байт, то мы рискуем записать данные уарта мимо буфера package_data. а если больше 16 байт, то это проблема завтрашнего дня
|
||||||
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
|
||||||
|
uint8_t read_data[MAX_PACKAGE_SIZE] = {0};
|
||||||
|
|
||||||
|
bool page_data_is_written(void)
|
||||||
|
{
|
||||||
|
// читаем ту же страницу в другой буфер
|
||||||
|
memset(read_data, 0xFF, MAX_PACKAGE_SIZE);
|
||||||
|
HAL_SPIFI_W25_ReadData(&spifi, (uint32_t)hBootloader.address, MAX_PACKAGE_SIZE, read_data);
|
||||||
|
// побайтово сравниваем содержимое двух буферов
|
||||||
|
for (uint16_t i = 0; i < MAX_PACKAGE_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (read_data[i] != page_data[i])
|
||||||
|
// если не сходится хоть один байт, прерываем проверку
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void mem_write()
|
void mem_write()
|
||||||
{
|
{
|
||||||
@ -202,18 +218,27 @@ void mem_write()
|
|||||||
|
|
||||||
// записываем страницу в 256 байт в spifi
|
// записываем страницу в 256 байт в spifi
|
||||||
HAL_SPIFI_W25_PageProgram(&spifi, (uint32_t)hBootloader.address, MAX_PACKAGE_SIZE, page_data);
|
HAL_SPIFI_W25_PageProgram(&spifi, (uint32_t)hBootloader.address, MAX_PACKAGE_SIZE, page_data);
|
||||||
|
|
||||||
|
// проверить, записалось ли действительно содержимое буфера
|
||||||
|
if (!page_data_is_written())
|
||||||
|
{
|
||||||
|
// если не записалось, выставим ошибку по crc и выходим
|
||||||
|
hBootloader.error = ERROR_CRC;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// увеличиваем адреса, по которым писать и стирать
|
// увеличиваем адреса, по которым писать и стирать
|
||||||
hBootloader.address += MAX_PACKAGE_SIZE;
|
hBootloader.address += MAX_PACKAGE_SIZE;
|
||||||
// обнуляем часть буфера, которая была записана в память и уменьшаем счетчик заполнения буфера на столько, сколько было записано
|
// очищаем часть буфера, которая была записана в память и уменьшаем счетчик заполнения буфера на столько, сколько было записано
|
||||||
if (page_fill_size <= MAX_PACKAGE_SIZE)
|
if (page_fill_size <= MAX_PACKAGE_SIZE)
|
||||||
page_fill_size = 0;
|
page_fill_size = 0;
|
||||||
else
|
else
|
||||||
page_fill_size -= MAX_PACKAGE_SIZE;
|
page_fill_size -= MAX_PACKAGE_SIZE;
|
||||||
memset(&page_data[0], 0, MAX_PACKAGE_SIZE);
|
memset(&page_data[0], 0xFF, MAX_PACKAGE_SIZE);
|
||||||
// хвост копируем в начало буфера, чтобы записать его в следующий раз
|
// хвост копируем в начало буфера, чтобы записать его в следующий раз
|
||||||
memcpy(&page_data[0], &page_data[MAX_PACKAGE_SIZE], TAIL_SIZE);
|
memcpy(&page_data[0], &page_data[MAX_PACKAGE_SIZE], TAIL_SIZE);
|
||||||
// а сам хвост обнуляем
|
// а сам хвост очищаем
|
||||||
memset(&page_data[MAX_PACKAGE_SIZE], 0, TAIL_SIZE);
|
memset(&page_data[MAX_PACKAGE_SIZE], 0xFF, TAIL_SIZE);
|
||||||
}
|
}
|
||||||
void Bootloader_parseHexAndLoadInMemory(uint8_t rx_data[])
|
void Bootloader_parseHexAndLoadInMemory(uint8_t rx_data[])
|
||||||
{
|
{
|
||||||
@ -235,7 +260,7 @@ void Bootloader_parseHexAndLoadInMemory(uint8_t rx_data[])
|
|||||||
memcpy(&page_data[page_fill_size], &rx_data[DATA_POS], rx_data[BYTE_COUNT_POS]);
|
memcpy(&page_data[page_fill_size], &rx_data[DATA_POS], rx_data[BYTE_COUNT_POS]);
|
||||||
// указываем, на сколько заполнился буфер
|
// указываем, на сколько заполнился буфер
|
||||||
page_fill_size += rx_data[BYTE_COUNT_POS];
|
page_fill_size += rx_data[BYTE_COUNT_POS];
|
||||||
// если пора записывать целую страницу - пишемм
|
// если пора записывать целую страницу - пишем
|
||||||
if (page_fill_size >= 256)
|
if (page_fill_size >= 256)
|
||||||
mem_write();
|
mem_write();
|
||||||
break;
|
break;
|
||||||
@ -244,7 +269,12 @@ void Bootloader_parseHexAndLoadInMemory(uint8_t rx_data[])
|
|||||||
Bootloader_UART_WriteByte(ACK);
|
Bootloader_UART_WriteByte(ACK);
|
||||||
// если есть недозаполненная страница, записываем ее как есть
|
// если есть недозаполненная страница, записываем ее как есть
|
||||||
if (page_fill_size != 0)
|
if (page_fill_size != 0)
|
||||||
|
{
|
||||||
mem_write();
|
mem_write();
|
||||||
|
// если при записи остатков возникли ошибки, здесь в основную программу не будем переходить
|
||||||
|
if (hBootloader.error)
|
||||||
|
return;
|
||||||
|
}
|
||||||
// и идем в записанную программу
|
// и идем в записанную программу
|
||||||
go_to_spifi();
|
go_to_spifi();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user