Полностью ли поддерживается C++ STL на Arduino?
У меня пока нет платы Arduino для запуска кода, и, как следует из заголовка, мне интересно, поддерживается ли C++ STL полностью на Arduino и является ли он частью Arduino IDE. STL, вероятно, является наиболее эффективным, полностью протестированным и требующим минимальных ресурсов (что является несколько избыточной фразой, поскольку я уже упоминал эффективность) общедоступным кодом C++, и он значительно облегчит жизнь при программировании для Arduino.
Если STL не является частью Arduino IDE, то как включить определенные библиотеки, такие как <algorithm>
и <utility>
? (Мне очень хочется спросить «почему она не включена?», но это кажется слишком общим.)
@NonCreature0714, 👍11
Обсуждение4 ответа
Лучший ответ:
STL не является частью Arduino IDE.
Хотя это эффективно по стандартам настольных компьютеров, консенсус в том, что это не помещается комфортно в ограниченном пространстве Arduino. Тем не менее, вот кто-то, кто, кажется, сделал это:
https://github.com/maniacbug/StandardCplusplus
Проверьте вилки, они кажутся более современными
ОБНОВЛЕНИЕ 01 ИЮЛЯ 24 ГОДА
Спустя годы я хотел бы указать на убедительные альтернативы:
- etl https://github.com/ETLCPP/etl
- моя собственная estdlib https://github.com/malachi-iot/estdlib
Я против этого консенсуса :p, так что это уже не совсем консенсус? ;p его следует использовать с умом, но он может быть очень мощным/полезным. Не все из него может работать так же хорошо. Но мы использовали std::queue для создания очереди сообщений, которую Arduino очистит. Теоретически она может переполниться, но обычно это более эффективно с точки зрения пространства, чем установка фиксированного буфера. Потому что нужно установить буфер достаточно большим, но в итоге всегда будет «использована» вся память буфера., @Paul
@Paul Не могли бы вы объяснить, почему у вас другая точка зрения? Я уверен, что это интересно/познавательно., @NonCreature0714
@Paul, вы используете версию maniacbug или другую версию? Пожалуйста, поделитесь. STL кажется мне интересным, но он немного склоняется к динамическому распределению, и rtti уклонился от многих (включая меня) от использования его в сценариях AVR, @Malachi
Я отредактировал свой ответ, в основном создание фиксированного буфера для вашего хранилища менее эффективно с точки зрения пространства, чем использование динамического хранилища. Проблемы у вас будут только тогда, когда закончится память, и поскольку оно динамическое, его трудно предсказать. Но в целом позже должно давать сбой., @Paul
Это было на самом деле на втором курсе, мы использовали GNU-GCC toolchain с, я думаю, AVR-GCC, avrdude и eclipse. Но я не знаю, как мы получили stl, это казалось простым в то время, @Paul
Тема с некоторыми другими вариантами и мыслями по STL: https://forum.arduino.cc/index.php?topic=360116.0, @Malachi
Я потерял набор инструментов, так как у меня появился новый ноутбук. Мне очень жаль, но у меня есть код из того проекта. Я спрошу у одноклассников, могут ли они найти документ по настройке GCC для AVR с STL, @Paul
Но, я думаю, стоит попробовать, особенно с новыми микроконтроллерами, с большим объемом оперативной памяти. Если вы попробуете, это может действительно работать очень хорошо., @Paul
Даже при ограниченном объеме оперативной памяти, если вы попытаетесь написать свой собственный связанный список, вы можете обнаружить, что у вас не получится сделать это лучше, чем с помощью STL., @Nick Gammon
Прошло много лет, но я хотел бы указать на убедительные альтернативы: etl
(https://github.com/ETLCPP/etl) и мой собственный estdlib
(https://github.com/malachi-iot/estdlib), @Malachi
STL не является частью Arduino и не поддерживает libstc++ от AVR.
Однако мой «ответ» отличается от ответа Малахии в одном месте, как объяснено в комментариях.
Я не думаю, что вам не следует этого делать, просто потому что "большинство людей говорят", что вам не следует этого делать. Есть много людей, которые даже думают, что вам вообще не следует использовать C++. Проблема в том, что C++ (и стандартная библиотека C++) очень мощные и могут быть портированы неэффективным способом.
Зачем использовать libstdc++?
Однако я думаю, что если использовать его с осторожностью, он может быть очень полезен.
Допустим, у нас есть два буфера: буфер отправки и буфер приема. С C вы бы сохранили их в фиксированном массиве символов. В C++ вы можете использовать динамические контейнеры.
Так что в C вы будете использовать 2x 256 байт памяти для сохранения сообщений. Более длинное сообщение не поместится.
В C++ вы будете использовать только те байты, которые необходимы в определенный момент (плюс, вероятно, некоторые дополнительные). А если вы получите более длинное сообщение, оно просто увеличится.
Если C++ вам подходит, и вы его очень-очень хорошо протестировали, почему бы не использовать его? В среднем он будет использовать меньше памяти, так как вы не назначаете ее всю, когда она не используется. У вас возникнут проблемы, когда ваши сообщения станут слишком большими, так как ваша память переполнится, что часто приведет к сбросу микроконтроллера. Но если в вашей программе больше динамических буферов, один может оставить немного места для другого и т. д. Эффективнее используя память!
Но без динамического выделения памяти это может быть немного безопаснее, поскольку вы уже затребовали эти части памяти, нет способа, которым вы не можете их использовать. Любое сообщение большего размера просто не влезет, но вы можете легко это проверить. Другое дело, что C++ stl, которые вы найдете, могут быть не так хорошо оптимизированы для вашей архитектуры/микроконтроллера.
Кроме того, создание собственного динамического хранилища на языке C может вызвать еще больше проблем, чем C++ stl ;). И это не значит, что вам нужно использовать динамическое хранилище для всего, просто иметь возможность это делать уже приятно.
Современные микроконтроллеры также становятся намного серьезнее, например, 8-битные Arduino (328P). За 20 долларов вы можете купить Teensy 3.2 с 256 КБ флэш-памяти, 64 КБ ОЗУ
, поэтому в этом случае динамическая память может быть очень полезна (если вы уверены, что у вас всегда достаточно памяти).
Также: Все продукты STM32F41xxx содержат: до 192 Кбайт системной SRAM, включая 64 Кбайт ОЗУ данных CCM (core coupled memory)
К тому же, это может быть очень хорошим способом изучить C++ и программировать на том же языке, на котором вы работаете на ПК. Но имейте в виду, что на 8-битном микроконтроллере вам следует проверить, не создают ли ваши stl-функции слишком много накладных расходов.
Как использовать стандартную библиотеку шаблонов C++ для AVR?
Я следил за блогом Энди Брауна и теперь у меня есть итераторы/строки/векторы, работающие в AtmelStudio.
Хотя я и получил некоторые ошибки, первая группа ошибок включала:
Error '_M_deallocate' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] D:\avr-stl\include\string 173
Message declarations in dependent base 'std::_String_alloc_base<char, std::allocator<char>, true>' are not found by unqualified lookup D:\avr-stl\include\string 173
Message use 'this->_M_deallocate' instead D:\avr-stl\include\string 173
Эта ошибка на самом деле объясняет сама себя; вам следует использовать this->_M_deallocate
.
После этого я получил неопределенную ссылку на "operator new(unsigned int, void*)
. Но я исправил это, включив "pnew.cpp" прямо под #include <new>
в stl_construct.h
, что странно, но работает.
(Фрагмент stl_construct.h)
#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
#define __SGI_STL_INTERNAL_CONSTRUCT_H
#include <new>
#include <pnew.cpp>
__STL_BEGIN_NAMESPACE
После проверки некоторых материалов в Интернете, действительно оказывается, что статическое распределение чаще всего лучше динамического. Поскольку проблемы (возможные переполнения, меньший контроль и фрагментация кучи) вряд ли перевесят преимущества. НО это не значит, что все должны прекратить экспериментировать с ним ;) и что он не может быть полезен в некоторых узкоспециализированных приложениях (поэтому не так уж и плохо иметь его "установленным")., @Paul
Крутая толпа, я не думаю, что вы заслуживаете отрицательный ответ! Фрагментация кучи — одна из главных причин, по которой я не хочу использовать динамическую память на AVR. Однако на более крупных чипах я фанат — при осторожном использовании., @Malachi
STL эффективен на платформе, для которой он был разработан, то есть на персональных компьютерах и устройствах аналогичного масштаба, где выделение одного байта в куче занимает страницу памяти размером 4 КБ (это в несколько раз больше, чем ВСЯ оперативная память Arduino), и где индексы массивов можно эффективно заменить указателями (8-битным микроконтроллерам требуется не менее двух команд для работы с указателем). Так что нет, он неэффективен с Arduino.
Подумайте об алгоритме быстрой сортировки — он очень хорошо работает на больших списках, но его легко превзойдет простая сортировка, если вам нужно отсортировать массив из 5 элементов. Быть асимптотически эффективным не означает быть эффективным в каждом случае.
Если только библиотека не будет переписана для AVR. Теоретически это будет лучше/эффективнее, чем я, пытаясь запрограммировать очередь или приоритетную очередь на C. Если вам действительно нужно такое поведение, вы должны хотя бы рассмотреть или попробовать его., @Paul
Я бы лично использовал порт AVR C++ STL, который есть на GitHub, и побеспокоил бы людей на GitHub, если у вас есть лучшая реализация, так мы сможем заставить его работать, вместо того, чтобы каждый решал создавать свою собственную реализацию ;) И поскольку он есть на GitHub (и может даже иметь несколько участников) и нацелен на AVR. Он должен работать разумно и быть проверен несколькими. Что, вероятно, лучше/быстрее, чем некоторый самостоятельно написанный код. Но я согласен с частью: «используйте с осторожностью». Но не «не используйте, потому что версия для ПК будет бесполезной»., @Paul
@Paul Если бы STL был переписан для AVR, он автоматически потерял бы свой статус «полностью протестированного/зрелого», не так ли?, @Dmitry Grigoryev
Ну, если бы вы реализовали его самостоятельно, он автоматически потерял бы свой статус полностью протестированного :p, а если вы сотрудничаете на github, он будет более полно протестирован, чем когда вы делаете это в одиночку? (:, @Paul
Плюс, stl полностью протестирован; да, это так, для ПК. (:, @Paul
STL не является частью Arduino IDE.
Другой ответ — упоминание https://github.com/maniacbug/StandardCplusplus, хотя эта библиотека, похоже, больше не поддерживается.
Возможно, лучшей идеей будет попробовать https://github.com/mike-matera/ArduinoSTL
Это порт uClibc++, упакованный как библиотека Arduino.
Я использовал Arduino STL Майка Матары, и он отлично работал на моих платах на базе AVR. Однако я только что вошел в мир ESP8266 и не получил удовольствия... куча ошибок компиляции с предупреждением о том, что он "совместим с AVR и SAMD, но может быть несовместим с ESP8266". Ох!., @Volksman
- Безопасно ли использовать std::array (из C++ STL) на Arduino? Использует ли он динамическое выделение памяти?
- Как использовать лямбда-функции в Arduino?
- Как объявить динамический массив?
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
Проблема с «эффективностью» в том, что она не определяет, *насколько* она эффективна; будет ли она хорошо работать на устройстве с тактовой частотой 16 МГц и всего лишь 2 КБ ОЗУ?, @Ignacio Vazquez-Abrams
и уже часть Arduino IDE
- в последний раз, когда я смотрел, ее не было. Лично мне нравится STL, и я думаю, что ее следует включить. Можете ли вы терпеть накладные расходы или нет, это, безусловно, решение конечного пользователя? Я установил библиотеку Maniacbug сравнительно недавно, и она, похоже, работала нормально., @Nick Gammon