Stm32 Часть 1: Основы

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

— Кен Томпсон Пожалуй, моя любимая цитата.

Именно она стала причиной того, что я решил нырнуть в самую глубину кроличьей норы.

Свой путь в мир программирования я начал совсем недавно, прошло всего около месяца и я решил писать статьи для закрепления материала.

Все началось с простой задачи — синхронизировать лампы в моей фотостудии с помощью Arduino. Проблема решилась, но в фотостудию я больше не ходила, времени не было.

С этого момента я решил основательно заняться программированием микроконтроллеров.

Arduino хоть и привлекательна своей простотой, но как платформа мне не понравилась.

Выбор пал на компанию СТ и их популярную продукцию.

В тот момент я еще не понял, в чем разница, но, как типичный потребитель, сравнил скорость «процессора» и объем памяти и купил себе внушительную плату с дисплеем STM32F746NG — Discovery. Я пропущу отчаянные моменты и перейду сразу к делу.

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

И как я уже описал выше, мне хотелось изучить, ну всё.

И для этого я поставил цель, никаких готовых решений, только свои.

И если у меня все получилось, то и у вас тоже получится.

Список всего, что вам понадобится:

  1. Виртуальная машина Убунту 16+ или что у вас есть под рукой
  2. рука компилятор - скачать по ссылке Developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
  3. openocd отладчик и программатор - скачать по ссылке не получится, компилируем из исходников, инструкция прилагается
      
      
      
      
       

    git clone https://git.code.sf.net/p/openocd/code openocd

  4. Текстовый редактор на ваш выбор
Как только все будет установлено и собрано, мы сможем приступить к нашему первому проекту! И нет, это даже не мигающая лампочка.

Сначала надо углубиться в процесс инициализации самого МК.

То, что нам нужно:

  1. Makefile
  2. Linker.ld
  3. Init.c
Начнем с последнего пункта Init.c. Прежде всего, наш микроконтроллер должен загрузить адрес «указателя стека», это указатель на адрес памяти, который используется для инструкций PUSH и POP. Настоятельно рекомендую вам внимательно изучить эти две инструкции, так как я не буду подробно объяснять все инструкции.

Ниже описано, как это реализовать.



extern void *_estack; void *vectors[] __attribute__((section(".

isr_vector"), used)) = { &_estack }

Теперь давайте посмотрим на этот пример.

Extern означает, что символ является внешним, и этот символ мы объявили в файле Linker.ld, к нему вернемся чуть позже.



__attribute__((section(".

isr_vector"), used))

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

И его первым элементом будет тот самый указатель.

Теперь разберемся, для чего нужен этот массив и с чем МК его будет есть.

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

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

Позволь мне привести пример.

Учитывая, что стек начинается с адреса 0x20010000, а код программы — 0x0800008. тогда массив можно записать как

void *vectors[] __attribute__((section(".

isr_vector"), used)) = { 0x20010000, 0x08000008 }

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

Теперь самое главное, что в зависимости от модели эти цифры могут быть разными, но на примере stm32f7 я могу с уверенностью сказать, что этот массив должен находиться в памяти по адресу 0x08000000. Именно с этого адреса МК начнет свою работу после включения или перезагрузки.

Теперь давайте передохнем и уделим внимание тому, как именно поместить этот массив в нужный нам раздел.

Это то, что делает «ld» или компоновщик.

Эта программа объединяет всю нашу программу и использует для этого скрипт Linker.ld. Я приведу пример и мы его разберем дальше.



MEMORY{

Теги: #stm32 #разработка на Arduino #stm32f7
Вместе с данным постом часто просматривают: