Boot memory selection stm32 для чего нужен

от admin

22. Процесс начальной загрузки

В Главе 20 мы увидели, что обработчик исключения сброса Reset соответствует первой процедуре, которая должна быть выполнена при запуске ЦПУ. Фиксированная модель организации памяти процессоров на базе Cortex-M устанавливает, что адрес обработчика исключения сброса Reset размещается в памяти сразу после указателя основного стека (Main Stack Pointer, MSP), то есть по адресу 0x0000 0004 . Это расположение в памяти обычно соответствует началу Flash-памяти. Однако производители интегральных схем могут обойти это ограничение, «отражая (aliasing)» другие памяти на адрес 0x0000 0000 с помощью операции, называемой физическим перераспределением памяти. Данная операция выполняется аппаратно после нескольких тактовых циклов, и она отличается от перемещения таблицы векторов, рассмотренного в Главе 20 , которое выполняется с помощью того же кода, выполняемого на микроконтроллере.

Кроме того, платформа STM32 предоставляет предварительно запрограммированный на заводе загрузчик, который можно использовать для загрузки микропрограммы во Flashпамять из нескольких источников. В зависимости от семейства STM32 и используемого вида поставки микроконтроллер STM32 может загружать код с помощью коммуникационных периферийных устройств USART, USB, CAN, I²C и SPI. Загрузчик выбирается благодаря специальным загрузочным выводам (boot pins).

Данная глава завершает Главу 20 , демонстрируя процесс начальной загрузки (booting process), выполняемый микроконтроллерами STM32 после системного сброса. В ней дано подробное описание шагов, выполняемых во время начальной загрузки, и кратко показано, как использовать предварительно запрограммированный заводской загрузчик во всех микроконтроллерах STM32. В конечном счете, также показан пользовательский загрузчик, который позволяет обновить встроенное ПО с помощью интерфейса USART и специальной процедуры загрузки.

22.1. Единая система памяти Cortex-M и процесс начальной загрузки

В отличие от более продвинутых микропроцессорных архитектур, таких как ARM Cor- tex-A, микроконтроллеры Cortex-M не предоставляют модуль управления памятью (Memory Management Unit, MMU), который позволяет отразить (alias) логические адреса на фактические физические адреса. Это означает, что с точки зрения ядра Cortex-M карта памяти является фиксированной и стандартизированной среди всех реализаций.

В микроконтроллерах на базе Cortex-M область кода начинается с адреса 0x0000 0000 (доступ к которому осуществляется через шины I-Bus/D-Bus 1 в Cortex-M3/4/7 и через S-Bus в Cortex-M0/0+) в то время как область данных (SRAM) начинается с адреса 0x2000 0000 (доступ через S-Bus). Процессоры Cortex-M всегда выбирают таблицу

1 Для получения дополнительной информации об этих шинах см. Главу 9 .

Процесс начальной загрузки

векторов по шине I-Bus, что означает, что она загружается только из области кода (которая обычно соответствует Flash-памяти).

Микроконтроллеры STM32 реализуют специальный механизм, называемый физическим перераспределением памяти (physical remap), для выполнения начальной загрузки из других памятей помимо Flash-памяти, которое заключается в считывании двух специальных выводов микроконтроллера, называемых BOOT0 и BOOT1 2 . Электрическое состояние этих выводов определяет начальный адрес для начальной загрузки и, следовательно, память источника.

Таблица 1: Режимы начальной загрузки, доступные в микроконтроллере STM32F401RE

В таблице 1 показаны режимы начальной загрузки, доступные в микроконтроллере STM32F401RE, и она взята из соответствующего справочного руководства. Символ «х» в столбце BOOT1 означает, что, когда вывод BOOT0 подключен к земле, логическое состояние вывода BOOT1 может быть произвольным. Первая строка соответствует наиболее распространенному режиму начальной загрузки: микроконтроллер отразит Flashпамять на адрес 0x0000 0000 . Два других режима начальной загрузки соответствуют начальной загрузке с внутреннего SRAM и системной памяти – памяти ПЗУ, содержащей специальный загрузчик во всех микроконтроллерах STM32 и которую мы изучим чуть позже.

Состояние выводов BOOT защелкивается на 4-м фронте SYSCLK после сброса. После сброса пользователь может установить выводы BOOT для выбора необходимого режима начальной загрузки. Выводы BOOT также перепроверяются при выходе из режима ожидания с пониженным энергопотреблением. Следовательно, они должны быть сохранены в требуемой конфигурации режима начальной загрузки при переходе в режим ожидания. По истечении этого времени начального запуска ЦПУ выбирает указатель основного стека (MSP) с адреса 0x0000 0000 и запускает выполнение кода из загрузочной памяти, начиная с адреса 0x0000 0004 . Выбранная память (Flash, SRAM или ПЗУ) всегда доступна с ее оригинальным адресным пространством.

Если мы сконфигурируем микроконтроллер с начальной загрузкой из памяти SRAM, которая является энергозависимой памятью, мы должны загрузить программный код в эту память и убедиться, что действительная таблица векторов (по меньшей мере, состоящая из указателя основного стека и указателя на исключение сброса Reset) правильно

2 В зависимости от используемого корпуса в некоторых микроконтроллерах STM32 вывод BOOT1 отсутствует и заменяется специальным битом, называемым nBOOT1, внутри области байтов конфигурации. Обратитесь к справочному руководству по вашему микроконтроллеру для получения дополнительной информации об этом. В некоторых других семействах STM32, таких как STM32F7, функциональность вывода BOOT1 полностью заменена двумя специальными байтами конфигурации. Наконец, в тех микроконтроллерах, которые предоставляют два загрузочных вывода, BOOT0 в большинстве случаев является специализированным выводом, используемым исключительно для выбора источника начальной загрузки, в то время как BOOT1 используется совместно с выводом GPIO. После считывания BOOT1 соответствующий вывод GPIO освобождается и может использоваться для других целей. Однако существуют исключения среди микроконтроллеров с менее чем 36 выводами, где даже вывод BOOT0 считается входным GPIO, один раз считываемым в течение первых тактовых циклов (например, STM32L011K4T является одним из них).

Процесс начальной загрузки

установлена по адресу 0x0000 0000 . Это требуется для того, чтобы мы использовали инструмент отладчика, который предварительно загружает весь необходимый код внутрь SRAM перед началом выполнения. Кроме того, также необходим собственный скрипт компоновщика. Мы увидим полный пример позже.

22.1.1. Программное физическое перераспределение памяти

Как только микроконтроллер загружается, то есть выполняется исключение сброса Reset, все еще возможно перераспределить память, доступную через область кода (то есть через линии I-Bus и D-Bus), программируя некоторые биты регистра отображения памяти контроллера SYSCFG ( SYSCFG->MEMRMP в библиотеке CMSIS).

В зависимости от конкретного микроконтроллера STM32 могут быть перераспределены следующие памяти:

• Банк 1 FMC SDRAM

Последние две памяти доступны только в тех микроконтроллерах, которые предостав-

ляют контроллер внешней памяти (Flexible Memory Controller, FMC) – периферийное устройство, которое позволяет подключать внешние памяти NVM и SDRAM. В соответствии с таблицей 1, прямая начальная загрузка из внешней памяти NOR-Flash, а также из памяти SDRAM не допускается. Эти памяти могут отображаться по адресу 0x0000 0000

только при помощи программного физического перераспределения памяти, после того как микроконтроллер уже запущен с минимальной микропрограммой, загруженной из внутренней Flash-памяти.

