Удобное использование libmaple в Eclipse CDT

Библиотека libmaple для работы с stm32 уже упоминалась здесь. Для начинающих осваивать stm32 она представляет собой значительно более высокоуровневую, простую и понятную альтернативу CMSIS+SPL.

Входит она в состав Maple IDE от leaflabs, который является подобием среды ардуино. И если в IDE всё делается классическими скетчами, то сама libmaple, доступна отдельно от IDE и позволяет писать под stm32 на С/С++. Это и есть её основное назначение, на сайте присутствует соответствующая документация. Используются для этого внешние arm-none-eabi тулчейны, хотя наверняка можно изверуться и использовать входящий в состав IDE тулчейн на базе Code Sourcery G++.

Полученый бинарник заливается через USB bootloader, который тоже доступен в исходных кодах. Собственно-говоря, у них всё доступно в исходных кодах. Использование бутлоадера необязательно. Можно спокойно заливать через st-link, смещая базовый адрес на 0x5000 от начала flash, для сохранения бутлоадера. После сброса он передаст управление вашему коду. Но использовать бутлоадер вполне удобно, в libmaple есть всё необходимое для этого.

Надо сказать, что саму библиотеку libmaple предлагается использовать достаточно забавным способом — каждый раз делать свой проект на основе копии сорцов библиотеки. Буквально — скачиваем (git clone) её сорцы, переименовываем каталог и хакаем её, превращая в собственный проект. В ней уже содержистя своя билд-система на make с обильным использованием фрагментов мэйкфайлов.

Понятное дело, когда такой проект всего один (два-три максимум) — это нестрашно. Но по мере роста количества проектов (с учётом лёгкости её использования), кол-во бардака во вселенной начинает расти… Каждый раз, когда выходят апдейты к библиотеке на github (мы же не против получить фиксы и улучшения), нам необходимо смержить их с каждым своим проектом. А если мы сами что-то поправили в библиотеке, нам точно так же необходимо ручками разнести это во все проекты. Это неудобно. И потому…

И потому, в один прекрасный момент, сотрудник leaflabs Marti Bolivar решил сделать мир чуточку лучше. И выпустил свой проект example-libmaple-project, который является шаблоном пустого проекта, использующего библиотеку libmaple, лежащую в стороне, в количестве одного экземпляра. В ней больше вообще ненадо ничего менять.

Wow! Скажем мы :) Мир заиграл новыми красками! И будем почти правы… Почти — потому что не бывает всегда всё хорошо, что-то должно быть обязательно не так :) И оно не так — проект использовал shell-скрипт в качестве обёртки вокруг make. Что плохо укладывалось в концепцию Makefile project with existing sources в Eclipse CDT.

Когда меня это стало огорчать совсем сильно, я пошёл и отослал автору фикс, который он любезно включил в проект с моими дополнениями в README на тему удобного использования этого счастья в Eclipse CDT. Теперь там красота — никаких хаков с шелл-скриптами, честный Makefile и полная любовь с Eclipse.

На всякий случай мой репозиторий, в котором могут быть некоторые фиксы, ещё не принятые автором исходного проекта.

Заодно была пофикшена сама libmaple — теперь она умеет работать с Summon/Linaro GCC.

К сожалению, до сих пор не преодолён недостаток билд-системы самой libmaple, из за которого она требует, чтобы в её корне обязательно находился хотя бы пустой main.cpp. Поэтому, в описании ниже, мы кладём его туда, но в репозиторий он не добавляется и апдейтам самой libmaple никак не мешает.

Стоит упомянуть ещё один недостаток libmaple — она не только альтернативна CMSIS, но и не опирается на него в своей реализации. Это приводит к определённым усилиям по портированию её на более свежие/продвинутые камни и к достаточно чувствительным задержкам в её развитии. Если не ошибаюсь, были одна-две попытки переписать её поверх CMSIS, но особого успеха они не принесли.

