Внутренняя flash-память

Встроенная flash-память может быть запрограммирована через ICP (in-circuit programming) или IAP (in-circuit programming). Первый предоставляется через разъём программирования JTAG/SWD, а второй, как не сложно догадаться, через приложение зашитое на МК. Цели программировать flash-память изнутри могут быть разными: от сохранения каких-либо настроек для последующих запусков, до перепрошивки устройства.

В данном случае, нас интересует именно сохранение настроек, например яркости экрана в дневное и ночное время1.

Детально процесс работы с памятью описан в документе «PM0075 Programming manual». В нём, а также в Reference Manual, можно найти таблицу с описанием размера страницы и их количество.

flash mem table

В зависимости от МК, размер страницы может быть разным и занимать, например, 2 Кб. Кроме того, все страницы объединены в блоки. В нашем случае он один, но в других моделях блоков может быть несколько.

Память разбита на три части.

Всеми операциями, будь то чтение, запись или блокировки управляет специальный контроллер Flash Program/Erase Controller (FPEC). Он отвечает за корректную работу с памятью. Особенность flash в stm32 заключается в том, что она работает не на той же частоте, что и ядро (у NXP, например, flash разгоняется до скорости ядра). Это позволяет делать МК немного дешевле, так как такая память дешевле/проще в производстве. В разделе про тактирование при настройке PLL мы использовали следующая строчка:

Согласно документации, встроенная память может работать корректно без каких либо ухищрений вплоть до 24 МГц (FLASH_Latency_0). При более высоких частотах контроллер должен вставлять пустую операцию, что бы операция чтения\записи успела завершиться. Для частот от 24 до 48 МГц вставляется один такт задержки (FLASH_Latency_1), для частот от 48 до 72 МГц два такта (FLASH_Latency_2).

Как же определить свободную страницу? Это зависит от размера прошивки. Проще всего использовать последнюю страницу в памяти (вы вряд ли умудритесь заполнить все 64 Кб). Мы, однако, для примера возьмём 16-тую страницу. Её адрес можно вычислить как [начальный адрес] + [номер страницы - 1] * [размер страницы].

Определим её в коде:

Особенность flash такова, что для перезаписи данных необходимо стереть всю страницу. Поэтому перед операцией записи скопируйте все ваши данные в буфер, затем внесите в него изменения, а только потом приступайте к записи непосредственно на flash. Пример с использованием стандартной библиотеки периферии.

flash data

Для удобства работы с настройками можно создать структуру. Сделайте это самостоятельно.

Считать данные можно написав вот такую функцию:

У flash-памяти есть лимит по количеству циклов перезаписи, 100 000 для stm32f1, после которого производитель не гарантирует сохранность данных. Вам правда придётся стирать и записывать в память примерно по 275 раз каждый день в течении года, чтобы достигнуть такого состояния. Тем не менее, в качестве тренировки вы можете попробовать написать модуль, который будите использовать в дальнейших проектах, где "распределение" нагрузки производится равномерно. Предположим у нас имеется следующая структура:

В памяти она занимает 16 байт (4 раза по 4 байта). По описанному выше принципу, все их можно сложить в памяти последовательно. При внесении изменений новые данные можно положить в следующие 16 байт, а не стирать каждый раз страницу. Далее нужно только определить, по какому адресу лежат актуальные настройки.


Назад | Оглавление | Дальше


1 В некоторых микроконтроллерах, например, AVR, или даже STM32L1-серии, присутствует модуль памяти EEPROM, которую можно использовать для сохранения пользовательских данных. Однако, в STM32F1-серии такого модуля нет.