После того, как внешняя память была физически перераспределена по адресу 0x0000 0000 , ЦПУ может получить к ней доступ по линиям I-Bus и D-Bus, а не по переполненной S-Bus, что повышает общую производительность. Это особенно важно для микроконтроллеров на базе Cortex-M7, где эти линии тесно связаны с выделенным кэшем L1.

Когда процессор выполняет начальную загрузку, содержимое регистра SYSCFG->MEMRMP привязывается к значениям выводов BOOT: это означает, что физическое перераспределение памяти автоматически выполняется из микроконтроллера при выборке выводов BOOT. Перед изменением содержимого этого регистра для выполнения перераспределения памяти важно иметь в целевой памяти рабочую таблицу векторов 3 .

22.1.2. Перемещение таблицы векторов

В Главе 20 мы увидели, как переместить таблицу векторов в CCM-память, чтобы мы могли воспользоваться преимуществами данной памяти. Когда мы выполняем физическое перераспределение памяти, устанавливая выводы BOOT, либо конфигурируя регистр SYSCFG->MEMRMP соответственно, нет необходимости выполнять перемещение таблицы

3 Важно уточнить, что ЦПУ не будет перезапускать последовательность сброса, вызывая обработчик исключения сброса Reset, после того как память была перераспределена с помощью регистра SYSCFG->MEMRMP . Вы будете нести ответственность за вызов этого обработчика исключений и за обеспечение того, чтобы ЦПУ был переведен в начальные условия, которые целевая микропрограмма ожидает найти (например, все периферийные устройства отключены и т. д.).

Процесс начальной загрузки

векторов, поскольку микроконтроллер автоматически присваивает начальный адрес 0x0000 0000 выбранной памяти. Иногда, однако, мы хотим переместить таблицу векторов в другие области памяти, которые не соответствуют ее источнику. Например, мы можем захотеть хранить два независимых образа микропрограммы во Flash-памяти (см. рисунок 1) и выбрать один из них в соответствии с заданным начальным условием. Это случай загрузчиков (bootloaders) – специальных «системных» программ, которые выполняют важные задачи конфигурации, такие как обновление основной микропрограммы, как мы увидим позже в данной главе.

Регистр смещения таблицы векторов (Vector Table Offset Register, VTOR) – это регистр в блоке управления системой (System Control Block, SCB) ( SCB->VTOR в библиотеке CMSIS), ко-

торый позволяет настроить базовый адрес таблицы векторов. Как только содержимое этого регистра будет установлено, ЦПУ будет обрабатывать адреса, начиная с новой базовой ячейки памяти, в качестве указателей на процедуры обслуживания прерываний.

Рисунок 1: Два независимых образа микропрограммы могут храниться во Flash-памяти

Boot memory selection stm32 для чего нужен

В этой статье дан обзор внутренней системы шин и памяти микроконтроллеров STM32F4 (перевод раздела «2 Memory and bus architecture» даташита [1]). Все непонятные термины и сокращения см. в Словарике [7].

[Архитектура системы]

STM32F405xx/07xx и STM32F415xx/17xx. Основная внутренняя система основана на 32-разрядной многослойной матрице шин AHB, которая соединяет:

• 8 главных устройств (master):

– Cortex®-M4 ядро с FPU I-bus, D-bus и S-bus
– шина памяти DMA1
– шина памяти DMA2
– шина периферийных устройств DMA2
– шина Ethernet DMA
– шина USB OTG HS DMA

• 7 подчиненных устройств (slave):

– шина внутренней памяти Flash ICode
– шина внутренней памяти Flash DCode
– основная внутренняя память SRAM1 (112 килобайт)
– дополнительная внутренняя память SRAM2 (16 килобайт)
– периферийные устройства AHB1, включая мосты AHB — APB и периферийные устройства APB
– периферийные устройства AHB2
– FSMC

Матрица шин предоставляет доступ от master к slave, позволяя реализовать конкурентный доступ и эффективную работу даже когда одновременно работают несколько высокоскоростных периферийных устройств. 64-килобайтная память данных CCM (Core Coupled Memory) не является частью матрицы шин, и к ней можно осуществлять доступ только через ядро CPU. Эта архитектура показана на рис. 1.

Рис. 1. Архитектура системы MCU STM32F405xx/07xx и STM32F415xx/17xx.

STM32F42xx и STM32F43xx. Основная внутренняя система основана на 32-разрядной многослойной матрице шин AHB, которая соединяет:

• 10 главных устройств (master):

– Cortex®-M4 ядро с FPU I-bus, D-bus и S-bus
– шина памяти DMA1
– шина памяти DMA2
– шина периферийных устройств DMA2
– шина Ethernet DMA
– шина USB OTG HS DMA
– шина DMA контроллера LCD [5]
– шина памяти DMA2D (Chrom-Art Accelerator™)

• 8 подчиненных устройств (slave):

– шина внутренней памяти Flash ICode – шина внутренней памяти Flash DCode
– основная внутренняя память SRAM1 (112 килобайт)
– дополнительная внутренняя память SRAM2 (16 килобайт)
– дополнительная внутренняя память SRAM3 (64 килобайта)
– периферийные устройства AHB1, включая мосты AHB — APB и периферийные устройства APB
– периферийные устройства AHB2
– FSMC

Матрица шин предоставляет доступ от master к slave, позволяя реализовать конкурентный доступ и эффективную работу даже когда одновременно работают несколько высокоскоростных периферийных устройств. 64-килобайтная память данных CCM (Core Coupled Memory) не является частью матрицы шин, и к ней можно осуществлять доступ только через ядро CPU. Эта архитектура показана на рис. 2.

STM32F4 sysarch STM32F42xxx STM32F43xxx fig02

Рис. 2. Архитектура системы MCU STM32F42xxx и STM32F43xxx.

I-bus. Эта шина соединяет с матрицей шин шину инструкций ядра Cortex®-M4. Шина I-bus используется ядром для выборки инструкций. Эта шина работает с памятью, где находится код (внутренняя память Flash/SRAM или внешние устройства памяти, доступные через контроллер FSMC/FMC).

D-bus. Эта шина соединяет память данных 64-килобайт CCM с шиной данных ядра Cortex®-M4 через матрицу шин (BusMatrix). Шина D-bus используется ядром для загрузки данных и доступа к отладке. Эта шина работает с памятью, где содержится код или данные (внутренняя память Flash или внешние устройства памяти, доступные через контроллер FSMC/FMC).

S-bus. Эта шина соединяет системную шину ядра Cortex®-M4 с BusMatrix. Шина S-bus используется для доступ к памяти, находящейся в периферийном устройстве или в SRAM. Через эту шину может также осуществляться выборка инструкций (с меньшей эффективностью по сравнению с ICode). Шина S-bus работает с внутренней памятью SRAM1, SRAM2 и SRAM3, периферийными устройствами AHB1, включая периферийные устройства APB, периферийные устройства AHB2 и внешние устройства памяти, доступные через контроллер FSMC/FMC.

Шина памяти DMA. Эта шина соединяет мастера шины памяти DMA с BusMatrix. Шина памяти DMA используется блоком DMA для выполнения перемещения данных между областями памяти. Эта шина работает со следующими областями данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3) и внешние устройства памяти, доступные через контроллер FSMC/FMC.

Шина DMA периферийных устройств. Эта шина соединяет интерфейс мастера DMA периферии с BusMatrix. Шина DMA периферийных устройств используется блоком DMA для доступа к периферийным устройствам AHB, или для выполнения перемещений данных между областями памяти. Эта шина работает с периферийными устройствами AHB и APB плюс с памятью данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3) и внешние устройства памяти, доступные через контроллер FSMC/FMC.