Краткий перевод-компиляция необходимых шагов:

  1. Устанавливаем тулчейн и прописываем его в PATH, я поставил Summon ARM GCC в ~/sat/
  2. Устанавливаем Eclipse CDT (у меня 3.7, всё дальнейшее в соотв. с этой версией).
  3. Открываем окно терминала и делаем:
    cd ~/my-some-work-dir
    git clone https://github.com/leaflabs/libmaple
    git clone https://github.com/mbolivar/example-libmaple-project
    git clone https://github.com/leaflabs/maple-bootloader
    

  4. Копируем пустой main.cpp из корня example-libmaple-project в корень libmaple.
  5. Идём в Makefile проекта example-libmaple-project и задаём значения следующих переменных:
    • BOARD — тип платы. Посмотреть список совместимых можно с помощью make list-boards.
    • MEMORY_TARGET — способ установки бинарника: flash, ram или jtag. Подробности смотрим в make help и документации libmaple.
  6. Можно прописать глобально переменную окружения LIB_MAPLE_HOME, указывающую на корень libmaple, но можно этого и не делать, если мы будем использовать разные версии для разных проектов. Если вы собираетесь работать из командной строки без Eclipse, то можно ничего больше не делать. Единственное, что LIB_MAPLE_HOME тогда стоит всё же задать — либо через переменную окружения, либо в Makefile.
  7. Запускаем Eclipse CDT и создаём/открываем workspace.
  8. Для каждого из трёх проектов делаем: File -> New -> Project… -> Makefile Project with Existing Code и указываем на нужный проект.
  9. Правый клик на проект example-libmaple-project, идём в Properties -> C/C++ Build -> Behaviour tab и меняем дефолтный target all на sketch
  10. Если мы не задали переменную окружения LIB_MAPLE_HOME глобально, мы можем задать её для конкретного проекта: Properties -> C/C++ Build -> Environment.
  11. Наконец, если мы вообще нигде не определили LIB_MAPLE_HOME, можно прописать её значение явно в Makefile проекта example-libmaple-project.
  12. Идём в Properties -> C/C++ General -> Indexer и включаем чекбоксы: 'Enable project specific settings', 'Index unused headers as C files' и 'Index unused headers as C++ files'.
  13. Теперь идём в Properties -> C/C++ General -> Paths and Symbols и добавляем следующие пути на вкладке Includes (можно прописать абсолютные пути, но удобнее всё же пользоваться переменной LIB_MAPLE_HOME, которую мы задали ранее). При задании каждого пути стоит включить чекбоксы, отвечающие за создание пути для каждого языка и конфигурации. Необходимые пути (не перепутайте тип скобок):
    ${LIB_MAPLE_HOME}/wirish/include
    ${LIB_MAPLE_HOME}/libmaple/include
    ${LIB_MAPLE_HOME}/wirish/boards/<directory with your board name>/include
    ${LIB_MAPLE_HOME}/libmaple/<directory with your cpu family code>/include
    

    Пример моих путей для проца и платы:
    ${LIB_MAPLE_HOME}/wirish/boards/maple_RET6/include
    ${LIB_MAPLE_HOME}/libmaple/stm32f1/include
    

  14. На забудьте сохранить настройки кнопкой Apply или OK.
  15. Теперь можно делать проекту clean и build.

Вопросы и исправления приветствуются!
  • +2
  • 10 января 2013, 03:13
  • dipspb

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

RSS свернуть / развернуть
Для начинающих осваивать stm32 она представляет собой значительно более высокоуровневую, простую и понятную альтернативу CMSIS.
Ну не CMSIS, а SPL и прочим HAL-библиотекам. Ну и оно не только для STM32, что является веским плюсом.
Можно спокойно заливать через st-link, смещая базовый адрес на 0x5000 от начала flash, для сохранения бутлоадера.
У них что, бутлоадер целых 20 КБ?
0
  • avatar
  • Vga
  • 10 января 2013, 14:10
1) CMSIS — это тоже HAL, прямая цитата от ARM: «The ARM® Cortex™ Microcontroller Software Interface Standard (CMSIS) is a vendor-independent hardware abstraction layer for the Cortex-M processor series.» IMHO, libmaple это альтернатива CMSIS+SPL, если говорить точнее.

