Если вдруг хочется написать свой бутлоадер или встроенный самообновлятор ПО, то непременно нужно уметь перезаписывать флеш-память.
Микроконтроллеры STM32 предоставляют такую возможность, впрочем, как и все современные микроконтроллеры.
читать дальшеПо умолчанию любая флеш-память стёрта: то есть все байты читаются как 0xFF. Контроллер умеет при записи превращать любые выбранные единицы в нолики, и только. Вне зависимости от того, что содержится в других битах. Обратно же вернуть единицу может только полное стирание сектора.
Секторов во встроенной флеш-памяти совсем немного: 12 штук для МК с памятью 1 мегабайт. В новых контроллерах (F2xx/F3xx), где памяти больше (до двух мегабайт), секторов тоже больше.
Сектора все разного размера. Первые 64 килобайта памяти разбиты на 4 сектора, по 16 килобайт. Потом идёт сектор размером уже 64 килобайта, весь остальной мегабайт забит секторами по 128 килобайт:
0. 0x08000000-0x08003FFF (16 кБ)
1. 0x08004000-0x08007FFF (16 кБ)
2. 0x08008000-0x0800BFFF (16 кБ)
3. 0x0800C000-0x0800FFFF (16 кБ)
4. 0x08010000-0x0801FFFF (64 кБ)
5. 0x08020000-0x0803FFFF (128 кБ)
6. 0x08040000-0x0805FFFF (128 кБ)
7. 0x08060000-0x0807FFFF (128 кБ)
8. 0x08080000-0x0809FFFF (128 кБ)
9. 0x080A0000-0x080BFFFF (128 кБ)
10. 0x080C0000-0x080DFFFF (128 кБ)
11. 0x080E0000-0x080FFFFF (128 кБ)
Как-то так. Второй мегабайт флеша секторно организован точно так же, как и первый. Если флеша меньше, то соответствующие сектора отсутствуют.
Сектор стирается целиком, по номеру. Программируется же произвольно. Размер записываемого определяется напряжением питания. Например, побайтово записывать можно при любом уровне напряжений. При нормальном напряжении (3 В) можно записывать по 4 байта за раз. Есть опции для записи по 2 или 8 байт за раз, но фиг с ними.
Потому первым делом после запуска скажем, по сколько байт мы будем записывать. Это определяет поле PSIZE в регистре FLASH_CR:
0b00 - 1 байт
0b01 - 2 байта
0b10 - 4 байта
0b11 - 8 байт
Но чтоб использовать регистр FLASH_CR и менять его, надо получить к нему доступ (по умолчанию он залочен намертво). Записываем в FLASH_KEYR два числа по очереди: сначала 0x45670123, а потом 0xCDEF89AB. Такой вот пассворд.
Для возвращения защиты вполне достаточно устновить флаг LOCK в регистре FLASH_CR:
Стирание осуществляется так:
1. На всякий случай проверяем отсутствие флага BSY в регистре FLASH_SR или ждём его сброса, если он всё же есть;
2. В регистре FLASH_CR, в поле SNB [3:6] указываем номер сектора, который мы хотим стереть;
3. В том же регистре указываем, что мы хотим стереть один сектор, установив флаг SER;
4. Начнём стирание, установив флаг STRT в регистре FLASH_CR;
5. Ожидаем сброса флага BSY в регистре FLASH_SR (UPD: правильнее ожидать появления флага EOP);
6. Снимаем флаг SER;
Программирование выполняется похожим образом:
1. На всякий случай проверяем отсутствие флага BSY в регистре FLASH_SR или ждём его сброса, если он всё же есть;
2. Указываем, что мы хотим программировать, установив флаг PG;
3. Записываем число выбранного размера (см. PSIZE) по любому (выровненному) адресу во флеш;
4. Ждём исчезновения флага BSY в регистре FLASH_CR (UPD: правильнее ожидать появления флага EOP);
5. Повторяем нужное количество раз.
6. Снимаем флаг PG;
Ну и надо не забывать снимать блокировку регистра на время этих операций.
Данный метод можно применять для обновления ПО, для хранения настроек или ещё для чего-нибудь.
В проекте примера во флеше хранятся настройки, в файле settings.h объявлена структура, описывающая способ хранения настроек в памяти и все поля. Есть переменная Settings, которая реализует эту структуру в оперативной памяти.
При запуске эта переменная инициализируется из флеша. Если код настроек не совпадает (Magic), значит, настроек нет и их нужно инициализировать, для чего вывзывается соответствующая функция. После изменения настроек и запроса на сохранение, содержимое переменной записывается во флеш.
В примере моргает зелёный светодиод, индицируя работу. По нажатию на кнопку меняется поле настроек (Settings.Value1) и сохраняется. Красный светодиод показывает состояние этой настройки, чтоб можно было увидеть, что и после сброса питания, всё сохраняется.
Пысы, флеш очень медленный при стирании и записи, так как сектора гигантские. Если настроек мало и подключена батарейка часовая, то лучше их хранить в Backup SRAM, это куда как быстрее. Но это отдельная тема.
И, если хотите вдруг делать обновлятор: передавайте и контрольную сумму для проверки корректности принятой прошивки. Ведь будет потом очень грустно, если будет пропущен или неправилен хотя бы один байт) И зашивать только в том случае, если вся целиком прошивка корректна и цела! Лучше уж не зашить ничего, чем зашить шлак.
Файлы:
flash.c
settings.c
test.c
main.c
Проект.
<< Предыдущее Следующее >>
STM32F4. FLASH
Если вдруг хочется написать свой бутлоадер или встроенный самообновлятор ПО, то непременно нужно уметь перезаписывать флеш-память.
Микроконтроллеры STM32 предоставляют такую возможность, впрочем, как и все современные микроконтроллеры.
читать дальше
<< Предыдущее Следующее >>
Микроконтроллеры STM32 предоставляют такую возможность, впрочем, как и все современные микроконтроллеры.
читать дальше
<< Предыдущее Следующее >>