Шина Ethernet DMA. Эта шина соединяет интерфейс мастера Ethernet DMA с BusMatrix. Шина используется блоком Ethernet DMA для обмена данными с памятью. Шина Ethernet DMA работает с памятью данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3), внутренняя память Flash и внешние устройства памяти, доступные через контроллер FSMC/FMC.

Шина USB OTG HS DMA. Эта шина соединяет интерфейс мастера USB OTG HS DMA с BusMatrix. Шина используется блоком USB OTG HS DMA для обмена данными с памятью. Шина USB OTG HS DMA работает с памятью данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3), внутренняя память Flash и внешние устройства памяти, доступные через контроллер FSMC/FMC.

Шина DMA контроллера LCD-TFT. Эта шина соединяет интерфейс мастера DMA контроллера LCD [5] с BusMatrix. Шина используется блоком LCD-TFT DMA для обмена данными с памятью. Шина DMA контроллера LCD-TFT работает с памятью данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3), внутренняя память Flash и внешние устройства памяти, доступные через контроллер FMC.

Шина DMA2D. Эта шина соединяет интерфейс мастера DMA2D с BusMatrix. Шина используется блоком графического ускорителя DMA2D для обмена данными с памятью. Шина DMA2D работает с памятью данных: внутренние банки SRAM (SRAM1, SRAM2 и SRAM3), внутренняя память Flash и внешние устройства памяти, доступные через контроллер FMC.

BusMatrix. Матрица шин управляет арбитражем между мастерами. Арбитраж использует алгоритм round-robin (циклическая передача приоритета).

Мосты AHB/APB. Два моста AHB/APB, APB1 и APB2, предоставляют полное синхронное соединение между шиной AHB и двумя шинами APB, что позволяет гибко выбирать частоту тактирования периферийных устройств. Для получения подробной информации по максимальным частотам шин APB1 и APB2 см. даташит на используемый MCU. В таблице 1 показано отображение адресов AHB и периферийных устройств APB.

После каждого сброса MCU тактирование всех периферийных устройств запрещено (кроме интерфейса памяти SRAM и Flash). Поэтому перед использованием периферийного устройства необходимо разрешить его тактирование программированием регистров контроллера RCC (RCC_AHBxENR или RCC_APBxENR).

Примечание: когда к регистру APB осуществляется 16-битный или 8-битный доступ, этот доступ преобразуется в 32-битный: мост дублирует 16-битные или 8-битные данные для подачи 32-битного вектора.

[Организация памяти]

Память программы, память данных, регистры и порты ввода/вывода организованы в одном общем, линейном пространстве адресов объемом 4 гигабайта.

Данные хранятся в памяти в формате little endian [6]. Байт с наименьшим номером в слове (с самым малым адресом) считается самым младшим значащим байтом этого слова. И наоборот, байт с самым большим номером (с самым большим адресом) считается самым значащим байтом слова.

Подробную информацию по адресам регистров периферийных устройств см. соответствующие разделы даташита [1].

Адресуемое пространство памяти поделено на 8 основных блоков, каждый по 512 мегабайт. Все области памяти, которые не принадлежат встроенным в чип областям памяти и периферийным устройствам считаются зарезервированными. См. карту памяти в даташите на используемый микроконтроллер.

[Карта памяти]

Подробную схему карты памяти см. в таблице, соответствующей вашему используемому MCU и периферийному устройству. Таблица 1 показывает границы адресов периферийных устройств, имеющихся во всех MCU STM32F4xx.

Таблица 1. Области адресов регистров STM32F4xx.

Границы адресов Периферийное устройство Шина Карта регистров (в даташите [1])
0xA0000000 — 0xA0000FFF FSMC control register (STM32F405xx/07xx и STM32F415xx/17xx) /
FMC control register (STM32F42xxx и STM32F43xxx)
AHB3 «36.6.9: FSMC register map», стр. 1600
«37.8: FMC register map», стр. 1680
0x50060800 — 0x50060BFF RNG AHB2 «24.4.4: RNG register map», стр. 771
0x50060400 — 0x500607FF HASH «25.4.9: HASH register map», стр. 795
0x50060000 — 0x500603FF CRYP «23.6.13: CRYP register map», стр. 763
0x50050000 — 0x500503FF DCMI «15.8.12: DCMI register map», стр. 478
0x50000000 — 0x5003FFFF USB OTG FS «34.16.6: OTG_FS register map», стр. 1326
0x40040000 — 0x4007FFFF USB OTG HS AHB1 «5.12.6: OTG_HS register map», стр. 1472
0x4002B000 — 0x4002BBFF DMA2D «11.5: DMA2D registers», стр. 352
0x40028000 — 0x400293FF ETHERNET MAC «33.8.5: Ethernet register maps», стр. 1236
0x40026400 — 0x400267FF DMA2 «10.5.11: DMA register map», стр. 335
0x40026000 — 0x400263FF DMA1
0x40024000 — 0x40024FFF BKPSRAM
0x40023C00 — 0x40023FFF Регистры интерфейса Flash «3.9: Flash interface registers»
0x40023800 — 0x40023BFF RCC «7.3.24: RCC register map», стр. 265
0x40023000 — 0x400233FF CRC «4.4.4: CRC register map», стр. 115
0x40022800 — 0x40022BFF GPIOK «8.4.11: GPIO register map», стр. 287
0x40022400 — 0x400227FF GPIOJ
0x40022000 — 0x400223FF GPIOI «8.4.11: GPIO register map», стр. 287
0x40021C00 — 0x40021FFF GPIOH
0x40021800 — 0x40021BFF GPIOG
0x40021400 — 0x400217FF GPIOF
0x40021000 — 0x400213FF GPIOE
0x40020C00 — 0x40020FFF GPIOD
0x40020800 — 0x40020BFF GPIOC
0x40020400 — 0x400207FF GPIOB
0x40020000 — 0x400203FF GPIOA
0x40016800 — 0x40016BFF LCD-TFT APB2 «16.7.26: LTDC register map», стр. 512
0x40015800 — 0x40015BFF SAI1 «29.17.9: SAI register map», стр. 963
0x40015400 — 0x400157FF SPI6 «28.5.10: SPI register map», стр. 925
0x40015000 — 0x400153FF SPI5
0x40014800 — 0x40014BFF TIM11 «19.5.12: TIM10/11/13/14 register map», стр. 694
0x40014400 — 0x400147FF TIM10
0x40014000 — 0x400143FF TIM9 «19.4.13: TIM9/12 register map», стр. 684
0x40013C00 — 0x40013FFF EXTI «12.3.7: EXTI register map», стр. 387
0x40013800 — 0x40013BFF SYSCFG «9.2.8: SYSCFG register map» для STM32F405xx/07xx и STM32F415xx/17xx стр. 294
«9.3.8: SYSCFG register map» для STM32F42xxx и STM32F43xxx стр. 301
0x40013400 — 0x400137FF SPI4 «28.5.10: SPI register map», стр. 925
0x40013000 — 0x400133FF SPI1
0x40012C00 — 0x40012FFF SDIO «31.9.16: SDIO register map», стр. 1074
0x40012000 — 0x400123FF ADC1, ADC2, ADC3 «13.13.18: ADC register map», стр. 430
0x40011400 — 0x400117FF USART6 «30.6.8: USART register map», стр. 1018
0x40011000 — 0x400113FF USART1
0x40010400 — 0x400107FF TIM8 «17.4.21: TIM1 and TIM8 register map», стр. 587
0x40010000 — 0x400103FF TIM1
0x40007C00 — 0x40007FFF UART8 APB1 «30.6.8: USART register map», стр. 1018
0x40007800 — 0x40007BFF UART7
0x40007400 — 0x400077FF DAC «14.5.15: DAC register map», стр. 453
0x40007000 — 0x400073FF PWR «5.6: PWR register map», стр. 149
0x40006800 — 0x40006BFF CAN2 «32.9.5: bxCAN register map», стр. 1118
0x40006400 — 0x400067FF CAN1
0x40005C00 — 0x40005FFF I2C3 «27.6.11: I2C register map», стр. 872
0x40005800 — 0x40005BFF I2C2
0x40005400 — 0x400057FF I2C1
0x40005000 — 0x400053FF UART5 «30.6.8: USART register map», стр. 1018
0x40004C00 — 0x40004FFF UART4
0x40004800 — 0x40004BFF USART3
0x40004400 — 0x400047FF USART2
0x40004000 — 0x400043FF I2S3ext «28.5.10: SPI register map», стр. 925
0x40003C00 — 0x40003FFF SPI3 / I2S3
0x40003800 — 0x40003BFF SPI2 / I2S2
0x40003400 — 0x400037FF I2S2ext
0x40003000 — 0x400033FF IWDG «21.4.5: IWDG register map», стр. 712
0x40002C00 — 0x40002FFF WWDG «22.6.4: WWDG register map», стр. 719
0x40002800 — 0x40002BFF Регистры RTC и BKP «26.6.21: RTC register map», стр. 836
0x40002000 — 0x400023FF TIM14 «19.5.12: TIM10/11/13/14 register map», стр. 694
0x40001C00 — 0x40001FFF TIM13
0x40001800 — 0x40001BFF TIM12 «19.4.13: TIM9/12 register map», стр. 684
0x40001400 — 0x400017FF TIM7 «20.4.9: TIM6 and TIM7 register map», стр. 707
0x40001000 — 0x400013FF TIM6
0x40000C00 — 0x40000FFF TIM5 «18.4.21: TIMx register map», стр. 648
0x40000800 — 0x40000BFF TIM4
0x40000400 — 0x400007FF TIM3
0x40000000 — 0x400003FF TIM2

