Stm32 узнать объем памяти

Обновлено: 07.07.2024

Продолжаем тему программирования контроллера STM32F4.

И сегодня мы попробуем к данному контроллеру подключить последовательную FLASH-память серии W25Q.

Подключается такая память по интерфейсу SPI, а также по многопроводным интерфейсам Dual SPI, Quad SPI и QPI.

Мы же пока будем подключим данную микросхему по обычному интерфейсу SPI.

Краткие основные характеристики W25Q:

Потребляемая мощность и температурный диапазон:

  • Напряжение питания 2.7…3.6 В
  • Типичный потребляемый ток: 4 мА (активный режим), <1 мкА (в режиме снижения мощности)
  • Рабочий температурный диапазон -40°C…+85°C.

Гибкая архитектура с секторами размером 4 кбайт:

  • Посекторное стирание (размер каждого сектора 4 кбайт)
  • Блочное стирание (32кбайт и 64 кбайт)
  • Программирование от 1 до 256 байт
  • До 100 тыс. циклов стирания/записи
  • 20-летнее хранение данных

Максимальная частота работы микросхемы:

Есть ещё много различных возможностей, но это самые основные.

Также микросхема существует в различных корпусах, но в большинстве случаев распространён корпус SMD SO8.

Распиновка микросхемы следующая


Назначение каждого вывода:

В зависимости от типа подключения схема подключения микросхемы к контроллеру также может различаться.

В режиме обычного SPI подключение будет следующее:


Следует отметить, что микросхема W25Q устроена так же как FLASH-память у stm32, то есть память у неё разбита на страницы по 256 байт, страницы объединены в секторы по 4096 байт, а секторы в блоки по 65536 байт. Организацию памяти микросхемы можно посмотреть на схеме


Перед тем как что-то записать, нужно стереть сектор (4096 байт) или блок (65536 байт). Можно стереть несколько секторов или блоков, или весь чип полностью. Во время стирания ячейки заполняются значениями 0xFF.

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


Подключим нашу микросхему к отладочной плате


Подключим отладочную плату к USB компьютера и приступим к проекту, который мы сегодня сделаем с нуля.

Запустим Cube MX создадим проект, выбрав для начала контроллер



Включим HSE и задействуем кварцевый резонатор


В Clock Configuration внесем следующие настройки


Включим USART1, оставив все его настройки по умолчанию


У нас включились необходимые ножки



Увеличим делитель, так как у нас длинные провода, да и скорость нам сейчас не нужна



Увеличим скорость данной ножки, так как вдруг потом мы всё же решимся поднять частоту SPI

Где то с месяц назад заметил интересный момент на stm32, на разных камнях, дело в объеме флеша. На новизну не претендую, просто нигде на глаза не попадалась информация об этом.

Начну издалека, в STM32 ST-LINK utility, есть два окошечка над отображением содержания прошивки: Address и Size. Собственно при чтении камня он читает начиная с Address размер Size (в байтах), если указать размер больше, чем есть в камне, то он в процессе чтения сругается, мол не могу прочитать такой то адрес, тоесть он не проверяет размер для читаемого камня (который пишет в окне логов при подключении к камню), а читает сколько сможет. Поскольку подключаю разные камни, размер указываю на 1 мегабайт, пусть читает все а я уже найду что мне надо. Где то месяц назад обратил внимание что на stm32f103C8 он читает не 64 килобайта а 128 килобайт (хотя по даташиту там 64), провел эксперимент, записал в эту область свои данные, переподключил, данные на месте о_О К сожалению нет свободного времени нормально проверить эту «дополнительную» память на камнях из кода, думал проверю да поделюсь, да вот месяц прошел, а найти на это время я не смог, поэтому выкладываю свои наблюдения в «сыром» виде. Сразу оговорюсь, не стоит на эту память надеяться в серийном производстве и не факт что эту «дополнительную» память вы найдете у себя, возможно мне такая партия досталась, на это можно рассчитывать в собственных поделках или там где вы можете все камни проверить и если «не повезло», заменить без ущерба для себя. Но мне кажется все дело в тех процессах, им дешевле сделать не серии 16/32/64/128/256/512/1024… а обойтись 32/128/256/1024, как то так. Мои наблюдения между делом показали что у sm32f030f4 вместо 16 килобайт в наличии 32 килобайта, у stm32f103c8 вместо 64 килобайт — 128, у stm32f407ve вместо 512 — 1024, хотя в области размера флеша находится значение 512. Насчет наличия бОльшего SRAM вообще никак не проверял, хотя тоже возможно…
Дак вот, к чему я об этом пишу, у кого есть время и возможность проверьте пожалуйста «доступность» этой «дополнительной» памяти для прошивки МК, если она конечно вообще существует в реальности, а не в моей фантазии… и отпишитесь, думаю тем, кто собирает что то для себя будет полезно. И еще уже многие видели st-link на stm32f101, есть мысль что серия 101,102,103 на самом деле имеет одну и ту же начинку, а их разделение на серии происходит на этапе тестирования образцов перед маркировкой (лучшее в 103, похуже 102, слабые 101)… но и это лишь мои мысли…

