Почему C доминирует на рынке встроенного программного обеспечения? [закрыто]

14

Почти каждый сейчас скажет благословение:

производительность !

Хорошо, C позволяет писать спортивный код. Но есть и другие языки, которые могут это сделать, в конце концов! И оптимизирующая мощь современных компиляторов потрясающая. Есть ли у С некоторые преимущества, которых нет у других языков? Или просто нет необходимости в более гибких инструментах в домене?

лозы
источник
1
FWIW, Arduino можно контролировать с помощью C #: arduino.cc/playground/Interfacing/Csharp
FrustratedWithFormsDesigner
@ Разочарованный: Да, но это один из примеров, и большинство людей, строящих устройства, используют Arduino.
Эд С.
2
Связанный: stackoverflow.com/questions/1601893/…
Стив S
2
См. Также: stackoverflow.com/questions/812717/…
Стив Мельникофф,
1
@ dan04, в подавляющем большинстве случаев это не было проблемой. Примерно в 1988 году группа моделирования 6DOF в Texas Instruments Defence Systems and Electronics Group провела небольшой эксперимент. До этого времени они выполняли все свои моделирования в Фортране. Они пытались написать один в PASCAL, чтобы увидеть, как плохо это повредит. Они обнаружили, что PASCAL дал им небольшой удар по производительности, но увеличение надежности и простоты отладки БОЛЬШЕ, чем восполнило это. Грубо говоря, они обнаружили, что строгая проверка типов в PASCAL была ХОРОШЕЙ. (И да, они делали массивы.)
Джон Р. Штром

Ответы:

41

Почти каждый сейчас скажет благословение:

производительность!

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

  1. Прямой доступ к аппаратным API низкого уровня.
  2. Вы можете найти компилятор C для подавляющего большинства этих устройств. Это не верно для любого языка высокого уровня в моем опыте.
  3. C (среда выполнения и ваш сгенерированный исполняемый файл) «маленький». Вам не нужно загружать кучу вещей в систему для запуска кода.
  4. Аппаратный API / драйвер (ы), скорее всего, будут написаны на C или C ++.
Эд С.
источник
14
+1 Наличие компиляторов. Когда мы писали все на ассемблере, компиляторы первого поколения были просто богом.
Кристофер Биббс
8
+1, я думаю, что детерминированное использование ресурсов является одной из наиболее важных причин. У вас недостаточно памяти для того, чтобы заниматься сборкой мусора в посудомоечной машине.
user281377
4
+1 также за «детерминированное использование ресурсов». Во многих встроенных системах это требование даже исключает использование динамического выделения памяти. Многие другие языки сильно зависят от динамического выделения памяти (даже многим полезным аспектам C ++ требуется динамическая память).
Майкл Барр
2
Я бы добавил еще одно замечание, которое оказывается скорее социальной, чем технической причиной - я думаю, что разработчики встроенного программного обеспечения, как правило, гораздо более консервативны и устойчивы к изменениям, чем другие разработчики. В зависимости от вашей точки зрения, это может быть хорошо или плохо.
Майкл Берр
1
Говоря как системный парень, я опасаюсь больших абстракций. Они великолепны, пока не перестают работать или делают что-то смешное, и в этом случае отладка может быть огромной головной болью. Это не то, что я хочу в системе низкого уровня.
Эд С.
18

C был разработан для моделирования процессора, потому что C был создан для того, чтобы сделать Unix переносимым между платформами, а не просто писать на ассемблере.

Это означает, что программы на C хорошо работают в качестве языка программирования для программ, которые должны иметь уровень абстракции, очень близкий к фактическому CPU, как в случае со встроенным оборудованием.

Примечание: C был разработан примерно в 1970 году, и тогда процессоры были проще.


источник
3
+1: Это, безусловно , причина. Может быть, люди пытались разработать новые языки высокого уровня, которые отражают особенности современных процессоров, но никто не разработал язык для этого, который завоевал популярность.
Кен Блум,
2
@vines, C - небольшой язык с большой библиотекой времени выполнения. Все это можно сделать в библиотеке времени выполнения. Он просто не будет автоматически мигрировать в стандартную библиотеку C, поэтому он зависит от платформы.
3
+1. C был создан и первоначально использовался на PDP-7, который имел максимум 64 килограммов 18-битных слов. Многие другие "современные" языки с трудом вписываются в такое пространство. Специально для написания ОС как Unix.
Greyfade
2
@greyfade: не так. UNIX возникла на PDP-7, а C - нет. Цитируя предисловие к языку программирования C : «C был изначально разработан и реализован в операционной системе UNIX на DEC PDP-11 Деннисом Ричи».
Джерри Гроб
1
@vines: хотя разумно предусмотреть прямую поддержку потоков в языке (ср. Concurrent C), большая часть кеша заключается в том, что он ускоряет работу без какого-либо вмешательства со стороны программиста или языка.
Джерри Гроб
11