Встроенная SRAM. В микроконтроллерах STM32F405xx/07xx и STM32F415xx/17xx имеется 4 килобайта Backup SRAM и 192 килобайта системной памяти SRAM. В микроконтроллерах STM32F42xxx и STM32F43xxx имеется 4 килобайта Backup SRAM и 192 килобайта системной памяти SRAM. Описание Backup SRAM см. в секции «5.1.2: Battery backup domain» даташита [1].

К встроенной SRAM можно обращаться как к байтам, половинкам слов (16 бит) или к полным словам (32 бита). Операции чтения и записи выполняются на полной скорости CPU без циклов задержек на ожидание (0 wait state). Встроенная SRAM поделена на 3 блока:

• SRAM1 и SRAM2, отображенная на адрес 0x20000000, и доступная для всех мастеров AHB.
• SRAM3 (имеется у STM32F42xxx и STM32F43xxx), отображенная на адрес 0x20020000, и доступная для всех мастеров AHB.
• CCM (Core Coupled Memory), отображенная на адрес 0x10000000, и доступная для CPU через D-bus.

Мастера AHB поддерживают конкурентные попытки доступа к SRAM (от Ethernet или USB OTG HS): например, Ethernet MAC может читать/записывать SRAM2, в то время как CPU читает/записывает SRAM1 или SRAM3.

CPU может обращаться к SRAM1, SRAM2 и SRAM3 через системную шину (System Bus) или через шины I-Code/D-Code, когда выбрана загрузка (boot) из SRAM, или когда выбрано физическое переназначение карты памяти (physical remap, см. секцию «9.2.1: SYSCFG memory remap register (SYSCFG_MEMRMP)» описания контроллера SYSCFG даташита [1]). Чтобы получить максимальную производительность выполнения кода из SRAM, должно быть выполнено physical remap (выбор кода boot или программы).

Память Flash. Интерфейс памяти Flash обслуживает доступ шин CPU AHB I-Code и D-Code к памяти Flash. Он реализован для операций стирания и программирования памяти Flash, и для механизмов защиты от чтения и записи. Интерфейс ускоряет выполнение кода с помощью предварительной выборки инструкции и линеек кеша.

Память Flash организована следующим образом:

• Основной блок памяти поделен на секторы.
• Системная память, из которой загружается система в режиме загрузки System memory boot mode.
• 512 байт OTP (однократно программируемая память) для данных пользователей.
• Байты опций, предназначенные для конфигурирования защиты чтения и записи, уровня детектора пропадания питания для сброса (BOR), программно/аппаратного сторожевого таймера и сброса, когда MCU находится в режиме Standby или Stop.

Подробнее см. секцию «3: Embedded Flash memory interface» в даташите [1].

Битовые операции (bit banding). Карта памяти Cortex®-M4 с FPU включает две группы бит (bit-band). Эти регионы отображают каждое слово ссылочного региона памяти на бит в группе (bit-band) памяти. Запись слова ссылочного региона дает тот же эффект, что и операция read-modify-write (чтение-модификация-запись) целевого бита группы bit-band.

В микроконтроллерах STM32F4xx как регистры периферийных устройств, так и SRAM, отображены на область bitband, поэтому дозволяются одиночные операции bit-band записи и чтения. Эти операции доступны только для доступа Cortex®-M4 с FPU, но не от других мастеров шины (например DMA).

Формула отображения показывает, как осуществляется ссылка на каждое слово в алиас-регионе на соответствующий бит группы в регионе bit-band:

bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number x 4)

bit_word_addr — адрес слова в алиас-регионе памяти, которая отображается на целевой бит.
bit_band_base — начальный адрес алиас-региона.
byte_offset — номер байта в регионе bit-band, который содержит целевой бит.
bit_number — позиция (0 .. 7) целевого бита.

Следующий пример показывает, как отображается бит 2 байта, находящегося в SRAM по адресу 0x20000300, на алиас-регион:

0x22006008 = 0x22000000 + (0x300*32) + (2*4)

Запись по адресу 0x22006008 дает тот же эффект, что и операция read-modify-write бита 2 байта SRAM по адресу 0x20000300.

Чтение адреса 0x22006008 возвратит значение бита 2 (0x01 или 0x00) байта по адресу 0x20000300 (0x01 бит установлен, 0x00 бит сброшен).

Подробнее про bit-banding см. руководство по программированию PM0214 [3].

[Конфигурация загрузки]

Из-за фиксированной карты памяти область кода (программа) начинается с адреса 0x00000000 (эта область памяти доступна через шины ICode/DCode), в то время как область данных (SRAM) начинается с адреса 0x20000000 (эта область доступна через системную шину). CPU Cortex®-M4 всегда делает выборку инструкции по вектору сброса на шине ICode. Это подразумевает, что область загрузки доступна только в области кода (обычно память Flash). Микроконтроллеры STM32F4xx реализуют специальный механизм, позволяющий загрузиться из других областей памяти (наподобие внутренней SRAM).

В STM32F4xx есть 3 разных режима загрузки, выбираемые ножками корпуса BOOT[1:0], что показано в таблице 2.

Таблица 2. Режимы загрузки.

Выводы для выбора режима загрузки Режим загрузки
На что происходит ссылка
BOOT1 BOOT0
x 0 Основная память Flash В качестве области загрузки выбрана основная память Flash.
0 1 Системная память В качестве области загрузки выбрана System Memory.
1 1 Встроенная SRAM В качестве области загрузки выбрана встроенная SRAM.

Значения на выводах BOOTx защелкиваются на 4-ом фронте нарастания уровня тактов SYSCLK после сброса. Пользователь должен установить логический уровень ножек корпуса BOOT1 и BOOT0, чтобы после сброса был выбран необходимый режим загрузки.