Комментарии ( 54 )

Это, в общем, не новость. На казусе уже обсуждалось. STM производит не так много кристаллов и, по видимому, сортирует их по соответствию параметрам.
Алсо я слышал, что камни рапортуют программатору реальный размер флеша, а не тот, что должен быть по маркировке.
Использовать «бонусный контент» можно, но без каких-либо гарантий.
Ну и да, судя по всему, 101-я серия — отбраковка из 103-й, насчет 102 — не знаю.

напишите, пожалуйста, ссылку где это обсуждалось, почитаю на досуге =)

С 102 та же ситуация. Лично игрался с партией 102(по маркировке), а на самом деле определялись отладчиком как 103. И RAM было действительно больше и она работала.

Никогда не используйте недокументированные возможности, чтобы не чесать потом репу типа «почему на одном камне работает, а на другом не робит». Прога Stlink написана криво- читает те адреса, которые забиваешь ручками. 21 век, а автоопределение размера флеша сделать не могут… Хотя в окошечке «Flash Size» размер памяти определяется верно.

В STM32F100C4 реально 32к флеша. Сильно подозреваю, что реальный ассортимент кристаллов соответсвует набору дефайнов в CMSIS — т.е где-то 4 штуки, LD, MD, HD и XD. Серий тоже меньше, чем кажется — 101 по начинке соответствует 103.
Вероятно, типичная отбраковка — примерно как младшие серии CPU/GPU для компов.
В одном ты прав — использовать это не следует. Впрочем, в чисто любительских целях можно при желании потратить время на тестирование и заюзать недокументированные бонусы.

Разбираемся как устроена память микроконтроллера на примере STM32F205VGT6.

Так же мы используем CubeMX для подготовки проекта.

Где хранятся данные , где стек, где код программы?

Генерим сначала пустой проект оставляет только пустой main().

читаем ld файл

Linker script for STM32F205VG Device with ** 1024KByte FLASH, 128KByte RAM.

ld файл это основа, здесь CubeMx прописывает все исходные параметры памяти, стека, кода. Именно его надо спокойно/внимательно изучить, здесь все очевидно на самом деле.

Стек в микроконтроллерах на ядрах ARM растёт сверху вниз.

RAM по даташиту Up to 128 + 4 Kbytes of SRAM. То есть есть еще какие-то 4Kb SRAM в конце.

Стек располагается отдельно от остальных блоков памяти, в конце ОЗУ. Конец ОЗУ по мнению CubeMX это 0x20020000=..131072 примерно (128+4Kb).

Для контроля минимальных запасов стека и кучи в CubeMX есть такие установки

(_user_heap_stack = _Min_Heap_Size + _Min_Stack_Size )

list полезный по информации файл на выходе сборки

.text — /* The program code and other data goes into FLASH */ , это скомпилированный машинный код - помещается во FLASH;
.data — /* Initialized data sections goes into RAM, load LMA copy after code */ - Переменные, это помещается в RAM; и зачем-то копия помещается еще во FLASH.
.rodata — /* Constant data goes into FLASH */ - аналог .data для неизменяемых данных, но помещается во FLASH;
.bss — /* Uninitialized data section */ , глобальные и статические переменные, которые при старте содержат нулевое значение - помещаются в RAM.

Момент истины

Как вдруг я понял это безобразие : FLASH может содержать только неизменяемые данные , т.е. их нельзя в процессе исполнения перезаписать. (FLASH (rx) ) rx = read +execute . Отсюда и идет весь этот винигред.

ld файл все прописывает где и куда какие данные сохранить

>RAM - это помещается в RAM !

файл startup_stm32f205xx.s

Этот файл генерируется CubeMX. Он на ассемблере.

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

Теперь для закрепления понимания поэкспериментируем

Эффекта изменения распределения памяти не произойдет

Сделаем так : char buf[10000]=; - ничего не меняется

Теперь в main сделаем так :

И .bss увеличивается с 00000020 до 00002730 (10032!) . То есть ушло в RAM!

Теперь делаем так :

И .rodata увеличивается с 10 до 00002784 (10116) ! То есть ушло во FLASH (кстати только при условии явной инициализации=).

Выводы такие :

Побольше const

Если RAM памяти не хватает или не хватает стека (он всегда есть часть RAM), то можно попробовать все что не меняется обозвать const , инициализировать обязательно и тогда это попадет не в RAM , а в FLASH.

section `._user_heap_stack' will not fit in region `RAM'

Вот такая бяка появляется, когда RAM не хватает, например добавили нового кода , сторонние библиотеки .

У меня (на самом деле) эта ошибки ушла после удаления файла startupxxx.s и перегенерации заново проекта(и файла startup) из CubeMx.

Файлы для скачивания

