Когда вы говорите «встроенная разработка», имейте в виду, что вы должны учитывать масштаб проекта.
При программировании чего-либо в масштабе микроконтроллера или прошивки для ASIC вы склонны видеть, что C и сборка доминируют на сцене. Разработчики встраиваемых систем, как правило, «специализируются» на этих языках, поскольку компиляторы для них доступны практически для каждой встроенной целевой платформы. Если ваш проект переносится, скажем, с микросхемы с ядром PowerPC на микросхему с ядром ARM, вы можете быть достаточно уверены, что ваш код C не будет слишком трудным для переноса. Некоторые чипы имеют компиляторы, доступные для других языков, но обычно они не соответствуют компилятору C с точки зрения эффективности получаемого двоичного файла. Поскольку у встроенных систем часто не хватает ресурсов, разработчики систем хотят сделать свой код максимально эффективным (это также одна из причин, почему вы видите много кода на ассемблере). Я видел инструменты разработки, доступные для таких языков, как C ++, Pascal, Basic и другие, но они, как правило, являются нишевыми инструментами, которые недостаточно развиты, чтобы соответствовать эффективности доступных компиляторов Си. Инструменты отладки для этих языков также, как правило, труднее найти, чем то, что доступно для C / Assembly.
Вы также упомянули приставки. Встраиваемые системы такого масштаба могут обеспечить эквивалентную мощность настольного компьютера 7-8 лет назад. Их доступная оперативная память, место для хранения и вычислительная мощность позволяют им запускать полнофункциональные операционные системы и интерпретаторы для языков более высокого уровня. В этих более мощных системах вы по-прежнему будете видеть C и язык ассемблера (для кода драйвера, если не для чего-то еще), но другие языки (такие как Java, Lua, Tcl, Ruby и т. Д.) Становятся все более распространенными. Использование интерпретированных языков делает перенос кода с одной платформы на другую еще проще, если у платформы достаточно ресурсов для обработки накладных расходов на интерпретатор языка. Любой низкоуровневый код, который напрямую взаимодействует с аппаратным обеспечением (драйверами), все еще, как правило, использует ассемблер или C, поскольку языки высокого уровня не всегда способны делать подобные вещи. Все, что работает как приложение поверх встроенной операционной системы, обычно может быть разработано и протестировано в эмуляторе или виртуальной машине, поэтому вы увидите, что много кода разрабатывается на любом языке, который удобен для разработчика.
Версия TLDR: C популярен, потому что это универсальный язык, с которым знакомы почти все разработчики. Сборка популярна, потому что она обеспечивает низкоуровневый доступ к оборудованию способами, которые в противном случае были бы трудными или невозможными. Интерпретируемые / скриптовые языки, такие как Java, становятся все более популярными, но требования к ресурсам интерпретаторов для этих языков могут быть слишком большими для некоторых встроенных систем. Качество и разнообразие инструментов разработки / отладки для языков C и ассемблера также делают эти варианты привлекательными.