2) В оригинале, libmaple только для STM32. Цитата раз: «LeafLabs’ libmaple (source code on GitHub) is the library we have developed for the STM32 line of ARM Cortex M3 microcontrollers.», цитата два:
mpro:libmaple dipspb$ pwd
/Users/dipspb/work/maple/libmaple
mpro:libmaple dipspb$ ls -l wirish/boards | grep drwx
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 VLDiscovery
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 maple
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 maple_RET6
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 maple_mini
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 maple_native
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 olimex_stm32_h103
drwxrwxr-x  4 dipspb  staff  136 Jan  5 23:52 st_stm3220g_eval
mpro:libmaple dipspb$ ls -l libmaple | grep drwx
drwxrwxr-x   3 dipspb  staff    102 Jan  5 23:52 include
drwxrwxr-x  17 dipspb  staff    578 Jan  5 23:52 stm32f1
drwxrwxr-x  16 dipspb  staff    544 Jan  5 23:52 stm32f2
drwxrwxr-x   6 dipspb  staff    204 Jan  5 23:52 usb


Другое дело, что она разработана семантически совместимо с AVR библиотеками Arduino и Wiring. Но это не значит, что можно использовать для AVR/Arduino. Но степень переносимости — да, хорошая.

3) Размер бутлоадера под RET6 = 15508 байт. Что и зачем они туда впихнули — можно посмотреть здесь. Насколько я вижу по TODO, на этот момент они используют неупакованные структуры. Но не думаю, что упаковка сильно сократит размер. Подробнее про бутлоадер — тут.
0
IMHO, libmaple это альтернатива CMSIS+SPL, если говорить точнее.
Вообще, я libmaple не ковырял, но наверняка она тоже работает поверх CMSIS. CMSIS — это по сути хедеры с описанием регистров, без них никак. HAL там только для стандартного ядра CM3.
В оригинале, libmaple только для STM32.
Ее давно уже приспособили и для других кортексов. Nuvoton, например.
3) Размер бутлоадера под RET6 = 15508 байт.
Довольно здоровый. Хотя на бордах Maple оно возможно и несущественно.
0
Увы — она не работает поверх CMSIS. Ребята пошли героическим путём. Добавил в текст про это.

Именно libmaple — не приспособили. Приспособили проекты от неё отпочкованные. Степень их живости и актуальности нужно смотреть.

Размер бута меня тоже впечатлил, но да — для кортексов действительно некритично. Что-то мне подсказывает, что его можно ужать.
0
Надо же. Вот извращенцы)
0
Я так же поступил для LPC23xx, там все регистры в CMSIS объявлены дефайнами, а мне хотелось структуры иметь для упрощения.

Но зачем для кортексов так делать, не знаю ><
0
Но степень переносимости — да, хорошая.
Ещё бы оно в F103-й помещалось, было бы совсем замечательно =)
0
Дык помещается, какие проблемы?
0
Не знаю, пробовал я свой Simple Dumping Monitor портировать, но тут же стек переполнился. Соответственно беглое ознакомление с кодом дало неутешительный вердикт — в Arduino стоит самый толстый камень в линейке, а в сабж поставили исходя из соотношения качество/цена, то есть середнячок. Так что как говорится и на том спасибо, от этой идеи пришлось отказаться. Надеюсь, что до лучших времён, ARM-ы пока только осваиваю =)
0
спасибо за ссылку, у Вас интересный ресурс. Сложил в закладки :)
+1
Видимо надо соответствующие настройки покрутить, что бы стека было больше. Или с алгоритмом разобраться. Или и то и другое вместе. «Сабж» это либа, а не конкретная железка, пользоваться ею можно для самых разных камней и даже линеек.