Для функции BOOT0 выделена специальная ножка корпуса, в то время как функция BOOT1 совмещена с ножкой порта GPIO. Как только уровень BOOT1 был прочитан, соответствующая ножка GPIO освобождается, и может использоваться для других целей.

Уровни на ножках BOOT также анализируются, когда MCU выходит из режима Standby. Следовательно, необходимо сохранить требуемую конфигурацию режима загрузки, когда MCU находится в режиме Standby. После того, как задержка startup закончится, CPU делает выборку значение вершины стека по адресу 0x00000000, и затем начинает выполнять код из памяти загрузки (boot memory), начиная с 0x00000004.

Примечание: когда MCU загружается из SRAM, в коде инициализации приложения необходимо переразместить таблицу векторов в SRAM, используя таблицу исключений контроллера прерываний (NVIC exception table) и регистр смещения.

В случае, когда микроконтроллеры STM32F42xxx и STM32F43xxx загружаются из основной памяти Flash, программа приложения может загрузиться либо из банка 1, либо из банка 2. По умолчанию выбран банк 1.

Для выбора загрузки из банка 2 памяти Flash установите бит BFB2 в байтах опций пользователя. Когда этот бит установлен, и ножки управления загрузкой установлены на загрузку из основной памяти Flash, устройство загружается из системной памяти, и загрузчик делает безусловный переход на выполнение приложения пользователя, запрограммированного в банке 2 памяти Flash. Для дополнительной информации см. апноут AN2606 (для микроконтроллеров STM32F42xxx и STM32F43xxx см. статью [4]).

Встроенный загрузчик. Режим встроенного загрузчика используется для перепрограммирования памяти Flash, используя один из следующих последовательных интерфейсов:

• USART1 (ножки портов PA9/PA10)
• USART3 (ножки портов PB10/PB11 и PC10/PC11)
• CAN2 (ножки потов PB5 и PB13)
• USB OTG FS (ножки портов PA11/PA12) в режиме устройства USB (этот интерфейс обозначается аббревиатурой DFU: device firmware upgrade, обновление ПО устройства).

Периферийные устройства USART работают от внутреннего высокоскоростного RC-генератора 16 МГц (HSI), в то время как CAN и USB OTG FS требуют внешнего источника тактов (обычно это кварц, генератор HSE) с частой, нацело делящейся на 1 МГц (в диапазоне от 4 до 26 МГц).

Встроенный загрузчик находится в системной памяти, он программируется компанией ST в процессе производства. Для дополнительной информации см. апноут AN2606 (для микроконтроллеров STM32F42xxx и STM32F43xxx см. статью [4]).

Читать:
Как посчитать погрешность периода колебаний

Physical remap STM32F405xx/07xx и STM32F415xx/17xx. Как только выбрано состояние выводов управления загрузкой, программа приложения может изменить память, доступную в области кода (таким способом код может быть выполнен через шину ICode вместо того, чтобы выполняться через системную шину). Эта модификация выполняется программированием регистра переназначения памяти (SYSCFG memory remap register, SYSCFG_MEMRMP) контроллера SYSCFG, см. [1].

Переназначение (remap) может быть применено к следующим областям памяти:

• Основная память Flash
• Системная память
• Встроенная SRAM1 (112 килобайт)
• FSMC bank 1 (NOR/PSRAM 1 и 2)

Таблица 3. Отображение памяти при Boot mode/physical remap для STM32F405xx/07xx и STM32F415xx/17xx.

Адреса Boot/Remap
в основную Flash
Boot/Remap
во встроенную SRAM
Boot/Remap
в System Memory
Remap в FSMC
0x2001C000 — 0x2001FFFF SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB)
0x20000000 — 0x2001BFFF SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB)
0x1FFF0000 — 0x1FFF77FF System Memory System Memory System Memory System Memory
0x08100000 — 0x0FFFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x08000000 — 0x080FFFFF Память Flash Память Flash Память Flash Память Flash
0x04000000 — 0x07FFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x00000000 — 0x000FFFFF (1)(2) Ссылка на Flash (1 MB) Ссылка на SRAM1 (112 KB) Ссылка на System
Memory (30 KB)
Ссылка на FSMC bank 1 NOR
/PSRAM 1 (128 MB)

(1) Когда FSMC переназначен на адрес 0x00000000, могут быть переназначены только первые 2 региона банка 1 контроллера памяти (bank 1 NOR/PSRAM 1 и NOR/PSRAM 2). В режиме переназначения (remap mode), CPU может получить доступ к внешней памяти через шину ICode вместо системной шины, что улучшает производительность.
(2) Даже когда память ссылочно отображена на область загрузки (boot memory space), эта соответствующая память все еще доступна по своим оригинальным адресам на карте памяти.

Physical remap STM32F42xxx и STM32F43xxx. Как только выбрано состояние выводов управления загрузкой, программа приложения может изменить память, доступную в области кода (таким способом код может быть выполнен через шину ICode вместо того, чтобы выполняться через системную шину). Эта модификация выполняется программированием регистра переназначения памяти (SYSCFG memory remap register, SYSCFG_MEMRMP) контроллера SYSCFG, см. [1].

Переназначение (remap) может быть применено к следующим областям памяти:

• Основная память Flash
• Системная память
• Встроенная SRAM1 (112 килобайт)
• FSMC bank 1 (NOR/PSRAM 1 и 2)
• FMC SDRAM bank 1

Таблица 4. Отображение памяти при Boot mode/physical remap для STM32F42xxx и STM32F43xxx.

Адреса Boot/Remap
в основную Flash
Boot/Remap
во встроенную SRAM
Boot/Remap
в System Memory
Remap в FMC
0x20020000 — 0x2002FFFF SRAM3 (64 KB) SRAM3 (64 KB) SRAM3 (64 KB) SRAM3 (64 KB)
0x2001C000 — 0x2001FFFF SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB)
0x20000000 — 0x2001BFFF SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB)
0x1FFF0000 — 0x1FFF77FF System Memory System Memory System Memory System Memory
0x08100000 — 0x0FFFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x08000000 — 0x080FFFFF Память Flash Память Flash Память Flash Память Flash
0x04000000 — 0x07FFFFFF Зарезервировано Зарезервировано Зарезервировано Ссылка на FMC bank 1 NOR
/PSRAM 2 (128 MB)
0x00000000 — 0x001FFFFF (1)(2) Ссылка на Flash (2 MB) Ссылка на SRAM1 (112 KB) Ссылка на System
Memory (30 KB)
Ссылка на FMC bank 1 NOR
/PSRAM 1 (128 MB),
или ссылка на FMC SDRAM
bank 1 (128 MB)

(1) Когда FSMC переназначен на адрес 0x00000000, могут быть переназначены только первые 2 региона банка 1 контроллера памяти (bank 1 NOR/PSRAM 1 и NOR/PSRAM 2) или SDRAM bank 1. В режиме переназначения (remap mode), CPU может получить доступ к внешней памяти через шину ICode вместо системной шины, что улучшает производительность.
(2) Даже когда память ссылочно отображена на область загрузки (boot memory space), эта соответствующая память все еще доступна по своим оригинальным адресам на карте памяти.

Boot memory selection stm32 для чего нужен

Например, начиная с флэш-памяти, в этом случае доступ к адресам 0x0 и 0x0800 0000 абсолютно одинаков.
Итак, после запуска cotex-M3 берет MSP с адреса 0x0, а ПК с адреса 0x4, что означает, что он принимает 0x8000000 и 0x08000004. Эквивалентны.
Однако запуск ОЗУ является исключением.

Даже если мы выберем загрузку из ОЗУ, мы не сможем получить доступ с 0x2000 0000 до 0x0.
Как начинается ОЗУ?