Одна из причин доминирования состоит в том, что у него есть правильные инструменты для решения этой задачи. После разработки встраиваемых платформ на Java и C / C ++ я могу вам сказать, что простой подход C ++ более естественен. Спасение разработчика от ощущения, что он или она прыгают через обручи, потому что язык слишком высок, - довольно раздражающая вещь. Хорошим примером является отсутствие в Java переменных без знака.

А удобные функции ВМ / интерпретируемых языков обычно неосуществимы и остаются вне реализации, например, сборка мусора.

celebdor
источник
3
«и Java и C / C ++» - надеюсь, вы имели в виду «все три: Java C и C ++», поскольку C и C ++ - это разные языки.
BЈовић
1
@ BЈовић: Отвечая годами позже, чтобы подтвердить, что да, я имел в виду все три. Я был назначен обоими в соответствии с этим определением: «используется как функциональное слово, чтобы указать и подчеркнуть включение каждой из двух или более вещей» (две или более вещей) :-)
celebdor
10

Сами по себе требует очень мало поддержки времени выполнения, поэтому издержки намного ниже. Вы не тратите память или хранилище на поддержку времени выполнения, не тратите время / усилия на то, чтобы свести к минимуму эту поддержку, или не должны учитывать это при разработке проекта.

geekosaur
источник
1
Неужели никогда не случается так, что вам нужна эта функциональность и вы изобретаете ее сами? Например, большие конечные автоматы, созданные с помощью switches, ужасны, а те же машины, построенные с иерархиями классов, хороши и удобны в обслуживании.
виноградные лозы
1
@vines - у вас обычно есть определенный набор входов, конечные автоматы, построенные на коммутаторе / если лестницы более понятны и более документируемы, чем иерархия магии «за кулисами» полиморфных вызовов.
Мартин Беккет
2
@Martin: кому-то, имеющему небольшой опыт в разработке ОО, полиморфные вызовы не являются ни «волшебными», ни «закулисными», и представление о том, что огромные операторы switch / if более ясны и более документируемы, кажется совершенно странным.
Майкл Боргвардт
3
Найдите, что происходит, когда pin27 поднимается высоко. Вариант 1, поиск «case PIN27»: «Вариант 2 проследить итератор по карте функторов, чтобы определить, какой из них будет вызываться для объектов PIN, назначенных для вывода 27 во время выполнения. Проблема с большим количеством ОО-кода заключается в том, что единственный способ прочитать его - по сути запустить его. На платформе без отладки во время выполнения или даже на консоли, что означает отслеживание кода на бумаге или в вашей голове.
Мартин Беккет
2
Немного касательно этого обсуждения, есть логика лестничной диаграммы причины (еще более примитивная версия switch, можно сказать) все еще используется во многих встроенных приложениях. Проще отладить, проще проверить.
geekosaur
9

Как упоминалось в других ответах, C был разработан в начале 1970-х годов для замены языка ассемблера в архитектуре мини-компьютера. Тогда эти компьютеры обычно стоят десятки тысяч долларов, включая память и периферийные устройства.

В настоящее время вы можете получить такую ​​же или более высокую мощность компьютера с 16-разрядным встроенным микроконтроллером, который стоит четыре доллара или меньше в отдельных количествах, включая встроенную память и контроллеры ввода / вывода. 32-битный микроконтроллер стоит, может быть, доллар или два больше.

Когда я программирую этих маленьких ребят, что я и делаю в 90% случаев, когда я не проектирую платы, на которых они сидят, мне нравится визуализировать, что будет делать процессор. Если бы я мог программировать достаточно быстро на ассемблере, я бы сделал это.

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

tcrosley
источник
1
Для некоторых встроенных приложений этот «доллар или два больше» очень важен. Никто не будет замечать влияние цены на их автомобиль, но они будут на своем термостате или проигрывателе компакт-дисков.
Дэвид Торнли
3
@ Дэвид Торнли, да, полностью согласен, поэтому у меня в настоящее время есть проекты, использующие 8, 16 и 32-битные микросхемы одновременно для разных клиентов. (Потребление энергии - еще одна причина для использования с небольшими устройствами.)
tcrosley
1
Цена определяется меньшей стоимостью процессора, чем количество выводов. Доски намного дороже фишек.
Иттрилл
7

