Микроконтроллеры 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
Проект.
<< Предыдущее Следующее >>
@темы: arm, программизмы, электроника, stm32f4discovery, stm32
Спасибо большое за статью! Есть необходимость сделать собственный обновлятор. Я уже побаловался стиранием и записью во флешь и действительно ВСЕ работает вплоть до того что можно стереть свою же собственную прошивку своими руками! Вот только я одного не понял: Как же сделать свой обновлятор, если после стирания нулевого сектора, где хранится программа, МК уже ничего больше делать не может??? Если будет время и желание напишите пожалуйста мне на почту: [email protected] Спасибо!
Да и вообще хранить настройки в какой-нибудь внешней фрамке.
Почему-то не получается писать по 2 байта... запись по 4 идёт как по маслу, а при записи по 2 флеш остаётся чистым, хотя FLASH_CR настроил правильно.
В FLASH_CR записано 0x00000101.
Что за команда такая?
А вы как записываете по два байта? Похоже на то, что совсем неправильно: PGPERR: Programming parallelism error. Set by hardware when the size of the access (byte, half-word, word, double word) during the program sequence does not correspond to the parallelism configuration PSIZE (x8, x16, x32, x64).
сейчас сделал вот так:
и заработало.
наверно,из-за этого: u32 *D = (u32*)Address; потом пытаюсь в 4 байта писать - контроллер и ругается.
В первом варианте брались 16 бит, расширялись до 32 (тип D 32 битный) и записывались такой посылкой. Естественно, это флешу не нравилось, а если б и нравилось, всё равно было бы неправильно.
«When the read protection Level 1 is set:
– No access (read, erase, program) to Flash memory or backup SRAM can be
performed while the debug feature is connected or while booting from RAM or
system memory bootloader. A bus error is generated in case of read request.
– When booting from Flash memory, accesses (read, erase, program) to Flash
memory and backup SRAM from user code are allowed.»
Т.е. чтение и запись отключаются, если происходит запуск с отладочным прибором или из системного бутлоадера.
Если отладчиком прочитать нельзя да через системный бутлоадер тоже, то доступ к флешу только через вашу программу. А там уж как напишете. Можно только запись сделать, да ещё и с шифрованием...
Если отладчиком прочитать нельзя да через системный бутлоадер тоже, то доступ к флешу только через вашу программу. А там уж как напишете. Можно только запись сделать, да ещё и с шифрованием...
Если отладчиком прочитать нельзя да через системный бутлоадер тоже, то доступ к флешу только через вашу программу. А там уж как напишете. Можно только запись сделать, да ещё и с шифрованием...
У меня ещё вопрос, как из самой програмы проверить стоит ли зашита и включить её?
Мм, прочитать байт опций? Не помню, можно ль его записывать или нет (да можно, наверное)
Я иногда писать Вам не могу, пишет что "Администратор запретил вам публиковать ссылки в коментариях", хотя в моих сообщениях никаких ссылок нет.
PS: Я очень благодарен, что Вы не оставили меня без внимания.
Насчёт байт опций посмотрите в рефмане таблицу "Table 15. Description of the option bytes (STM32F405xx/07xx and STM32F415xx/17xx)" — там всё начинается с байта защиты.
Не знаю о.о Я о таком нитчего не знаю, ни о ссылках, ни о запрете. Может, это сайта админы знают.