А если говорить конкретно о лифлабсовских платах, то в силу особенностей стм-ок Maple от Maple RET6 отличается только микроконтроллером, сами платы идентичны. С минимальными доделками платы в нее можно запаивать вообще любой камень в соответствующем корпусе из линеек F103/F2x/F4x. На F3 еще не смотрел, но подозреваю, что и их тоже.
0
+1, я на flymaple запускаю, туда F4 запросто перепаять можно. Хотя и тесновато всё.
0
Я разрабатывал три из 5 плат на openstm32hw, потому, собственно, в курсе всех потрохов меплов.
0
Но есть варианты libmaple, адаптированные под STM32F4 сторонними разработчиками.
0
Текущая (на гитхабе) версия тоже поддерживает F4.
0
Простите, туплю… Вот смотрю и в упор не вижу соотв каталогов include под эти серии. Ткните пальцем в конкретное место репозитория пожалуйста.
0
Для F1:
mpro:libmaple dipspb$ find . -type f | xargs grep STM32_SERIES_F1
./examples/test-usart-dma.cpp:#if STM32_MCU_SERIES == STM32_SERIES_F1
./libmaple/include/libmaple/stm32.h:#define STM32_SERIES_F1 0
./libmaple/include/libmaple/stm32.h: * At time of writing, allowed values are: STM32_SERIES_F1,
./libmaple/stm32f1/include/series/stm32.h:#define STM32_MCU_SERIES                STM32_SERIES_F1
./wirish/HardwareSerial.cpp:#if STM32_MCU_SERIES == STM32_SERIES_F1
./wirish/include/wirish/HardwareTimer.h:#if (STM32_MCU_SERIES == STM32_SERIES_F1) && defined(STM32_HIGH_DENSITY)
./wirish/include/wirish/wirish.h:#if STM32_MCU_SERIES == STM32_SERIES_F1 /* FIXME [0.0.13?] port to F2 */
mpro:libmaple dipspb$ 

Для F2:
mpro:libmaple dipspb$ find . -type f | xargs grep STM32_SERIES_F2
./examples/test-usart-dma.cpp:#elif (STM32_MCU_SERIES == STM32_SERIES_F2 || \
./libmaple/include/libmaple/stm32.h:#define STM32_SERIES_F2 1
./libmaple/include/libmaple/stm32.h: * STM32_SERIES_F2. This set of values will expand as libmaple adds
./libmaple/stm32f2/include/series/stm32.h:#define STM32_MCU_SERIES                STM32_SERIES_F2
./wirish/HardwareSerial.cpp:#elif (STM32_MCU_SERIES == STM32_SERIES_F2) ||    \
mpro:libmaple dipspb$ 

Для F4 только какие-то наброски с serial:
mpro:libmaple dipspb$ find . -type f | xargs grep STM32_SERIES_F4
./examples/test-usart-dma.cpp:       STM32_MCU_SERIES == STM32_SERIES_F4)
./libmaple/include/libmaple/stm32.h:#define STM32_SERIES_F4 3
./wirish/HardwareSerial.cpp:      (STM32_MCU_SERIES == STM32_SERIES_F4)
mpro:libmaple dipspb$ 
0
F2 от F4 отличается только набором инструкций. Что, как бы, намекает, что достаточно собрать либу с соответствующими ключами компилятора.
0
Не только… Отличается частотой, а значит неплохо бы изменить константы в хидерах, для правильной работы таймеров. Даже те же ключи нужно проставить в мейкфайлы.

И тем не менее, никаких изменений на эту я не вижу в репозитории libmaple. Когда девелопер ala42 сделал патч libmaple для работы с f4, его изменения коснулись самой libmaple и бутлоадера. Но в репозитории github.com/leaflabs они, насколько я вижу на этот момент, не вошли. IMHO, они вошли в сторонние репы aeroquad, openstm32sw и libopencm3.

Поэтому, утверждать: «Текущая (на гитхабе) версия тоже поддерживает F4.» — некорректно. Допилить несколькими штрихами — возможно. Но «из коробки» — не вижу этого.
0
Ну ключи в мейкфайл это, как бы, не сильно проблематично. Константы — возможно. Что касается бутлоадера, то он, во-первых, ничего по сути не делает после патча ala42, а во-вторых все бутлоадеры живут отдельно и не являются частью libmaple.
0
Если кому-то интересно вот мои наработки по libmaple для stm32f4discovery code.google.com/p/stm32f4discovery-libmaple/
За основу взял libmaple использующийся в aeroquad и допилил чтоб он компилялся в виндах.
+1
спасибо! Но разве софт aeroquad32 не был построен уже на патче ala42?
0
«несложно» — согласен. Но в репе этого нет. А где можно посмотреть патч ala42 в чистом виде? Я его выделял из openstm32sw методом сравнения с libmaple того времени.
0
В форуме была ссылка на него, но с ходу я не нашел.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.