Он не полностью доминирует, поскольку C ++ все чаще используется, так как улучшаются компиляторы и повышается производительность оборудования. Однако C по-прежнему очень популярен по нескольким причинам;

  1. Широкая поддержка. Практически каждый производитель чипов предоставляет компилятор переменного тока, и любой пример кода и драйверов, вероятно, будет написан на языке c. Компиляторы C ++ все чаще встречаются, но не являются мертвым свидетельством для данного чипа, и они часто бывают ошибочными. Вы также знаете, что любой встроенный инженер сможет работать в ц. Это лингва франка индустрии.

  2. Производительность. Да, ты сказал это. Производительность по-прежнему важна, и в среде, где основные подпрограммы все еще часто пишутся на ассемблере или, по крайней мере, оптимизируются на c со ссылкой на выходные данные сборки, никогда не стоит недооценивать важность этого. Часто встроенные цели будут очень дешевыми и будут иметь очень маленькую память и несколько мипов.

  3. Размер. C ++ имеет тенденцию быть больше. Конечно, все, что использует STL, будет больше. Как правило, с точки зрения размера программы и объема памяти.

  4. Консерватизм. Это очень консервативная индустрия. Отчасти потому, что стоимость отказов часто выше, а отладка часто менее доступна, отчасти потому, что не нужно было менять. Для небольшого встроенного проекта c хорошо справляется со своей задачей.

Люк Грэм
источник
11
Видите ли, это №3, который кажется одним из самых распространенных мифов о C ++. Напишите контейнер с безопасным типом для 5 различных типов в C, и вы вызовете как минимум столько же «раздувания», сколько и использование одного контейнера STL для 5 различных типов. Программисты на C могут обойти это, написав контейнеры для непрозрачных типов (void *). Сравнение ТО с шаблоном STL является ошибкой категории. Должен признать, что это действительно одна из наиболее распространенных «причин», чтобы отдавать предпочтение C.
Эдвард Стрендж,
Я полностью согласен с тем, что для репликации полной функциональности в c вы в конечном итоге занимает то же место, что и c ++. «Преимущество» c в том, что он позволяет вам быть избирательным. В любом значительном проекте я бы предпочел использовать c ++, но иногда целевое оборудование ограничено до такой степени, что это не практично. Сказав, что № 1 действительно главная причина в моем опыте.
Люк Грэм
6

Для встраиваемых систем большое значение имеет производительность . Но, как вы сказали, почему C, а не какой-то другой язык-исполнитель?

Многие люди до сих пор упоминали о доступности компиляторов , но никто не упоминал о доступности разработчиков . C уже знает больше разработчиков, чем, скажем, OCaml.

Это три большие

BlueRaja - Дэнни Пфлугхофт
источник
6

Встроенное программное обеспечение очень отличается.

В настольном приложении абстракции и библиотеки экономят ваше время на разработку. Вы можете позволить себе выбросить еще пару мегабайт или гигабайт оперативной памяти или несколько 64-разрядных процессорных ядер 2 + ГГц, и кто-то другой (пользователи) платит за это оборудование. Вы можете не знать, на каких системах будет работать приложение.

Во встроенном проекте ресурсы часто очень ограничены. В одном проекте, над которым я работал (процессоры серии PIC 17X), аппаратное обеспечение имело 2Kwords программной памяти, 8 уровней (аппаратного) стека и 192 байта (<0,2 КБ) оперативной памяти. Разные выводы ввода / вывода имели разные возможности, и вы настраивали оборудование по мере необходимости, записывая данные в регистры оборудования. Отладка включает в себя осциллограф и логический анализатор.

Встраиваемые абстракции часто мешают и будут управлять (и стоить) ресурсами, которых у вас нет. Например, большинство встроенных систем не имеют файловой системы. Микроволновые печи являются встроенными системами. Контроллеры автомобильных двигателей. Некоторые электрические зубные щетки. Некоторые наушники с шумоподавлением.

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

Абстракции и закулисное «волшебство» (например, сборщик мусора) отлично подходит для настольных приложений. Сборщики мусора сэкономят вам МНОГО времени, чтобы избежать утечек памяти, когда память может / может быть выделена динамически.

Однако в мире встраиваемых систем реального времени нам необходимо знать и контролировать, сколько времени занимает процесс, иногда до наносекунд, и мы не можем выбросить еще пару мегабайт ОЗУ или более быстрый ЦП. Один простой пример: при программном затемнении светодиодов с помощью управления рабочим циклом (центральный процессор контролировал только светодиоды вкл / выкл), процессор не может выключиться и выполнить, например, сборку мусора в течение 100 мс, потому что дисплей будет визуально мигать ярким или погаснуть.

Более гипотетический пример - контроллер двигателя, который напрямую зажигает свечи зажигания. Если этот процессор отключается и выполняет сборку мусора в течение 50 мс, двигатель на мгновение отключится или сработает в неправильном положении коленчатого вала, что может привести к остановке двигателя (при прохождении?) Или механическому повреждению. Вы можете убить кого-то.

технофилов
источник
Это так же верно, как и не имеет отношения к C - проблема, на которую вы ссылаетесь, заключается только в поведении GC ... C ++ не имеет GC, и знаете что? Я лично использую это из-за строковых комментариев и более строгого типа безопасности =)
лозы