3. Загрузка RAM

  1. Система не выполняет сопоставление от 0x2000 0000 до 0x0, но присваивает значения 0x2000 0000 и 0x20000004 SP и ПК при запуске с помощью внутреннего метода системы.
  2. Система выполняет сопоставление от 0x2000 0000 до 0x0 во время включения питания. После запуска (после включения MSP и ПК) сопоставление отключается, а затем два пространства открываются независимо.

3.2.1 Создание нового элемента проекта RAM

Найдите простой проект, который может стабильно работать на флеш-памяти, и создайте новый элемент проекта для запуска RAM.

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

После переключения вы увидите, что название проекта слева другое.

Каждый должен заранее ознакомиться с настройкой загрузки флеш-памяти.

Здесь мы переключаемся на загрузку из ОЗУ.
Сначала посмотрите на размер скомпилированного файла.

Откройте файл карты

можно увидеть
Размер созданного bin-файла составляет 5884 байта.

Таким образом, мы можем выделить в ПЗУ более 5884.

Здесь тоже яма, это последнее слово.

3.2.4 Добавить глобальный макрос VECT_TAB_SRAM

ОЗУ нельзя запрограммировать на загрузку флеш-памяти таким образом, и нельзя ее перезапустить после выключения питания.
в основном работает в режиме отладки.

После входа в отладку вы можете пошагово, на полной скорости и сбросить.
В Интернете есть сообщения о том, что они не могут сбросить настройки, но я с ними не сталкивался. Они могут работать нормально.

Иногда он будет нестабильным при запуске и выйдет из режима отладки при сообщении об ошибке, но его также можно использовать.

Я долго бегал после просмотра картинки.

Когда я запускал ОЗУ, я вводил аппаратное исключение каждый раз, когда сталкивался с SystemInit, что меня очень расстраивало. Я чувствовал, что это ненормально, как только я нажимал на стек. Однако я был действительно подавлен, когда отслеживал изменения MSP в соответствии с моими ожиданиями. На выяснение причины ушло много времени.
Я видел этот абзац в китайском руководстве по stm32 раньше,

stm32f103, который я использовал для тестирования, я думал, что RAM 64k, то есть 0x2000 0000

0x 2001 0000 .
На самом деле это совсем не так. ОЗУ stm32f103c8t6 составляет всего 20 КБ, поэтому пара операций SP является ненормальной и осуществляется доступ к недопустимому адресу.
После изменения размера это нормально.

Boot memory selection stm32 для чего нужен

STM32F4 sysarch STM32F405xx 07xx STM32F415xx 17xx fig01

STM32F4 sysarch STM32F42xxx STM32F43xxx fig02

Границы адресов Периферийное устройство Шина Карта регистров (в даташите [1])
0xA0000000 — 0xA0000FFF FSMC control register (STM32F405xx/07xx и STM32F415xx/17xx) /
FMC control register (STM32F42xxx и STM32F43xxx)
AHB3 «36.6.9: FSMC register map», стр. 1600
«37.8: FMC register map», стр. 1680
0x50060800 — 0x50060BFF RNG AHB2 «24.4.4: RNG register map», стр. 771
0x50060400 — 0x500607FF HASH «25.4.9: HASH register map», стр. 795
0x50060000 — 0x500603FF CRYP «23.6.13: CRYP register map», стр. 763
0x50050000 — 0x500503FF DCMI «15.8.12: DCMI register map», стр. 478
0x50000000 — 0x5003FFFF USB OTG FS «34.16.6: OTG_FS register map», стр. 1326
0x40040000 — 0x4007FFFF USB OTG HS AHB1 «5.12.6: OTG_HS register map», стр. 1472
0x4002B000 — 0x4002BBFF DMA2D «11.5: DMA2D registers», стр. 352
0x40028000 — 0x400293FF ETHERNET MAC «33.8.5: Ethernet register maps», стр. 1236
0x40026400 — 0x400267FF DMA2 «10.5.11: DMA register map», стр. 335
0x40026000 — 0x400263FF DMA1
0x40024000 — 0x40024FFF BKPSRAM
0x40023C00 — 0x40023FFF Регистры интерфейса Flash «3.9: Flash interface registers»
0x40023800 — 0x40023BFF RCC «7.3.24: RCC register map», стр. 265
0x40023000 — 0x400233FF CRC «4.4.4: CRC register map», стр. 115
0x40022800 — 0x40022BFF GPIOK «8.4.11: GPIO register map», стр. 287
0x40022400 — 0x400227FF GPIOJ
0x40022000 — 0x400223FF GPIOI «8.4.11: GPIO register map», стр. 287
0x40021C00 — 0x40021FFF GPIOH
0x40021800 — 0x40021BFF GPIOG
0x40021400 — 0x400217FF GPIOF
0x40021000 — 0x400213FF GPIOE
0x40020C00 — 0x40020FFF GPIOD
0x40020800 — 0x40020BFF GPIOC
0x40020400 — 0x400207FF GPIOB
0x40020000 — 0x400203FF GPIOA
0x40016800 — 0x40016BFF LCD-TFT APB2 «16.7.26: LTDC register map», стр. 512
0x40015800 — 0x40015BFF SAI1 «29.17.9: SAI register map», стр. 963
0x40015400 — 0x400157FF SPI6 «28.5.10: SPI register map», стр. 925
0x40015000 — 0x400153FF SPI5
0x40014800 — 0x40014BFF TIM11 «19.5.12: TIM10/11/13/14 register map», стр. 694
0x40014400 — 0x400147FF TIM10
0x40014000 — 0x400143FF TIM9 «19.4.13: TIM9/12 register map», стр. 684
0x40013C00 — 0x40013FFF EXTI «12.3.7: EXTI register map», стр. 387
0x40013800 — 0x40013BFF SYSCFG «9.2.8: SYSCFG register map» для STM32F405xx/07xx и STM32F415xx/17xx стр. 294
«9.3.8: SYSCFG register map» для STM32F42xxx и STM32F43xxx стр. 301
0x40013400 — 0x400137FF SPI4 «28.5.10: SPI register map», стр. 925
0x40013000 — 0x400133FF SPI1
0x40012C00 — 0x40012FFF SDIO «31.9.16: SDIO register map», стр. 1074
0x40012000 — 0x400123FF ADC1, ADC2, ADC3 «13.13.18: ADC register map», стр. 430
0x40011400 — 0x400117FF USART6 «30.6.8: USART register map», стр. 1018
0x40011000 — 0x400113FF USART1
0x40010400 — 0x400107FF TIM8 «17.4.21: TIM1 and TIM8 register map», стр. 587
0x40010000 — 0x400103FF TIM1
0x40007C00 — 0x40007FFF UART8 APB1 «30.6.8: USART register map», стр. 1018
0x40007800 — 0x40007BFF UART7
0x40007400 — 0x400077FF DAC «14.5.15: DAC register map», стр. 453
0x40007000 — 0x400073FF PWR «5.6: PWR register map», стр. 149
0x40006800 — 0x40006BFF CAN2 «32.9.5: bxCAN register map», стр. 1118
0x40006400 — 0x400067FF CAN1
0x40005C00 — 0x40005FFF I2C3 «27.6.11: I2C register map», стр. 872
0x40005800 — 0x40005BFF I2C2
0x40005400 — 0x400057FF I2C1
0x40005000 — 0x400053FF UART5 «30.6.8: USART register map», стр. 1018
0x40004C00 — 0x40004FFF UART4
0x40004800 — 0x40004BFF USART3
0x40004400 — 0x400047FF USART2
0x40004000 — 0x400043FF I2S3ext «28.5.10: SPI register map», стр. 925
0x40003C00 — 0x40003FFF SPI3 / I2S3
0x40003800 — 0x40003BFF SPI2 / I2S2
0x40003400 — 0x400037FF I2S2ext
0x40003000 — 0x400033FF IWDG «21.4.5: IWDG register map», стр. 712
0x40002C00 — 0x40002FFF WWDG «22.6.4: WWDG register map», стр. 719
0x40002800 — 0x40002BFF Регистры RTC и BKP «26.6.21: RTC register map», стр. 836
0x40002000 — 0x400023FF TIM14 «19.5.12: TIM10/11/13/14 register map», стр. 694
0x40001C00 — 0x40001FFF TIM13
0x40001800 — 0x40001BFF TIM12 «19.4.13: TIM9/12 register map», стр. 684
0x40001400 — 0x400017FF TIM7 «20.4.9: TIM6 and TIM7 register map», стр. 707
0x40001000 — 0x400013FF TIM6
0x40000C00 — 0x40000FFF TIM5 «18.4.21: TIMx register map», стр. 648
0x40000800 — 0x40000BFF TIM4
0x40000400 — 0x400007FF TIM3
0x40000000 — 0x400003FF TIM2

bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number x 4)

0x22006008 = 0x22000000 + (0x300*32) + (2*4)

Выводы для выбора режима загрузки Режим загрузки
На что происходит ссылка
BOOT1 BOOT0
x 0 Основная память Flash В качестве области загрузки выбрана основная память Flash.
0 1 Системная память В качестве области загрузки выбрана System Memory.
1 1 Встроенная SRAM В качестве области загрузки выбрана встроенная SRAM.
Адреса Boot/Remap
в основную Flash
Boot/Remap
во встроенную SRAM
Boot/Remap
в System Memory
Remap в FSMC
0x2001C000 — 0x2001FFFF SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB)
0x20000000 — 0x2001BFFF SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB)
0x1FFF0000 — 0x1FFF77FF System Memory System Memory System Memory System Memory
0x08100000 — 0x0FFFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x08000000 — 0x080FFFFF Память Flash Память Flash Память Flash Память Flash
0x04000000 — 0x07FFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x00000000 — 0x000FFFFF (1)(2) Ссылка на Flash (1 MB) Ссылка на SRAM1 (112 KB) Ссылка на System
Memory (30 KB)
Ссылка на FSMC bank 1 NOR
/PSRAM 1 (128 MB)
Адреса Boot/Remap
в основную Flash
Boot/Remap
во встроенную SRAM
Boot/Remap
в System Memory
Remap в FMC
0x20020000 — 0x2002FFFF SRAM3 (64 KB) SRAM3 (64 KB) SRAM3 (64 KB) SRAM3 (64 KB)
0x2001C000 — 0x2001FFFF SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB) SRAM2 (16 KB)
0x20000000 — 0x2001BFFF SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB) SRAM1 (112 KB)
0x1FFF0000 — 0x1FFF77FF System Memory System Memory System Memory System Memory
0x08100000 — 0x0FFFFFFF Зарезервировано Зарезервировано Зарезервировано Зарезервировано
0x08000000 — 0x080FFFFF Память Flash Память Flash Память Flash Память Flash
0x04000000 — 0x07FFFFFF Зарезервировано Зарезервировано Зарезервировано Ссылка на FMC bank 1 NOR
/PSRAM 2 (128 MB)
0x00000000 — 0x001FFFFF (1)(2) Ссылка на Flash (2 MB) Ссылка на SRAM1 (112 KB) Ссылка на System
Memory (30 KB)
Ссылка на FMC bank 1 NOR
/PSRAM 1 (128 MB),
или ссылка на FMC SDRAM
bank 1 (128 MB)

STM32 Jump to System Memory Bootloader

All STM32 MCUs has a builtin bootloader stored in so-called system memory. The system memory is a ROM (read-only memory) which is created during the production of the MCU and can never be changed (it can however be disabled — see Read Out Protection). When the MCU startup the Boot0 pin is asserted and if high (pulled up to VCC) the MCU will execute the bootloader.

Contents

The «problem» (or challenge)

But what if we would like to execute this bootloader programmatically based on some other event for example the press of a user button or a command in a serial console. While this is entirely possible it is surprisingly difficult. The problem is that the built-in bootloader make a lot of assumptions and it is necessary to make certain all these assumptions are met before jumping to it. In general that would look something like:

  • Find system memory location for specific STM32 in AN2606 (see Miscellaneous Links)
  • Set RCC to default values (the same as on startup) [Internal clock, no PLL, etc.)
  • Disable SysTick interrupt and reset it to default
  • Disable all interrupts
  • Map system memory to 0x00000000 location
  • Set jump location to memory location + 4 bytes offset
  • Set main stack pointer to value stored at system memory location address
  • Call virtual function assigned before

Depending on which peripherals is being used, the above can be quite complicated and changes in code can easily screw this up.

The easy solution

Fortunately, there is in fact an easier way to do this. If we look at the code generated by STM32CubeMX the startup is like this:

By the time the main function is being called, only the memory has been initialized (BSS has been set to 0x00 throughout), and if we were to do the jump immediately (in the USER CODE BEGIN 1 section) that would work just fine. That would look something like this:

Of course the result of that would be an application that always executed the bootloader, and that is not really useful, nor is it what we wanted to do.

What we need is a way to store a flag, which will survive a system restart of the MCU. This is a little bit tricky since the user memory (RSS) is set to zero during restart. There are multiple examples online of how to store variables/flags which will survive a processor reset. A common approach is to use the user registers of the Real Time Clock (RTC), however this approach is quite complicated (require the RTC to be initialized) and it is quite hard to make it generic for all STM32s since the RTC differs quite a lot between the STM32 variants.

Fortunately there’s a hack which can be utilized here. If we look at the memory (RAM) of a typical STM32 application it looks something like:

Typical RAM layout.png

