Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кармин Новиелло - Освоение STM32.pdf
Скачиваний:
2754
Добавлен:
23.09.2021
Размер:
47.68 Mб
Скачать

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-Bus1 в Cortex-M3/4/7 и через S-Bus в Cortex-M0/0+) в то время как область данных (SRAM) начинается с адреса 0x2000 0000 (доступ через S-Bus). Процессоры Cortex-M всегда выбирают таблицу

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

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

575

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

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

Таблица 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 является одним из них).

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

576

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

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

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

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

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

Системная память

Внутреннее SRAM

Банк 1 FMC NVM

Банк 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. Вы будете нести ответственность за вызов этого обработчика исключений и за обеспечение того, чтобы ЦПУ был переведен в начальные условия, которые целевая микропрограмма ожидает найти (например, все периферийные устройства отключены и т. д.).

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

577

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

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

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

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

Рисунок 2: Структура регистра VTOR