Общий вопрос, здесь и в других местах. Подходит ли C ++ для встраиваемых систем?
Микроконтроллеры? RTOSes? Тостеры? Встроенные ПК?
ООП полезен на микроконтроллерах?
С ++ удаляет программиста слишком далеко от оборудования, чтобы быть эффективным?
Следует ли рассматривать Arduino C ++ (без динамического управления памятью, шаблонов, исключений) как «настоящий C ++»?
(Надеюсь, эта вики послужит местом для размещения этой потенциальной священной войны)
microcontroller
embedded
programming
c++
Toby Jaffey
источник
источник
Ответы:
Да, C ++ все еще полезен во встроенных системах. Как уже говорили все, это все еще зависит от самой системы, так как 8-битный UC, вероятно, был бы нет-нет в моей книге, даже если там есть компилятор, и некоторые люди делают это (вздрагивает). Еще есть преимущество использования C ++, даже когда вы уменьшаете его до чего-то вроде «C +» даже в 8-битном микромире. Что я имею в виду под "C +"? Я имею в виду, что не используйте new / delete, избегайте исключений, избегайте виртуальных классов с наследованием, возможно, избегайте наследования все вместе, будьте очень осторожны с шаблонами, используйте встроенные функции вместо макросов и используйте
const
переменные вместо#defines
.Я работаю как на C, так и на C ++ во встраиваемых системах уже более десяти лет, и часть моего юношеского энтузиазма по поводу C ++ определенно исчезла из-за проблем реального мира, которые сотрясают наивность. Я видел худшее в C ++ во встраиваемых системах, которое я хотел бы назвать «программисты CS сумасшедшие в мире EE». На самом деле, это то, над чем я работаю со своим клиентом, чтобы улучшить эту одну кодовую базу, которую они имеют среди других.
Опасность C ++ заключается в том, что это очень очень мощный инструмент, очень похожий на обоюдоострый меч, который может отрезать вам руку и ногу, если он не обучен и не дисциплинирован должным образом в своем языке и самом общем программировании. С больше похож на односторонний меч, но все же такой же острый. С C ++ слишком легко получить очень высокие уровни абстракции и создавать запутанные интерфейсы, которые в долгосрочной перспективе теряют смысл, и это отчасти объясняется гибкостью C ++ в решении одной и той же проблемы с помощью множества различных языковых функций (шаблоны, ООП, процедурные, RTTI, ООП + шаблоны, перегрузка, встраивание).
Я закончил два 4-часовых семинара по встраиваемому программному обеспечению на C ++ от гуру C ++ Скотта Мейерса. Он указал на некоторые вещи о шаблонах, которые я никогда раньше не рассматривал, и насколько они могут помочь в создании критического для безопасности кода. Суть в том, что в программном обеспечении не может быть мертвого кода, который должен соответствовать строгим требованиям к безопасности. Шаблоны могут помочь вам в этом, так как компилятор создает только тот код, который ему нужен при создании экземпляров шаблонов. Тем не менее, нужно быть более образованным в их использовании, чтобы правильно проектировать эту функцию, которую труднее реализовать в C, потому что компоновщики не всегда оптимизируют мертвый код.
Скотт Мейерс - очень большой сторонник шаблонов и разумного использования встраивания, и я должен сказать, что я все еще скептически отношусь к тому, чтобы быть фанатом шаблонов. Я склонен уклоняться от них, хотя он говорит, что их следует применять только тогда, когда они становятся лучшим инструментом. Он также подчеркивает, что C ++ дает вам инструменты для создания действительно хороших интерфейсов, которые легко использовать правильно и которые трудно использовать неправильно. Опять же, это сложная часть. Нужно прийти к уровню мастерства в C ++, прежде чем вы сможете узнать, как применять эти функции наиболее эффективным способом, чтобы стать лучшим дизайнерским решением.
То же самое касается ООП. Во встроенном мире вы должны ознакомиться с тем, какой код компилятор собирается выплеснуть, чтобы узнать, сможете ли вы справиться с затратами во время выполнения полиморфизма во время выполнения. Вы также должны быть готовы к измерениям, чтобы доказать, что ваш дизайн будет соответствовать вашим срокам. Этот новый класс InterruptManager сделает мою задержку прерывания слишком длинной? Существуют и другие формы полиморфизма, которые могут лучше всего соответствовать вашей проблеме, такие как полиморфизм во время компоновки, который C может сделать также, но C ++ может сделать через шаблона проектирования Pimpl (непрозрачный указатель) .
Я говорю это все, чтобы сказать, что C ++ имеет свое место во встроенном мире. Вы можете ненавидеть все, что хотите, но это не уйдет. Он может быть написан очень эффективным способом, но научиться делать это правильно сложнее, чем с C. Иногда он может работать лучше, чем C, при решении проблемы, а иногда выражая лучший интерфейс, но опять же, вы должны обучай себя и не бойся учиться как.
источник
C ++ абсолютно подходит для встраиваемых систем. Теперь я использую наличие / отсутствие хороших инструментов разработки (или их отсутствие) в качестве основного критерия того, следует ли использовать тот или иной микропроцессор.
Области C ++, которые хорошо использовать во встроенных системах, потому что они имеют низкую стоимость ресурсов:
ОК области:
Области, которые нельзя использовать, в основном из-за накладных расходов, что недопустимо в небольших системах:
источник
foo
вызовыbar
внутри блокаtry
/catch
иbar
создание некоторых объектов и вызововboz
, которые выдают исключение, система должна каким-то образом вызывать деструкторы дляbar
созданных объектов, прежде чем возвращать управлениеfoo
. Если исключения полностью не отключены, уbar
них не будет возможности узнать,boz
могут ли они быть сгенерированы, и поэтому они должны включать дополнительный код, чтобы учесть такую возможность. Я хотел бы увидеть вариант C ++ с «проверенными исключениями», чтобы справиться с этим; если подпрограммы, которые могли бы позволить исключениям избегать ...add r15,r14,#2
вместоmov r15,r14
; выйти через исключениеldrhs r0,[r14] / add r15,r14,r0
. Нулевая стоимость цикла для нормального выхода и никаких ограничений стекового кадра.Да, C ++, безусловно, подходит для встраиваемых систем. Для начала давайте разберемся с несколькими неправильными представлениями о разнице между C и C ++:
Во встроенном микро-устройстве вам всегда нужно будет осторожно использовать языки высокого уровня, если вас беспокоит ограничение времени или пространства. Например, многие MCU плохо обрабатывают указатели и поэтому очень неэффективны при использовании стека. Это означает, что вы должны быть осторожны при передаче переменных в функции, используя массивы и указатели, а также рекурсию. Простая строка C вроде:
может генерировать около 4 страниц инструкций в зависимости от характера этих переменных.
Всякий раз, когда вы используете какой-либо язык высокого уровня и беспокоитесь о временных и пространственных ограничениях, вам необходимо знать, как каждая функция этого языка преобразуется в машинные инструкции на вашем MCU (по крайней мере, для каждой функции, которую вы используете). Это верно для C, C ++, Ada, что угодно. Вероятно, все языки будут содержать функции, которые не будут эффективно переводиться на небольшие микроконтроллеры. Всегда проверяйте списки разборки, чтобы убедиться, что компилятор не генерирует стопки инструкций для чего-то тривиального.
Подходит ли C для встроенных микроконтроллеров? Да, если вы следите за сгенерированным кодом.
Подходит ли C ++ для встроенных микроконтроллеров? Да, если вы следите за сгенерированным кодом.
Вот почему я думаю, что C ++ лучше, чем C, даже на 8-битных MCU: C ++ обеспечивает улучшенную поддержку:
Ни одна из этих функций не тяжелее, чем типичные особенности C.
При перемещении до 16- или 32-битных MCU начинает иметь смысл использовать более тяжелые функции C (стек, куча, указатели, массивы, printf и т. Д.). Таким же образом на более мощном MCU становится уместным использовать более тяжелые возможности C ++ (стек, куча, ссылки, STL, new / delete).
Таким образом, нет необходимости содрогаться при мысли о C ++ на PIC16. Если вы знаете свой язык и MCU правильно, то вы будете знать, как эффективно использовать их оба вместе.
источник
a[i] = b[j] * c[k];
может генерировать около 4 страниц инструкций в зависимости от характера этих переменных." Если ваш MCU / компилятор делает это, это потому, что вы используете какой-то гаражный процессор 80-х годов.Я всегда нахожу эти дебаты интересными для чтения. Не столько для интеллектуальной дискуссии о плюсах и минусах различных доступных языков, сколько потому, что вы обычно можете придерживаться чьей-то позиции по теме, основываясь на их работе / опыте / сфере интересов. Это прямо там с аргументами «преждевременной оптимизации», когда майоры и программисты CS цитировали Кнута влево и вправо и тех, кто работает в реальном мире, где вопросы производительности думают, что они все сумасшедшие (я член последней группы по честному).
В конце концов, вы можете разработать отличное программное обеспечение на C или C ++ или вставить язык здесь . Все сводится к возможностям разработчика, а не к языку. Быть экспертом по языку обычно требуется только в том случае, если вы выбрали неправильный язык для начала, и теперь вам нужно обратить его в решение вашей проблемы, в большинстве случаев это единственные ситуации, когда вам нужно погрузиться в неясные функции или компилятор трюки для достижения цели.
Я часто слышу, как люди начинают эти аргументы как «Я эксперт по языку X и бла-бла». Я честно немедленно дискредитирую этих людей, потому что, по моему мнению, они уже подошли к проблеме с неправильной точки зрения, и все, что после этого испорчено по их желанию использовать свой инструмент для решения проблемы и показать, как это круто.
Я так часто наблюдаю, как разработчики сначала выбирают набор инструментов, а потом пытаются согнуть его до своей проблемы, что совершенно неверно и приводит к дерьмовым решениям.
Как я упоминал в комментарии к другому ответу, эти языковые войны часто сводятся к утверждению, что язык X позволяет программисту делать более глупые вещи. Несмотря на то, что читать интересно, все эти утверждения действительно означают, что у вас есть проблема с наймом хороших разработчиков, и вам нужно обратиться к этой проблеме напрямую, а не пытаться объединить усилия для помощи ситуации, продолжая нанимать плохих разработчиков и выбирая инструменты так, чтобы они могли делать как можно меньше повреждение как можно
На мой взгляд, хорошие разработчики, будь то разработка программного или аппаратного обеспечения, исследуют проблему, создают решение и находят инструменты, которые позволяют им наилучшим образом выразить решение. Это не должно иметь значения, если необходимый инструмент - это то, что вы никогда не использовали раньше, после того, как вы использовали 3-4 языка / инструменты разработки для проектов, новые должны иметь минимальное влияние на ваше время разработки.
Конечно, «лучший способ» - это субъективный термин, который также должен быть определен на этапе исследования. Нужно учитывать множество вопросов: производительность, простота выражения, плотность кода и т. Д. В зависимости от рассматриваемой проблемы. Я не включил ремонтопригодность в этот список по какой-то причине, мне все равно, какой язык вы выберете, если вы выбрали подходящий инструмент и нашли время, чтобы понять проблему, которая должна появиться «бесплатно». Трудно поддерживать код часто является результатом выбора неправильного инструмента или плохой структуры системы, что приводит к ужасному хаосу, который заставляет его работать.
Утверждать, что любой язык «лучше», чем любой другой, глупо без определения конкретной проблемы, представляющей интерес. Объектно-ориентированный подход не всегда лучше, чем функциональный подход. Есть некоторые проблемы, которые очень хорошо подходят для объектно-ориентированной парадигмы проектирования. Есть много, которые этого не делают. То же самое можно сказать и о многих языковых особенностях, которые люди, похоже, любят использовать.
Если вы тратите более 20% своего времени на проблему, связанную с набором кода, возможно, вы создаете очень плохую систему или у вас очень плохие разработчики (или вы все еще учитесь). Вы должны тратить большую часть своего времени на то, чтобы составить схему проблемы и определить, как взаимодействуют различные части приложения. Заставить группу талантливых разработчиков в комнате с доской для маркеров и решить проблему и сказать им, что им не разрешается писать какой-либо код или выбирать какие-либо инструменты, пока они не будут чувствовать себя комфортно со всей системой, сделает больше для улучшения качества производительность и скорость разработки, чем выбор любого горячего нового инструмента, гарантированно сокращают время разработки. (посмотрите на развитие схватки как на точку отсчета, противоположную моему аргументу)
Часто прискорбная реальность такова, что многие компании могут измерить ценность разработчика только по количеству написанных строк или по «ощутимому результату». Они рассматривают 3 недели в комнате с маркером как потерю производительности. Разработчики часто вынуждены проходить через «продуманную» стадию разработки или вынуждены использовать набор инструментов из-за какой-то политической проблемы внутри компании: «Брат моего босса работает на IBM, поэтому мы можем использовать только их инструменты», такого рода мусор , Или, что еще хуже, вы получаете от компании постоянно изменяющийся набор требований, потому что они не способны проводить надлежащее исследование рынка или не понимают влияния изменений на цикл разработки.
Извините за то, что немного не в теме с этой напыщенной работой, у меня есть довольно сильные мнения по этой теме
источник
Любой язык может подойти для встроенной системы. Встроенный просто означает: часть большего устройства, в отличие от бесплатного компьютера.
Вопрос более актуален, когда его спрашивают о (жесткой) системе в реальном времени или с ограниченными ресурсами .
Для системы реального времени C ++ является одним из самых популярных языков, который по-прежнему подходит при программировании для жестких временных ограничений. За исключением использования кучи (свободный оператор), в нем нет конструкций, которые имеют неопределенное время выполнения, поэтому вы можете проверить, соответствует ли ваша программа требованиям синхронизации, и, имея некоторый опыт, вы можете даже предсказать его. Разумеется, следует избегать использования кучи, хотя новый оператор все еще можно использовать для одноразового распределения. Конструкции, которые C ++ предлагает над C, могут найти хорошее применение во встроенной системе: OO, исключения, шаблоны.
Для систем с очень ограниченными ресурсами (8-битные микросхемы, меньше, чем несколько килобайт ОЗУ, нет доступного стека) полный C ++ может оказаться неподходящим, хотя все еще может использоваться как «лучший C».
Я думаю, к сожалению, что Ада, кажется, используется только в некоторых нишах. Во многих отношениях это Pascal ++, но без бремени совместимости вверх с языком, который с самого начала был серьезным путаницей. (отредактируйте: серьезный беспорядок - конечно C. Паскаль - красивый, но несколько непрактичный язык.)
================================================== ==============
РЕДАКТИРОВАТЬ: Я печатал ответ на новый вопрос («В каких случаях C ++ необходим, когда мы программируем микроконтроллеры»?), Который был закрыт со ссылкой на этот вопрос, поэтому я добавлю то, что я написал:
Никогда не существует основополагающей причины для использования любого языка программирования, но могут быть аргументы, которые имеют больший или меньший вес в конкретной ситуации. Дискуссии по этому поводу можно найти во многих местах, причем их позиции варьируются от «никогда не используйте C ++ для микроконтроллера» до «всегда используйте C ++». Я больше с последней позиции. Я могу привести некоторые аргументы, но вам придется решить для себя, какой вес они несут в конкретной ситуации (и в каком направлении).
В моем блоге есть несколько статей об использовании C ++ в небольших системах (= микроконтроллеры).
источник
По моему опыту, C ++ обычно плохо подходит для небольших встроенных систем. Я имею в виду микроконтроллеры и устройства без ОС.
Многие методы ООП C ++ основаны на динамическом распределении памяти. Это часто отсутствует в небольших системах.
STL и Boost действительно демонстрируют мощь C ++, оба занимают огромное место.
C ++ поощряет программиста абстрагироваться от машины, где в стесненных системах она должна использоваться.
В прошлом году я перенес коммерческий продукт для удаленного рабочего стола на мобильные телефоны. Он был написан на C ++ и работал на Windows, Linux и OSX. Но он сильно зависел от STL, динамической памяти и исключений C ++. Чтобы запустить его в средах WinCE, Symbian и без ОС, перезапись C была самым разумным вариантом.
источник
Я надеюсь добавить больше света, чем тепла в эту дискуссию о C ++ на голом металле и системах с ограниченными ресурсами.
Проблемы в C ++:
Исключением является, в частности, проблема с оперативной памятью, поскольку требуемый «аварийный буфер» (где, например, используется исключение нехватки памяти) может быть больше доступной оперативной памяти и, безусловно, является пустой тратой на микроконтроллеры. Для получения дополнительной информации см. N4049 и n4234 . Они должны быть отключены (что в настоящее время является неопределенным поведением, поэтому будьте уверены и никогда не бросайте). SG14 в настоящее время работает над лучшими способами сделать это.
RTTI, вероятно, никогда не стоит накладных расходов, его следует отключить
Большие отладочные сборки, хотя это не проблема при разработке классического десктопа, если отладка не помещается в чип, это может быть проблемой. Проблема возникает из шаблонного кода или дополнительных вызовов функций, добавленных для ясности. Эти дополнительные вызовы функций будут снова удалены оптимизатором, и дополнительная ясность или гибкость могут быть большим преимуществом, однако в отладочных сборках это может быть проблемой.
Распределение кучи. Хотя STL допускает использование пользовательских распределителей, это может быть сложным для большинства программистов. Распределение кучи недетерминировано (т. Е. Не является жестким в реальном времени), и фрагментация может привести к неожиданным ситуациям нехватки памяти, несмотря на то, что они работали в тестировании. Бухгалтерский учет, необходимый куче для отслеживания свободного места и разного размера, может быть проблемой для небольших объектов. Обычно лучше использовать распределение пула (как в C, так и в C ++), но это может быть ненормально для программистов на C ++, которые привыкли использовать только кучу.
Полиморфизм во время выполнения и другие косвенные вызовы, как правило, сильно снижают производительность, проблема обычно заключается в том, что оптимизатор не может видеть сквозь них больше, чем фактическая выборка и переход к адресу. По этой причине следует избегать косвенных вызовов в C и C ++, где, как и в C ++, они более укоренились в культуре (и весьма полезны в других областях).
неявное взаимодействие с clib может быть проблематичным. Может показаться нелогичным, что проблемы с клибом находятся в категории C ++, но проблема возникает из-за неявного совместного использования ресурсов в параллельных средах (совместное использование более очевидно в C). Использование общей реализации newLib часто приводит к большому количеству раздувания, которое обычно не требуется в uC, с другой стороны, newLibNanno не является реентерабельным, поэтому доступ к нему должен быть сериализован (упрощенное здесь). Это проблема и для C, но доступ более явный. Как правило, по существу ничего не следует использовать из пространства имен std в контексте ISR, если вы не уверены, что оно каким-то образом не обращается к состоянию в clib (например, errorno или куча). Также важно, если вы используете потоки (я предпочитаю RTC) для переопределения новых и удаления для синхронизации доступа к malloc и free.
В заключение, у С ++ есть некоторые проблемы, но по сути все они исправимы или их можно избежать.
Теперь для C, здесь проблема более высокого порядка. У меня нет синтаксической способности в C абстрагировать вещи таким образом, чтобы я мог выполнять оптимизацию или проверять инварианты во время компиляции. Поэтому я не могу должным образом инкапсулировать вещи таким образом, чтобы пользователю не нужно было знать, как они работают, чтобы использовать их, и большая часть моего обнаружения ошибок выполняется во время выполнения (что не только слишком поздно, но и увеличивает стоимость). По сути, единственный способ быть универсальным в C - это данные, я передаю строку формата в printf или scanf, которая оценивается, например, во время выполнения. Тогда компилятору довольно сложно доказать, что я не использую некоторые опции, которые теоретически возможны при передаче правильных данных, что означает потенциальную генерацию мертвого кода и потерю потенциала оптимизации.
Я знаю, что, возможно, здесь развязывается дерьмо, но мой опыт работы с 32-битными микроконтроллерами заключается в том, что в сравнении яблок и яблок C и C ++, написанные экспертами (как, например, в C ++, потенциально сильно шаблонизированные), C ++ является гораздо более эффективным языком, как только все должно быть вообще универсальным (как в любой библиотеке), и они практически эквивалентны в не универсальных случаях. Для новичка также легче использовать опыт опытного разработчика библиотеки на C ++.
В то же время на самом деле существует очень мало функций, которым я не могу передать неверные данные, как только ввод не является целым, а
something
для которых я использую целое число как метод представления, тогда есть вероятность получить его. неправильный (передайте неверное значение или «otherThing», а не «что-то»). В C мой единственный метод проверки, если пользователь ошибся, это во время выполнения. В C ++ у меня есть возможность выполнять некоторые проверки, не все проверки, но некоторые проверки во время компиляции, которые бесплатны.В конце концов, команда C часто столь же сильна, как и ее самый слабый программист, и в результате получаемый код имеет многопользовательский режим 1 или снижение производительности. Под этим я подразумеваю, что это либо высокая производительность для одной и только одной уникальной работы в уникальной среде с уникальными проектными решениями, либо она достаточно универсальна для использования в нескольких средах (другой микроконтроллер, другая стратегия управления памятью, другая задержка или компромисс между пропускной способностью и т. д. и т. д.), но присущий производительности.
В C ++ вещи могут быть инкапсулированы экспертами и использованы во многих средах, где генерация временного кода компиляции адаптируется к конкретной задаче, а статическая проверка не дает пользователям делать глупости при нулевых затратах. Здесь у нас гораздо меньше компромиссов между универсальностью и быстротой, и, следовательно, в конечном счете, с точки зрения затрат и выгод - более производительный, безопасный и продуктивный язык.
Это справедливая критика, что все еще существует большой дефицит хороших библиотек C ++ для встраиваемых систем, что может привести к прагматичным решениям использовать в основном C на компиляторе C ++. Решения об использовании только C в проекте по сути либо идеологически обусловлены, из-за необходимости поддержки прежних версий или признания того, что команда недостаточно дисциплинирована, чтобы воздерживаться от очень глупого набора вещей, которые можно делать в C ++, но не в C и в то же время достаточно дисциплинированный, чтобы не делать ничего из гораздо большего набора глупостей, от которых нельзя обойтись в C, но в C ++.
источник
Мое прошлое: только что закончил школу под руководством старых программистов Bell Labs; работаю 3 года, 2 над исследовательским проектом бакалавриата; сбор данных / управление процессом в VB.NET. Потратил 1,5 года на работу над приложением корпоративной базы данных в VB6. В настоящее время работает над проектом для встроенного ПК с 2 ГБ памяти, 512 МБ оперативной памяти, 500 МГц x86 CPU; несколько приложений, работающих одновременно, написаны на C ++ с промежуточным механизмом IPC. Да я молод
Мое мнение: я думаю, что C ++ может работать эффективно, учитывая среду, которую я написал выше . По общему признанию, жесткая производительность в реальном времени не является требованием для приложения, в котором я работаю, и в некоторых встроенных приложениях это может быть проблемой. Но вот что я узнал:
C ++ принципиально отличается от C (то есть C / C ++ отсутствует). В то время как все, что является допустимым C, является C ++, C ++ - это совсем другой язык, и нужно научиться программировать на C ++, а не на C, чтобы эффективно использовать его в любой ситуации. В C ++ вам нужно программировать объектно-ориентированное, а не процедурное и не гибридное из двух (большие классы с большим количеством функций). В общем, вы должны сосредоточиться на создании маленьких классов с небольшим количеством функций и объединить все маленькие классы в более крупное решение. Один из моих коллег объяснил мне, что я обычно программировал на объектах, что является большим беспорядком и его трудно поддерживать. Когда я начал применять более объектно-ориентированные методы, я обнаружил, что удобство сопровождения / читаемости моего кода повысилось.
C ++ предоставляет дополнительные функции в форме объектно-ориентированной разработки, которые могут упростить код для облегчения его чтения / сопровождения . Честно говоря, я не думаю, что в ООП можно улучшить производительность / эффективность использования пространства. Но я думаю, что ООП - это метод, который может помочь разбить сложную проблему на множество маленьких частей. И это полезно для людей, работающих над кодом, элемент этого процесса, который нельзя игнорировать.
Многие аргументы против C ++ имеют отношение главным образом к динамическому распределению памяти. С тоже имеет такую же проблему. Вы можете написать объектно-ориентированное приложение без использования динамической памяти, хотя одно из преимуществ использования объектов заключается в том, что вы можете легко и быстро распределять эти объекты. Как и в C, вы должны быть осторожны с тем, как управлять данными, чтобы уменьшить утечки памяти, но техника RAII делает это проще в C ++ (делает динамическое разрушение памяти автоматически, инкапсулируя ее в объектах). В некоторых приложениях, где каждая ячейка памяти имеет значение, это может быть слишком диким и шероховатым для управления.
РЕДАКТИРОВАТЬ:
источник
Да, проблема с C ++ заключается в увеличенном объеме кода.
В некоторых системах вы подсчитываете байты, и в этом случае вам придется принять расходы на запуск, близкие к границам ваших систем, это увеличенные затраты на разработку C.
Но даже в C для хорошо спроектированной системы вам нужно хранить все в капсуле. Хорошо спроектированные системы сложны, и C ++ дает программистам место для очень структурированного и контролируемого метода разработки. Изучение ООП обходится дорого, и, если вы хотите переключиться на него, вы очень его принимаете, и во многих случаях руководство предпочло бы продолжить с C и не платить за него, так как трудно измерить результаты переключения, которое увеличивает производительность. Вы можете увидеть статью гуру встраиваемых систем Джека Гэнсле здесь .
Динамическое управление памятью - это дьявол. Не совсем, дьявол - это автоматическая маршрутизация, динамическое управление памятью отлично работает на ПК, но вы можете ожидать перезагрузки ПК, по крайней мере, каждые несколько недель. Вы обнаружите, что, поскольку встраиваемая система продолжает работать в течение 5 лет, динамическое управление памятью может действительно испортиться и фактически начать отказывать. Ganssle обсуждает такие вещи, как стек и куча в своей статье.
В C ++ есть некоторые вещи, которые более склонны вызывать проблемы и использовать много ресурсов, удаление динамического управления памятью и шаблонов - это большие шаги, чтобы держать след C ++ ближе к следу C. Это все еще C ++, вам не нужен динамический Управление памятью или шаблоны для написания хорошего C ++. Я не осознавал, что они удалили исключения, я считаю исключения важной частью моего кода, которую я удаляю в релизе, но использую до этого момента. В полевом тестировании я могу генерировать сообщения об исключениях, чтобы сообщить мне об обнаруженном исключении.
источник
Я подумал, что эта анти-С ++ разглагольствование Линуса Торвальдса было интересным.
Он говорит не о мире встраиваемых систем, а о разработке ядра Linux. Для меня актуальность заключается в следующем: C ++ требует понимания более широкого контекста, и я могу научиться использовать набор шаблонов объектов, я не доверяю себе, чтобы помнить их, когда мне нужно обновить код через несколько месяцев.
(С другой стороны, в настоящее время я работаю над встроенным устройством, использующим Python (не C ++, но использую ту же самую ООП-парадигму), которое будет иметь именно эту проблему. В мою защиту, это встроенная система, достаточно мощная, чтобы называться ПК 10 лет назад.)
источник
Я думаю, что другие ответы послужили хорошим аргументом в пользу плюсов и минусов и факторов принятия решений, поэтому я хотел бы просто подвести итог и добавить несколько комментариев.
Для маленьких микроконтроллеров (8-битных) никак. Вы просто просите причинить себе боль, вы ничего не получите, и вы потеряете слишком много ресурсов.
Для высокопроизводительных микроконтроллеров (например, 32-разрядных, 10 или 100 МБ для оперативной памяти и хранилища), имеющих приличную ОС, это вполне нормально и, я бы даже сказал, даже рекомендуется.
Итак, вопрос: где граница?
Я не знаю наверняка, но однажды я разработал систему для 16-битного uC с 1 МБ ОЗУ и 1 МБ для хранения на C ++, но потом пожалею об этом. Да, это сработало, но дополнительная работа, которую я имел, не стоила этого. Мне нужно было сделать так, чтобы такие вещи, как исключения, не вызывали утечек (поддержка OS + RTL была довольно ошибочной и ненадежной). Более того, приложение OO обычно делает много небольших выделений, и куча накладных расходов для них была еще одним кошмаром.
Учитывая этот опыт, я бы предположил, что для будущих проектов я выберу C ++ только в системах, по крайней мере, 16-битных, и с как минимум 16 МБ для оперативной памяти и хранилища. Это произвольный предел, и, вероятно, он будет варьироваться в зависимости от типа приложения, стилей кодирования, идиом и т. Д. Но, учитывая предостережения, я бы рекомендовал аналогичный подход.
источник
Есть некоторые особенности C ++, которые полезны во встроенных системах. Есть и другие, например исключения, которые могут быть дорогими, и чьи затраты не всегда очевидны.
Если бы у меня были мои барабанщики, был бы популярный язык, который сочетал бы лучшее из обоих миров и включал в себя некоторые функции, которых не хватает в обоих языках; некоторые поставщики включают несколько таких функций, но нет стандартов. Несколько вещей, которые я хотел бы увидеть:
Я знаю, что отец C ++ не слишком увлечен встроенной версией C ++, но я думаю, что она может предложить некоторые значительные улучшения по сравнению с использованием C.
Кто-нибудь знает, рассматривается ли что-либо подобное выше для какого-либо стандарта?
источник
C ++ - это больше, чем один язык программирования:
а) это "лучше" C б) это объектно-ориентированный язык в) это язык, который позволяет нам писать универсальные программы
Хотя все эти функции можно использовать отдельно, наилучшие результаты достигаются при одновременном использовании трех из них. Тем не менее, если вы выберете только один из них, качество встроенного программного обеспечения повысится.
а) Это "лучше" C
C ++ - строго типизированный язык; сильнее, чем C. Ваши программы получат выгоду от этой функции.
Некоторые люди боятся указателей. C ++ включает ссылки. Перегруженные функции.
И стоит сказать: ни одна из этих функций не возникает в больших или медленных программах.
б) это объектно-ориентированный язык
В этом посте кто-то сказал, что абстрагирование машины в микроконтроллерах не очень хорошая идея. Неправильно! Все мы, инженеры встраиваемых систем, всегда абстрагировали машину, просто с другим синтаксисом, чем у C ++. Проблема, которую я вижу в этом аргументе, заключается в том, что некоторые программисты не привыкли мыслить объектами, поэтому они не видят преимуществ ООП.
Всякий раз, когда вы готовы использовать периферийное устройство микроконтроллера, вполне вероятно, что это периферийное устройство было выделено для нас (от вас самих или третьей стороны) в виде драйвера устройства. Как я уже говорил ранее, этот драйвер использует синтаксис C, как показано в следующем примере (взято непосредственно из примера NXP LPC1114):
/ * Настройка таймера для совпадения и прерывания в TICKRATE_HZ * /
Chip_TIMER_Reset (LPC_TIMER32_0);
Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);
Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq / TICKRATE_HZ2));
Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);
Chip_TIMER_Enable (LPC_TIMER32_0);
Вы видите абстракцию? Таким образом, при использовании C ++ для той же цели абстракция переносится на следующий уровень с помощью механизма абстракции и инкапсуляции C ++ с нулевой стоимостью!
в) это язык, который позволяет нам писать универсальные программы
Общие программы достигаются с помощью шаблонов, и шаблоны также не требуют затрат для наших программ.
Кроме того, статический полиморфизм достигается с помощью шаблонов.
Виртуальные методы, RTTI и исключения.
При использовании виртуальных методов существует компромисс: лучшее программное обеспечение против некоторого снижения производительности. Однако помните, что динамическое связывание может быть реализовано с использованием виртуальной таблицы (массив указателей на функции). Я делал то же самое в C много раз (даже на регулярной основе), поэтому я не вижу недостатков в использовании виртуальных методов. Более того, виртуальные методы в C ++ более элегантны.
Наконец, совет относительно RTTI и исключений: НЕ ИСПОЛЬЗУЙТЕ ИХ во встроенных системах. Избегайте их любой ценой!
источник
Мой фон, встроенный (MCU, ПК, Unix, другие), в режиме реального времени. Безопасность критична. Я представил предыдущего работодателя в STL. Я так больше не делаю.
Некоторый контент Flame
Подходит ли C ++ для встраиваемых систем?
Мех. C ++ - это боль в написании и боль в поддержке. C + вроде нормально (не используйте некоторые функции)
С ++ в микроконтроллерах? RTOSes? Тостеры? Встроенные ПК?
Я снова говорю Мех. C + не так уж и плох, но ADA менее болезненный (и это действительно что-то говорит). Если вам повезет, как и мне, вы сможете использовать встроенную Java. Проверенный доступ к массиву и отсутствие арифметики с указателями обеспечивает очень надежный код. Сборщики мусора во встроенной Java не имеют наивысшего приоритета, и объем памяти и повторное использование объектов ограничены, поэтому хорошо разработанный код может работать вечно без GC.
ООП полезен на микроконтроллерах?
Уверенный. UART - это объект ..... DMAC - это объект ...
Объект состояний машин очень прост.
С ++ удаляет программиста слишком далеко от оборудования, чтобы быть эффективным?
Если это не PDP-11, C не ваш процессор. Изначально C ++ был препроцессором поверх C, поэтому Бьярн Страуструп перестал смеяться за медленное моделирование Simula, когда он работал в AT & T. C ++ не ваш процессор.
Принесите MCU, который запускает Java-байт-коды. Программа на Java. Смейтесь над парнями.
Следует ли рассматривать Arduino C ++ (без динамического управления памятью, шаблонов, исключений) как «настоящий C ++»?
Нет. так же, как и все убогие компиляторы C для MCU.
В-четвертых, встроенная Java или встроенная ADA стандартизированы (ish); все остальное - печаль.
источник
Встроенные системы предназначены для выполнения какой-то конкретной задачи, а не для универсального компьютера для выполнения нескольких задач. Встроенная система представляет собой комбинацию компьютерного оборудования и программного обеспечения. С является матерью всех современных языков. Это низкий уровень, но полный язык и работает со всеми видами оборудования. Таким образом, C / C ++ является оптимальным выбором для разработки программного обеспечения для встраиваемых систем, которое очень полно используется для каждой встраиваемой системы. Как мы знаем, C является развивающимся языком. Операционная система UNIX написана на C. Поскольку успешная разработка программного обеспечения так часто связана с выбором лучшего языка для данного проекта, удивительно обнаружить, что язык C / C ++ зарекомендовал себя как для 8-битных, так и для 64-битных процессоров. ; в системах с байтами, килобайтами и мегабайтами памяти. C имеет преимущество независимости от процессора, что позволяет программистам сосредоточиться на алгоритмах и приложениях, а не на деталях конкретной архитектуры процессора. Однако многие из этих преимуществ в равной степени применимы и к другим языкам высокого уровня. Но C / C ++ преуспел там, где многие другие языки потерпели неудачу?
источник
<Напыщенная>
Я думаю, что C ++ - это дерьмовый язык в первую очередь. Если вы хотите использовать ООП, пишите программы на Java. C ++ ничего не делает для обеспечения соблюдения ООП-парадигм, так как прямой доступ к памяти полностью в вашем распоряжении (ab).
Если у вас есть MCU, вы говорите о менее чем 100 КБ флэш-памяти. Вы хотите программировать на языке, абстракция памяти которого: когда я объявляю переменную или массив, он получает память, точка; malloc (иначе называемое «новое» ключевое слово в C ++) должно быть более или менее запрещено использовать во встроенном программном обеспечении, за исключением, возможно, в редких случаях одного вызова во время запуска программы.
Черт, во встроенном программировании (часто) бывают случаи, когда C не достаточно низкоуровневый, и вам нужно делать такие вещи, как распределение переменных в регистрах и писать встроенную сборку, чтобы ужесточить процедуры обработки прерываний (ISR). Такие ключевые слова, как «изменчивый», становятся чертовски важными для понимания. Вы тратите много времени на управление памятью на уровне битов , а не на уровне объектов .
Почему вы хотите обмануть себя, думая, что все проще, чем на самом деле?
</ Декламация>
источник