The DATA and RSS are being reset during restart, but everything above that (heap + stack) are being left alone. Not only is it being left alone, but we got variables from the linker which tells us exactly where they are independent of the actual MCU. Looking at a typical linker script (generated by STM32CubeMX we will find the following:

In other word, the _estack points to the highest memory location (the stack grows down, while the heap grows up).

Of course under «normal» circumstances one shouldn’t mess with the stack, but in our case immediately after messing with it we perform a system reset, so we can afford to lose whatever is stored somewhere in the stack. If we debug the application the MCU registers contain the following at the start of the main function:

Registers at start of main.png

The interesting register here is the stack pointer SP which contains 0x2001fff0. The highest RAM address on the particular MCU used in this example (Black Pill STM32F411) is 0x2001ffff, so the stack at this point have used about 15 bytes. Any value after that (remember the stack grow down, so lower address) will be unused at this point. If we create a pointer like this:

we can store a «known» value at that location, reset the MCU and then check that value immediately at startup.

Our initial code shown earlier can now be expanded like this:

If our bootloader flag contains anything but BOOTLOADER_FLAG_VALUE, the application will move on with it’s normal initialization of interrupts, timers, peripherals etc., but IF our flag contains BOOTLOADER_FLAG_VALUE it will jump — successfully — to the internal bootloader. Triggering this with a user button could look like this:

In this case, if a button connected to BTN_Pin is pressed for more than 1 second, the device will reboot in bootloader mode.

Evaluation

Now, I am fully aware that messing with the stack like I do in this example is quite naughty. The question is, is there any way this could go wrong. Well, the answer is a «yes» but unlikely. If we look at the point where we do mess with the stack, it looks like this:

I guess that if a interrupt happened between setting the bootloader flag and calling the reset something unexpected could happen. Also a possible issue would be if the HAL_NVIC_SystemReset function call pushed the return address pushed to the stack would be at the exact offset location. This might require a bit more analysis.

Boot memory selection stm32 для чего нужен

[Note: Learn the STM32 summary of the notes, do not spray. There are still some shortcomings.
—— This article is reproduced from the original, infringement, please contact the author, thank you. 】
Original blog address:

First, three BOOT mode introduction
The so-called startup, generally means that after we have a good program, when the chip is restarted, the fourth rising edge of SYSCLK, the value of the BOOT pin will be latched. The user can select the startup mode after reset by setting the state of the BOOT1 and BOOT0 pins.

Main Flash memory
is the built-in Flash of STM32. Generally, when we use JTAG or SWD mode to download the program, it is downloaded to this, and it will start the program directly after restarting.

System memory
Boot from system memory, the program function started in this mode is set by the manufacturer. In general, this type of startup is used less. The system memory is a specific area inside the chip. When the STM32 is shipped from the factory, the ST presets a BootLoader inside the area. This is the ISP program we often say. This is a ROM.
cannot be modified after shipment. Generally speaking, when we use this startup mode, we download the program from the serial port. Because the BootLoader provided by the manufacturer provides the firmware of the serial download program, the program can be downloaded to the system Flash through the BootLoader. But this download method requires the following steps:
Step1: Set BOOT0 to 1, BOOT1 to 0, and then press the reset button to start BootLoader from system memory.
Step2: Finally, with the help of BootLoader, download the program to Flash through the serial port.
Step3: After the program download is completed, it is necessary to set BOOT0 to GND and reset manually. In this way, STM32 can be booted from Flash and can be seen. , need to jump over the cap to jump, very do not pay attention to the user experience.

Embedded Memory
Built-in SRAM, since it is SRAM, naturally there is no program storage capability. This mode is generally used for program debugging. If I only modified a small place in the code, then I need to erase the entire Flash again. The time-consuming comparison can be considered to start the code from this mode (that is, the memory of STM32) for fast program debugging, etc. After the program debugging is completed, the program is downloaded to the SRAM.

Second, develop BOOT mode selection.
1, usually use the program code stored in the main flash memory, configuration mode: BOOT0 = 0, BOOT1 = X;

2, Flash lock solution:

During the development and debugging process, the internal flash is locked for some reason, the SWD and Jtag debugging cannot be connected, and the device cannot be read. The code can be rewritten by modifying the BOOT mode.

Modified to BOOT0=1, BOOT1=0 can be booted from the system memory, ST comes with the Bootloader program, SWD and JTAG debug interface are dedicated. After re-programming, you can change the BOOT mode to BOOT0=0, BOOT1=X to use normally.

———————————————- Reproduce the summary article, If there is any infringement, please contact the author to delete, thank you.

Русские Блоги

[Stm32] Глубокие размышления о запуске оперативной памяти stm32 (2)

1. Введение

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

2. Три режима запуска

В настоящее время stm32 поддерживает 3 режима запуска.

BOOT0 BOOT1 Режим запуска Начальный адрес
0 x flash 0x0800 0000
1 0 Системная память 0x1FF00000
1 1 RAM 0x2000 0000

Начиная с флэш-памяти и системной памяти, система выполнит сопоставление адресов.

STM32 рассматривает область от 0x00000000 до 0x0005FFFF как область псевдонима загрузочного пространства.

Например, начиная с флэш-памяти, в этом случае доступ к адресам 0x0 и 0x0800 0000 абсолютно одинаков.
Итак, после запуска cotex-M3 берет MSP с адреса 0x0, а ПК с адреса 0x4, что означает, что он принимает 0x8000000 и 0x08000004. Эквивалентны.
Однако запуск ОЗУ является исключением.

Даже если мы выберем загрузку из ОЗУ, мы не сможем получить доступ с 0x2000 0000 до 0x0.
Как начинается ОЗУ?

3. Загрузка RAM

3.1 Принцип

Прежде всего, мы знаем, что когда boot0 = 1, boot1 = 1, то есть при запуске RAM, cotex-m3 должен принимать msp из 0x0 и pc из 0x4, а 0x2000 0000 и 0x0 не отображаются вместе после запуска .
Итак, у нас есть две догадки:

  1. Система не выполняет сопоставление от 0x2000 0000 до 0x0, но присваивает значения 0x2000 0000 и 0x20000004 SP и ПК при запуске с помощью внутреннего метода системы.
  2. Система выполняет сопоставление от 0x2000 0000 до 0x0 во время включения питания. После запуска (после включения MSP и ПК) сопоставление отключается, а затем два пространства открываются независимо.

Я не нашел никакой информации, чтобы объяснить это, но эффект, достигаемый обоими, одинаков.Лично я предпочитаю второй, который легко запомнить.
Вырежьте реальное изображение, и вы увидите, что они действительно разные.

3.2 Методика эксперимента

3.2.1 Создание нового элемента проекта RAM

Найдите простой проект, который может стабильно работать на флеш-памяти, и создайте новый элемент проекта для запуска RAM.

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

После переключения вы увидите, что название проекта слева другое.

За исключением связанных с конфигурацией, все добавленные файлы кода являются общим набором.

3.2.2 Изменение адресов ПЗУ и ОЗУ

Каждый должен заранее ознакомиться с настройкой загрузки флеш-памяти.

Здесь мы переключаемся на загрузку из ОЗУ.
Сначала посмотрите на размер скомпилированного файла.

Откройте файл карты

можно увидеть
Размер созданного bin-файла составляет 5884 байта.

Таким образом, мы можем выделить в ПЗУ более 5884.

Здесь тоже яма, это последнее слово.

3.2.3 настройки вкладки отладки

Удалить приложение загрузки при запуске
Загрузите CpuRam.ini, который я также нашел в Интернете.

3.2.4 Добавить глобальный макрос VECT_TAB_SRAM

VECT_TAB_SRAM в основном используется для сброса таблицы векторов прерываний во время systemInit.

3.2.5 Вкладка "Настроить утилиты"

3.2.6 Изменение уровня пина загрузки оборудования

Подключите Boot0 и BOOT1 к высокому уровню.

3.2.7 Запуск в режиме отладки

ОЗУ нельзя запрограммировать на загрузку флеш-памяти таким образом, и нельзя ее перезапустить после выключения питания.
в основном работает в режиме отладки.

После входа в отладку вы можете пошагово, на полной скорости и сбросить.
В Интернете есть сообщения о том, что они не могут сбросить настройки, но я с ними не сталкивался. Они могут работать нормально.

Иногда он будет нестабильным при запуске и выйдет из режима отладки при сообщении об ошибке, но его также можно использовать.

Я долго бегал после просмотра картинки.

4. Обнаружена яма

Когда я запускал ОЗУ, я вводил аппаратное исключение каждый раз, когда сталкивался с SystemInit, что меня очень расстраивало. Я чувствовал, что это ненормально, как только я нажимал на стек. Однако я был действительно подавлен, когда отслеживал изменения MSP в соответствии с моими ожиданиями. На выяснение причины ушло много времени.
Я видел этот абзац в китайском руководстве по stm32 раньше,

stm32f103, который я использовал для тестирования, я думал, что RAM 64k, то есть 0x2000 0000

0x20010000, поэтому ROM разделен на 0x2000 0000

0x2000 8000, RAM разделен на 0x2000 8000

0x 2001 0000 .
На самом деле это совсем не так. ОЗУ stm32f103c8t6 составляет всего 20 КБ, поэтому пара операций SP является ненормальной и осуществляется доступ к недопустимому адресу.
После изменения размера это нормально.

Похожие статьи