* STM32F205VGT6_MemoryUsed [zip]
пустышка для изучения распределения памяти в контроллере STM32


Сегодняшняя статья, как вы уже поняли из названия, будет посвящена микроконтроллерам STM32 и работе со встроенной flash-памятью 🙂 Да-да, именно с той памятью, в которой хранится прошиваемая нами программа. Поскольку в STM32 нет EEPROM (энергонезависимой памяти) для хранения данных можно использовать flash-память контроллера, и сегодня мы как раз и разберемся, как же это работает.

Сразу же скажу, что согласно документации flash-память в STM32 позволяет осуществить минимум 10000 циклов перезаписи, что в принципе достаточно для того, чтобы использовать ее в качестве энергонезависимой памяти.

Давайте для начала разберемся со структурой памяти. Возьмем в качестве примера контроллер семейства STM32F10x, относящийся к High-Density устройствам (например, STM32F103VET6). Его память выглядит следующим образом:

STM32 Flash-память.

Как видите, все жестко структурировано. Information Block содержит 2 раздела:

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

С теорией все понятно, давайте рассмотрим некоторые практические моменты. Я буду, как и обычно, использовать SPL, а значит нам понадобятся файлы stm32f10x_flash.c и stm32f10x_flash.h в нашем проекте. И для того, чтобы работать с flash-памятью нужно сначала ее разблокировать. Для этого в специальный регистр FLASH_KEYR надо записать два числа, одно за другим:

В SPL для этого реализована функция FLASH_Unlock(). После разблокировки уже можно стирать и записывать данные. Для очистки мы будем использовать функцию:

В качестве параметра мы должны передать в функцию адрес стираемой страницы. Итак, страница стерта, как же записать данные? А для этого у нас есть:

Вот и все, ничего сложного! На этом сегодняшняя небольшая статья подходит к концу, в следующий раз мы будем обсуждать Bootloader, так что до скорого!

Для того, чтобы безопасно что то записать во Flash память, надо сначала выяснить ее структуру. Нас интересует Main memory. Именно в ней хранится программа и в эту память мы будем писать. Конечно, в не занятый программой участок памяти. Flash память разбита на страницы. Количество и размер страниц в разных контроллерах разная. О структуре памяти Вашего микроконтроллера читайте в Programming manual.

stm32_flash

Эта таблица приведена для всех STM32F103 medium-density devices. У нашего контроллера STM32F103C8 64 Кб Flash памяти. То есть, адрес начала последней страницы 0x800FC00.

  • Писать можно только в предварительно вытертую память. В стертой памяти все биты установлены в "1".
  • Вытирать можно только страницу целиком. То есть, мы не можем вытереть 1, 2, или 10 байт, только страницу целиком. В нашем случае - это блок в 1 КБ.
  • Писать во Flash надо словами по 32 бита.

Теперь перейдем к практической реализации.

Перед тем, к начинать работу с Flash надо выполнить пару функций - FLASH_PrefetchBufferCm, FLASH_SetLatency.

Эти функции могут быть выполнены при настройке рабочей частоты. Смотри статью "4 STM32. Программирование STM32F103. Тактирования"

FLASH Latency рекомендуется устанавливать:

FLASH_Latency_0 - 0 < SYSCLK≤ 24 MHz FLASH_Latency_1 - 24 MHz < SYSCLK ≤ 48 MHz FLASH_Latency_2 - 48 MHz < SYSCLK ≤ 72 MHz

Для записи во Flash память надо её разблокировать, стереть страницу, записать информацию, заблокировать Flash:

Читать 32-битными словами не всегда удобно и, как правило, нам нужно хранить несколько настроек с различными типами данных. Для упрощения этого процесса сделаем структуру с параметрами, которые нам надо сохранять:

Одно требование к этой структуре: ее длина должна быть кратная 32 битам, то есть кратно 4 байт, поскольку мы можем писать в Flash память только 32 битными словами. Например, создадим такую структуру, с тремя параметрами:

Эти параметры занимают только 3 байта, то есть 24 бита. Надо "дотянуть" размер до целого 32-битного слова. Можно просто добавить дополнительный параметр, назовем его nothing:

Теперь нам понадобится две функции для чтения и записи нашей структуры:

MY_FLASH_PAGE_ADDR - это адрес страницы, где мы будем хранить наши настройки. SETTINGS_WORDS - количество 32-битных слов, которые занимает структура.

Полный код программы:

Памятка

Надо помнить, что Flash память имеет ограничения на количество циклов записи. Согласно документации - минимум 10000. Это не очень и много, если достаточно интенсивно использовать Flash память. Но для хранения настроек вполне достаточно.

UPD: Важно помнить, что для записи во Flash используется HSI - внутренний тактовый генератор. HSI должен быть включен при записи во Flash.

"Эта таблица приведена для всех STM32F103 medium-density devices. У нашего контроллера STM32F103C8 64 Кб Flash памяти. То есть, адрес начала последней страницы 0x800FC00."

Читайте также: