Заметка про сохранение структур во flash памяти на STM32

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

При разработке проекта для микроконтроллера часто возникает необходимость сохранения данных во Flash-память перед выключением устройства, например глобальные структуры, содержащие информацию о настройках различной периферии, данные с внешних датчиков и прочее. В этом посте я хочу показать простой механизм записи структуры во FLASH память микроконтроллера STM32, которым я сам часто пользуюсь в своих проектах.   

Для начала рассмотрим работу с flash на контроллере STM32F103C8T6 (blue pill). Начнем с изучения документации. Смотрим, как разбита память, в reference manual, в разделе Embedded Flash memory. Либо можно подключить контроллер через программатор и посмотреть в Cube Programmer.

Таблица памяти из datasheet
Таблица памяти из datasheet

Память контроллера разбита на страницы объемом 1 Кбайт. В datasheet приведена длительность на операцию стирания - максимум 40 мс.

Тайминги работы с Flash на F103
Тайминги работы с Flash на F103

Пользовательская прошивка хранится в начале памяти, поэтому для записи данных я использую страницы с конца микроконтроллера. Будем писать в 126 страницу по адресу 0x0801F800. 127 страница остается как запасная, если данные не помещаются на одну страницу.

#define flashADDR   0x0801F800

Далее создадим структуру, содержимое которой будет записываться в ячейку памяти:

struct
{
	uint8_t  var1;
	uint16_t var2;
	uint32_t var3;
	double   var4;
} test_struct;

Заполняю ее случайными значениями:

test_struct.var1 = 200;
test_struct.var2 = 59999;
test_struct.var3 = 98765;
test_struct.var4 = 45.11;

Теперь перейдем к записи во Flash. Более подробно про это можно почитать тут и тут, но если коротко, то в начале нам необходимо разблокировать память, стереть нужную нам страницу, после уже произвести запись и заблокировать обратно. 

Создадим отдельную функцию и переменные:

uint8_t writeFlash (uint32_t addr)
{
	HAL_StatusTypeDef status;
	uint32_t structureSize = sizeof(test_struct);
	FLASH_EraseInitTypeDef FlashErase; 
	uint32_t pageError = 0;

После этого отключаем прерывания, чтобы не нарушать процесс записи и разблокируем память:

__disable_irq();
status = HAL_FLASH_Unlock();

Настроим процесс стирания - укажем, что удалять будем постранично (еще можно массово), с какого адреса начнем и сколько страниц это затронет. Последнее рассчитаем, исходя из размера структуры.

FlashErase.TypeErase = FLASH_TYPEERASE_PAGES;
FlashErase.PageAddress = addr; 
FlashErase.NbPages = structureSize / 1024 + 1; 

Теперь очистим необходимое нам пространство. Если случилась ошибка в процессе стирания, то закрываем память и сообщаем об этом.

if (HAL_FLASHEx_Erase(&FlashErase, &pageError) != HAL_OK)
	{
		HAL_FLASH_Lock(); 
		return HAL_ERROR;
	}

Теперь все готово к записи нашей структуры. Создаем указатель на неё и с помощью функции HAL_FLASH_Program записываем все её содержимое. Функция первым аргументом запрашивает, каким объемом будут писать данные - по 1, 2 или четырем байтам за раз (FLASH_TYPEPROGRAM_BYTE/HALFWORD/WORD соответственно). Забавно то, что дальше эта функция, вне зависимости от вашего выбора, будет писать строго по 2 байта

Источник: https://habr.com/ru/articles/791252/


Интересные статьи

Интересные статьи

Деструктурирующее присваивание в JavaScript — это изящный способ извлечения значений из массивов и объектов, при котором в полной мере реализуется принцип DRY (англ. Don’t repeat yourself — ...
В предыдущей части статьи, было рассказано об основных принципах работы и особенностях проектирования радаров для применения в дорожной инфраструктуре. Теперь попробуем разобраться с радарами для авто...
Во второй части публикации о составном устройстве USB я расскажу о том, как работает звуковое устройство USB, которое STM32CubeMX генерирует по умолчанию «из коробки», а также как подго...
Идём в глубь острова сокровищ с названием "Алгоритм". Читать дальше →
Мозг человека — очень сложная система. Даже для решения простейшей математической задачи мозг должен выполнить большое количество промежуточных операций. И для того, чтобы эти операции стали во...